Vytvoření pass manageru pro dynamické oddělení
Verze balíčků
Kód na této stránce byl vyvinut s použitím následujících závislostí. Doporučujeme používat tyto verze nebo novější.
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
Tato stránka ukazuje, jak použít pass PadDynamicalDecoupling k přidání techniky potlačení chyb zvané dynamické oddělení (dynamical decoupling) do obvodu.
Dynamické oddělení funguje tak, že k nečinným Qubitům přidává pulzní sekvence (známé jako sekvence dynamického oddělení), které je překlápějí kolem Blochovy sféry. Tím se ruší vliv šumových kanálů a potlačuje se dekohérence. Tyto pulzní sekvence jsou podobné refokusačním pulzům používaným v nukleární magnetické rezonanci. Úplný popis najdeš v článku A Quantum Engineer's Guide to Superconducting Qubits.
Protože pass PadDynamicalDecoupling pracuje pouze s naplánovanými obvody a zahrnuje Gate, které nemusejí být bázovými Gate našeho cíle, budeš potřebovat také passy ALAPScheduleAnalysis a BasisTranslator.
Tento příklad používá ibm_fez, který byl inicializován dříve. Získej informace target z backend a ulož názvy operací jako basis_gates, protože target bude potřeba upravit tak, aby obsahoval informace o načasování Gate používaných při dynamickém oddělení.
# 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)
Vytvoř Circuit efficient_su2 jako příklad. Nejprve transpiluj Circuit na Backend, protože pulzy dynamického oddělení je nutné přidat až po transpilaci a naplánování obvodu. Dynamické oddělení obvykle funguje nejlépe tehdy, když je v kvantových obvodech mnoho doby nečinnosti – tedy když některé Qubity nejsou používány, zatímco jiné jsou aktivní. To je případ tohoto obvodu, protože dvoQubitové Gate ecr jsou v tomto ansatzu aplikovány postupně.
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)
Sekvence dynamického oddělení je řada Gate, jejichž složením vznikne identita a které jsou v čase rozmístěny rovnoměrně. Například začni vytvořením jednoduché sekvence zvané XY4 skládající se ze čtyř Gate.
from qiskit.circuit.library import XGate, YGate
X = XGate()
Y = YGate()
dd_sequence = [X, Y, X, Y]
Kvůli pravidelnému načasování sekvencí dynamického oddělení je nutné do target přidat informace o YGate, protože to není bázový Gate, zatímco XGate jím je. Víme však a priori, že YGate má stejnou dobu trvání a chybovost jako XGate, takže tyto vlastnosti stačí načíst z target a přidat je zpět pro objekty YGate. Proto také byly basis_gates uloženy zvlášť – přidáváme instrukci YGate do target, přestože to není skutečný bázový Gate 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)
Ansatzové Circuit jako efficient_su2 jsou parametrizované, takže jim musí být před odesláním na Backend přiřazeny hodnoty. Zde přiřaď náhodné parametry.
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
)
Dále spusť vlastní passy. Inicializuj PassManager s ALAPScheduleAnalysis a PadDynamicalDecoupling. Spusť nejprve ALAPScheduleAnalysis, aby byly do kvantového obvodu přidány informace o načasování, a teprve poté lze přidat rovnoměrně rozmístěné sekvence dynamického oddělení. Tyto passy se spustí na obvodu pomocí .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)
Pomocí vizualizačního nástroje timeline_drawer si zobraz načasování obvodu a ověř, že se v obvodu objevuje rovnoměrně rozmístěná sekvence objektů XGate a YGate.
from qiskit.visualization import timeline_drawer
timeline_drawer(qc_dd, idle_wires=False, target=target)
Nakonec, protože YGate není skutečným bázovým Gate našeho Backend, ručně aplikuj pass BasisTranslator (jde o výchozí pass, ale ten se spouští před plánováním, takže je nutné ho aplikovat znovu). Knihovna ekvivalencí session je knihovnou ekvivalencí obvodů, která umožňuje Transpileru rozložit Circuit do bázových Gate – ta je také zadána jako 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)
Nyní jsou objekty YGate z našeho obvodu odstraněny a místo nich jsou explicitní informace o načasování v podobě Gate Delay. Tento transpilovaný Circuit s dynamickým oddělením je nyní připraven k odeslání na Backend.
Další kroky
- Chceš-li se naučit, jak používat funkci
generate_preset_passmanagermísto psaní vlastních passů, začni tématem Výchozí nastavení a možnosti konfigurace Transpileru. - Vyzkoušej průvodce Porovnání nastavení Transpileru.
- Viz dokumentace rozhraní Transpile API.