Spouštěj kvantové úlohy z workflow
Verze balíčků
Kód na této stránce byl vyvinut s použitím následujících požadavků. Doporučujeme používat tyto verze nebo novější.
qiskit[all]~=2.6.1
qiskit-ibm-runtime~=0.51.0
qiskit-serverless~=0.38.0
Kvantově-klasický workflow běží jako jedna úloha spravovaného workflow. Jeho klasické fáze běží na tvém výpočetním profilu a primitivní úlohy, které odesílá na QPU IBM Quantum®, běží na tvé instanci a započítávají se do tvého využití. Z této jedné úlohy můžeš hlásit každou fázi, najít úlohy na QPU a zrušit je. Informace o spuštění úlohy a kontrole jejího stavu a logů najdeš v části Spuštění spravovaného workflow.
Než začneš, nasaď svůj první spravovaný workflow.
Vytvoř službu Runtime
Vytvoř službu Runtime v kódu svého workflow pomocí get_runtime_service() a používej ji stejným způsobem, jakým lokálně používáš QiskitRuntimeService. Následující workflow spustí Bellův obvod pomocí primitiva Sampler, hlásí každou fázi pomocí update_status() a vrátí počty měření:
# 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() vrací QiskitRuntimeService, který je nastavený pro tvou úlohu spravovaného workflow, a poskytuje následující:
-
Přihlašovací údaje. Služba Runtime používá API klíč, instanci a kanál, které jsi použil při volání
run(), takže kód workflow žádné přihlašovací údaje nepotřebuje. -
Sledování. Workflow zaznamenává každou primitivní úlohu, která běží přes tuto službu Runtime, pod úlohu spravovaného workflow, včetně úloh Sampler, Estimator a Executor a úloh v session nebo batch. Můžeš je vypsat pomocí
job.runtime_jobs(). -
Rušení. Když zavoláš
job.cancel(), spravovaný workflow zruší také session, batche a primitivní úlohy workflow, které stále běží.
Spravovaný workflow nesleduje ani neruší úlohy služby, kterou vytvoříš pomocí QiskitRuntimeService(), i když tyto úlohy stále běží. Pokud musí workflow použít jinou službu, zruš její úlohy v obslužné funkci SIGTERM.
Spouštěj primitiva v session nebo batch
Spravovaný workflow sleduje také primitivní úlohy, které běží v session nebo batch. Vytvoř session nebo batch z backendu, který vrátila služba Runtime, a primitiva vytvoř uvnitř bloku with. Session funguje stejným způsobem:
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]
Hlas průběh pomocí update_status()
Workflow v části Vytvoř službu Runtime volá update_status() na začátku každé fáze, aby stav úlohy ukazoval, kde se workflow nachází, například RUNNING: WAITING_FOR_QPU. Předej jednu z následujících konstant Job:
| Volání ve workflow | Stav úlohy |
|---|---|
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() vrací True, pokud workflow změnil stav. Vrací False a zapíše varování do logů, pokud hodnota není jednou z těchto konstant, pokud úloha již není aktivní nebo pokud se kód spouští mimo úlohu. Nevyvolává chybu, takže překlep workflow nezastaví.
Pro průběh uvnitř fáze, například iterace optimalizátoru, zapisuj řádky logu.
Najdi úlohy na QPU jednoho běhu
Ve svém lokálním notebooku vyber QPU, ke kterému má tvá instance přístup. client.backends() je vypíše a client.least_busy() vrátí to s nejmenším počtem čekajících úloh:
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']
Nahraj workflow a při jeho spuštění předej název backendu:
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()
Po skončení úlohy získej z úlohy spravovaného workflow ID úloh workflow na QPU:
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
Každé ID je běžné ID primitivní úlohy. Informace o čtení stavu a výsledků úlohy najdeš v části Získání výsledků úlohy později.
Pokud workflow spouštěl primitiva v session nebo batch, vypiš ID session a batchů pomocí runtime_sessions() a jedno z nich předej do runtime_jobs(), abys získal pouze úlohy v něm:
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']
Objekt job existuje pouze v notebooku, který běh spustil. V novém notebooku získej úlohu znovu pomocí client.job("<your-job-id>") a poté na ní zavolej runtime_jobs(). Viz Najdi úlohu z nové session.
Informace o využití QPU a dobách běhu každé úlohy na QPU najdeš v části Zobrazení metrik úlohy. Využití celé své instance v aktuálním období zjistíš voláním client.usage(). Chceš-li zjistit, jak dlouho trvala každá fáze úlohy spravovaného workflow, viz Zkontroluj, jak dlouho trvala každá fáze.
Zruš propojené úlohy na QPU
Když zrušíš úlohu spravovaného workflow pomocí job.cancel(), workflow se také pokusí zrušit práci na QPU, kterou spustil:
-
Session a batche. Workflow zruší každou ze svých session a batchů, čímž zruší i jejich úlohy ve frontě.
-
Další primitivní úlohy. Workflow zruší každou ze svých dalších primitivních úloh, které jsou stále ve frontě nebo běží.
job.cancel() vrací zprávu pro každou úlohu na QPU a každou session, takže můžeš zkontrolovat, co bylo zrušeno:
run_workflow_remotely.ipynb
print(job.cancel())
U workflow, který běžel v batch, vypadá zpráva takto:
Job is stopping. Canceled runtime session: eb8874c9-a15e-45f8-9a90-a9fb35267f9d and associated runtime jobs.
Pokud klient nemůže z tvých lokálních přihlašovacích údajů vytvořit QiskitRuntimeService, zruší pouze úlohu spravovaného workflow. Úlohy na QPU zruš sám pomocí jejich ID z job.runtime_jobs().
Když workflow zastaví úlohu sám, například proto, že dosáhla 24hodinového limitu, své úlohy na QPU nezruší. Zruš je pomocí jejich ID z job.runtime_jobs().
Řešení potíží s úlohami na QPU ve workflow
| Problém | Příčina |
|---|---|
get_runtime_service() vyvolá KeyError: 'QISKIT_IBM_CHANNEL'. | Kód běží v tvém lokálním notebooku, ne v úloze spravovaného workflow. Lokálně použij QiskitRuntimeService(). |
update_status() vrací False a logy ukazují 'sub_status' not provided or is not valid. | Hodnota není jednou z konstant Job nebo úloha již není aktivní. |
job.runtime_jobs() vrací []. | Workflow vytvořil svou službu pomocí QiskitRuntimeService() nebo ještě nespustil žádné primitivum. |
| Úlohy session nejsou sledovány. | Session byla vytvořena z backendu jiné služby. Získej backend z get_runtime_service(). |
Logy workflow ukazují Could not associate runtime job with serverless job. | Workflow nemohl zaznamenat primitivní úlohu. Primitivní úloha stále běží, ale není sledována. |
job.cancel() ukazuje No QiskitRuntimeService can be associated to the given token and instance. | Klient nemohl z tvých lokálních přihlašovacích údajů vytvořit QiskitRuntimeService, proto zrušil pouze úlohu spravovaného workflow. |
client.job() selže s Job [...] not found. | ID úlohy je špatné nebo úloha patří jinému uživateli. |
Další kroky
- Spusť spravovaný workflow, abys zkontroloval stav, výsledek a logy úlohy a našel příčinu chyby.