Skip to main content
IBM Quantum Platform

Créer un gestionnaire de passes pour un découplage dynamique

  • Le code de cette page a été développé en tenant compte des exigences suivantes. Nous recommandons d'utiliser ces versions ou des versions plus récentes.

    qiskit[all]~=2.5.1
    qiskit-ibm-runtime~=0.47.0
    

Cette page montre comment utiliser le PadDynamicalDecoupling pour ajouter au circuit une technique de suppression des erreurs appelée découplage dynamique.

Le découplage dynamique consiste à ajouter des séquences d'impulsions (connues sous le nom de séquences de découplage dynamique ) à des qubits inactifs pour les faire basculer autour de la sphère de Bloch, ce qui annule l'effet des canaux de bruit et supprime ainsi la décohérence. Ces séquences d'impulsions sont similaires aux impulsions de recentrage utilisées en résonance magnétique nucléaire. Pour une description complète, voir A Quantum Engineer's Guide to Superconducting Qubits.

Étant donné que la passe PadDynamicalDecoupling ne fonctionne que sur des circuits programmés et implique des portes qui ne sont pas nécessairement des portes de base de notre cible, vous aurez besoin des éléments suivants ALAPScheduleAnalysis et BasisTranslator également.

Récupérez les target informations dans le backend et enregistrez les noms des opérations sous le nom de basis_gates car le target devra être modifié afin d'y ajouter les informations de synchronisation pour les portes utilisées dans le découplage dynamique.

Note

Le backend FakeSherbrooke fictif de qiskit_ibm_runtime est utilisé dans ces exemples, mais vous pouvez l'essayer sur n'importe quel backend réel ou fictif compatible avec Qiskit. Vos résultats peuvent varier.

from qiskit_ibm_runtime.fake_provider import FakeSherbrooke

backend = FakeSherbrooke()

target = backend.target
basis_gates = list(target.operation_names)

Créez un circuit efficient_su2 à titre d'exemple. Tout d'abord, transpilez le circuit vers le backend car les impulsions de découplage dynamique doivent être ajoutées après que le circuit a été transpilé et programmé. Le découplage dynamique fonctionne souvent mieux lorsqu'il y a beaucoup de temps mort dans les circuits quantiques, c'est-à-dire lorsque des qubits ne sont pas utilisés alors que d'autres sont actifs. C'est le cas dans ce circuit parce que les portes ecr à deux qubits sont appliquées séquentiellement dans cet ansatz.

from qiskit.transpiler import generate_preset_pass_manager
from qiskit.circuit.library import efficient_su2

qc = efficient_su2(12, entanglement="circular", reps=1)
pm = generate_preset_pass_manager(1, target=target, seed_transpiler=12345)
qc_t = pm.run(qc)
qc_t.draw("mpl", fold=-1, idle_wires=False)

Output:

Output of the previous code cell

Une séquence de découplage dynamique est une série de portes qui composent l'identité et sont régulièrement espacées dans le temps. Par exemple, commencez par créer une séquence simple appelée XY4, composée de quatre portes.

from qiskit.circuit.library import XGate, YGate

X = XGate()
Y = YGate()

dd_sequence = [X, Y, X, Y]

En raison de la régularité des séquences de découplage dynamique, les informations relatives au YGate doivent être ajoutées au target car il ne s'agit pas d'une porte de base, contrairement au XGate . Nous savons a priori que le YGate a la même durée et la même erreur que le XGate, cependant, nous pouvons donc simplement récupérer ces propriétés à partir du target et les rajouter pour les YGate objets. C'est également la raison pour laquelle les basis_gates ont été enregistrés séparément, puisque nous ajoutons YGate l'instruction au target bien qu'il ne s'agisse pas d'une porte de base réelle de ibm_fez.

from qiskit.transpiler import InstructionProperties

y_gate_properties = {}
for qubit in range(target.num_qubits):
    y_gate_properties.update(
        {
            (qubit,): InstructionProperties(
                duration=target["x"][(qubit,)].duration,
                error=target["x"][(qubit,)].error,
            )
        }
    )

target.add_instruction(YGate(), y_gate_properties)

Les circuits d'Ansatz tels que efficient_su2 sont paramétrés, ils doivent donc être associés à une valeur avant d'être envoyés au backend. Il s'agit ici d'attribuer des paramètres aléatoires.

import numpy as np

rng = np.random.default_rng(1234)
qc_t.assign_parameters(
    rng.uniform(-np.pi, np.pi, qc_t.num_parameters), inplace=True
)

Ensuite, exécutez les passes personnalisées. Instanciez le site PassManager avec ALAPScheduleAnalysis et PadDynamicalDecoupling. Exécutez d'abord ALAPScheduleAnalysis pour ajouter des informations temporelles sur le circuit quantique avant d'ajouter les séquences de découplage dynamique régulièrement espacées. Ces passages sont effectués sur le circuit avec .run().

from qiskit.transpiler import PassManager
from qiskit.transpiler.passes.scheduling import (
    ALAPScheduleAnalysis,
    PadDynamicalDecoupling,
)

dd_pm = PassManager(
    [
        ALAPScheduleAnalysis(target=target),
        PadDynamicalDecoupling(target=target, dd_sequence=dd_sequence),
    ]
)
qc_dd = dd_pm.run(qc_t)

Utilisez l'outil de timeline_drawer visualisation pour voir la synchronisation du circuit et confirmer qu'une séquence régulièrement espacée XGate d'objets et YGate d'objets apparaît dans le circuit.

from qiskit.visualization import timeline_drawer

timeline_drawer(qc_dd, idle_wires=False, target=target)

Output:

Output of the previous code cell

Enfin, comme le site YGate n'est pas une porte de base réelle de notre backend, appliquez manuellement la passe BasisTranslator (il s'agit d'une passe par défaut, mais elle est exécutée avant l'ordonnancement, et doit donc être appliquée à nouveau). La bibliothèque d'équivalences de sessions est une bibliothèque d'équivalences de circuits qui permet au transpileur de décomposer les circuits en portes de base, également spécifiées en tant qu'argument.

from qiskit.circuit.equivalence_library import (
    SessionEquivalenceLibrary as sel,
)
from qiskit.transpiler.passes import BasisTranslator

qc_dd = BasisTranslator(sel, basis_gates)(qc_dd)
qc_dd.draw("mpl", fold=-1, idle_wires=False)

Output:

Output of the previous code cell

À présent, YGate les objets sont absents de notre circuit, et il existe des informations de synchronisation explicites sous la forme de Delay portes. Ce circuit transposé avec découplage dynamique est désormais prêt à être envoyé au backend.


Etapes suivantes

Recommandations
Cette page a-t-elle été utile ?
Signaler un bogue, une coquille ou proposer du contenu sur GitHub.