Magpatakbo ng mga quantum job mula sa isang workflow
Mga bersyon ng package
Ang code sa pahinang ito ay binuo gamit ang mga sumusunod na requirement. Inirerekomenda naming gamitin ang mga bersyong ito o mas bago.
qiskit[all]~=2.6.1
qiskit-ibm-runtime~=0.51.0
qiskit-serverless~=0.38.0
Ang isang quantum-classical workflow ay tumatakbo bilang isang managed workflow job. Ang mga classical stage nito ay tumatakbo sa iyong compute profile, at ang mga primitive job na ipinapadala nito sa isang IBM Quantum® QPU ay tumatakbo sa iyong instance at kasama sa iyong usage. Mula sa iisang job na iyon, maaari mong i-report ang bawat stage, hanapin ang mga QPU job, at kanselahin ang mga ito. Para magsimula ng job at tingnan ang status at mga log nito, tingnan ang Magpatakbo ng managed workflow.
Bago ka magsimula, i-deploy ang una mong managed workflow.
Gawin ang Runtime service
Gawin ang Runtime service sa code ng workflow mo gamit ang get_runtime_service(), at gamitin ito tulad ng paggamit mo sa QiskitRuntimeService nang local. Nagpapatakbo ang sumusunod na workflow ng Bell circuit gamit ang Sampler primitive, nire-report ang bawat stage gamit ang update_status(), at ibinabalik ang mga count:
# 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
Ang get_runtime_service() ay nagbabalik ng QiskitRuntimeService na naka-set up para sa managed workflow job mo, at ibinibigay nito ang mga sumusunod:
-
Mga credential. Ginagamit ng Runtime service ang API key, instance, at channel na ginamit mo sa pagtawag ng
run(), kaya hindi kailangan ng code ng workflow ng mga credential. -
Pag-track. Nire-record ng isang workflow ang bawat primitive job na tumatakbo sa Runtime service na ito sa ilalim ng managed workflow job, kasama ang mga Sampler, Estimator, at Executor job, at mga job sa isang session o batch. Maaari mong ilista ang mga ito gamit ang
job.runtime_jobs(). -
Pagkansela. Kapag tinawag mo ang
job.cancel(), kinakansela rin ng managed workflow ang mga session, batch, at primitive job ng workflow na tumatakbo pa.
Hindi tina-track o kinakansela ng managed workflow ang mga job ng service na ginawa mo gamit ang QiskitRuntimeService(), bagaman tumatakbo pa rin ang mga job. Kung kailangang gumamit ng ibang service ang workflow, kanselahin ang mga job nito sa isang SIGTERM handler.
Magpatakbo ng mga primitive sa isang session o batch
Tina-track din ng managed workflow ang mga primitive job na tumatakbo sa isang session o batch. Gawin ang session o batch mula sa isang Backend na ibinalik ng Runtime service, at gawin ang mga primitive sa loob ng with block. Ganito rin gumagana ang 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]
Mag-report ng progress gamit ang update_status()
Tinatawag ng workflow sa Gawin ang Runtime service ang update_status() sa simula ng bawat stage, para ipakita ng status ng job kung nasaan ang workflow, gaya ng RUNNING: WAITING_FOR_QPU. Magpasa ng isa sa mga sumusunod na Job constant:
| Tawag sa workflow | Status ng 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 |
Ang update_status() ay nagbabalik ng True kung binago ng workflow ang status. Nagbabalik ito ng False at nagsusulat ng babala sa mga log kung ang value ay hindi isa sa mga constant na ito, kung hindi na aktibo ang job, o kung tumatakbo ang code sa labas ng job. Hindi ito nagtataas ng error, kaya hindi pinipigilan ng typo ang workflow.
Para sa progress sa loob ng isang stage, gaya ng mga iteration ng isang optimizer, magsulat ng mga log line.
Hanapin ang mga QPU job ng isang run
Sa local mong notebook, pumili ng QPU na maa-access ng instance mo. Inililista ito ng client.backends(), at ibinabalik ng client.least_busy() ang may pinakakaunting pending na job:
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']
I-upload ang workflow, at ipasa ang pangalan ng Backend kapag pinatakbo mo ito:
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()
Pagkatapos matapos ang job, kunin ang mga ID ng mga QPU job ng workflow mula sa managed workflow job:
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
Ang bawat ID ay isang regular na primitive job ID. Para basahin ang status at mga resulta ng isang job, tingnan ang Kunin ang mga resulta ng job sa ibang pagkakataon.
Kung nagpatakbo ang workflow ng mga primitive sa isang session o batch, ilista ang mga session at batch ID gamit ang runtime_sessions(), at magpasa ng isa sa runtime_jobs() para makuha lang ang mga job dito:
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']
Ang job object ay umiiral lang sa notebook na nagsimula ng run. Sa bagong notebook, kunin muli ang job gamit ang client.job("<your-job-id>"), saka tawagin ang runtime_jobs() dito. Tingnan ang Hanapin ang job mula sa bagong session.
Para sa QPU usage at mga run time ng bawat QPU job, tingnan ang Tingnan ang mga metric ng job. Para sa usage ng buong instance mo sa kasalukuyang period, tawagin ang client.usage(). Para makita kung gaano katagal ang bawat stage ng managed workflow job, tingnan ang Tingnan kung gaano katagal ang bawat stage.
Kanselahin ang mga naka-link na QPU job
Kapag kinansela mo ang isang managed workflow job gamit ang job.cancel(), sinusubukan din ng workflow na kanselahin ang QPU work na sinimulan ng workflow:
-
Mga session at batch. Kinakansela ng workflow ang bawat session at batch ng workflow, na kinakansela rin ang mga naka-queue nilang job.
-
Iba pang primitive job. Kinakansela ng workflow ang bawat iba pang primitive job ng workflow na naka-queue o tumatakbo pa.
Ang job.cancel() ay nagbabalik ng mensahe para sa bawat QPU job at session, para masuri mo kung ano ang nakansela:
run_workflow_remotely.ipynb
print(job.cancel())
Para sa workflow na tumakbo sa isang batch, ganito ang hitsura ng mensahe:
Job is stopping. Canceled runtime session: eb8874c9-a15e-45f8-9a90-a9fb35267f9d and associated runtime jobs.
Kung hindi makagawa ang client ng QiskitRuntimeService mula sa mga local mong credential, ang managed workflow job lang ang kakanselahin nito. Kanselahin mo mismo ang mga QPU job gamit ang mga ID nila mula sa job.runtime_jobs().
Kapag ang workflow mismo ang nagpatigil ng job, halimbawa dahil umabot ito sa 24-oras na limitasyon, hindi nito kinakansela ang mga QPU job nito. Kanselahin ang mga ito gamit ang mga ID nila mula sa job.runtime_jobs().
Mag-troubleshoot ng mga QPU job sa isang workflow
| Problema | Sanhi |
|---|---|
Nagtataas ang get_runtime_service() ng KeyError: 'QISKIT_IBM_CHANNEL'. | Tumatakbo ang code sa local mong notebook, hindi sa managed workflow job. Gamitin ang QiskitRuntimeService() nang local. |
Nagbabalik ang update_status() ng False, at ipinapakita ng mga log ang 'sub_status' not provided or is not valid. | Ang value ay hindi isa sa mga Job constant, o hindi na aktibo ang job. |
Nagbabalik ang job.runtime_jobs() ng []. | Ginawa ng workflow ang service nito gamit ang QiskitRuntimeService(), o wala pa itong napapatakbong primitive. |
| Hindi tina-track ang mga job ng isang session. | Ginawa ang session mula sa Backend ng ibang service. Kunin ang Backend mula sa get_runtime_service(). |
Ipinapakita ng mga log ng workflow ang Could not associate runtime job with serverless job. | Hindi ma-record ng workflow ang isang primitive job. Tumatakbo pa rin ang primitive job, pero hindi ito tina-track. |
Ipinapakita ng job.cancel() ang No QiskitRuntimeService can be associated to the given token and instance. | Hindi nakagawa ang client ng QiskitRuntimeService mula sa mga local mong credential, kaya ang managed workflow job lang ang kinansela nito. |
Pumapalya ang client.job() na may Job [...] not found. | Mali ang job ID, o ang job ay pag-aari ng ibang user. |
Mga susunod na hakbang
- Magpatakbo ng managed workflow para tingnan ang status, resulta, at mga log ng isang job, at hanapin ang sanhi ng isang error.