Přeskočit na hlavní obsah

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)

Output of the previous code cell

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)

Output of the previous code cell

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)

Output of the previous code cell

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

Doporučení