انتقل إلى المحتوى الرئيسي

تشغيل المهام في جلسة

Package versions

The code on this page was developed using the following requirements. We recommend using these versions or newer.

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
scipy~=1.16.3
Note

لا يستطيع مستخدمو الخطة المفتوحة (Open Plan) إرسال مهام الجلسات. يجب تشغيل أعباء العمل في وضع المهمة أو وضع الدُفعة.

استخدم الجلسات حين تحتاج إلى وصول حصري ومخصص إلى وحدة المعالجة الكمومية (QPU).

الإعداد لاستخدام الجلسات

قبل بدء الجلسة، يجب أن تُعدّ Qiskit Runtime وتُهيّئها كخدمة:

# 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,
)

service = QiskitRuntimeService()

فتح جلسة

يمكنك فتح جلسة runtime باستخدام مدير السياق with Session(...) أو بإنشاء نسخة من الصنف Session. عند بدء الجلسة، يجب تحديد وحدة QPU بتمرير كائن backend. تبدأ الجلسة فعليًا عند تنفيذ أول مهمة فيها.

ملاحظة

إذا فتحت جلسة ولم ترسل إليها أي مهام خلال 30 دقيقة، فستُغلق الجلسة تلقائيًا.

صنف Session

تنبيه

سيُعيد كتلة الكود التالية خطأً لمستخدمي الخطة المفتوحة لأنها تستخدم الجلسات. لا يمكن تشغيل أعباء العمل في الخطة المفتوحة إلا في وضع المهمة أو وضع الدُفعة.

backend = service.least_busy(operational=True, simulator=False)
session = Session(backend=backend)
estimator = Estimator(mode=session)
sampler = Sampler(mode=session)
# Close the session because no context manager was used.
session.close()

مدير السياق

يفتح مدير السياق الجلسةَ ويُغلقها تلقائيًا.

تنبيه

سيُعيد كتلة الكود التالية خطأً لمستخدمي الخطة المفتوحة لأنها تستخدم الجلسات. لا يمكن تشغيل أعباء العمل في الخطة المفتوحة إلا في وضع المهمة أو وضع الدُفعة.

from qiskit_ibm_runtime import (
Session,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
)

backend = service.least_busy(operational=True, simulator=False)
with Session(backend=backend):
estimator = Estimator()
sampler = Sampler()

مدة الجلسة

يحدد الحد الأقصى لوقت حياة الجلسة (TTL) المدة التي يمكن للجلسة تشغيلها. يمكنك ضبط هذه القيمة بالمعامل max_time، ويجب أن تتجاوز وقت تنفيذ أطول مهمة.

يبدأ هذا المؤقت عند بدء الجلسة. عند الوصول إلى القيمة المحددة، تُغلق الجلسة. أي مهام قيد التشغيل ستُكمل عملها، لكن المهام المنتظرة في الطابور ستفشل.

تنبيه

سيُعيد كتلة الكود التالية خطأً لمستخدمي الخطة المفتوحة لأنها تستخدم الجلسات. لا يمكن تشغيل أعباء العمل في الخطة المفتوحة إلا في وضع المهمة أو وضع الدُفعة.

with Session(backend=backend, max_time="25m"):
...

ثمة أيضًا قيمة لوقت حياة التفاعل (interactive TTL) لا يمكن تغييرها. إذا لم تُوضع أي مهام جلسة في الطابور خلال تلك الفترة، تُوقف الجلسة مؤقتًا.

القيم الافتراضية:

نوع الحساب (الخطة المفتوحة أو المميزة)وقت حياة التفاعلالحد الأقصى لوقت الحياة
الخطة المميزة (Premium Plan)60 ثانية*8 ساعات*
* قد تكون بعض نسخ الخطة المميزة مُهيَّأة بقيمة مختلفة.

لتحديد الحد الأقصى لوقت حياة الجلسة أو وقت حياة التفاعل، اتبع التعليمات في الاطلاع على تفاصيل الجلسة وابحث عن قيمة max_time أو interactive_timeout على التوالي.

إنهاء الجلسة

تنتهي الجلسة في الحالات التالية:

  • الوصول إلى الحد الأقصى لوقت المهلة (TTL)، مما يؤدي إلى إلغاء جميع المهام المنتظرة في الطابور.
  • إلغاء الجلسة يدويًا، مما يؤدي إلى إلغاء جميع المهام المنتظرة في الطابور.
  • إغلاق الجلسة يدويًا. تتوقف الجلسة عن قبول مهام جديدة لكنها تواصل تنفيذ المهام المنتظرة بأولوية.
  • عند استخدام Session كمدير سياق، أي with Session()، تُغلق الجلسة تلقائيًا عند انتهاء السياق (نفس سلوك session.close()).

إغلاق الجلسة

