تصوير توقيت الدائرة
إصدارات الحزم
تم تطوير الكود في هذه الصفحة باستخدام المتطلبات التالية. نوصي باستخدام هذه الإصدارات أو أحدث.
qiskit[all]~=2.6.1
qiskit-ibm-runtime~=0.50.0
على الرغم من أن رسم الخط الزمني المضمَّن في Qiskit مفيد للدوائر الثابتة، فإنه قد لا يعكس بدقة توقيت الدوائر الديناميكية بسبب العمليات الضمنية مثل البث وتحديد الفروع. كجزء من دعم الدوائر الديناميكية، يُعيد IBM Quantum Compute Service معلومات توقيت الدائرة الدقيقة داخل نتائج المهمة عند الطلب.
- هذه وظيفة تجريبية، وهي في مرحلة الإصدار التجريبي المسبق، ولذلك قد تتغيّر.
- تنطبق هذه الوظيفة فقط على مهام IBM Quantum Sampler وExecutor.
- على الرغم من أن إجمالي وقت الدائرة يُعاد في بيانات وصفية "compilation"، إلا أن هذا ليس الوقت المُستخدَم للفوترة (وقت QPU).
يعمل هذا الخيار أيضاً مع وظائف التشغيل التجريبي. مرّر dry_run=True إلى run() للحصول على جدول التوقيت الزمني للدائرة دون استخدام أي وقت QPU.
تمكين استرداد بيانات التوقيت
لتمكين استرداد بيانات التوقيت، اضبط علامة scheduler_timing التجريبية على True عند تشغيل مهمة الـ primitive.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"qiskit": "qiskit", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_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")
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.transpiler import generate_preset_pass_manager
# Legacy server-side primitive before qiskit-ibm-runtime v0.50.0
# from qiskit_ibm_runtime import Sampler
# Client-side primitive introduced in qiskit-ibm-runtime v0.50.0
from qiskit_ibm_runtime.executor_sampler import Sampler
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)
sampler = Sampler(backend)
sampler.options.experimental = {
"execution": {
"scheduler_timing": True,
},
}
sampler_job = sampler.run([isa_circuit])
result = sampler_job.result()
الوصول إلى بيانات توقيت الدائرة
عند الطلب، تُعاد بيانات توقيت الدائرة لكل PUB في البيانات الوصفية لنتيجة المهمة، ضمن ["compilation"]["scheduler_timing"]["timing"]. يحتوي هذا الحقل على معلومات التوقيت الخام. لعرض معلومات التوقيت، استخدم أداة التصوير المضمَّنة كما هو موضح في قسم تصوير التوقيتات.
استخدم الكود التالي للوصول إلى بيانات توقيت الدائرة للـ PUB الأول:
job_result = sampler_job.result()
circuit_schedule = job_result[0].metadata["compilation"]["scheduler_timing"]
circuit_schedule_timing = circuit_schedule["timing"]
فهم بيانات التوقيت الخام
على الرغم من أن تصوير بيانات توقيت الدائرة باستخدام طريقة draw_circuit_schedule_timing هو الاستخدام الأكثر شيوعًا، قد يكون من المفيد فهم هيكل بيانات التوقيت الخام المُعادة. يمكن أن يساعدك ذلك مثلاً في استخراج المعلومات برمجيًا.
بيانات التوقيت المُعادة في ["compilation"]["scheduler_timing"]["timing"] هي قائمة من السلاسل النصية. كل سلسلة تمثل تعليمة واحدة على قناة ما، وهي مفصولة بفاصلة إلى أنواع البيانات التالية:
-
Branch- يُحدِّد ما إذا كانت التعليمة في تدفق تحكم (then / else) أو فرع رئيسي. -
Instruction- البوابة والـ qubit المُراد التشغيل عليه. -
Channel- القناة المُخصَّصة للتعليمة. يمكن أن تكون إحدى التالية:-
Qubit x- قناة التشغيل للكيوبت x. -
AWGRx_y(مولِّد أشكال موجية اعتباطية للقراءة) - تُستخدَم بواسطة قنوات القراءة للتواصل عند قياس الكيوبتات. تتوافق الوسيطتان x و_y_ مع معرِّف أداة القراءة ورقم الكيوبت على التوالي.
-
-
T0- وقت بدء التعليمة ضمن الجدول الكامل -
Duration- مدة التعليمة بوحدات ثوانٍ dt، حيث 1 dt = دورة جدولة واحدة. يمكنك إيجاد قيمةdtللـ Backend باستخدامbackend.dt. -
Pulse- نوع عملية النبضة المُستخدَمة.
مثال:
main,barrier,Qubit 0,7,0,barrier # A barrier on the main branch on qubit 0 at time 7 with 0 duration
main,reset_0,Qubit 0,7,64,play # A reset instruction on the main branch on qubit 0 at time 7 with duration 64 and a play operation
...
تصوير التوقيتات
مع qiskit-ibm-runtime الإصدار v0.43.0 أو أحدث، يمكنك تصوير توقيتات الدائرة. للتصوير، تحتاج أولاً إلى تحويل البيانات الوصفية للنتيجة إلى fig باستخدام طريقة draw_circuit_schedule_timing. تُعيد هذه الطريقة شكل plotly، يمكنك عرضه مباشرةً أو حفظه في ملف أو كليهما. لمزيد من المعلومات حول أوامر plotly المُستخدَمة، راجع fig.show() وfig.write_image("<path.format>").
from qiskit_ibm_runtime.visualization import draw_circuit_schedule_timing
# Create a figure from the metadata
fig = draw_circuit_schedule_timing(
circuit_schedule=circuit_schedule_timing,
included_channels=None,
filter_readout_channels=False,
filter_barriers=False,
width=1000,
)
# Uncomment the following line to display the figure
# fig.show(renderer="notebook")
# Save to a file
# fig.write_html("scheduler_timing.html")

