Représenter les ordinateurs quantiques pour le transpileur
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
Pour convertir un circuit abstrait en circuit ISA pouvant s'exécuter sur un QPU (unité de traitement quantique) spécifique, le transpileur a besoin de certaines informations sur ce QPU. Ces informations se trouvent à deux endroits : l'objet BackendV2 (ou l'ancien BackendV1) vers lequel tu prévois de soumettre des jobs, et l'attribut Target du backend.
- Le
Targetcontient toutes les contraintes pertinentes d'un appareil, telles que ses portes de base natives, la connectivité des qubits, et les informations d'impulsion ou de timing. - Le
Backendpossède unTargetpar défaut, contient des informations supplémentaires — comme l'InstructionScheduleMap— et fournit l'interface pour soumettre des jobs de circuit quantique.
Tu peux également fournir explicitement des informations au transpileur, par exemple si tu as un cas d'usage spécifique, ou si tu penses que ces informations l'aideront à générer un circuit plus optimisé.
La précision avec laquelle le transpileur produit le circuit le plus adapté à un matériel spécifique dépend de la quantité d'informations sur ses contraintes que contient le Target ou le Backend.
Comme beaucoup des algorithmes de transpilation sous-jacents sont stochastiques, il n'est pas garanti qu'un meilleur circuit sera trouvé.
Cette page présente plusieurs exemples de transmission d'informations QPU au transpileur. Ces exemples utilisent la cible du backend fictif FakeSherbrooke.
Configuration par défaut
La façon la plus simple d'utiliser le transpileur est de lui fournir toutes les informations sur le QPU via le Backend ou le Target. Pour mieux comprendre comment fonctionne le transpileur, construis un circuit et transpile-le avec différentes informations, comme suit.
Importe les bibliothèques nécessaires et instancie le QPU :
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
backend = FakeSherbrooke()
target = backend.target
L'exemple de circuit utilise une instance d'efficient_su2 de la bibliothèque de circuits de Qiskit.
from qiskit.circuit.library import efficient_su2
qc = efficient_su2(12, entanglement="circular", reps=1)
qc.draw("mpl")
Cet exemple utilise les paramètres par défaut pour transpiler vers le target du backend, qui fournit toutes les informations nécessaires pour convertir le circuit en un circuit pouvant s'exécuter sur le backend.
from qiskit.transpiler import generate_preset_pass_manager
pass_manager = generate_preset_pass_manager(
optimization_level=1, target=target, seed_transpiler=12345
)
qc_t_target = pass_manager.run(qc)
qc_t_target.draw("mpl", idle_wires=False, fold=-1)
Cet exemple est utilisé dans les sections suivantes de ce sujet pour illustrer que la carte de couplage et les portes de base sont les informations essentielles à transmettre au transpileur pour une construction optimale du circuit. Le QPU peut généralement sélectionner des paramètres par défaut pour les autres informations non transmises, comme le timing et la planification.
Carte de couplage
La carte de couplage est un graphe qui montre quels qubits sont connectés et donc disposent de portes à deux qubits entre eux. Ce graphe est parfois directionnel, ce qui signifie que les portes à deux qubits ne peuvent aller que dans un seul sens. Cependant, le transpileur peut toujours inverser la direction d'une porte en ajoutant des portes à qubit unique supplémentaires. Un circuit quantique abstrait peut toujours être représenté sur ce graphe, même si sa connectivité est limitée, en introduisant des portes SWAP pour déplacer l'information quantique.
Les qubits de nos circuits abstraits sont appelés qubits virtuels et ceux de la carte de couplage sont des qubits physiques. Le transpileur fournit une correspondance entre les qubits virtuels et les qubits physiques. L'une des premières étapes de la transpilation, l'étape de layout, effectue cette correspondance.
Bien que l'étape de routage soit étroitement liée à l'étape de layout — qui sélectionne les qubits réels — par défaut, ce sujet les traite comme des étapes séparées pour simplifier. La combinaison du routage et du layout est appelée mapping de qubits. Pour en savoir plus sur ces étapes, consulte le sujet Étapes du transpileur.
Passe l'argument nommé coupling_map pour voir son effet sur le transpileur :
coupling_map = target.build_coupling_map()
pass_manager = generate_preset_pass_manager(
optimization_level=0, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv0 = pass_manager.run(qc)
qc_t_cm_lv0.draw("mpl", idle_wires=False, fold=-1)
Comme indiqué ci-dessus, plusieurs portes SWAP ont été insérées (chacune composée de trois portes CX), ce qui entraînera beaucoup d'erreurs sur les appareils actuels. Pour voir quels qubits sont sélectionnés sur la topologie réelle des qubits, utilise plot_circuit_layout des visualisations Qiskit :
from qiskit.visualization import plot_circuit_layout
plot_circuit_layout(qc_t_cm_lv0, backend, view="physical")
Cela montre que nos qubits virtuels 0 à 11 ont été trivialement mappés à la ligne de qubits physiques 0 à 11. Revenons au niveau par défaut (optimization_level=1), qui utilise VF2Layout si un routage est nécessaire.
pass_manager = generate_preset_pass_manager(
optimization_level=1, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv1 = pass_manager.run(qc)
qc_t_cm_lv1.draw("mpl", idle_wires=False, fold=-1)
À présent, aucune porte SWAP n'est insérée et les qubits physiques sélectionnés sont les mêmes qu'avec la classe target.
from qiskit.visualization import plot_circuit_layout
plot_circuit_layout(qc_t_cm_lv1, backend, view="physical")
Maintenant le layout est en anneau. Comme ce layout respecte la connectivité du circuit, il n'y a aucune porte SWAP, ce qui donne un circuit bien meilleur pour l'exécution.
Portes de base
Chaque ordinateur quantique prend en charge un ensemble d'instructions limité, appelé ses portes de base. Chaque porte du circuit doit être traduite en éléments de cet ensemble. Cet ensemble doit être composé de portes à un et deux qubits qui forment un ensemble de portes universel, ce qui signifie que toute opération quantique peut être décomposée en ces portes. Cette opération est effectuée par le BasisTranslator, et les portes de base peuvent être spécifiées comme argument nommé du transpileur pour fournir cette information.
basis_gates = list(target.operation_names)
print(basis_gates)
['sx', 'switch_case', 'x', 'if_else', 'measure', 'for_loop', 'delay', 'ecr', 'id', 'reset', 'rz']
Les portes à qubit unique par défaut sur ibm_sherbrooke sont rz, x et sx, et la porte à deux qubits par défaut est ecr (echoed cross-resonance). Les portes CX sont construites à partir de portes ecr, donc sur certains QPUs, ecr est spécifiée comme porte de base à deux qubits, tandis que sur d'autres, cx est la valeur par défaut. La porte ecr est la partie d'intrication de la porte cx. En plus des portes de contrôle, il y a aussi des instructions delay et measurement.
Les QPUs ont des portes de base par défaut, mais tu peux choisir les portes que tu veux, du moment que tu fournis l'instruction ou que tu ajoutes des portes d'impulsion (voir Créer des passes de transpilation.). Les portes de base par défaut sont celles pour lesquelles des calibrations ont été effectuées sur le QPU, donc aucune instruction supplémentaire ni porte d'impulsion n'est nécessaire. Par exemple, sur certains QPUs cx est la porte à deux qubits par défaut et ecr sur d'autres. Consulte la liste des portes et opérations natives possibles pour plus de détails.
pass_manager = generate_preset_pass_manager(
optimization_level=1,
coupling_map=coupling_map,
basis_gates=basis_gates,
seed_transpiler=12345,
)
qc_t_cm_bg = pass_manager.run(qc)
qc_t_cm_bg.draw("mpl", idle_wires=False, fold=-1)
Note que les objets CXGate ont été décomposés en portes ecr et en portes de base à qubit unique.
Taux d'erreur de l'appareil
La classe Target peut contenir des informations sur les taux d'erreur des opérations sur l'appareil.
Par exemple, le code suivant récupère les propriétés de la porte echoed cross-resonance (ECR) entre le qubit 1 et le qubit 0 (note que la porte ECR est directionnelle) :
target["ecr"][(1, 0)]
InstructionProperties(duration=5.333333333333332e-07, error=0.007494257741828603)
La sortie affiche la durée de la porte (en secondes) et son taux d'erreur. Pour révéler les informations d'erreur au transpileur, construis un modèle de cible avec les basis_gates et la coupling_map ci-dessus et remplis-le avec les valeurs d'erreur du backend FakeSherbrooke.
from qiskit.transpiler import Target
from qiskit.circuit.controlflow import IfElseOp, SwitchCaseOp, ForLoopOp
err_targ = Target.from_configuration(
basis_gates=basis_gates,
coupling_map=coupling_map,
num_qubits=target.num_qubits,
custom_name_mapping={
"if_else": IfElseOp,
"switch_case": SwitchCaseOp,
"for_loop": ForLoopOp,
},
)
for i, (op, qargs) in enumerate(target.instructions):
if op.name in basis_gates:
err_targ[op.name][qargs] = target.instruction_properties(i)
Transpile avec notre nouvelle cible err_targ en tant que cible :
pass_manager = generate_preset_pass_manager(
optimization_level=1, target=err_targ, seed_transpiler=12345
)
qc_t_cm_bg_et = pass_manager.run(qc)
qc_t_cm_bg_et.draw("mpl", idle_wires=False, fold=-1)
Comme la cible inclut des informations sur les erreurs, la passe VF2PostLayout tente de trouver les qubits optimaux à utiliser, ce qui donne le même circuit que celui trouvé initialement avec les mêmes qubits physiques.
Étapes suivantes
- Comprendre les paramètres par défaut et options de configuration de la transpilation.
- Consulter le sujet Paramètres couramment utilisés pour la transpilation.
- Essayer le guide Comparer les paramètres du transpileur.
- Voir la documentation API de Transpile.