ข้ามไปยังเนื้อหาหลัก

สร้าง pass manager สำหรับ dynamical decoupling

เวอร์ชันของ package

โค้ดในหน้านี้พัฒนาโดยใช้ requirement ต่อไปนี้ แนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1

หน้านี้สาธิตวิธีใช้ pass PadDynamicalDecoupling เพื่อเพิ่มเทคนิคการยับยั้งข้อผิดพลาดที่เรียกว่า dynamical decoupling ให้กับ Circuit

Dynamical decoupling ทำงานโดยการเพิ่ม pulse sequence (เรียกว่า dynamical decoupling sequence) ให้กับ Qubit ที่ว่างอยู่เพื่อพลิกรอบ Bloch sphere ซึ่งยกเลิกผลของ noise channel ทำให้ลด decoherence ได้ pulse sequence เหล่านี้คล้ายกับ refocusing pulse ที่ใช้ใน nuclear magnetic resonance สำหรับคำอธิบายเต็มรูปแบบ ดู A Quantum Engineer's Guide to Superconducting Qubits

เนื่องจาก pass PadDynamicalDecoupling ทำงานเฉพาะกับ scheduled circuit และมี Gate ที่ไม่ได้เป็น basis gate ของ target จึงต้องใช้ pass ALAPScheduleAnalysis และ BasisTranslator ด้วย

ตัวอย่างนี้ใช้ ibm_fez ที่เริ่มต้นไว้แล้วก่อนหน้านี้ ดึงข้อมูล target จาก backend และบันทึกชื่อ operation เป็น basis_gates เพราะ target จะต้องถูกแก้ไขเพื่อเพิ่มข้อมูล timing สำหรับ Gate ที่ใช้ใน dynamical decoupling

# 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)

สร้าง Circuit efficient_su2 เป็นตัวอย่าง ขั้นแรก transpile Circuit ไปยัง Backend เพราะ dynamical decoupling pulse ต้องเพิ่มหลังจาก Circuit ถูก transpile และ scheduled แล้ว Dynamical decoupling มักทำงานได้ดีที่สุดเมื่อมี idle time มากใน quantum circuit กล่าวคือ มี Qubit ที่ไม่ได้ใช้งานในขณะที่ Qubit อื่นๆ กำลังทำงาน กรณีนี้เกิดขึ้นใน Circuit นี้เพราะ ecr Gate แบบ two-qubit ถูกนำไปใช้ตามลำดับใน 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 of the previous code cell

dynamical decoupling sequence คือชุดของ Gate ที่ประกอบกันเป็น identity และเว้นระยะห่างสม่ำเสมอตามเวลา ตัวอย่างเช่น เริ่มต้นด้วยการสร้าง sequence ง่ายๆ ชื่อ XY4 ที่ประกอบด้วย Gate สี่ตัว

from qiskit.circuit.library import XGate, YGate

X = XGate()
Y = YGate()

dd_sequence = [X, Y, X, Y]

เนื่องจาก timing ของ dynamical decoupling sequence มีระยะสม่ำเสมอ จึงต้องเพิ่มข้อมูลเกี่ยวกับ YGate ลงใน target เพราะ YGate ไม่ใช่ basis gate ในขณะที่ XGate เป็น อย่างไรก็ตาม เรารู้ ล่วงหน้า ว่า YGate มี duration และ error เดียวกันกับ XGate จึงสามารถดึง property เหล่านั้นจาก target และเพิ่มกลับสำหรับ object YGate ได้ นี่คือสาเหตุที่บันทึก basis_gates แยกไว้ด้วย เนื่องจากเราเพิ่มคำสั่ง YGate ลงใน target แม้ว่ามันไม่ใช่ basis 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)

Circuit ansatz เช่น efficient_su2 เป็นแบบ parameterized จึงต้องผูกค่าก่อนส่งไปยัง Backend ที่นี่กำหนด parameter แบบสุ่ม

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
)

ขั้นต่อไป รัน custom pass สร้าง PassManager ด้วย ALAPScheduleAnalysis และ PadDynamicalDecoupling รัน ALAPScheduleAnalysis ก่อนเพื่อเพิ่มข้อมูล timing ของ quantum circuit ก่อนที่จะเพิ่ม dynamical decoupling sequence ที่มีระยะสม่ำเสมอได้ pass เหล่านี้รันบน Circuit ด้วย .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)

ใช้เครื่องมือ visualization timeline_drawer เพื่อดู timing ของ Circuit และยืนยันว่า sequence ของ object XGate และ YGate ที่มีระยะห่างสม่ำเสมอปรากฏใน Circuit

from qiskit.visualization import timeline_drawer

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

Output of the previous code cell

สุดท้าย เนื่องจาก YGate ไม่ใช่ basis gate จริงของ Backend นำ pass BasisTranslator ไปใช้ด้วยตนเอง (เป็น pass เริ่มต้น แต่รันก่อน scheduling จึงต้องนำไปใช้อีกครั้ง) session equivalence library คือ library ของ circuit equivalence ที่ช่วยให้ Transpiler แยกวิเคราะห์ Circuit เป็น basis gate ตามที่ระบุเป็น 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

ตอนนี้ object YGate หายไปจาก Circuit แล้ว และมีข้อมูล timing ที่ชัดเจนในรูปของ Delay Gate Circuit ที่ transpile แล้วพร้อม dynamical decoupling นี้พร้อมส่งไปยัง Backend แล้ว

ขั้นตอนถัดไป

คำแนะนำ
Source: IBM Quantum docs — updated 1 เม.ย. 2569
English version on doQumentation — updated 7 พ.ค. 2569
This translation based on the English version of 11 มี.ค. 2569