รันงานใน Session
เวอร์ชันของแพ็กเกจ
โค้ดในหน้านี้พัฒนาขึ้นโดยใช้ requirement ต่อไปนี้ แนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า
qiskit[all]~=2.3.1
qiskit-ibm-runtime~=0.45.0
scipy~=1.17.1
ผู้ใช้แผน Open ไม่สามารถส่ง session job ได้ งานต้องรันในโหมด job mode หรือ batch mode
ใช้ Session เมื่อต้องการสิทธิ์การเข้าถึง QPU แบบ dedicated และ exclusive
ตั้งค่าเพื่อใช้งาน Session
ก่อนเริ่ม session ต้องตั้งค่า Qiskit Runtime และ initialize เป็น service ก่อน:
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime scipy
from qiskit_ibm_runtime import (
QiskitRuntimeService,
Session,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
Executor,
)
service = QiskitRuntimeService()
เปิด Session
เปิด runtime session ได้โดยใช้ context manager with Session(...) หรือสร้าง instance ของ class Session
เมื่อเริ่ม session ต้องระบุ QPU โดยส่ง object backend เข้าไป session จะเริ่มทำงานเมื่อ job แรกเริ่ม execute
ถ้าเปิด session แต่ไม่ส่ง job ใดเลยเป็นเวลา 30 นาที session จะปิดโดยอัตโนมัติ
Session class
โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น
backend = service.least_busy(operational=True, simulator=False)
session = Session(backend=backend)
estimator = Estimator(mode=session)
sampler = Sampler(mode=session)
executor = Executor(mode=session)
# Close the session because no context manager was used.
session.close()
Context manager
Context manager จะเปิดและปิด session โดยอัตโนมัติ
โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น
from qiskit_ibm_runtime import (
Session,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
Executor,
)
backend = service.least_busy(operational=True, simulator=False)
with Session(backend=backend):
estimator = Estimator()
sampler = Sampler()
executor = Executor()
ระยะเวลา Session
เวลาสูงสุดที่ session จะมีชีวิต (TTL) กำหนดว่า session จะรันได้นานแค่ไหน ตั้งค่านี้ได้ด้วย parameter max_time ควรตั้งให้มากกว่าเวลา execute ของ job ที่ยาวที่สุด
timer นี้เริ่มนับเมื่อ session เริ่มทำงาน เมื่อถึงค่าที่กำหนด session จะปิดลง job ที่กำลังรันอยู่จะทำงานจนเสร็จ แต่ job ที่ยังรออยู่ใน queue จะถูก fail
โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น
with Session(backend=backend, max_time="25m"):
...
นอกจากนี้ยังมีค่า interactive time to live (interactive TTL) ที่ไม่สามารถปรับแต่งได้ ถ้าไม่มี session job ถูก queue ภายในช่วงเวลานั้น session จะถูกปิดการใช้งานชั่วคราว
ค่าเริ่มต้น:
| ประเภท Instance (แผน Open หรือ Premium) | Interactive TTL | Maximum TTL |
|---|---|---|
| Premium Plan | 60 วินาที* | 8 ชั่วโมง* |
| * instance บางส่วนของ Premium Plan อาจตั้งค่าไว้แตกต่างออกไป |
เพื่อดู max TTL หรือ interactive TTL ของ session ให้ทำตามขั้นตอนใน ดูรายละเอียด session และหาค่า max_time หรือ interactive_timeout ตามลำดับ
สิ้นสุด Session
Session สิ้นสุดในกรณีต่อไปนี้:
- ถึงค่า timeout สูงสุด (TTL) ส่งผลให้ job ทั้งหมดที่อยู่ใน queue ถูกยกเลิก
- Session ถูกยกเลิกด้วยตนเอง ส่งผลให้ job ทั้งหมดที่อยู่ใน queue ถูกยกเลิก
- Session ถูกปิดด้วยตนเอง session จะหยุดรับ job ใหม่แต่ยังคงรัน job ที่อยู่ใน queue ด้วยลำดับความสำคัญ
- ถ้าใช้ Session เป็น context manager นั่นคือ
with Session()session จะปิดโดยอัตโนมัติเมื่อ context สิ้นสุด (พฤติกรรมเดียวกับการใช้session.close())
ปิด Session
Session จะปิดโดยอัตโนมัติเมื่อออกจาก context manager เมื่อออกจาก session context manager แล้ว session จะเข้าสู่สถานะ "In progress, not accepting new jobs" หมายความว่า session จะยังคงประมวลผล job ที่กำลังรันหรืออยู่ใน queue ทั้งหมดจนกว่าจะถึงค่า maximum timeout หลังจาก job ทั้งหมดเสร็จสิ้น session จะปิดทันที วิธีนี้ช่วยให้ scheduler รัน job ถัดไปได้โดยไม่ต้องรอ session interactive timeout จึงลดเวลา queue เฉลี่ยของ job ไม่สามารถส่ง job ไปยัง session ที่ปิดแล้วได้
โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น
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()
# Create parameters and mapped observables to submit
params = np.random.uniform(size=(2, 3)).T
observables = [
SparsePauliOp(["XX", "IY"], [0.5, 0.5]),
SparsePauliOp("XX"),
SparsePauliOp("IY"),
]
mapped_observables = [
[observable.apply_layout(transpiled_circuit.layout)]
for observable in observables
]
sampler_pub = (transpiled_circuit_sampler, params)
estimator_pub = (transpiled_circuit_sampler, mapped_observables, params)
with Session(backend=backend) as session:
estimator = Estimator()
sampler = Sampler()
job1 = estimator.run([estimator_pub])
job2 = sampler.run([sampler_pub])
# The session is no longer accepting jobs but the submitted job will run to completion.
result = job1.result()
result2 = job2.result()
ถ้าไม่ได้ใช้ context manager ให้ปิด session ด้วยตนเองเพื่อหลีกเลี่ยงค่าใช้จ่ายที่ไม่ต้องการ ปิด session ได้ทันทีที่ส่ง job ครบแล้ว เมื่อปิด session ด้วย session.close() session จะไม่รับ job ใหม่ แต่ job ที่ส่งไปแล้วจะยังคงรันจนเสร็จและดึงผลลัพธ์ได้
โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น
session = Session(backend=backend)
# If using qiskit-ibm-runtime earlier than 0.24.0, change `mode=` to `session=`
estimator = Estimator(mode=session)
sampler = Sampler(mode=session)
job1 = estimator.run([estimator_pub])
job2 = sampler.run([sampler_pub])
print(f"Result1: {job1.result()}")
print(f"Result2: {job2.result()}")
# Manually close the session. Running and queued jobs will run to completion.
session.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=156>), shape=(3, 2)), metadata={'circuit_metadata': {}})], metadata={'execution': {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-03-15 07:33:44', stop='2026-03-15 07:33:51', size=24576>)])}, 'version': 2})
ตรวจสอบสถานะ Session
ดูสถานะของ session เพื่อทำความเข้าใจสถานะปัจจุบันได้ด้วย session.status() หรือดูที่หน้า Workloads
สถานะของ session มีได้ดังนี้:
Pending: Session ยังไม่เริ่มหรือถูกปิดการใช้งานชั่วคราว session job ถัดไปต้องรอใน queue เหมือน job ทั่วไปIn progress, accepting new jobs: Session กำลังทำงานและรับ job ใหม่ได้In progress, not accepting new jobs: Session กำลังทำงานแต่ไม่รับ job ใหม่ การส่ง job เข้า session จะถูกปฏิเสธ แต่ session job ที่ค้างอยู่จะรันจนเสร็จ session จะปิดโดยอัตโนมัติเมื่อ job ทั้งหมดเสร็จClosed: ถึงค่า maximum timeout ของ session หรือ session ถูกปิดอย่างชัดเจน
ดูรายละเอียด Session
เพื่อดูภาพรวมโดยละเอียดของการตั้งค่าและสถานะของ session ให้ใช้ method session.details()
โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น
from qiskit_ibm_runtime import (
QiskitRuntimeService,
Session,
EstimatorV2 as Estimator,
)
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
with Session(backend=backend) as session:
print(session.details())
{'id': 'a9fd2f9d-6239-4451-a19c-9b45aa6a0618', 'backend_name': 'ibm_torino', 'interactive_timeout': 60, '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': 'dedicated', 'usage_time': None}
รูปแบบการใช้งาน
Session มีประโยชน์อย่างมากสำหรับ algorithm ที่ต้องการการสื่อสารบ่อยครั้งระหว่าง classical และ quantum resources
ตัวอย่าง: รัน iterative workload ที่ใช้ classical SciPy optimizer เพื่อ minimize cost function ในโมเดลนี้ SciPy ใช้ output ของ cost function เพื่อคำนวณ input ถัดไป
โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น
from scipy.optimize import minimize
from qiskit.circuit.library import efficient_su2
def cost_func(params, ansatz, hamiltonian, estimator):
# Return estimate of energy from estimator
energy = sum(
estimator.run([(ansatz, hamiltonian, params)]).result()[0].data.evs
)
return energy
hamiltonian = SparsePauliOp.from_list(
[("YZ", 0.3980), ("ZI", -0.3980), ("ZZ", -0.0113), ("XX", 0.1810)]
)
su2_ansatz = efficient_su2(hamiltonian.num_qubits)
pm = generate_preset_pass_manager(backend=backend, optimization_level=3)
ansatz = pm.run(su2_ansatz)
mapped_hamiltonian = [
operator.apply_layout(ansatz.layout) for operator in hamiltonian
]
num_params = ansatz.num_parameters
x0 = 2 * np.pi * np.random.random(num_params)
session = Session(backend=backend)
# If using qiskit-ibm-runtime earlier than 0.24.0, change `mode=` to `session=`
estimator = Estimator(mode=session, options={"default_shots": int(1e4)})
res = minimize(
cost_func,
x0,
args=(ansatz, mapped_hamiltonian, estimator),
method="cobyla",
options={"maxiter": 25},
)
# Close the session because no context manager was used.
session.close()
รัน VQE สองตัวใน Session โดยใช้ threading
ใช้ประโยชน์จาก session ได้มากขึ้นด้วยการรัน workload หลายรายการพร้อมกัน ตัวอย่างต่อไปนี้แสดงวิธีการรัน VQE algorithm สองตัวที่ใช้ classical optimizer ต่างกัน พร้อมกันภายใน session เดียว มีการใช้ job tag เพื่อแยกแยะ job จาก workload แต่ละรายการด้วย
โค้ดบล็อกต่อไปนี้จะเกิด error สำหรับผู้ใช้แผน Open เนื่องจากใช้ session งานในแผน Open รันได้เฉพาะในโหมด job mode หรือ batch mode เท่านั้น
from concurrent.futures import ThreadPoolExecutor
from qiskit_ibm_runtime import EstimatorV2 as Estimator
def minimize_thread(estimator, method):
return minimize(
cost_func,
x0,
args=(ansatz, mapped_hamiltonian, estimator),
method=method,
options={"maxiter": 25},
)
with Session(backend=backend), ThreadPoolExecutor() as executor:
estimator1 = Estimator()
estimator2 = Estimator()
# Use different tags to differentiate the jobs.
estimator1.options.environment.job_tags = ["cobyla"]
estimator2.options.environment.job_tags = ["nelder-mead"]
# Submit the two workloads.
cobyla_future = executor.submit(minimize_thread, estimator1, "cobyla")
nelder_mead_future = executor.submit(
minimize_thread, estimator2, "nelder-mead"
)
# Get workload results.
cobyla_result = cobyla_future.result()
nelder_mead_result = nelder_mead_future.result()
ขั้นตอนถัดไป
- ลองทำตัวอย่างใน tutorial Quantum approximate optimization algorithm (QAOA)
- ดู reference ของ Session API
- ทำความเข้าใจ ขีดจำกัดของ Job เมื่อส่ง job ไปยัง IBM® QPU
- ทบทวน คำถามที่พบบ่อยเกี่ยวกับ execution mode