Запуск квантових завдань із workflow
Версії пакетів
Код на цій сторінці розроблено з використанням наведених нижче вимог. Ми рекомендуємо використовувати ці версії або новіші.
qiskit[all]~=2.6.1
qiskit-ibm-runtime~=0.51.0
qiskit-serverless~=0.38.0
Квантово-класичний workflow виконується як одне завдання керованого workflow. Його класичні етапи виконуються на твоєму обчислювальному профілі, а завдання примітивів, які він надсилає на QPU IBM Quantum®, виконуються на твоєму екземплярі та враховуються у твоєму використанні. З цього одного завдання ти можеш повідомляти про кожен етап, знаходити завдання QPU і скасовувати їх. Щоб запустити завдання та перевірити його статус і логи, див. Запуск керованого workflow.
Перш ніж почати, розгорни свій перший керований workflow.
Створення служби Runtime
Створи службу Runtime у коді свого workflow за допомогою get_runtime_service() і використовуй її так само, як використовуєш QiskitRuntimeService локально. Наведений нижче workflow запускає схему Белла з примітивом Sampler, повідомляє про кожен етап за допомогою 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, налаштований для твого завдання керованого workflow, і забезпечує таке:
-
Облікові дані. Служба Runtime використовує API-ключ, екземпляр і канал, які ти використав(-ла) для виклику
run(), тому коду workflow облікові дані не потрібні. -
Відстеження. Workflow записує кожне завдання примітива, що виконується через цю службу Runtime, під завданням керованого workflow, зокрема завдання Sampler, Estimator і Executor, а також завдання в сесії або batch. Ти можеш вивести їх список за допомогою
job.runtime_jobs(). -
Скасування. Коли ти викликаєш
job.cancel(), керований workflow також скасовує сесії, batch і завдання примітивів workflow, які ще виконуються.
Керований workflow не відстежує й не скасовує завдання служби, яку ти створюєш за допомогою QiskitRuntimeService(), хоча завдання все одно виконуються. Якщо workflow має використовувати іншу службу, скасовуй її завдання в обробнику SIGTERM.
Запуск примітивів у сесії або batch
Керований workflow також відстежує завдання примітивів, які виконуються в сесії або batch. Створи сесію чи batch із бекенда, який повернула служба Runtime, а примітиви створюй усередині блоку 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()
Workflow у розділі Створення служби Runtime викликає update_status() на початку кожного етапу, щоб статус завдання показував, де перебуває workflow, наприклад RUNNING: WAITING_FOR_QPU. Передай одну з таких констант Job:
| Виклик у workflow | Статус завдання |
|---|---|
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, якщо workflow змінив статус. Вона повертає False і записує попередження в логи, якщо значення не є однією з цих констант, якщо завдання більше не активне або якщо код виконується поза завданням. Вона не викликає помилки, тому одруківка не зупиняє workflow.
Для прогресу всередині етапу, наприклад ітерацій оптимізатора, записуй рядки логу.
Знайди завдання QPU запуску
У своєму локальному ноутбуку вибери QPU, до якого має доступ твій екземпляр. 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']
Завантаж workflow і передай ім'я бекенда під час його запуску:
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 цього workflow із завдання керованого workflow:
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
Кожен ідентифікатор — це звичайний ідентифікатор завдання примітива. Щоб прочитати статус і результати завдання, див. Отримання результатів завдання пізніше.
Якщо workflow виконував примітиви в сесії або batch, виведи список ідентифікаторів сесій і batch за допомогою 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, див. Перегляд метрик завдання. Щоб побачити використання всього твого екземпляра за поточний період, виклич client.usage(). Щоб побачити, скільки тривав кожен етап завдання керованого workflow, див. Перевірка тривалості кожного етапу.
Скасування пов'язаних завдань QPU
Коли ти скасовуєш завдання керованого workflow за допомогою job.cancel(), workflow також намагається скасувати роботу QPU, яку він запустив:
-
Сесії та batch. Workflow скасовує кожну зі своїх сесій і batch, що також скасовує їхні завдання в черзі.
-
Інші завдання примітивів. Workflow скасовує кожне зі своїх інших завдань примітивів, які ще в черзі або виконуються.
job.cancel() повертає повідомлення для кожного завдання QPU і сесії, тож ти можеш перевірити, що було скасовано:
run_workflow_remotely.ipynb
print(job.cancel())
Для workflow, який виконувався в batch, повідомлення виглядає так:
Job is stopping. Canceled runtime session: eb8874c9-a15e-45f8-9a90-a9fb35267f9d and associated runtime jobs.
Якщо клієнт не може створити QiskitRuntimeService із твоїх локальних облікових даних, він скасовує лише завдання керованого workflow. Скасуй завдання QPU самостійно за їхніми ідентифікаторами з job.runtime_jobs().
Коли workflow сам зупиняє завдання, наприклад тому, що воно досягло 24-годинного ліміту, він не скасовує його завдання QPU. Скасуй їх за ідентифікаторами з job.runtime_jobs().
Усунення проблем із завданнями QPU у workflow
| Проблема | Причина |
|---|---|
get_runtime_service() викликає KeyError: 'QISKIT_IBM_CHANNEL'. | Код виконується у твоєму локальному ноутбуці, а не в завданні керованого workflow. Використовуй QiskitRuntimeService() локально. |
update_status() повертає False, а логи показують 'sub_status' not provided or is not valid. | Значення не є однією з констант Job, або завдання більше не активне. |
job.runtime_jobs() повертає []. | Workflow створив свою службу за допомогою QiskitRuntimeService() або ще не виконав жодного примітива. |
| Завдання сесії не відстежуються. | Сесію створено з бекенда іншої служби. Отримай бекенд з get_runtime_service(). |
Логи workflow показують Could not associate runtime job with serverless job. | Workflow не зміг записати завдання примітива. Завдання примітива все одно виконується, але не відстежується. |
job.cancel() показує No QiskitRuntimeService can be associated to the given token and instance. | Клієнт не зміг створити QiskitRuntimeService із твоїх локальних облікових даних, тому скасував лише завдання керованого workflow. |
client.job() завершується помилкою Job [...] not found. | Ідентифікатор завдання неправильний, або завдання належить іншому користувачу. |
Наступні кроки
- Запуск керованого workflow, щоб перевірити статус, результат і логи завдання та знайти причину помилки.