تُغلق الجلسة تلقائيًا عند الخروج من مدير السياق. حين يُغادَر سياق الجلسة، تدخل الجلسة في حالة "قيد التشغيل، لا تقبل مهامًا جديدة". هذا يعني أن الجلسة تُكمل معالجة جميع المهام الجارية أو المنتظرة حتى الوصول إلى الحد الأقصى لوقت المهلة. بعد اكتمال جميع المهام، تُغلق الجلسة فورًا. يتيح هذا للجدولة تشغيل المهمة التالية دون انتظار مهلة تفاعل الجلسة، مما يُقلل من متوسط وقت انتظار المهام. لا يمكنك إرسال مهام إلى جلسة مغلقة.

تنبيه

سيُعيد كتلة الكود التالية خطأً لمستخدمي الخطة المفتوحة لأنها تستخدم الجلسات. لا يمكن تشغيل أعباء العمل في الخطة المفتوحة إلا في وضع المهمة أو وضع الدُفعة.

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()
نصيحة

إذا لم تكن تستخدم مدير السياق، أغلق الجلسة يدويًا لتفادي أي تكاليف غير مقصودة. يمكنك إغلاق الجلسة فور الانتهاء من إرسال المهام إليها. حين تُغلق الجلسة باستخدام session.close()، لن تقبل مهامًا جديدة، لكن المهام المُرسلة مسبقًا ستواصل التشغيل حتى الاكتمال ويمكن استرداد نتائجها.

تنبيه

سيُعيد كتلة الكود التالية خطأً لمستخدمي الخطة المفتوحة لأنها تستخدم الجلسات. لا يمكن تشغيل أعباء العمل في الخطة المفتوحة إلا في وضع المهمة أو وضع الدُفعة.

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=133>), shape=(3, 2)), metadata={'circuit_metadata': {}})], metadata={'execution': {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-01-15 07:53:15', stop='2026-01-15 07:53:21', size=24576>)])}, 'version': 2})

التحقق من حالة الجلسة

يمكنك الاستعلام عن حالة الجلسة لمعرفة وضعها الحالي باستخدام session.status() أو بزيارة صفحة أعباء العمل.

يمكن أن تكون حالة الجلسة إحدى الحالات التالية:

  • Pending: الجلسة لم تبدأ بعد أو تم إيقافها مؤقتًا. تحتاج مهمة الجلسة التالية إلى الانتظار في الطابور مثل سائر المهام.
  • In progress, accepting new jobs: الجلسة نشطة وتقبل مهامًا جديدة.
  • In progress, not accepting new jobs: الجلسة نشطة لكنها لا تقبل مهامًا جديدة. يُرفض إرسال المهام إلى الجلسة، لكن المهام القائمة ستُكمل تشغيلها. تُغلق الجلسة تلقائيًا بعد انتهاء جميع المهام.
  • Closed: تم الوصول إلى الحد الأقصى لوقت مهلة الجلسة، أو تم إغلاقها صراحةً.

الاطلاع على تفاصيل الجلسة

للحصول على نظرة شاملة على إعدادات الجلسة وحالتها، استخدم session.details() method.

تنبيه

سيُعيد كتلة الكود التالية خطأً لمستخدمي الخطة المفتوحة لأنها تستخدم الجلسات. لا يمكن تشغيل أعباء العمل في الخطة المفتوحة إلا في وضع المهمة أو وضع الدُفعة.

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': 'be84569d-86b5-4a7f-be5e-7d33e80dc220', '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}

أنماط الاستخدام

الجلسات مفيدة بشكل خاص للخوارزميات التي تتطلب تواصلًا متكررًا بين الموارد الكلاسيكية والكمومية.

مثال: تشغيل عبء عمل تكراري يستخدم المُحسِّن الكلاسيكي SciPy لتقليل دالة التكلفة. في هذا النموذج، يستخدم SciPy ناتج دالة التكلفة لحساب مدخله التالي.

تنبيه

سيُعيد كتلة الكود التالية خطأً لمستخدمي الخطة المفتوحة لأنها تستخدم الجلسات. لا يمكن تشغيل أعباء العمل في الخطة المفتوحة إلا في وضع المهمة أو وضع الدُفعة.

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 في جلسة واحدة باستخدام الخيوط المتوازية

يمكنك الاستفادة أكثر من الجلسة بتشغيل أعباء عمل متعددة في وقت واحد. يوضح المثال التالي كيف يمكنك تشغيل خوارزميتَي VQE، كل منهما باستخدام مُحسِّن كلاسيكي مختلف، في وقت واحد داخل جلسة واحدة. كما تُستخدم وسوم المهام للتمييز بين مهام كل عبء عمل.

تنبيه

سيُعيد كتلة الكود التالية خطأً لمستخدمي الخطة المفتوحة لأنها تستخدم الجلسات. لا يمكن تشغيل أعباء العمل في الخطة المفتوحة إلا في وضع المهمة أو وضع الدُفعة.

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()

الخطوات التالية

Recommendations