Transpiler
ฟังก์ชัน generate_boxing_pass_manager() เป็นเครื่องมือที่ยืดหยุ่นและสะดวกสำหรับสร้าง qiskit.transpiler.PassManager ที่สามารถจัดกลุ่มคำสั่งของ circuit เป็น box ที่มี annotation ได้ ซึ่งเป็นทางเลือกที่ง่ายแทนการจัดกลุ่มและใส่ annotation ให้ circuit ด้วยตนเอง และมีประโยชน์สำหรับการทำเวิร์กโฟลว์ให้เป็นอัตโนมัติ การทดสอบกลยุทธ์การใส่ box ให้ circuit ที่ต่างกัน และอื่น ๆ
คู่มือนี้แสดงวิธีใช้ generate_boxing_pass_manager() และอาร์กิวเมนต์ของมัน เพื่อเน้นผลของแต่ละอาร์กิวเมนต์ของฟังก์ชัน ส่วนต่อไปนี้จะอ้างอิง circuit ด้านล่างเป็นหลัก
from qiskit.circuit import Parameter, QuantumCircuit
circuit = QuantumCircuit(4, 7)
circuit.h(1)
circuit.h(2)
circuit.cz(1, 2)
circuit.h(1)
circuit.cx(1, 0)
circuit.cx(2, 3)
circuit.measure(range(1, 4), range(3))
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.cx(2, 3)
for qubit in range(4):
circuit.rz(Parameter(f"th_{qubit}"), qubit)
circuit.rx(Parameter(f"phi_{qubit}"), qubit)
circuit.rz(Parameter(f"lam_{qubit}"), qubit)
circuit.measure(range(4), range(3, 7))
circuit.draw("mpl", scale=0.8)
จัดกลุ่มการดำเนินการเป็น box
สามารถตั้งอาร์กิวเมนต์ enable_gates เป็น True หรือ False เพื่อระบุว่าควรจัดกลุ่ม gate แบบ two-qubit เป็น box หรือไม่ ในทำนองเดียวกัน enable_measures ระบุว่าควรจัดกลุ่มการวัดหรือไม่ สนิปเป็ตต่อไปนี้แสดงตัวอย่างที่จัดกลุ่มทั้ง gate และการวัด
from samplomatic.transpiler import generate_boxing_pass_manager
boxing_pass_manager = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=True,
)
transpiled_circuit = boxing_pass_manager.run(circuit)
transpiled_circuit.draw("mpl", scale=0.8)

