Skip to main content
IBM Quantum Platform

Démarrage rapide

Ce guide présente un exemple minimal fonctionnel du paquet qiskit-addon-obp . Nous utilisons la rétropropagation des opérateurs (OBP) pour réduire la profondeur d'un circuit quantique en intégrant les portes de fin dans l'observable.

Une valeur attendue ⟨O⟩=⟨ψ∣U†OU∣ψ⟩\langle O \rangle = \langle \psi | U^\dagger O U | \psi \rangle reste inchangée si l'on retire un bloc de portes situé à la fin du circuit UU et si l'on effectue la conjugaison classique de l'observable par rapport à ce bloc. OBP applique cette méthode à plusieurs reprises, en évaluant une partie du circuit de manière classique afin que seul un circuit moins complexe soit exécuté sur le matériel. Le prix à payer est que chaque porte absorbée peut décomposer l'observable en un plus grand nombre de termes de Pauli; il faut donc mettre en balance le gain en profondeur obtenu et l'augmentation de la complexité de l'observable.

Pour découvrir des exemples illustrant comment créer des workflows réalistes à l'aide de cet outil et les exécuter sur du matériel quantique, consultez les tutoriels disponibles sur la plateforme « IBM Quantum Platform » ( Tutoriel OBP ).


Préparer les données pour l'OBP

L'OBP prend en entrée une liste de tranches de circuit et une observable. Il effectue une rétropropagation des tranches une par une, depuis la fin du circuit vers l'observable, ce qui réduit la profondeur du circuit au prix de l'ajout de termes de Pauli supplémentaires dans l'observable. Nous générons ici un circuit d'évolution temporelle pour un modèle de Heisenberg à 10 qubits et le découpons par type de porte.

Nous représentons ci-dessous le circuit d'origine, puis ce même circuit en version modifiée, avec des barrières marquant les limites des tranches — chaque tranche constituant une unité pouvant être intégrée à l'observable en une seule étape de rétropropagation.

import numpy as np
from qiskit.quantum_info import SparsePauliOp
from qiskit.synthesis import LieTrotter
from qiskit.transpiler import CouplingMap
from qiskit_addon_utils.problem_generators import (
    generate_time_evolution_circuit,
    generate_xyz_hamiltonian,
)
from qiskit_addon_utils.slicing import combine_slices, slice_by_gate_types

# Generate a circuit to reduce
coupling_map = CouplingMap.from_heavy_hex(3, bidirectional=False)
reduced_coupling_map = coupling_map.reduce(
    [0, 13, 1, 14, 10, 16, 5, 12, 8, 18]
)

hamiltonian = generate_xyz_hamiltonian(
    reduced_coupling_map,
    coupling_constants=(np.pi / 8, np.pi / 4, np.pi / 2),
    ext_magnetic_field=(np.pi / 3, np.pi / 6, np.pi / 9),
)

circuit = generate_time_evolution_circuit(
    hamiltonian,
    time=0.2,
    synthesis=LieTrotter(reps=2),
)

# Slice the circuit and define an observable
slices = slice_by_gate_types(circuit)
observable = SparsePauliOp("IIIIIIIIIZ")

print(f"Original circuit depth: {circuit.depth()}")
print(f"Number of slices: {len(slices)}")
print(f"Observable terms: {len(observable)}")

Output:

Original circuit depth: 18
Number of slices: 18
Observable terms: 1
# Recombine the slices with barriers to make the slice boundaries visible
sliced_circuit = combine_slices(slices, include_barriers=True)

print("Original circuit:")
display(circuit.draw("mpl", scale=0.6, fold=-1))
print("Sliced circuit (recombined with barriers for visualization)")
sliced_circuit.draw("mpl", scale=0.6, fold=-1)

Output:

Original circuit:
Output of the previous code cell
Sliced circuit (recombined with barriers for visualization)
Output of the previous code cell

Réduire la profondeur du circuit grâce à l'OBP

Nous appelons backpropagate cela « intégrer des tranches » dans l'observable. La fonction renvoie l'observable développé, les tranches de circuit qui n'ont pas été propagées, ainsi que les métadonnées relatives à la procédure.

Si on ne fait rien, l'observable peut tendre vers des termes d' 2n2^n -Pauli. Cette limite operator_budget restreint cette croissance : ici, nous autorisons au maximum 8 groupes commutatifs au niveau des qubits, ce qui détermine approximativement le nombre d'itérations nécessaires pour évaluer l'observable sur le QPU. La rétropropagation s'arrête dès que l'absorption de la tranche suivante dépasserait le budget, ce qui est exactement ce qui se passe ci-dessous : seules 7 des 18 tranches sont absorbées avant que l'observable ne remplisse les 8 groupes de commutation et que la procédure ne s'arrête.

Pour approfondir l'analyse du circuit, l'argument « keyword truncation_error_budget » de peut backpropagate être utilisé pour éliminer les termes de Pauli à faible coefficient de l'observable à mesure que celle-ci augmente. Cela atténue la croissance de la grandeur observable, au prix d'une erreur proportionnelle à l'amplitude des termes de Pauli qui sont tronqués. Ces deux budgets sont complémentaires et peuvent être utilisés conjointement : permet de operator_budget contrôler la taille de la grandeur observable, tandis que permet de truncation_error_budget contrôler l' erreur induite par la suppression de certains termes.

from qiskit_addon_obp import backpropagate
from qiskit_addon_obp.utils.simplify import OperatorBudget

max_qwc_groups = 8
bp_obs, remaining_slices, metadata = backpropagate(
    observable,
    slices,
    operator_budget=OperatorBudget(max_qwc_groups=max_qwc_groups),
)

reduced_circuit = combine_slices(remaining_slices)
num_groups = len(bp_obs.group_commuting(qubit_wise=True))

print(
    f"Backpropagated {metadata.num_backpropagated_slices} of {len(slices)} slices."
)
print(
    f"Reduced circuit depth: {reduced_circuit.depth()} (was {circuit.depth()})"
)
print(f"Observable grew from {len(observable)} to {len(bp_obs)} Pauli terms.")
print(
    f"Filled {num_groups} of {max_qwc_groups} commuting groups, exhausting the budget."
)

Output:

Backpropagated 7 of 18 slices.
Reduced circuit depth: 11 (was 18)
Observable grew from 1 to 18 Pauli terms.
Filled 8 of 8 commuting groups, exhausting the budget.
reduced_circuit.draw("mpl", scale=0.6, fold=-1)

Output:

Output of the previous code cell
Cette page a-t-elle été utile ?
Signaler un bogue, une coquille ou proposer du contenu sur GitHub.