Jalankan job kuantum dari sebuah workflow
Versi paket
Kode di halaman ini dikembangkan dengan persyaratan berikut. Kami menyarankan memakai versi ini atau yang lebih baru.
qiskit[all]~=2.6.1
qiskit-ibm-runtime~=0.51.0
qiskit-serverless~=0.38.0
Workflow kuantum-klasik berjalan sebagai satu job managed workflow. Tahapan klasiknya berjalan di compute profile kamu, dan job primitive yang dikirimnya ke QPU IBM Quantum® berjalan di instance kamu dan dihitung dalam penggunaan kamu. Dari satu job itu, kamu bisa melaporkan setiap tahapan, menemukan job QPU, dan membatalkannya. Untuk memulai job dan memeriksa status serta lognya, lihat Jalankan managed workflow.
Sebelum mulai, deploy managed workflow pertamamu.
Buat Runtime service
Buat Runtime service di kode workflow kamu dengan get_runtime_service(), dan pakai seperti kamu memakai QiskitRuntimeService secara lokal. Workflow berikut menjalankan Circuit Bell dengan primitive Sampler, melaporkan setiap tahapan dengan update_status(), dan mengembalikan counts:
# 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() mengembalikan QiskitRuntimeService yang sudah disiapkan untuk job managed workflow kamu, dan menyediakan hal-hal berikut:
-
Kredensial. Runtime service memakai API key, instance, dan channel yang kamu pakai untuk memanggil
run(), jadi kode workflow tidak perlu kredensial. -
Pelacakan. Workflow mencatat setiap job primitive yang berjalan lewat Runtime service ini di bawah job managed workflow, termasuk job Sampler, Estimator, dan Executor, serta job di dalam Session atau batch. Kamu bisa mendaftarkannya dengan
job.runtime_jobs(). -
Pembatalan. Saat kamu memanggil
job.cancel(), managed workflow juga membatalkan Session, batch, dan job primitive milik workflow yang masih berjalan.
Managed workflow tidak melacak atau membatalkan job dari service yang kamu buat dengan QiskitRuntimeService(), meskipun job-nya tetap berjalan. Kalau workflow harus memakai service lain, batalkan job-nya di handler SIGTERM.
Jalankan primitive di Session atau batch
Managed workflow juga melacak job primitive yang berjalan di Session atau batch. Buat Session atau batch dari Backend yang dikembalikan Runtime service, lalu buat primitive di dalam blok with. Session bekerja dengan cara yang sama:
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]
Laporkan progres dengan update_status()
Workflow di Buat Runtime service memanggil update_status() di awal setiap tahapan, supaya status job menunjukkan posisi workflow, misalnya RUNNING: WAITING_FOR_QPU. Kirim salah satu konstanta Job berikut:
| Panggilan di workflow | Status 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() mengembalikan True kalau workflow mengubah statusnya. Fungsi ini mengembalikan False dan menulis peringatan ke log kalau nilainya bukan salah satu konstanta ini, kalau job sudah tidak aktif, atau kalau kode berjalan di luar job. Fungsi ini tidak memunculkan error, jadi salah ketik tidak menghentikan workflow.
Untuk progres di dalam satu tahapan, seperti iterasi optimizer, tulis baris log.
Temukan job QPU dari sebuah run
Di notebook lokal kamu, pilih QPU yang bisa diakses instance kamu. client.backends() mendaftarkannya, dan client.least_busy() mengembalikan yang paling sedikit job tertunda:
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']
Unggah workflow-nya, lalu kirim nama Backend saat menjalankannya:
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()
Setelah job selesai, ambil ID job QPU milik workflow dari job managed 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
Setiap ID adalah ID job primitive biasa. Untuk membaca status dan hasil sebuah job, lihat Ambil hasil job di lain waktu.
Kalau workflow menjalankan primitive di Session atau batch, daftarkan ID Session dan batch dengan runtime_sessions(), lalu kirim salah satunya ke runtime_jobs() untuk mendapatkan job di dalamnya saja:
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']
Objek job hanya ada di notebook yang memulai run. Di notebook baru, ambil job-nya lagi dengan client.job("<your-job-id>"), lalu panggil runtime_jobs() di atasnya. Lihat Temukan job dari Session baru.
Untuk penggunaan QPU dan waktu run tiap job QPU, lihat Lihat metrik job. Untuk penggunaan seluruh instance kamu di periode saat ini, panggil client.usage(). Untuk melihat berapa lama setiap tahapan job managed workflow berlangsung, lihat Cek berapa lama setiap tahapan berlangsung.
Batalkan job QPU yang terhubung
Saat kamu membatalkan job managed workflow dengan job.cancel(), workflow juga mencoba membatalkan pekerjaan QPU yang dimulainya:
-
Session dan batch. Workflow membatalkan setiap Session dan batch miliknya, yang juga membatalkan job mereka yang masih antre.
-
Job primitive lainnya. Workflow membatalkan setiap job primitive lain miliknya yang masih antre atau berjalan.
job.cancel() mengembalikan pesan untuk setiap job QPU dan Session, jadi kamu bisa cek apa saja yang dibatalkan:
run_workflow_remotely.ipynb
print(job.cancel())
Untuk workflow yang berjalan di batch, pesannya terlihat seperti berikut:
Job is stopping. Canceled runtime session: eb8874c9-a15e-45f8-9a90-a9fb35267f9d and associated runtime jobs.
Kalau klien tidak bisa membuat QiskitRuntimeService dari kredensial lokal kamu, klien hanya membatalkan job managed workflow. Batalkan sendiri job QPU-nya dengan ID dari job.runtime_jobs().
Saat workflow menghentikan job sendiri, misalnya karena mencapai batas 24 jam, workflow tidak membatalkan job QPU-nya. Batalkan dengan ID dari job.runtime_jobs().
Atasi masalah job QPU di workflow
| Masalah | Penyebab |
|---|---|
get_runtime_service() memunculkan KeyError: 'QISKIT_IBM_CHANNEL'. | Kode berjalan di notebook lokal kamu, bukan di job managed workflow. Pakai QiskitRuntimeService() secara lokal. |
update_status() mengembalikan False, dan log menampilkan 'sub_status' not provided or is not valid. | Nilainya bukan salah satu konstanta Job, atau job sudah tidak aktif. |
job.runtime_jobs() mengembalikan []. | Workflow membuat service-nya dengan QiskitRuntimeService(), atau belum menjalankan primitive. |
| Job milik sebuah Session tidak terlacak. | Session dibuat dari Backend milik service yang berbeda. Ambil Backend dari get_runtime_service(). |
Log workflow menampilkan Could not associate runtime job with serverless job. | Workflow tidak bisa mencatat sebuah job primitive. Job primitive-nya tetap berjalan, tapi tidak terlacak. |
job.cancel() menampilkan No QiskitRuntimeService can be associated to the given token and instance. | Klien tidak bisa membuat QiskitRuntimeService dari kredensial lokal kamu, jadi hanya job managed workflow yang dibatalkan. |
client.job() gagal dengan Job [...] not found. | ID job salah, atau job milik pengguna lain. |
Langkah berikutnya
- Jalankan managed workflow untuk memeriksa status, hasil, dan log sebuah job, serta menemukan penyebab error.