Перейти до основного вмісту
Цей проєкт у бета-версії. Знайшов(-ла) помилку? Відкрити issue на GitHub. Є запитання чи ідея? Запитати в Discussions — будемо раді твоєму відгуку!
Яка якість перекладу на цій сторінці?

Візуалізація часового розкладу схеми

Версії пакетів

Код на цій сторінці було розроблено з використанням таких вимог. Рекомендуємо використовувати ці або новіші версії.

qiskit[all]~=2.6.1
qiskit-ibm-runtime~=0.50.0

Хоча відображувач часової шкали, вбудований у Qiskit, корисний для статичних схем, він може не точно відображати часовий розклад динамічних схем через неявні операції, такі як широкомовна розсилка та визначення гілок. У рамках підтримки динамічних схем IBM Quantum Compute Service за запитом повертає точну інформацію про часовий розклад схеми у результатах завдання.

Примітки
  • Це експериментальна функція. Вона має статус попереднього випуску і тому може змінюватися.
  • Ця функція застосовується лише до завдань IBM Quantum Sampler та Executor.
  • Хоча загальний час схеми повертається в метаданих "compilation", це НЕ час, що використовується для виставлення рахунків (час QPU).
порада

Цей параметр також працює з dry-run завданнями. Передай dry_run=True до run(), щоб отримати розклад часу виконання схеми без використання часу QPU.

Увімкнення отримання даних часового розкладу​

Щоб увімкнути отримання даних часового розкладу, встанови експериментальний прапор scheduler_timing на True при запуску примітивного завдання.

# 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 — Вентиль та кубіт для операції.

  • Channel — Канал, якому призначається інструкція. Це може бути одним із таких:

    • Qubit x — Канал керування кубіта x.

    • AWGRx_y (генератор сигналів довільної форми для зчитування) — Використовується каналами зчитування для комунікації при вимірюванні кубітів. Аргументи x та y відповідають ідентифікатору інструмента зчитування та номеру кубіта відповідно.

  • T0 — Час початку інструкції в рамках повного розкладу

  • Duration — Тривалість інструкції в одиницях dt секунд, де 1 dt = 1 цикл планування. Значення 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")

Hovering over the output shows information such as the start, finish, and duration.

Розуміння згенерованого рисунку​

Зображення даних часового розкладу схеми, виведене draw_circuit_schedule_timing, передає таку інформацію:

  • Вісь X — це час в одиницях dt секунд, де 1 dt = 1 цикл планування. Значення dt для backend можна знайти за допомогою backend.dt.

  • Вісь Y — це канал (канали можна уявити як інструменти, що генерують імпульси).

    • Receive channel — Єдиний канал, що не є окремим інструментом. Це інструкція, виконувана на всіх каналах, що є частиною процедури зв'язку з хабом у цей час.

    • Qubit x — Канал керування кубіта x.

    • AWGRx_y (генератор сигналів довільної форми для зчитування) — Використовується каналами зчитування для комунікації при вимірюванні кубітів. Аргументи x та y відповідають ідентифікатору інструмента зчитування та номеру кубіта відповідно.

    • Hub — Керує мовленням.

Крім того, кожна інструкція має формат X_Y, де X — назва інструкції, а Y — тип імпульсу. Тип play застосовує керуючі імпульси, а capture записує стан кубіта. Можна також навести курсор на кожну інструкцію для отримання додаткових деталей. Наприклад, на попередньому рисунку показано керуючий імпульс для вентиля X, застосованого до кубіта 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")

Наступні кроки​