فهم الشكل المولَّد
تُعبِّر صورة بيانات توقيت الدائرة المُخرَجة بواسطة draw_circuit_schedule_timing عن المعلومات التالية:
-
المحور السيني هو الوقت بوحدات ثوانٍ dt، حيث 1 dt = دورة جدولة واحدة. يمكنك إيجاد قيمة
dtللـ Backend باستخدامbackend.dt. -
المحور الصادي هو القناة (فكِّر في القنوات كأدوات تُصدِر نبضات).
-
Receive channel- القناة الوحيدة التي ليست أداة بذاتها. هي تعليمة تُشغَّل على جميع القنوات التي تكون جزءًا من إجراء تواصل مع الموزِّع (Hub) في ذلك الوقت. -
Qubit x- قناة التشغيل للكيوبت x. -
AWGRx_y(مولِّد أشكال موجية اعتباطية للقراءة) - تُستخدَم بواسطة قنوات القراءة للتواصل عند قياس الكيوبتات. تتوافق الوسيطتان x و_y_ مع معرِّف أداة القراءة ورقم الكيوبت على التوالي. -
Hub- يتحكم في البث.
-
بالإضافة إلى ذلك، كل تعليمة لها تنسيق X_Y، حيث X هو اسم التعليمة وY هو نوع النبضة. نوع play يُطبِّق نبضات التحكم، ونوع capture يُسجِّل حالة الـ qubit. يمكنك أيضًا التمرير فوق كل تعليمة للحصول على مزيد من التفاصيل. على سبيل المثال، يُظهِر الشكل السابق نبضة تحكم لبوابة X المُطبَّقة على الـ qubit 10 عند 1161 dt.
مثال شامل
يُوضِّح هذا المثال كيفية تمكين الخيار، والحصول على معلومات توقيت الدائرة من البيانات الوصفية، وعرضها كصورة.
أولاً، هيِّئ البيئة وحدِّد الدوائر وحوِّلها إلى دوائر من نوع ISA، وحدِّد المهام وشغِّلها.
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit.transpiler import generate_preset_pass_manager
# Legacy server-side primitive before qiskit-ibm-runtime v0.50.0
# from qiskit_ibm_runtime import Sampler
# Client-side primitive introduced in qiskit-ibm-runtime v0.50.0
from qiskit_ibm_runtime.executor_sampler import Sampler
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# Create a dynamic circuit
qubits = QuantumRegister(1)
clbits = ClassicalRegister(1)
qc = QuantumCircuit(qubits, clbits)
(q0,) = qubits
(c0,) = clbits
qc.h(q0)
qc.measure(q0, c0)
with qc.if_test((c0, 1)):
qc.x(q0)
qc.measure(q0, c0)
# Convert to an ISA circuit for the given backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)
# Generate samplers for backend targets
sampler = Sampler(backend)
sampler.options.experimental = {"execution": {"scheduler_timing": True}}
# Submit jobs
sampler_job = sampler.run([isa_circuit])
result = sampler_job.result()
print(
f">>> {' Job ID:':<10} {sampler_job.job_id()} ({sampler_job.status()})"
)
>>> Job ID: dbjed5pkdqps7390ev00 (DONE)
بعد ذلك، احصل على توقيت جدول الدائرة:
# Get the circuit schedule timing
result[0].metadata["compilation"]["scheduler_timing"]["timing"]
'main,rz_0,Qubit 0,875,0,shift_phase\nmain,sx_0,Qubit 0,875,6,play\nmain,sx_0,Qubit 0,879,0,shift_phase\nmain,rz_0,Qubit 0,882,0,shift_phase\nmain,barrier,Qubit 0,882,0,barrier\nmain,measure_0,Qubit 0,882,180,play\nmain,measure_0,AWGR0_0,1003,205,capture\nmain,barrier,Qubit 0,1409,0,barrier\nmain,broadcast,Hub,1003,406,broadcast\nmain,receive,Receive,1409,7,receive\nthen,x_0,Qubit 0,1424,6,play\nmain,barrier,Qubit 0,1437,0,barrier\nmain,measure_0,Qubit 0,1437,180,play\nmain,measure_0,AWGR0_0,1558,205,capture\nmain,barrier,Qubit 0,1852,0,barrier\nmain,barrier,Qubit 0,1852,0,barrier\nmain,FINI_0,Qubit 0,1852,180,play\nmain,FINI_0,AWGR0_0,1973,205,capture\nmain,FINI_0,Qubit 0,2267,6,play\nmain,FINI_0,Qubit 0,2273,180,play\nmain,FINI_0,AWGR0_0,2394,205,capture\nmain,FINI_0,Qubit 0,2688,6,play\nmain,barrier,Qubit 0,2694,0,barrier\n'
أخيرًا، يمكنك تصوير التوقيت وحفظه:
from qiskit_ibm_runtime.visualization import draw_circuit_schedule_timing
circuit_schedule = result[0].metadata["compilation"]["scheduler_timing"][
"timing"
]
fig = draw_circuit_schedule_timing(
circuit_schedule=circuit_schedule,
included_channels=None,
filter_readout_channels=False,
filter_barriers=False,
width=1000,
)
# Uncomment the following line to display the figure
# fig.show(renderer="notebook")
# Save to a file
# fig.write_html("scheduler_timing.html")
الخطوات التالية
- التغذية الأمامية الكلاسيكية وتدفق التحكم (الدوائر الديناميكية)
- تصوير الدوائر