شغّل مهام كمّية من سير عمل
إصدارات الحزم
تم تطوير الكود في هذه الصفحة باستخدام المتطلبات التالية. نوصي باستخدام هذه الإصدارات أو الأحدث منها.
qiskit[all]~=2.6.1
qiskit-ibm-runtime~=0.51.0
qiskit-serverless~=0.38.0
يعمل سير العمل الكمّي-الكلاسيكي كمهمة سير عمل مُدار واحدة. تعمل مراحله الكلاسيكية على ملف الحوسبة الخاص بك، وتعمل مهام الـ primitive التي يرسلها إلى QPU من IBM Quantum® على نسختك (instance) وتُحتسب ضمن استخدامك. من هذه المهمة الواحدة، يمكنك الإبلاغ عن كل مرحلة، والعثور على مهام QPU، وإلغائها. لبدء مهمة والتحقق من حالتها وسجلاتها، راجع تشغيل سير عمل مُدار.
قبل أن تبدأ، انشر أول سير عمل مُدار لك.
إنشاء خدمة Runtime
أنشئ خدمة Runtime في كود سير العمل باستخدام get_runtime_service()، واستخدمها بالطريقة نفسها التي تستخدم بها QiskitRuntimeService محليًا. يشغّل سير العمل التالي دائرة Bell باستخدام Sampler primitive، ويُبلغ عن كل مرحلة باستخدام update_status()، ويُرجع العدّادات:
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"qiskit": "qiskit", "qiskit_ibm_catalog": "qiskit-ibm-catalog", "qiskit_ibm_runtime": "qiskit-ibm-runtime", "qiskit_serverless": "qiskit-serverless"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
# This cell is hidden from users. It creates the working directory.
from pathlib import Path
Path("./source_files").mkdir(exist_ok=True)
%%writefile ./source_files/my_workflow.py
from qiskit import QuantumCircuit
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime.executor_sampler import Sampler
from qiskit_serverless import (
Job,
get_arguments,
get_runtime_service,
save_result,
update_status,
)
arguments = get_arguments()
service = get_runtime_service()
backend = service.backend(arguments["backend_name"])
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
update_status(Job.OPTIMIZING_HARDWARE)
pass_manager = generate_preset_pass_manager(optimization_level=1, backend=backend)
isa_circuit = pass_manager.run(circuit)
update_status(Job.WAITING_QPU)
sampler = Sampler(mode=backend)
primitive_job = sampler.run([isa_circuit])
counts = primitive_job.result()[0].data.meas.get_counts()
update_status(Job.POST_PROCESSING)
save_result({"backend": backend.name, "counts": counts})
Overwriting ./source_files/my_workflow.py
تُرجع get_runtime_service() كائن QiskitRuntimeService مُعدًّا لمهمة سير العمل المُدار الخاصة بك، وهو يوفر ما يلي:
-
بيانات الاعتماد. تستخدم خدمة Runtime مفتاح API والنسخة (instance) والقناة التي استخدمتها لاستدعاء
run()، لذا لا يحتاج كود سير العمل إلى أي بيانات اعتماد. -
التتبع. يسجّل سير العمل كل مهمة primitive تعمل عبر خدمة Runtime هذه ضمن مهمة سير العمل المُدار، بما في ذلك مهام Sampler وEstimator وExecutor، والمهام داخل جلسة أو دفعة. يمكنك سردها باستخدام
job.runtime_jobs(). -
الإلغاء. عندما تستدعي
job.cancel()، يُلغي سير العمل المُدار أيضًا جلسات سير العمل ودفعاته ومهام الـ primitive التي لا تزال قيد التشغيل.
لا يتتبع سير العمل المُدار مهام خدمة تنشئها باستخدام QiskitRuntimeService() ولا يُلغيها، مع أن المهام تظل تعمل. إذا كان على سير العمل استخدام خدمة أخرى، فألغِ مهامها في معالج SIGTERM.
شغّل الـ primitives في جلسة أو دفعة
يتتبع سير العمل المُدار أيضًا مهام الـ primitive التي تعمل في جلسة أو دفعة. أنشئ الجلسة أو الدفعة من backend أرجعته خدمة Runtime، وأنشئ الـ primitives داخل كتلة with. تعمل Session بالطريقة نفسها:
source_files/my_workflow.py
from qiskit_ibm_runtime import Batch
with Batch(backend=backend) as batch:
sampler = Sampler(mode=batch)
primitive_jobs = [sampler.run([isa_circuit]) for _ in range(2)]
results = [primitive_job.result() for primitive_job in primitive_jobs]
الإبلاغ عن التقدم باستخدام update_status()
يستدعي سير العمل في إنشاء خدمة Runtime الدالة update_status() في بداية كل مرحلة، بحيث تُظهر حالة المهمة أين وصل سير العمل، مثل RUNNING: WAITING_FOR_QPU. مرّر إحدى ثوابت Job التالية:
| الاستدعاء في سير العمل | حالة المهمة |
|---|---|
update_status(Job.MAPPING) | RUNNING: MAPPING |
update_status(Job.OPTIMIZING_HARDWARE) | RUNNING: OPTIMIZING_FOR_HARDWARE |
update_status(Job.WAITING_QPU) | RUNNING: WAITING_FOR_QPU |
update_status(Job.EXECUTING_QPU) | RUNNING: EXECUTING_QPU |
update_status(Job.POST_PROCESSING) | RUNNING: POST_PROCESSING |
تُرجع update_status() القيمة True إذا غيّر سير العمل الحالة. وتُرجع False وتكتب تحذيرًا في السجلات إذا لم تكن القيمة إحدى هذه الثوابت، أو إذا لم تعد المهمة نشطة، أو إذا كان الكود يعمل خارج مهمة. ولا تُطلق خطأً، لذا لا يوقف الخطأ المطبعي سير العمل.
للتقدم داخل مرحلة، مثل تكرارات المُحسِّن، اكتب أسطر سجل.
العثور على مهام QPU الخاصة بتشغيل ما
في دفتر الملاحظات المحلي، اختر QPU يمكن لنسختك (instance) الوصول إليها. تسردها client.backends()، وتُرجع client.least_busy() الأقل انشغالًا، أي التي لديها أقل عدد من المهام المعلّقة:
from qiskit_ibm_catalog import ManagedWorkflowClient
client = ManagedWorkflowClient()
print([backend.name for backend in client.backends(simulator=False)])
backend_name = client.least_busy(operational=True, simulator=False).name
['ibm_boston', 'ibm_fez', 'ibm_kingston', 'ibm_marrakesh', 'ibm_phoenix', 'ibm_pittsburgh']
ارفع سير العمل، ومرّر اسم الـ backend عند تشغيله:
from qiskit_ibm_catalog import ManagedWorkflow
my_workflow = client.upload(
ManagedWorkflow(
title="my-workflow",
entrypoint="my_workflow.py",
working_dir="./source_files/",
)
)
job = my_workflow.run(backend_name=backend_name)
# This cell is hidden from users. It waits for the job to finish.
assert job.wait_for_final_state() == "DONE", job.logs()
بعد انتهاء المهمة، احصل على معرّفات مهام QPU الخاصة بسير العمل من مهمة سير العمل المُدار:
runtime_job_ids = job.runtime_jobs()
runtime_job_ids
['dbl6lst8ft8s738secf0']
# This cell is hidden from users. It checks the tracked job.
assert len(runtime_job_ids) == 1, runtime_job_ids
كل معرّف هو معرّف مهمة primitive عادي. لقراءة حالة مهمة ونتائجها، راجع استرجاع نتائج المهمة لاحقًا.
إذا شغّل سير العمل primitives في جلسة أو دفعة، فاسرد معرّفات الجلسات والدفعات باستخدام runtime_sessions()، ومرّر أحدها إلى runtime_jobs() للحصول على المهام التي فيه فقط:
run_workflow_remotely.ipynb
for session_id in job.runtime_sessions():
print(session_id, job.runtime_jobs(session_id))
dc101077-d085-40fb-8fbe-78852e355994 ['dbjqp48nceqs73aki1k0', 'dbjqp4l6p51s73clb91g']
الكائن job موجود فقط في دفتر الملاحظات الذي بدأ التشغيل. في دفتر ملاحظات جديد، احصل على المهمة مرة أخرى باستخدام client.job("<your-job-id>")، ثم استدعِ runtime_jobs() عليها. راجع العثور على مهمة من جلسة جديدة.
لمعرفة استخدام QPU وأوقات التشغيل لكل مهمة QPU، راجع عرض مقاييس المهمة. ولمعرفة استخدام نسختك (instance) بالكامل في الفترة الحالية، استدعِ client.usage(). ولمعرفة المدة التي استغرقتها كل مرحلة من مهمة سير العمل المُدار، راجع التحقق من مدة كل مرحلة.
إلغاء مهام QPU المرتبطة
عندما تُلغي مهمة سير عمل مُدار باستخدام job.cancel()، يحاول سير العمل أيضًا إلغاء عمل QPU الذي بدأه:
-
الجلسات والدفعات. يُلغي سير العمل كل جلسة ودفعة تخصّه، ما يُلغي أيضًا مهامها في الطابور.
-
مهام primitive الأخرى. يُلغي سير العمل كل مهمة primitive أخرى تخصّه ولا تزال في الطابور أو قيد التشغيل.
تُرجع job.cancel() رسالة لكل مهمة QPU وجلسة، بحيث يمكنك التحقق مما أُلغي:
run_workflow_remotely.ipynb
print(job.cancel())
بالنسبة لسير عمل شُغّل في دفعة، تبدو الرسالة كما يلي:
Job is stopping. Canceled runtime session: eb8874c9-a15e-45f8-9a90-a9fb35267f9d and associated runtime jobs.
إذا لم يستطع العميل إنشاء QiskitRuntimeService من بيانات الاعتماد المحلية الخاصة بك، فإنه يُلغي مهمة سير العمل المُدار فقط. ألغِ مهام QPU بنفسك باستخدام معرّفاتها من job.runtime_jobs().
عندما يوقف سير العمل مهمة بنفسه، على سبيل المثال لأنها وصلت إلى حد الـ 24 ساعة، فإنه لا يُلغي مهام QPU الخاصة بها. ألغِها باستخدام معرّفاتها من job.runtime_jobs().
استكشاف أخطاء مهام QPU في سير العمل وإصلاحها
| المشكلة | السبب |
|---|---|
تُطلق get_runtime_service() الخطأ KeyError: 'QISKIT_IBM_CHANNEL'. | الكود يعمل في دفتر الملاحظات المحلي، وليس في مهمة سير عمل مُدار. استخدم QiskitRuntimeService() محليًا. |
تُرجع update_status() القيمة False، وتُظهر السجلات 'sub_status' not provided or is not valid. | القيمة ليست إحدى ثوابت Job، أو لم تعد المهمة نشطة. |
تُرجع job.runtime_jobs() القيمة []. | أنشأ سير العمل خدمته باستخدام QiskitRuntimeService()، أو لم يشغّل أي primitive بعد. |
| مهام الجلسة غير متتبَّعة. | أُنشئت الجلسة من backend تابع لخدمة مختلفة. احصل على الـ backend من get_runtime_service(). |
تُظهر سجلات سير العمل Could not associate runtime job with serverless job. | لم يتمكن سير العمل من تسجيل مهمة primitive. تظل مهمة الـ primitive تعمل، لكنها غير متتبَّعة. |
تُظهر job.cancel() الرسالة No QiskitRuntimeService can be associated to the given token and instance. | لم يتمكن العميل من إنشاء QiskitRuntimeService من بيانات الاعتماد المحلية الخاصة بك، فأُلغيت مهمة سير العمل المُدار فقط. |
تفشل client.job() مع Job [...] not found. | معرّف المهمة خاطئ، أو أن المهمة تخص مستخدمًا آخر. |
الخطوات التالية
- شغّل سير عمل مُدار للتحقق من حالة المهمة ونتيجتها وسجلاتها، ولإيجاد سبب الخطأ.