รันงานในโหมด Batch
Package versions
โค้ดในหน้านี้พัฒนาขึ้นโดยใช้ requirement ต่อไปนี้ แนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
ใช้โหมด batch เพื่อส่ง primitive job หลายรายการพร้อมกัน ต่อไปนี้เป็นตัวอย่างการทำงานกับ batch
ตั้งค่าเพื่อใช้งาน batch
ก่อนเริ่ม batch ต้องตั้งค่า Qiskit Runtime และ initialize เป็น service ก่อน:
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime import (
QiskitRuntimeService,
Batch,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
Executor,
)
service = QiskitRuntimeService()
เปิด batch
เปิด runtime batch ได้โดยใช้ context manager with Batch(...) หรือสร้าง instance ของ class Batch
เมื่อเริ่ม batch ต้องระบุ QPU โดยส่ง object backend เข้าไป batch จะเริ่มทำงานเมื่อ job แรกเริ่ม execute
Batch class
backend = service.least_busy(operational=True, simulator=False)
batch = Batch(backend=backend)
estimator = Estimator(mode=batch)
sampler = Sampler(mode=batch)
executor = Executor(mode=batch)
# Close the batch because no context manager was used.
batch.close()
Context manager
Context manager จะเปิดและปิด batch โดยอัตโนมัติ
from qiskit_ibm_runtime import (
Batch,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
Executor,
)
backend = service.least_busy(operational=True, simulator=False)
with Batch(backend=backend):
estimator = Estimator()
sampler = Sampler()
executor = Executor()
ระยะเวลา Batch
กำหนดเวลาสูงสุดที่ batch จะมีชีวิต (TTL) ได้ด้วย parameter max_time ควรตั้งค่าให้มากกว่าเวลา execute ของ job ที่ยาวที่สุด timer นี้เริ่มนับเมื่อ batch เริ่มทำงาน เมื่อถึงค่าที่กำหนด batch จะปิดลง job ที่กำลังรันอยู่จะทำงานจนเสร็จ แต่ job ที่ยังรออยู่ใน queue จะถูก fail
with Batch(backend=backend, max_time="25m"):
...
นอกจากนี้ยังมีค่า interactive time to live (interactive TTL) ที่ไม่สามารถปรับแต่งได้ (1 นาทีสำหรับทุกแผน) ถ้าไม่มี batch job ถูก queue ภายในช่วงเวลานั้น batch จะถูกปิดการใช้งานชั่วคราว
ค่า maximum TTL เริ่มต้น:
| ประเภท Instance | Maximum TTL เริ่มต้น |
|---|---|
| แผนแบบเสียเงินทุกประเภท | 8 ชั่วโมง |
| Open | 10 นาที |
เพื่อดู maximum TTL หรือ interactive TTL ของ batch ให้ทำตามขั้นตอนใน ดูรายละเอียด batch และหาค่า max_time หรือ interactive_timeout ตามลำดับ
ปิด batch
Batch จะปิดโดยอัตโนมัติเมื่อออกจาก context manager เมื่อออกจาก batch context manager แล้ว batch จะเข้าสู่สถานะ "In progress, not accepting new jobs" หมายความว่า batch จะยังคงประมวลผล job ที่กำลังรันหรืออยู่ใน queue ทั้งหมดจนกว่าจะถึงค่า maximum TTL หลังจาก job ทั้งหมดเสร็จสิ้น batch จะปิดทันที ไม่สามารถส่ง job ไปยัง batch ที่ปิดแล้วได้
from qiskit.quantum_info import SparsePauliOp
from qiskit.circuit import QuantumCircuit, Parameter
from qiskit.transpiler import generate_preset_pass_manager
import numpy as np
# This cell is hidden from users
service = QiskitRuntimeService()
backend = service.least_busy()
# Define two circuits, each with one parameter with two parameters.
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.ry(Parameter("a"), 0)
circuit.cx(0, 1)
circuit.h(0)
circuit.measure_all()
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
transpiled_circuit = pm.run(circuit)
transpiled_circuit_sampler = transpiled_circuit
transpiled_circuit_sampler.measure_all()
params = np.random.uniform(size=(2, 3)).T
observables = [
[
SparsePauliOp(["XX", "IY"], [0.5, 0.5]).apply_layout(
transpiled_circuit.layout
)
],
[SparsePauliOp("XX").apply_layout(transpiled_circuit.layout)],
[SparsePauliOp("IY").apply_layout(transpiled_circuit.layout)],
]
sampler_pub = (transpiled_circuit_sampler, params)
estimator_pub = (transpiled_circuit_sampler, observables, params)
with Batch(backend=backend) as batch:
estimator = Estimator()
sampler = Sampler()
job1 = estimator.run([estimator_pub])
job2 = sampler.run([sampler_pub])
# The batch is no longer accepting jobs but the submitted job will run to completion.
result = job1.result()
result2 = job2.result()
ถ้าไม่ได้ใช้ context manager ให้ปิด batch ด้วยตนเอง ถ้าปล่อย batch ค้างไว้และส่ง job เพิ่มเติมในภายหลัง อาจเกิดกรณีที่ maximum TTL ถึงค่าก่อนที่ job ใหม่จะเริ่มรัน ทำให้ถูกยกเลิก ปิด batch ได้ทันทีที่ส่ง job ครบแล้ว เมื่อปิด batch ด้วย batch.close() batch จะไม่รับ job ใหม่ แต่ job ที่ส่งไปแล้วจะยังคงรันจนเสร็จและดึงผลลัพธ์ได้
batch = Batch(backend=backend)
# If using qiskit-ibm-runtime earlier than 0.24.0, change `mode=` to `batch=`
estimator = Estimator(mode=batch)
sampler = Sampler(mode=batch)
job1 = estimator.run([estimator_pub])
job2 = sampler.run([sampler_pub])
print(f"Result1: {job1.result()}")
print(f"Result2: {job2.result()}")
# Manually close the batch. Running and queued jobs will run to completion.
batch.close()
Result1: PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(3, 2), dtype=float64>), stds=np.ndarray(<shape=(3, 2), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(3, 2), dtype=float64>), shape=(3, 2)), metadata={'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32})], metadata={'dynamical_decoupling': {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'}, 'twirling': {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'}, 'resilience': {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False}, 'version': 2})
Result2: PrimitiveResult([SamplerPubResult(data=DataBin(meas=BitArray(<shape=(3, 2), num_shots=4096, num_bits=2>), meas0=BitArray(<shape=(3, 2), num_shots=4096, num_bits=133>), shape=(3, 2)), metadata={'circuit_metadata': {}})], metadata={'execution': {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-02-15 07:58:55', stop='2026-02-15 07:59:02', size=24576>)])}, 'version': 2})
ดูรายละเอียด batch
เพื่อดูภาพรวมโดยละเอียดของการตั้งค่าและสถานะของ batch รวมถึง interactive และ max TTL ให้ใช้ method batch.details()
from qiskit_ibm_runtime import (
QiskitRuntimeService,
batch,
SamplerV2 as Sampler,
)
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
with Batch(backend=backend) as batch:
print(batch.details())
{'id': '970fe01d-d2cf-45f0-b32b-f886b987a462', 'backend_name': 'ibm_torino', 'interactive_timeout': 1, 'max_time': 28800, 'active_timeout': 28800, 'state': 'open', 'accepting_jobs': True, 'last_job_started': None, 'last_job_completed': None, 'started_at': None, 'closed_at': None, 'activated_at': None, 'mode': 'batch', 'usage_time': None}
ปรับแต่ง job เพื่อประมวลผลแบบขนาน
มีหลายวิธีในการปรับแต่ง job เพื่อใช้ประโยชน์จากการประมวลผลแบบขนานที่ batch มอบให้ ตัวอย่างต่อไปนี้แสดงวิธีการแบ่ง Circuit รายการยาวออกเป็น job หลายรายการและรันเป็น batch เพื่อใช้ประโยชน์จากการประมวลผลแบบขนาน
from qiskit_ibm_runtime import SamplerV2 as Sampler, Batch
from qiskit.circuit.random import random_circuit
max_circuits = 100
circuits = [pm.run(random_circuit(5, 5)) for _ in range(5 * max_circuits)]
for circuit in circuits:
circuit.measure_active()
all_partitioned_circuits = []
for i in range(0, len(circuits), max_circuits):
all_partitioned_circuits.append(circuits[i : i + max_circuits])
jobs = []
start_idx = 0
with Batch(backend=backend):
sampler = Sampler()
for partitioned_circuits in all_partitioned_circuits:
job = sampler.run(partitioned_circuits)
jobs.append(job)
ถ้าตั้งค่า backend=backend ใน primitive โปรแกรมจะรันในโหมด job แม้จะอยู่ภายใน batch หรือ session context ก็ตาม การตั้งค่า backend=backend เป็น deprecated ตั้งแต่ Qiskit Runtime v0.24.0 แนะนำให้ใช้ parameter mode แทน
ขั้นตอนถัดไป
- ลองทำตัวอย่างใน tutorial รวม error mitigation หลายตัวเลือกกับ Estimator primitive
- ดู reference ของ Batch API
- ทำความเข้าใจ ขีดจำกัดของ Job เมื่อส่ง job ไปยัง IBM® QPU
- ทบทวน คำถามที่พบบ่อยเกี่ยวกับ execution mode.