ใช้ postselection ใน workloads
เวอร์ชันแพ็กเกจ
โค้ดในหน้านี้พัฒนาโดยใช้ requirements ต่อไปนี้ แนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า
qiskit[all]~=2.4.0
qiskit-ibm-runtime~=0.46.1
qiskit-addon-utils~=0.3.1
เมื่อ optimize กลยุทธ์ error mitigation ของ workload มักเป็นประโยชน์ที่จะกรองผลการวัดที่รู้ว่าถูกปนเปื้อนด้วยกระบวนการ noise แบบ non-Markovian (correlated) วิธีหนึ่งในการทำเช่นนี้คือการต่อท้าย circuit ด้วยขั้นตอน post-processing ที่วัด active และ "spectator" qubits ที่อยู่ติดกัน ใช้ rotation ช้าๆ กับแต่ละ qubit แล้ววัดอีกครั้ง ในกรณีที่การวัดสองครั้งไม่ยืนยัน qubit ที่พลิกตามที่คาดไว้ shot นั้นจะถูกทิ้งโดยการใช้ mask กับผลลัพธ์
แพ็กเกจ Qiskit addon utilities มีชุด transpiler passes และฟังก์ชัน postselection สำหรับใช้ mask หน้านี้ให้คำแนะนำเกี่ยวกับวิธีรวม postselection เข้าใน quantum workloads โดยใช้ GHZ state สี่ qubit เป็นตัวอย่าง
สร้าง workload
เริ่มด้วยการเตรียม circuit ที่จะรันและ transpile กับ backend ที่รองรับ fractional gates
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-addon-utils qiskit-ibm-runtime
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.circuit import QuantumCircuit
from qiskit.transpiler import generate_preset_pass_manager
circuit = QuantumCircuit(4)
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.cx(2, 3)
circuit.measure_all()
service = QiskitRuntimeService()
backend = service.least_busy(use_fractional_gates=True)
pm = generate_preset_pass_manager(optimization_level=3, backend=backend)
transpiled_circuit = pm.run(circuit)
transpiled_circuit.draw("mpl")
เพิ่ม postselection transpiler passes
จากนั้น สร้าง preset pass manager ที่รวม passes AddPostSelectionMeasures และ AddSpectatorMeasures จากแพ็กเกจ qiskit-addon-utils ซึ่งจะต่อท้าย circuit ด้วยลำดับ rotation RX มุมเล็ก (ผลิต X gate ยาวโดยประสิทธิผล) พร้อมกับชุดการวัดที่สอง
from qiskit.transpiler import PassManager
from qiskit_addon_utils.noise_management.post_selection import PostSelector
from qiskit_addon_utils.noise_management.post_selection.transpiler.passes import (
AddPostSelectionMeasures,
AddSpectatorMeasures,
)
post_selection_pm = PassManager(
[
AddSpectatorMeasures(backend.coupling_map, add_barrier=True),
AddPostSelectionMeasures(x_pulse_type="rx"),
]
)
template_circuit_ps = post_selection_pm.run(transpiled_circuit)
template_circuit_ps.draw("mpl", fold=-1, idle_wires=False)
รัน quantum program
จากนั้น เตรียม object QuantumProgram ที่มี circuit ที่จะรัน
from qiskit_ibm_runtime import QuantumProgram, Executor
shots = 4000
program = QuantumProgram(shots=shots)
program.append_circuit_item(template_circuit_ps)
# Initialize the Executor job and run
executor = Executor(backend)
executor_job = executor.run(program)
print(f"Job ID: {executor_job.job_id()}")
Job ID: d82dumugbeec73alm5g0
ตอนนี้คุณสามารถตีความผลลัพธ์ executor result เป็น dictionary ที่มี keys หลายตัว
executor_result = executor_job.result()[0]
executor_result.keys()
dict_keys(['meas', 'spec', 'meas_ps', 'spec_ps'])
Keys เหล่านี้สอดคล้องกับ active และ spectator qubits ก่อนคำสั่ง rx (meas และ spec) และหลังคำสั่ง rx (meas_ps และ spec_ps) แต่ละตัวเป็น array ของ arrays ตาม shots และ qubits ในกรณีนี้ shape คือ (1000, 4)
สร้าง postselection mask
จากการวัดเหล่านี้ คุณสามารถสร้าง mask โดยใช้ class PostSelector จาก qiskit-addon-utils mask นี้เป็น boolean array ที่แต่ละ shot ถูกทำเครื่องหมาย True หรือ False ตามกลยุทธ์ postselection สองแบบ กลยุทธ์แรก node ใช้ข้อมูล qubit เพื่อตัดสินใจว่า measurement shot ควรถูกทิ้ง และกลยุทธ์ที่สอง edge ใช้ข้อมูล nearest-neighbor connectivity เพื่อตัดสินใจนี้
post_selector = PostSelector.from_circuit(
circuit=template_circuit_ps, coupling_map=backend.coupling_map
)
mask_node = post_selector.compute_mask(executor_result, strategy="node")
mask_edge = post_selector.compute_mask(executor_result, strategy="edge")
ทั้งกลยุทธ์ node และ edge มักทิ้ง shots ที่แตกต่างกัน คุณสามารถเลือกใดก็ได้ notebook นี้ใช้ bitwise AND ซึ่งเป็นกลยุทธ์อนุรักษ์นิยมที่รักษา shot ไว้เฉพาะเมื่อผ่านทั้งกลยุทธ์ node และ edge
mask = mask_node & mask_edge
print(f"The combined mask: {mask}")
count_retained = 0
for m in mask:
count_retained += m
print(
f"Percentage of the shots retained is after post selection "
f"{100 * count_retained / shots}"
)
The combined mask: [ True True True ... True True True]
Percentage of the shots retained is after post selection 75.225
เปรียบเทียบ probability distribution ก่อนและหลัง postselection snippet ต่อไปนี้คำนวณ probability distribution ก่อนและหลัง postselection รวมถึงระยะห่างระหว่าง distribution ที่วัดได้และในอุดมคติ
counts = {}
counts_ps = {}
for idx, measurement in enumerate(executor_result["meas"]):
bitstring = ""
for bit in measurement:
bitstring += str(int(bit))
if bitstring in counts:
counts[bitstring] += 1
else:
counts[bitstring] = 1
# Compute count data for postselected shots based on the mask
if mask[idx]:
bitstring = ""
for bit in measurement:
bitstring += str(int(bit))
if bitstring in counts_ps:
counts_ps[bitstring] += 1
else:
counts_ps[bitstring] = 1
for key, val in counts.items():
counts[key] = val / shots
for key, val in counts_ps.items():
counts_ps[key] = float(val / count_retained)
เพื่อแสดงว่า postselection เปลี่ยนผลลัพธ์อย่างไร คำนวณระยะห่างระหว่าง probability distribution ในอุดมคติและที่วัดได้
import itertools
from qiskit.visualization import plot_histogram
bitstrings = ["".join(i) for i in itertools.product("01", repeat=4)]
counts_ideal = {}
for bitstring in bitstrings:
counts_ideal[bitstring] = 0.0
counts_ideal["1111"] = 0.5
counts_ideal["0000"] = 0.5
prob_distance = 0.0
prob_distance_ps = 0.0
for bitstring in counts_ideal.keys():
dist = 0.0
dist_ps = 0.0
if bitstring in counts:
dist = abs(counts[bitstring] - counts_ideal[bitstring])
if bitstring in counts_ps:
dist_ps = abs(counts_ps[bitstring] - counts_ideal[bitstring])
prob_distance += dist
prob_distance_ps += dist_ps
print(
f"Distance from ideal distribution before postselection: "
f"{1-prob_distance*0.5}"
)
print(
f"Distance from ideal distribution before after-selection: "
f"{1-prob_distance_ps*0.5}"
)
plot_histogram([counts, counts_ps], legend=["Normal", "Post selected"])
Distance from ideal distribution before postselection: 0.9015
Distance from ideal distribution before after-selection: 0.9416749750747756
แม้ว่า postselection สามารถปรับปรุงคุณภาพผลลัพธ์ได้อย่างมีนัยสำคัญโดยกรองการวัดผลที่ได้รับผลกระทบจาก non-Markovian noise แต่ไม่ใช่วิธีแก้ปัญหาครบถ้วนสำหรับ error mitigation ด้วยตัวเอง Postselection ลดผลกระทบของ errors บางอย่างโดยการทิ้งผลการวัดที่ไม่ถูกต้อง แต่มาพร้อมกับค่าใช้จ่าย sampling overhead ที่เพิ่มขึ้น และไม่ครอบคลุม error ทุกกลไกที่มีอยู่ใน quantum hardware ระยะใกล้ ดังนั้น จึงไม่น่าจะเพียงพอที่จะพึ่งพา postselection เพียงอย่างเดียวสำหรับ circuits ที่ซับซ้อนหรือลึกกว่า แต่ postselection มีประสิทธิภาพสูงสุดเมื่อใช้เป็นส่วนหนึ่งของกลยุทธ์ error mitigation ที่กว้างขึ้น ซึ่งเสริมเทคนิคเช่น measurement error mitigation, noise-aware circuit compilation หรือ probabilistic error cancellation เพื่อปรับปรุงความน่าเชื่อถือของ quantum workloads โดยสมดุลความแม่นยำและต้นทุนทรัพยากร
ขั้นตอนถัดไป
- ทำความเข้าใจวิธีรวม noise learning เข้าใน quantum workload
- อ่านเทคนิค error mitigation and suppression ที่มีอื่นๆ
- เรียนรู้วิธีใช้ spacetime codes สำหรับแนวทาง error detection ที่มี overhead ต่ำ