รัน dynamic circuits
เวอร์ชันแพ็กเกจ
โค้ดในหน้านี้พัฒนาโดยใช้ requirements ต่อไปนี้ แนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า
qiskit[all]~=2.4.0
qiskit-ibm-runtime~=0.46.1
Dynamic circuits เป็นเครื่องมือที่ทรงพลังที่คุณสามารถวัด qubits ระหว่างการรัน quantum circuit และดำเนินการ logic แบบ classical ภายใน circuit ตามผลของการวัดระหว่าง circuit เหล่านั้น กระบวนการนี้เรียกอีกอย่างว่า classical feedforward แม้ว่านี่จะเป็นช่วงแรกของการทำความเข้าใจวิธีใช้ประโยชน์จาก dynamic circuits ชุมชนวิจัย quantum ได้ระบุกรณีการใช้งานหลายอย่าง เช่น:
- การเตรียม quantum state ที่มีประสิทธิภาพ เช่น GHZ state, W-state (สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ W-state ดูที่ "State preparation by shallow circuits using feed forward") และ matrix product states ประเภทกว้างๆ
- Long-range entanglement ที่มีประสิทธิภาพ ระหว่าง qubits บน chip เดียวกันโดยใช้ shallow circuits
- การสุ่มตัวอย่าง IQP-like circuits ที่มีประสิทธิภาพ
อย่างไรก็ตาม การปรับปรุงเหล่านี้ที่ dynamic circuits นำมาพร้อมกับการแลกเปลี่ยน การวัดระหว่าง circuit และ classical operations โดยทั่วไปมีเวลาดำเนินการนานกว่า two-qubit gates และการเพิ่มขึ้นของเวลานี้อาจทำให้ประโยชน์ของ circuit depth ที่ลดลงหายไป ดังนั้น การลดความยาวของการวัดระหว่าง circuit จึงเป็นพื้นที่เน้นของการปรับปรุงเมื่อ IBM Quantum® เผยแพร่ เวอร์ชันใหม่ ของ dynamic circuits สำหรับข้อจำกัดอื่นๆ เมื่อใช้ dynamic circuits ดู Feature compatibility table ของ Estimator หรือ Sampler
OpenQASM 3 specification กำหนดโครงสร้าง control-flow หลายอย่าง แต่ Qiskit Runtime รองรับเฉพาะคำสั่ง conditional if เท่านั้น ใน Qiskit SDK สิ่งนี้สอดคล้องกับเมธอด if_test บน QuantumCircuit เมธอดนี้ส่งคืน context manager และโดยทั่วไปใช้ใน with statement คู่มือนี้อธิบายวิธีใช้ conditional statement นี้
ตัวอย่างโค้ดในคู่มือนี้ใช้คำสั่ง measure มาตรฐานสำหรับการวัดระหว่าง circuit อย่างไรก็ตาม แนะนำให้ใช้คำสั่ง MidCircuitMeasure แทน ถ้า backend รองรับ ดูรายละเอียดในส่วน Mid-circuit measurements
หา backends ที่รองรับ dynamic circuits
เพื่อหา backends ทั้งหมดที่บัญชีของคุณสามารถเข้าถึงและรองรับ dynamic circuits ให้รันโค้ดเช่นต่อไปนี้ ตัวอย่างนี้สมมติว่าคุณได้ บันทึก credentials แล้ว คุณยังสามารถ ระบุ credentials อย่างชัดเจน เมื่อ initialize Qiskit Runtime service account ของคุณ ซึ่งจะให้คุณดู backends ที่มีบน instance หรือประเภท plan เฉพาะได้
- Backends ที่มีสำหรับบัญชีขึ้นอยู่กับ instance ที่ระบุใน credentials
- เวอร์ชันใหม่ของ dynamic circuits ตอนนี้มีให้สำหรับผู้ใช้ทั้งหมดบน backends ทั้งหมด ดู ประกาศ สำหรับรายละเอียดเพิ่มเติม
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
# This cell is hidden from users. It hides all those "...instance was not set..." warnings.
import warnings
warnings.filterwarnings("ignore", message=".*Instance was not set*")
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
dc_backends = service.backends(dynamic_circuits=True)
print(dc_backends)
[<IBMBackend('ibm_pittsburgh')>, <IBMBackend('ibm_kingston')>, <IBMBackend('ibm_marrakesh')>, <IBMBackend('ibm_fez')>, <IBMBackend('ibm_boston')>]
Mid-circuit measurements
ก่อน qiskit-ibm-runtime v0.43.0 measure เป็นคำสั่งการวัดเดียวใน Qiskit อย่างไรก็ตาม mid-circuit measurements มีข้อกำหนดการปรับแต่งที่แตกต่างจากการวัด terminal (การวัดที่เกิดขึ้นตอนท้ายของ circuit) ตัวอย่างเช่น คุณต้องพิจารณา instruction duration เมื่อปรับแต่ง mid-circuit measurement เพราะ instructions ที่ยาวกว่าทำให้ circuits มี noise มากขึ้น คุณไม่จำเป็นต้องพิจารณา instruction duration สำหรับ terminal measurements เนื่องจากไม่มี instructions หลัง terminal measurements
คำสั่ง MidCircuitMeasure map ไปยังคำสั่ง measure_2 ที่รายงานใน supported_instructions ของ backend อย่างไรก็ตาม measure_2 ไม่รองรับบน backends ทั้งหมด ใช้ service.backends(filters=lambda b: "measure_2" in b.supported_instructions) เพื่อหา backends ที่รองรับ การวัดใหม่อาจเพิ่มในอนาคต แต่ไม่รับประกัน
เมธอด MidCircuitMeasure
ใน qiskit-ibm-runtime v0.43.0 มีการนำคำสั่ง MidCircuitMeasure มาใช้ ตามชื่อที่บ่งบอก เป็นคำสั่งการวัดใหม่ที่ optimize สำหรับ mid-circuit บน IBM® QPUs แม้ว่าคุณสามารถใช้ QuantumCircuit.measure สำหรับ mid-circuit measurement แต่ด้วยการออกแบบ MidCircuitMeasure โดยทั่วไปเป็นตัวเลือกที่ดีกว่า ตัวอย่างเช่น มี overhead น้อยกว่าใน circuit ของคุณกว่าเมื่อใช้ QuantumCircuit.measure
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime.circuit import MidCircuitMeasure
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, dynamic_circuits=True
)
circ = QuantumCircuit(2, 2)
circ.x(0)
circ.append(MidCircuitMeasure(), [0], [0])
# circ.measure([0], [0])
# circ.measure_all()
print(circ.draw(cregbundle=False))
┌───┐┌────────────┐
q_0: ┤ X ├┤0 ├
└───┘│ │
q_1: ─────┤ Measure_2 ├
│ │
c_0: ═════╡0 ╞
└────────────┘
c_1: ═══════════════════
- ต้องมี classical register อย่างน้อยหนึ่งรายการเพื่อใช้การวัด
- Sampler primitive ต้องการการวัด circuit คุณสามารถเพิ่มการวัด circuit ด้วย Estimator primitive แต่จะถูก ignore
Store
ด้วย qiskit-ibm-runtime เวอร์ชัน 0.47.0 หรือใหม่กว่า คุณสามารถใช้คำสั่ง store เพื่อบันทึกผลของ classical expression ถ้า expression นั้นจะถูกใช้ซ้ำหลายครั้ง operations จะถูก parallelize โดยอัตโนมัติ ทำให้โค้ดของคุณมีประสิทธิภาพมากขึ้นอย่างมีนัยสำคัญในช่วง runtime
สำหรับข้อมูลเพิ่มเติม ดูคู่มือ Classical feedforward and control flow
เมื่อคุณใช้ store เพื่อบันทึกค่าไปยัง classical register บน backend จริง ค่านั้นจะถูกบันทึกในหน่วยความจำระหว่างการรันเท่านั้นและไม่ได้ถูก copy หรือส่งคืนในผลลัพธ์ job
ตัวอย่างเช่น ในโค้ดต่อไปนี้ temp มีค่าเดียวกับ creg ระหว่างการรัน และ if_test ทำงานตามที่คาดหวัง แต่หลัง job เสร็จสิ้น temp BitArray ที่ส่งคืนในผลลัพธ์ job ไม่ ประกอบด้วยค่าของ creg นั่นคือ job.result()[0].data.temp เป็น 0
creg = ClassicalRegister(3, "c")
temp = ClassicalRegister(3, "temp")
...
qc.store(temp, creg)
with circuit.if_test((temp, 0b001)):
...
ตัวอย่างแบบสมบูรณ์
โค้ดต่อไปนี้สร้างและรัน dynamic circuit บน IBM® hardware
from qiskit_ibm_runtime import SamplerV2, QiskitRuntimeService
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit.transpiler import generate_preset_pass_manager
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, dynamic_circuits=True
)
# Create a dynamic circuit
qubits = QuantumRegister(1)
clbits = ClassicalRegister(1)
qc = QuantumCircuit(qubits, clbits)
(q0,) = qubits
(c0,) = clbits
qc.h(q0)
qc.measure(q0, c0)
with qc.if_test((c0, 1)):
qc.x(q0)
qc.measure(q0, c0)
# Convert to an ISA circuit for the given backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)
# Generate samplers for backend targets
sampler = SamplerV2(backend)
# Submit jobs
sampler_job = sampler.run([isa_circuit])
result = sampler_job.result()
print(
f">>> {' Job ID:':<10} {sampler_job.job_id()} ({sampler_job.status()})"
)
>>> Job ID: d88cakp789is7391vq0g (DONE)
ข้อจำกัดของ Qiskit Runtime
รับทราบข้อจำกัดต่อไปนี้เมื่อรัน dynamic circuits ใน Qiskit Runtime
-
เนื่องจากหน่วยความจำทางกายภาพที่จำกัดบน control electronics ยังมีขีดจำกัดสำหรับจำนวนคำสั่ง
ifและขนาดของ operands ขีดจำกัดนี้เป็นฟังก์ชันของจำนวน broadcasts และจำนวน broadcasted bits ใน job (ไม่ใช่ circuit)เมื่อประมวลผลเงื่อนไข
ifข้อมูลการวัดต้องถูกถ่ายโอนไปยัง control logic เพื่อทำการประเมิน broadcast คือการถ่ายโอนข้อมูล classical ที่ไม่ซ้ำกัน และ broadcasted bits คือจำนวน classical bits ที่ถูกถ่ายโอน พิจารณาสิ่งต่อไปนี้:c0 = ClassicalRegister(3)c1 = ClassicalRegister(5)...with circuit.if_test((c0, 1)) ...with circuit.if_test((c0, 3)) ...with circuit.if_test((c1[2], 1)) ...ในตัวอย่างโค้ดก่อนหน้า
if_testสองตัวแรกบนc0ถือว่าเป็น broadcast เดียวเพราะเนื้อหาของc0ไม่ได้เปลี่ยน ดังนั้นไม่จำเป็นต้อง re-broadcastif_testบนc1คือ broadcast ที่สอง อันแรก broadcasts ทั้งสาม bits ในc0และอันที่สอง broadcasts เพียงหนึ่ง bit ทำให้รวมเป็นสี่ broadcasted bitsปัจจุบัน ถ้าคุณ broadcast 60 bits แต่ละครั้ง job สามารถมีประมาณ 300 broadcasts ถ้าคุณ broadcast เพียงหนึ่ง bit แต่ละครั้ง job สามารถมี 2400 broadcasts
-
Operand ที่ใช้ใน
if_teststatement ต้องมี 32 bits หรือน้อยกว่า ดังนั้น ถ้าคุณกำลังเปรียบเทียบClassicalRegisterทั้งหมด ขนาดของClassicalRegisterนั้นต้องมี 32 bits หรือน้อยกว่า อย่างไรก็ตาม ถ้าคุณกำลังเปรียบเทียบเพียง bit เดียวจากClassicalRegisterClassicalRegisterนั้นสามารถมีขนาดใดก็ได้ (เนื่องจาก operand เป็นเพียงหนึ่ง bit)ตัวอย่างเช่น code block "Not valid" ไม่ทำงานเพราะ
crมีมากกว่า 32 bits อย่างไรก็ตาม คุณสามารถใช้ classical register ที่กว้างกว่า 32 bits ถ้าคุณกำลังทดสอบเพียงหนึ่ง bit ตามที่แสดงใน code block "Valid"- Not valid
- Valid
cr = ClassicalRegister(50)qr = QuantumRegister(50)circuit = QuantumCircuit(qr, cr)...circ.measure(qr, cr)with circ.if_test((cr, 15)):...cr = ClassicalRegister(50)qr = QuantumRegister(50)circuit = QuantumCircuit(qr, cr)...circ.measure(qr, cr)with circ.if_test((cr[5], 1)):... -
Nested conditionals ไม่อนุญาต ตัวอย่างเช่น code block ต่อไปนี้จะไม่ทำงานเพราะมี
if_testอยู่ภายในif_testอื่น:- Not valid
- Valid
c1 = ClassicalRegister(1, "c1")c2 = ClassicalRegister(2, "c2")...with circ.if_test((c1, 1)):with circ.if_test(c2, 1)):...cr = ClassicalRegister(2)...with circuit.if_test((cr, 0b11)):... -
การมี
resetหรือการวัดภายใน conditionals ไม่รองรับ -
Arithmetic operations ไม่รองรับ
-
ดู OpenQASM 3 feature table เพื่อกำหนดว่า OpenQASM 3 features ใดรองรับบน Qiskit และ Qiskit Runtime
-
เมื่อใช้ OpenQASM 3 (แทน
QuantumCircuit) เป็นรูปแบบ input เพื่อส่ง circuits ไปยัง Qiskit Runtime primitives รองรับเฉพาะคำสั่งที่สามารถ load ลงใน Qiskit ตัวอย่างเช่น classical operations ไม่รองรับเพราะไม่สามารถ load ลงใน Qiskit ดู Import an OpenQASM 3 program into Qiskit สำหรับข้อมูลเพิ่มเติม -
คำสั่ง
for,whileและswitchไม่รองรับ
ใช้ dynamic circuits กับ Estimator
เนื่องจาก Estimator ไม่รองรับ dynamic circuits คุณสามารถใช้ Sampler และสร้าง measurement circuits ของคุณเองแทน
เพื่อจำลองพฤติกรรมของ Estimator ทำตามกระบวนการนี้:
- จัดกลุ่ม terms ของ observables ทั้งหมดเป็น partition สามารถทำได้โดยใช้
PauliListAPI เช่นหมายเหตุคุณสามารถใช้ attribute primitive
BitArrayเพื่อคำนวณ expectation values ของ observables ที่ให้ - รัน basis change circuit หนึ่งอันต่อ partition (ไม่ว่าจะต้องทำ basis change ใดสำหรับแต่ละ partition) ดู Measurement bases addon utility
measurement_basesmodule สำหรับข้อมูลเพิ่มเติม สำหรับข้อมูลเพิ่มเติม ดู เอกสาร สำหรับแพ็กเกจ Qiskit addon utilities - รวมผลลัพธ์สำหรับแต่ละ partition กลับเข้าด้วยกัน
ข้อจำกัด
ทบทวน Feature compatibility table ใดๆ เพื่อทำความเข้าใจข้อจำกัดเมื่อใช้ dynamic circuits โปรดทราบว่าความเข้ากันได้ของ feature ไม่ขึ้นอยู่กับ primitive
ขั้นตอนถัดไป
- เรียนรู้วิธีใช้ dynamic decoupling ที่แม่นยำโดยใช้ stretch
- ทบทวนคู่มือ classical feedforward and control flow
- ใช้ circuit schedule visualization เพื่อ debug และ optimize dynamic circuits ของคุณ
- ฟังก์ชันบางอย่างไม่รองรับ dynamic circuits ดูส่วน feature compatibility สำหรับ Sampler หรือ Executor เพื่อดูรายละเอียด