Creează un pass manager pentru decuplarea dinamică
Versiuni de pachete
Codul de pe această pagină a fost dezvoltat folosind următoarele cerințe. Îți recomandăm să folosești aceste versiuni sau unele mai noi.
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
Această pagină demonstrează cum să folosești pass-ul PadDynamicalDecoupling pentru a adăuga o tehnică de suprimare a erorilor numită decuplare dinamică (dynamical decoupling) în Circuit.
Decuplarea dinamică funcționează prin adăugarea de secvențe de impulsuri (cunoscute ca secvențe de decuplare dinamică) la Qubiți inactivi, pentru a-i roti în jurul sferei Bloch, ceea ce anulează efectul canalelor de zgomot, suprimând astfel decoerența. Aceste secvențe de impulsuri sunt similare cu impulsurile de refocalizare utilizate în rezonanța magnetică nucleară. Pentru o descriere completă, consultă A Quantum Engineer's Guide to Superconducting Qubits.
Deoarece pass-ul PadDynamicalDecoupling operează doar pe circuite planificate și implică Gate-uri care nu sunt neapărat Gate-uri de bază ale țintei noastre, vei avea nevoie și de pass-urile ALAPScheduleAnalysis și BasisTranslator.
Acest exemplu folosește ibm_fez, care a fost inițializat anterior. Obține informațiile despre target din backend și salvează numele operațiunilor ca basis_gates, deoarece target-ul va trebui modificat pentru a adăuga informații de sincronizare pentru Gate-urile utilizate în decuplarea dinamică.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
backend = service.backend("ibm_fez")
target = backend.target
basis_gates = list(target.operation_names)
Creează un Circuit efficient_su2 ca exemplu. Mai întâi, transpilează Circuit-ul pentru Backend, deoarece impulsurile de decuplare dinamică trebuie adăugate după ce Circuit-ul a fost transpilat și planificat. Decuplarea dinamică funcționează cel mai bine atunci când există mult timp inactiv în Circuit-urile cuantice — adică există Qubiți care nu sunt folosiți în timp ce alții sunt activi. Acesta este cazul în acest Circuit, deoarece Gate-urile ecr cu doi Qubiți sunt aplicate secvențial în acest 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)
O secvență de decuplare dinamică este o serie de Gate-uri care compun identitatea și sunt espaciate regulat în timp. De exemplu, începe prin a crea o secvență simplă numită XY4, formată din patru Gate-uri.
from qiskit.circuit.library import XGate, YGate
X = XGate()
Y = YGate()
dd_sequence = [X, Y, X, Y]
Datorită sincronizării regulate a secvențelor de decuplare dinamică, informațiile despre YGate trebuie adăugate la target, deoarece acesta nu este un Gate de bază, spre deosebire de XGate. Știm a priori că YGate are aceeași durată și eroare ca XGate, deci putem prelua acele proprietăți din target și le putem adăuga înapoi pentru obiectele YGate. De aceea basis_gates a fost salvat separat, deoarece adăugăm instrucțiunea YGate la target, deși nu este un Gate de bază real al lui 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)
Circuit-urile ansatz precum efficient_su2 sunt parametrizate, deci trebuie să li se asocieze valori înainte de a fi trimise la Backend. Aici, atribuie parametri aleatori.
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
)
În continuare, execută pass-urile personalizate. Instanțiază PassManager-ul cu ALAPScheduleAnalysis și PadDynamicalDecoupling. Rulează mai întâi ALAPScheduleAnalysis pentru a adăuga informații de sincronizare despre Circuit-ul cuantic, înainte ca secvențele de decuplare dinamică espaciate regulat să poată fi adăugate. Aceste pass-uri sunt rulate pe Circuit cu .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)
Folosește instrumentul de vizualizare timeline_drawer pentru a vedea sincronizarea Circuit-ului și pentru a confirma că o secvență espaciată regulat de obiecte XGate și YGate apare în Circuit.
from qiskit.visualization import timeline_drawer
timeline_drawer(qc_dd, idle_wires=False, target=target)
În final, deoarece YGate nu este un Gate de bază real al Backend-ului nostru, aplică manual pass-ul BasisTranslator (acesta este un pass implicit, dar este executat înainte de planificare, deci trebuie aplicat din nou). Biblioteca de echivalențe de sesiune este o bibliotecă de echivalențe de Circuit-uri care permite Transpiler-ului să descompună Circuit-urile în Gate-uri de bază, specificată și ea ca 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)
Acum, obiectele YGate sunt absente din Circuit-ul nostru și există informații explicite de sincronizare sub forma Gate-urilor Delay. Acest Circuit transpilat cu decuplare dinamică este acum gata să fie trimis la Backend.
Pașii următori
- Pentru a afla cum să folosești funcția
generate_preset_passmanagerîn loc să îți scrii propriile pass-uri, începe cu subiectul Setările implicite de transpilare și opțiunile de configurare. - Încearcă ghidul Compară setările Transpiler-ului.
- Consultă documentația API pentru Transpile.