ดังที่เห็นในรูป pass manager สร้าง box สองชนิด คือ box ที่มี gate แบบ two-qubit ชั้นเดียว และ box ที่มีการวัดชั้นเดียว การแยกนี้สะท้อนแนวปฏิบัติมาตรฐานในโปรโตคอลการเรียนรู้และบรรเทา noise ซึ่งมักมุ่งเป้าที่ชั้นของการดำเนินการที่เป็นเนื้อเดียวกัน Gate แบบ two-qubit และการวัดจะถูกวางใน box ซ้ายสุดที่รองรับได้ และ gate แบบ single-qubit ทุกตัวจะถูกวางใน box เดียวกับ gate แบบ two-qubit หรือการวัดที่มันอยู่ก่อนหน้า
โค้ดต่อไปนี้แสดงตัวอย่างที่ตั้ง enable_gates เป็น False ดังที่เห็น gate แบบ two-qubit จะไม่ถูกจัดกลุ่มเป็น box และ gate แบบ single-qubit ที่อยู่ก่อนหน้าก็ไม่ถูกจัดกลุ่มด้วย
boxing_pass_manager = generate_boxing_pass_manager(
enable_gates=False,
enable_measures=True,
)
transpiled_circuit = boxing_pass_manager.run(circuit)
transpiled_circuit.draw("mpl", scale=0.8)
เลือกวิธีใส่ annotation ให้ box
Box ของ gate แบบ two-qubit และ box ของการวัดทั้งหมดใน circuit ที่ส่งคืนมี annotation แบบ left-dressed โดยเฉพาะ box ทั้งหมดที่มี gate แบบ two-qubit จะมี Twirl เป็น annotation สำหรับ box ของการวัด ผู้ใช้เลือกระหว่าง Twirl, BasisTranform (โดยตั้ง mode เป็น "measure") หรือทั้งสองอย่างได้ โค้ดต่อไปนี้สร้าง circuit ที่ box ทั้งหมดถูก twirl และ box ของการวัดมี BasisTranform เป็น annotation เพิ่มเติม
boxing_pass_manager = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=True,
measure_annotations="all",
)
transpiled_circuit = boxing_pass_manager.run(circuit)
เตรียม circuit สำหรับ noise injection
inject_noise_targets ช่วยให้คุณระบุได้ว่า box ใดควรได้รับ annotation InjectNoise ตัวอย่างเช่น โค้ดต่อไปนี้สร้าง circuit ที่ box ของ gate แบบ two-qubit มี annotation InjectNoise แต่ box ของการวัดไม่มี
boxing_pass_manager = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=True,
inject_noise_targets="gates",
)
transpiled_circuit = boxing_pass_manager.run(circuit)
หาก circuit มี box สองตัวขึ้นไปที่เทียบเท่ากันจนถึงระดับ gate แบบ single-qubit ทุกตัวจะมี annotation InjectNoise ที่มี ref เดียวกัน ดังนั้นจำนวน ref ที่ไม่ซ้ำกันใน circuit ที่ส่งคืนจึงเท่ากับจำนวน box ที่ไม่ซ้ำกัน
ค่าของ inject_noise_strategy มีผลต่อ annotation InjectNoise ค่าที่เป็นไปได้มีดังนี้
-
modifier_ref='': แนะนำเมื่อคุณไม่จำเป็นต้องปรับเปลี่ยน noise map ก่อนสุ่มตัวอย่างจากมัน -
modifier_ref=ref: แนะนำเมื่อ noise map ทั้งหมดต้องถูกปรับสเกลอย่างสม่ำเสมอด้วยตัวคูณเดียวกัน -
ค่า
modifier_refที่ไม่ซ้ำกัน: แนะนำเมื่อ noise map ทุกตัวต้องถูกปรับสเกลด้วยตัวคูณที่ต่างกัน
โค้ดต่อไปนี้สร้าง circuit ที่ box ของ gate แบบ two-qubit มี annotation InjectNoise ที่มีค่า modifier_ref ไม่ซ้ำกัน
boxing_pass_manager = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=True,
inject_noise_targets="gates",
inject_noise_strategy="individual_modification",
)
transpiled_circuit = boxing_pass_manager.run(circuit)
เลือกกลยุทธ์ twirling
Boxing pass manager เริ่มด้วยการเลือกว่า entangling gate และคำสั่งการวัดใดควรอยู่ใน box เดียวกัน เมื่อทำเสร็จแล้ว โดยทั่วไป box จะไม่กว้างเต็ม แต่น่าจะรวมเพียงส่วนหนึ่งของ qubit ที่ active ใน circuit หรืออยู่ใน backend target ในการกำหนดค่าทั่วไปของ boxing pass manager เนื่องจาก qubit ทั้งหมดที่คำสั่ง box กระทำถูก twirl (แม้แต่ qubit ที่ไม่มีคำสั่งใดใน box กระทำ) การมี box ความกว้างบางส่วนจึงมีผลต่อผลของการ twirl ในการปรับแต่ง noise Qubit ที่ว่างอยู่จะไม่ถูก twirl และอาจสะสม coherent error ได้ในขณะที่ box ถูกนำไปใช้ twirling_strategy มีตัวเลือกสำหรับขยาย qubit ที่แต่ละ box เป็นเจ้าของ ซึ่งเปลี่ยนจำนวน qubit ที่ว่างอยู่
-
"active"(ค่าเริ่มต้น) ไม่ขยาย box ไปยัง qubit ที่ว่างอยู่ -
"active_accum"ขยายทุก box ไปยัง qubit ที่ถูกคำสั่งก่อนหน้าใน circuit กระทำไปแล้ว มีประโยชน์หากคุณต้องการปล่อย qubit ตอนต้น circuit ไว้ใน ground state นานที่สุดเท่าที่เป็นไปได้ โดยไม่ twirl จนกว่าจะ active -
"active_circuit"ขยายทุก box ไปยัง qubit ที่ถูกคำสั่งใด ๆ ใน circuit กระทำ มีประโยชน์หากคุณมี circuit ที่มีโครงสร้างซึ่งมีชั้น entangling ซ้ำ ๆ และต้องการลดจำนวน box ที่ไม่ซ้ำกัน เพราะแต่ละตัวต้องเรียนรู้ noise ของมัน -
"all"ขยายทุก box ไปยัง qubit ทั้งหมดในทุก quantum register ของ circuit มีประโยชน์เป็นส่วนขยายของ"active_circuit"เมื่อคุณต้องการให้ qubit ทั้งหมดใน QPU ถูก twirl เสมอ
ในตัวอย่างต่อไปนี้ แต่ละกลยุทธ์ถูกนำไปใช้กับ circuit ฐาน จากนั้นวาดผลลัพธ์
circuit = QuantumCircuit(5, 2)
circuit.h(range(4))
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.cx(2, 3)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.cx(2, 3)
circuit.barrier()
circuit.h(range(4))
circuit.measure([1, 2], [0, 1])
circuit.draw("mpl", scale=0.6)
import matplotlib.pyplot as plt
plt.figure(figsize=(9, 6))
for idx, strategy in enumerate(["active", "active_accum", "active_circuit", "all"]):
ax = plt.subplot(2, 2, idx + 1)
pm = generate_boxing_pass_manager(twirling_strategy=strategy, remove_barriers="never")
transpiled_circuit = pm.run(circuit)
fig = transpiled_circuit.draw("mpl", scale=0.8, ax=ax)
ax.set_title(f"twirling_strategy='{strategy}'")
plt.tight_layout()

