Transpiler avec des gestionnaires de passes
Versions des packages
Le code de cette page a été développé avec les dépendances suivantes. Nous recommandons d'utiliser ces versions ou des versions plus récentes.
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
La méthode recommandée pour transpiler un circuit est de créer un gestionnaire de passes par étapes, puis d'exécuter sa méthode run avec le circuit en entrée. Cette page explique comment transpiler des circuits quantiques de cette façon.
Qu'est-ce qu'un gestionnaire de passes (par étapes) ?
Dans le contexte du SDK Qiskit, la transpilation désigne le processus de transformation d'un circuit d'entrée en une forme adaptée à l'exécution sur un appareil quantique. La transpilation se déroule généralement en une séquence d'étapes appelées passes de transpilation. Le circuit est traité par chaque passe de transpilation dans l'ordre, la sortie d'une passe devenant l'entrée de la suivante. Par exemple, une passe pourrait parcourir le circuit et fusionner toutes les séquences consécutives de portes à un seul qubit, puis la passe suivante pourrait synthétiser ces portes dans l'ensemble de base de l'appareil cible. Les passes de transpilation incluses avec Qiskit se trouvent dans le module qiskit.transpiler.passes.
Un gestionnaire de passes est un objet qui stocke une liste de passes de transpilation et peut les exécuter sur un circuit. Pour créer un gestionnaire de passes, initialise un PassManager avec une liste de passes de transpilation. Pour lancer la transpilation sur un circuit, appelle la méthode run avec un circuit en entrée.
Un gestionnaire de passes par étapes est un type particulier de gestionnaire de passes qui représente un niveau d'abstraction supérieur à celui d'un gestionnaire de passes ordinaire. Alors qu'un gestionnaire de passes ordinaire est composé de plusieurs passes de transpilation, un gestionnaire de passes par étapes est composé de plusieurs gestionnaires de passes. C'est une abstraction utile, car la transpilation se déroule généralement en étapes discrètes, comme décrit dans Étapes du transpiler, chaque étape étant représentée par un gestionnaire de passes. Les gestionnaires de passes par étapes sont représentés par la classe StagedPassManager. Le reste de cette page décrit comment créer et personnaliser des gestionnaires de passes (par étapes).
Générer un gestionnaire de passes par étapes prédéfini
Pour créer un gestionnaire de passes par étapes prédéfini avec des paramètres raisonnables par défaut, utilise la fonction generate_preset_pass_manager :
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
backend = service.backend("ibm_fez")
pass_manager = generate_preset_pass_manager(
optimization_level=3, backend=backend
)
Pour transpiler un circuit ou une liste de circuits avec un gestionnaire de passes, passe le circuit ou la liste de circuits à la méthode run. Faisons-le sur un circuit à deux qubits composé d'une porte Hadamard suivie de deux portes CX adjacentes :
from qiskit import QuantumRegister, QuantumCircuit
# Create a circuit
qubits = QuantumRegister(2, name="q")
circuit = QuantumCircuit(qubits)
a, b = qubits
circuit.h(a)
circuit.cx(a, b)
circuit.cx(b, a)
# Transpile it by calling the run method of the pass manager
transpiled = pass_manager.run(circuit)
# Draw it, excluding idle qubits from the diagram
transpiled.draw("mpl", idle_wires=False)
Consulte Paramètres par défaut et options de configuration de la transpilation pour une description des arguments possibles de la fonction generate_preset_pass_manager. Les arguments de generate_preset_pass_manager correspondent aux arguments de la fonction transpile.
Si les gestionnaires de passes prédéfinis ne répondent pas à tes besoins, personnalise la transpilation en créant des gestionnaires de passes (par étapes) ou même des passes de transpilation. Le reste de cette page décrit comment créer des gestionnaires de passes. Pour savoir comment créer des passes de transpilation, consulte Écrire ta propre passe de transpilation.
Créer ton propre gestionnaire de passes
Le module qiskit.transpiler.passes inclut de nombreuses passes de transpilation qui peuvent être utilisées pour créer des gestionnaires de passes. Pour créer un gestionnaire de passes, initialise un PassManager avec une liste de passes. Par exemple, le code suivant crée une passe de transpilation qui fusionne les portes adjacentes à deux qubits, puis les synthétise dans une base de portes , et .
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import (
Collect2qBlocks,
ConsolidateBlocks,
UnitarySynthesis,
)
basis_gates = ["rx", "ry", "rxx"]
translate = PassManager(
[
Collect2qBlocks(),
ConsolidateBlocks(basis_gates=basis_gates),
UnitarySynthesis(basis_gates),
]
)
Pour illustrer ce gestionnaire de passes en action, teste-le sur un circuit à deux qubits composé d'une porte Hadamard suivie de deux portes CX adjacentes :
from qiskit import QuantumRegister, QuantumCircuit
qubits = QuantumRegister(2, name="q")
circuit = QuantumCircuit(qubits)
a, b = qubits
circuit.h(a)
circuit.cx(a, b)
circuit.cx(b, a)
circuit.draw("mpl")
Pour exécuter le gestionnaire de passes sur le circuit, appelle la méthode run.
translated = translate.run(circuit)
translated.draw("mpl")
Pour un exemple plus avancé montrant comment créer un gestionnaire de passes afin d'implémenter la technique de suppression d'erreurs connue sous le nom de découplage dynamique, consulte Créer un gestionnaire de passes pour le découplage dynamique.
Créer un gestionnaire de passes par étapes
Un StagedPassManager est un gestionnaire de passes composé d'étapes individuelles, où chaque étape est définie par une instance de PassManager. Tu peux créer un StagedPassManager en spécifiant les étapes souhaitées. Par exemple, le code suivant crée un gestionnaire de passes par étapes avec deux étapes, init et translation. L'étape translation est définie par le gestionnaire de passes créé précédemment.
from qiskit.transpiler import PassManager, StagedPassManager
from qiskit.transpiler.passes import UnitarySynthesis, Unroll3qOrMore
basis_gates = ["rx", "ry", "rxx"]
init = PassManager(
[UnitarySynthesis(basis_gates, min_qubits=3), Unroll3qOrMore()]
)
staged_pm = StagedPassManager(
stages=["init", "translation"], init=init, translation=translate
)
Il n'y a pas de limite au nombre d'étapes que tu peux ajouter dans un gestionnaire de passes par étapes.
Une autre façon utile de créer un gestionnaire de passes par étapes est de commencer par un gestionnaire de passes par étapes prédéfini, puis de remplacer certaines étapes. Par exemple, le code suivant génère un gestionnaire de passes prédéfini avec le niveau d'optimisation 3, puis spécifie une étape pre_layout personnalisée.
import numpy as np
from qiskit.circuit.library import HGate, PhaseGate, RXGate, TdgGate, TGate
from qiskit.transpiler.passes import InverseCancellation
pass_manager = generate_preset_pass_manager(3, backend)
inverse_gate_list = [
HGate(),
(RXGate(np.pi / 4), RXGate(-np.pi / 4)),
(PhaseGate(np.pi / 4), PhaseGate(-np.pi / 4)),
(TGate(), TdgGate()),
]
logical_opt = PassManager(
[
InverseCancellation(inverse_gate_list),
]
)
# Add pre-layout stage to run extra logical optimization
pass_manager.pre_layout = logical_opt
Les fonctions de génération d'étapes peuvent être utiles pour construire des gestionnaires de passes personnalisés.
Elles génèrent des étapes qui fournissent des fonctionnalités courantes utilisées dans de nombreux gestionnaires de passes.
Par exemple, generate_embed_passmanager peut être utilisé pour générer une étape permettant d'« incorporer » un Layout initial sélectionné à partir d'une passe de placement vers l'appareil cible spécifié.
Étapes suivantes
- Écrire une passe de transpilation personnalisée.
- Créer un gestionnaire de passes pour le découplage dynamique.
- Pour en savoir plus sur la fonction
generate_preset_passmanager, consulte la rubrique Paramètres par défaut et options de configuration de la transpilation. - Essaie le guide Comparer les paramètres du transpiler.
- Consulte la documentation de l'API du transpiler.