ระบุวิธีจัดการ barrier
โดยค่าเริ่มต้น barrier จะถูกลบออกจาก circuit หลังจาก entangling gate และคำสั่งการวัดทั้งหมดถูกใส่ box ตามที่กำหนดแล้ว รวมถึงส่วนขยายจากการเลือก twirling_strategy แต่ก่อนที่ gate แบบ single-qubit จะถูกเพิ่มเข้า box ที่อยู่ทางขวาทันที หากเป็นไปได้
ตัวอย่างเช่น circuit ต่อไปนี้มี barrier
circuit_with_barrier = QuantumCircuit(4)
circuit_with_barrier.h(range(4))
circuit_with_barrier.cz(0, 1)
circuit_with_barrier.barrier()
circuit_with_barrier.cz(2, 3)
circuit_with_barrier.measure_all()
circuit_with_barrier.draw("mpl", scale=0.8)
พฤติกรรมเริ่มต้นป้องกันไม่ให้ entangling gate ทั้งสองไปอยู่ใน box เดียวกัน แม้ว่าจะปล่อยให้ gate แบบ single-qubit ถูกดูดซับเข้า box ถัดไปที่ใช้ได้ แม้จะมี barrier ก็ตาม
boxing_pass_manager = generate_boxing_pass_manager()
transpiled_circuit = boxing_pass_manager.run(circuit_with_barrier)
transpiled_circuit.draw("mpl", scale=0.8)
การตั้ง remove_barriers เป็น 'never' จะคง barrier ไว้ เพื่อให้ gate แบบ single-qubit ถูกจำกัด
boxing_pass_manager = generate_boxing_pass_manager(remove_barriers="never")
transpiled_circuit = boxing_pass_manager.run(circuit_with_barrier)
transpiled_circuit.draw("mpl", scale=0.8)
สุดท้าย หากลบ barrier ทันที entangler จะไม่ถูกจำกัดให้ต้องอยู่ใน box แยกกันอีกต่อไป
boxing_pass_manager = generate_boxing_pass_manager(remove_barriers="immediately")
transpiled_circuit = boxing_pass_manager.run(circuit_with_barrier)
transpiled_circuit.draw("mpl", scale=0.8)
การทำ stratification ทำงานอย่างไร
Boxing pass manager รัน pass หลักสองตัวตามลำดับ
-
GroupGatesIntoBoxes— แบ่ง entangling gate เป็นชั้นใน box โดยไม่สนใจ gate แบบ single-qubit ในขั้นนี้ และจัดกลุ่มเฉพาะ gate แบบ two-qubit -
AbsorbSingleQubitGates— ดูดซับ gate แบบ single-qubit แต่ละตัวเข้า box ที่เข้าเงื่อนไขใกล้ที่สุดทางขวาของมัน
ระหว่าง stratification GroupGatesIntoBoxes จะท่อง circuit DAG ตามลำดับ topological และวาง gate แบบ two-qubit แต่ละตัวใน กลุ่มแรกสุด ที่ qubit ของมันยังไม่ถูกใช้ คำสั่งสามชนิดทำหน้าที่เป็น delimiter ที่ปิดกลุ่มปัจจุบันสำหรับ qubit ของมัน ทำให้ gate ที่ตามมาบน qubit เหล่านั้นต้องไปอยู่ในกลุ่มใหม่
-
แบร์ริเออร์
-
คำสั่ง box ที่มีอยู่แล้ว
-
Measurements
Gate แบบ single-qubit ไม่ใช่ delimiter — มันไม่มีผลต่อการจัดกลุ่ม และปล่อยให้ AbsorbSingleQubitGates จัดการ ปัจจุบันยังไม่มีการวิเคราะห์ commutativity การจัดกลุ่มเป็นไปตามลำดับ topological ของ circuit ตามที่เป็นอยู่
ทำไม remove_barriers="after_stratification" จึงเป็นค่าเริ่มต้นที่แนะนำ
โหมดเริ่มต้นคือ "after_stratification" เพราะรวมข้อดีสองอย่างไว้ด้วยกัน
-
Barrier จำกัดวิธีจัดกลุ่ม entangling gate (มันทำหน้าที่เป็น delimiter ระหว่าง stratification)
-
Barrier ถูกลบ ก่อน ที่
AbsorbSingleQubitGatesจะรัน ดังนั้น gate แบบ single-qubit ยังคงเลื่อนข้ามตำแหน่งของ barrier เดิมได้ และถูกดูดซับเข้า box ที่ใกล้ที่สุด
ในทางตรงกันข้าม:
-
"never"คง barrier ไว้ตลอด ซึ่งดัก gate แบบ single-qubit ไว้ระหว่าง barrier กับ box ทำให้ถูกดูดซับไม่ได้ และทิ้งการหมุนที่ไม่ได้ twirl ไว้ใน circuit -
"immediately"ลบ barrier ก่อน stratification ดังนั้นมันจึงไม่มีผลต่อการจัดกลุ่ม -
"finally"มีประโยชน์เมื่อคุณต้องการให้มี barrier ใน circuit เอาต์พุต (เช่น เพื่อการแสดงภาพ) แต่ gate แบบ single-qubit ระหว่าง barrier กับ box จะไม่ถูกดูดซับ
Box ISA circuit ด้วย barrier
circuit ที่มีโครงสร้างซ้ำ ๆ เช่น การจำลอง Hamiltonian แบบ Trotterized, variational ansatz และลำดับการขยายข้อผิดพลาด มักถูกสร้างด้วยโปรแกรมแล้วจึง transpile เป็นรูปแบบ ISA การเพิ่ม box ลงใน circuit ที่ transpile แล้วด้วยมือนั้นยุ่งยาก ดังนั้นขั้นตอนที่เป็นธรรมชาติคือ
-
สร้าง logical circuit โดยแทรก barrier ตรงขอบเขตของ layer ที่ต้องการให้เป็นขอบเขตของ box
-
Transpile เป็น ISA circuit Transpiler ของ Qiskit จะรักษา barrier ไว้ตลอดการ routing และการ optimize
-
รัน
generate_boxing_pass_manager()บน ISA circuit
ต้องใช้ barrier เมื่อส่วนท้ายของ layer หนึ่งไม่ครอบคลุม qubit ทั้งหมด มิฉะนั้นอัลกอริทึมแบบ greedy จะนำ gate จาก layer ถัดไปบน qubit ที่ "ว่าง" เหล่านั้นมาไว้ในกลุ่มเดียวกัน ตัวอย่างที่เป็นรูปธรรมคือการจำลอง Heisenberg ZZ สองขั้นบน ring 5 qubit โดยแต่ละขั้น Trotter มี bond layer สามชั้น ได้แก่ bond คู่ (0,1), (2,3), bond คี่ (1,2), (3,4) และ bond วนกลับ (4,0) หลังจาก layer ของ bond คี่ qubit 0 และ 4 จะว่างทั้งคู่ หากไม่มี barrier bond วนกลับ (4,0) จะถูกจัดกลุ่มแบบ greedy รวมกับ bond จากขั้น Trotter ถัดไป ที่ใช้ qubit ว่างเหล่านั้น ทำให้ gate จากคนละขั้นปะปนอยู่ใน box เดียวกัน
from qiskit.circuit import Parameter, QuantumCircuit
n = 5 # 5-qubit ring: bonds (0,1), (1,2), (2,3), (3,4), (4,0)
dt = Parameter("dt")
heisenberg = QuantumCircuit(n)
for step in range(2):
# Layer 1: even bonds (0,1) and (2,3)
for idx in range(0, n - 1, 2):
heisenberg.rzz(dt, idx, idx + 1)
heisenberg.barrier()
# Layer 2: odd bonds (1,2) and (3,4) -- qubits 0 and 4 are now free
for idx in range(1, n - 1, 2):
heisenberg.rzz(dt, idx, idx + 1)
heisenberg.barrier()
# Layer 3: wrap bond (4,0) -- both qubits were free after layer 2
heisenberg.rzz(dt, n - 1, 0)
if step < 1:
heisenberg.barrier() # separates the two Trotter steps
heisenberg.measure_all()
heisenberg.draw("mpl", scale=0.7)
โค้ดต่อไปนี้ transpile circuit เป็นรูปแบบ ISA โดยสมมติว่าอุปกรณ์เบื้องหลังใช้ CX เป็น entangler แบบ native โปรดสังเกตว่า barrier ยังคงอยู่หลัง transpile และมองเห็นได้ใน circuit ผลลัพธ์
from qiskit.transpiler import generate_preset_pass_manager
preset_pm = generate_preset_pass_manager(
basis_gates=["rz", "sx", "cx"],
coupling_map=[[0, 1], [1, 2], [2, 3], [3, 4], [4, 0]],
optimization_level=1,
)
isa_circuit = preset_pm.run(heisenberg)
isa_circuit.draw("mpl", scale=0.5, fold=200)
ถัดไป ใช้ boxing pass manager กับ ISA circuit โดย bond layer ทั้งสามชั้นจะกลายเป็น box แยกกันในแต่ละขั้น Trotter
boxing_pm = generate_boxing_pass_manager()
boxed_isa = boxing_pm.run(isa_circuit)
boxed_isa.draw("mpl", scale=0.5, fold=100)
รวม pass manager ของ Samplomatic เข้ากับ preset pass manager ของ Qiskit
โค้ดด้านล่างแสดงวิธีรวม generate_boxing_pass_manager() เข้ากับ preset pass manager ของ Qiskit circuit ที่ transpile แล้วจะเป็น ISA และมี box อยู่ด้วย
from qiskit.transpiler import generate_preset_pass_manager
preset_pass_manager = generate_preset_pass_manager(
basis_gates=["rz", "sx", "cx"],
coupling_map=[[0, 1], [1, 2]],
optimization_level=0,
)
boxing_pass_manager = generate_boxing_pass_manager()
# Run the boxing pass manager after the scheduling stage
preset_pass_manager.post_scheduling = boxing_pass_manager
circuit = QuantumCircuit(3)
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(0, 2)
circuit.measure_all()
transpiled_circuit = preset_pass_manager.run(circuit)
transpiled_circuit.draw("mpl", scale=0.8)
รูปแบบนี้ยังใช้ร่วมกับเวิร์กโฟลว์ ISA boxing แบบใช้ barrier ได้อย่างเป็นธรรมชาติ boxing pass manager ทำงานเป็นขั้นตอนหลังการ scheduling หลังจากที่ barrier จาก logical circuit ต้นฉบับผ่านการ transpile มาแล้ว จึงนำทางการ stratification ได้ตามที่คาดไว้
preset_pm = generate_preset_pass_manager(
basis_gates=["rz", "sx", "cx"],
coupling_map=[[0, 1], [1, 2], [2, 3], [3, 4], [4, 0]],
optimization_level=1,
)
preset_pm.post_scheduling = generate_boxing_pass_manager()
boxed_heisenberg = preset_pm.run(heisenberg)
boxed_heisenberg.draw("mpl", scale=0.5, fold=100)
ตรวจสอบและแก้ไข annotation
หลังจาก auto-boxing คุณอาจต้องการตรวจสอบ annotation บน box ที่เจาะจงหรือปรับแก้ เช่น เพิ่ม noise injection ลบ annotation หรือเปลี่ยน twirling group Samplomatic มีชุดฟังก์ชันอรรถประโยชน์ใน samplomatic.utils สำหรับจุดประสงค์นี้ ทุกฟังก์ชันคืน circuit ใหม่ โดยไม่แก้ไขต้นฉบับ
extend_annotations() ต่อท้าย annotation หนึ่งรายการขึ้นไปให้กับทุก box ใน circuit
from samplomatic import InjectNoise, Twirl
from samplomatic.utils import extend_annotations
boxed = generate_boxing_pass_manager().run(circuit_with_barrier)
# Add InjectNoise to every box
with_noise = extend_annotations(boxed, InjectNoise("my_noise_ref"))
with_noise.draw("mpl", scale=0.8)
filter_annotations() เก็บเฉพาะ annotation ของประเภทที่ระบุและลบที่เหลือ replace_annotations() ใช้ callable กับ annotation แต่ละรายการ โดย callable จะคืนรายการ annotation มาแทนที่ (คืน [] เพื่อลบ คืนรายการที่มีหนึ่งองค์ประกอบเพื่อแทนที่ หรือคืนรายการที่มีหลายองค์ประกอบเพื่อขยาย)
from samplomatic.utils import filter_annotations, replace_annotations
# Keep only Twirl annotations, drop everything else
twirl_only = filter_annotations(with_noise, Twirl)
# Replace the twirling group on every Twirl annotation
updated = replace_annotations(
twirl_only, lambda a: [Twirl(group="local_c1")] if isinstance(a, Twirl) else [a]
)
ฟังก์ชันอเนกประสงค์ map_annotations() รับ callable ใดก็ได้ที่แปลงรายการ annotation เป็นรายการใหม่ ทำให้คุณควบคุมการแปลงแต่ละ box ได้เต็มที่ ส่วน strip_annotations() เป็น wrapper อำนวยความสะดวกที่ลบ annotation ทั้งหมดจากทุก box
สำหรับการเปลี่ยนแปลงแบบกลุ่ม เช่น การเพิ่ม InjectNoise ให้กับทุก gate box พารามิเตอร์ inject_noise_targets ของ generate_boxing_pass_manager() เป็นตัวเลือกที่กระชับที่สุด ยูทิลิตีเหล่านี้มีประโยชน์สำหรับการแก้ไขเฉพาะ box ที่พารามิเตอร์ของ pass manager ไม่ครอบคลุม
สร้าง circuit
ทุก pass manager ที่สร้างโดย generate_boxing_pass_manager() จะคืน circuit ที่สามารถแปลงเป็นคู่ template/samplex ได้สำเร็จด้วย build() ตัวอย่างเช่น โค้ดต่อไปนี้เรียกฟังก์ชัน build() กับ circuit ที่สร้างโดย boxing pass manager
from samplomatic import build
boxing_pass_manager = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=True,
)
transpiled_circuit = boxing_pass_manager.run(circuit)
template, samplex = build(transpiled_circuit)
เพื่อให้แน่ใจว่า circuit ที่ transpile แล้วทุกตัวสามารถ build ได้สำเร็จ pass manager จะรู้วิธีเพิ่ม box เพิ่มเติมเมื่อจำเป็น ตัวอย่างเช่น พิจารณา circuit ด้านล่าง ซึ่งลงท้ายด้วย qubit 0 ที่ไม่ได้วัด
circuit_with_unmeasured_qubit = QuantumCircuit(4, 3)
circuit_with_unmeasured_qubit.cz(0, 1)
circuit_with_unmeasured_qubit.cz(2, 3)
for qubit in range(4):
circuit_with_unmeasured_qubit.rz(Parameter(f"th_{qubit}"), qubit)
circuit_with_unmeasured_qubit.rx(Parameter(f"phi_{qubit}"), qubit)
circuit_with_unmeasured_qubit.rz(Parameter(f"lam_{qubit}"), qubit)
circuit_with_unmeasured_qubit.measure(range(1, 4), range(3))
circuit_with_unmeasured_qubit.draw("mpl", scale=0.8)
การวาด box แบบ left-dressed รอบ gate และการวัดจะได้ circuit ที่มี virtual gate ซึ่งยังไม่ได้เก็บบน qubit 0 และการเรียก build() กับ circuit นี้จะเกิดข้อผิดพลาด เพื่อหลีกเลี่ยง pass manager ที่คืนโดย generate_boxing_pass_manager() สามารถเพิ่ม box แบบ right-dressed เพื่อทำหน้าที่เป็นตัวเก็บได้ ตัวอย่างเช่น ในโค้ดต่อไปนี้ qubit 0 ถูกปิดท้ายด้วย box แบบ right-dressed ที่เก็บ virtual gate ที่ยังไม่ได้เก็บ single-qubit gate ที่กระทำกับ qubit 0 ก็ถูกวางไว้ใน box ด้วยเพื่อลดความลึกของ circuit ผลลัพธ์
boxing_pass_manager = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=True,
)
transpiled_circuit = boxing_pass_manager.run(circuit_with_unmeasured_qubit)
transpiled_circuit.draw("mpl", scale=0.8)
อีกตัวอย่างหนึ่ง box แบบ right-dressed ถูกเพิ่มเพื่อเก็บ virtual gate ที่มิฉะนั้นจะยังไม่ได้เก็บเนื่องจากการวัดที่ไม่ได้อยู่ใน box
boxing_pass_manager = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=False,
)
transpiled_circuit = boxing_pass_manager.run(circuit_with_unmeasured_qubit)
transpiled_circuit.draw("mpl", scale=0.8)