Implementează primul tău flux de lucru gestionat
Versiuni de pachete
Codul de pe această pagină a fost dezvoltat folosind următoarele cerințe. Te recomandăm să folosești aceste versiuni sau unele mai noi.
qiskit[all]~=2.6.1
qiskit-serverless~=0.38.0
Folosește această pagină pentru a încărca un flux de lucru, a-l rula și a obține rezultatul lui. Fluxul de lucru exemplu optimizează și simulează un circuit Qiskit. Simulează circuitul pe hardware clasic, deci nu folosește timp QPU.
Înainte de a începe, instalează pachetul client și autentifică-te.
Pentru a implementa propriul cod cu ajutorul unui asistent AI, folosește abilitățile AI din depozitul de șabloane Qiskit Function.
# 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_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")
Scrie un flux de lucru
Creează structura de foldere
Un flux de lucru gestionat este un folder cu fișiere Python și un fișier de punct de intrare. Un flux de lucru gestionat încarcă tot ce se află în folder, până la 50 MB, și rulează punctul de intrare ca script. Deoarece un flux de lucru încarcă întregul folder, păstrează fișierele tale locale, precum deploy.ipynb, în afara folderului. Creează următoarea structură:
hello_world_project/
├── deploy.ipynb # Your local notebook: upload and run the workflow
└── source_files/ # The working directory that you upload
└── hello_world.py # The entrypoint
Scrie punctul de intrare hello world
Punctul de intrare citește un circuit, îl optimizează și îl simulează, apoi salvează numărătorile și adâncimea pe doi qubiți. Salvează următorul cod ca source_files/hello_world.py:
Dacă citești această pagină ca notebook, celula de cod pentru hello_world.py începe cu comanda magică %%writefile. Când rulezi această celulă, ea salvează codul în fișier în loc să îl ruleze.
# 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/hello_world.py
from qiskit.primitives import StatevectorSampler
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_serverless import Job, get_arguments, save_result, update_status
# Read the arguments that you pass to run()
arguments = get_arguments()
circuit = arguments["circuit"]
shots = arguments.get("shots", 1024)
# Optimize the circuit. Printed text goes to the job's logs.
update_status(Job.OPTIMIZING_HARDWARE)
pass_manager = generate_preset_pass_manager(
optimization_level=1, basis_gates=["cz", "rz", "sx", "x"]
)
isa_circuit = pass_manager.run(circuit)
two_qubit_depth = isa_circuit.depth(lambda instruction: instruction.operation.num_qubits == 2)
print(f"Two-qubit depth after optimization: {two_qubit_depth}", flush=True)
# Simulate the circuit and return the counts
sampler = StatevectorSampler(seed=1234)
pub_result = sampler.run([isa_circuit], shots=shots).result()[0]
save_result({"counts": pub_result.data.meas.get_counts(), "two_qubit_depth": two_qubit_depth})
Writing ./source_files/hello_world.py
Punctul de intrare folosește trei funcții din qiskit_serverless:
-
get_arguments()returnează, sub formă de dicționar, argumentele cu nume pe care le transmiți larun(). Fiecare valoare trebuie să fie serializabilă în JSON sau un obiect pe care clientul îl poate codifica, precum unQuantumCircuit. Obiectele codificate ajung ca aceleași obiecte pe care le-ai transmis. -
update_status(Job.OPTIMIZING_HARDWARE)setează starea detaliatăRUNNING: OPTIMIZING_FOR_HARDWARE, pe care o poți vedea cât timp rulează jobul. Vezi Raportarea progresului cu update_status(). -
save_result()stochează o valoare serializabilă în JSON pe care o citești mai târziu cujob.result(). Fluxul de lucru returnează numărătorile ca dicționar și adâncimea pe doi qubiți a circuitului optimizat ca număr întreg.
Tot ce scrie fluxul de lucru la ieșirea standard, precum adâncimea pe doi qubiți, ajunge în jurnalele jobului. Pentru a adăuga marcaje de timp și niveluri de jurnalizare, folosește modulul logging. Vezi Scrierea jurnalelor și gestionarea erorilor.
Încarcă fluxul de lucru
În notebook-ul tău local, rulează următorul cod din folderul hello_world_project. Codul se conectează cu contul tău salvat, definește fluxul de lucru și îl încarcă. entrypoint este fișierul pe care îl rulează fluxul de lucru, iar working_dir este folderul pe care îl încarci:
from qiskit_ibm_catalog import ManagedWorkflow, ManagedWorkflowClient
client = ManagedWorkflowClient()
hello_world = ManagedWorkflow(
title="hello-world",
entrypoint="hello_world.py",
working_dir="./source_files/",
)
hello_world = client.upload(hello_world)
Rulează fluxul de lucru cu intrări
Construiește un circuit GHZ pe trei qubiți pe care să îl transmiți ca intrare lui hello_world:
from qiskit import QuantumCircuit
circuit = QuantumCircuit(3)
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.measure_all()
Rulează hello_world cu circuitul și numărul de shot-uri ca argumente cu nume. Numele argumentelor corespund cheilor pe care punctul de intrare le citește cu get_arguments():
job = hello_world.run(circuit=circuit, shots=1024)
print(job.job_id)
54705348-5117-44b7-935b-e6986ef182fa
run() returnează un Job după ce fluxul de lucru pune jobul în coadă. Nu așteaptă ca jobul să ruleze. Jobul continuă în cloud după ce închizi sesiunea Python. Pentru a-l găsi din nou mai târziu, listează joburile tale recente cu client.jobs().
Obține starea, rezultatul și jurnalele
Imediat după ce apelezi run(), starea este de obicei QUEUED:
job.status()
'QUEUED'
Starea se schimbă din QUEUED în INITIALIZING, RUNNING și apoi DONE.
job.result() așteaptă până se termină jobul, apoi returnează valoarea pe care fluxul de lucru a transmis-o lui save_result():
job.result()
{'counts': {'111': 514, '000': 510}, 'two_qubit_depth': 2}
# This cell is hidden from users. It checks the result.
assert set(_["counts"]) <= {"000", "111"} # noqa: F821
assert sum(_["counts"].values()) == 1024 # noqa: F821
from qiskit.visualization import plot_histogram
plot_histogram(job.result()["counts"])
Poți citi jurnalele cât timp rulează jobul. Fluxul de lucru încarcă linii noi la aproximativ fiecare 15 secunde. Jurnalele includ linia pe care a afișat-o fluxul de lucru:
print(job.logs())
Two-qubit depth after optimization: 2
# This cell is hidden from users. It checks the logs.
assert "Two-qubit depth after optimization" in job.logs()
Actualizează fluxul de lucru
Pentru a modifica un flux de lucru, editează fișierele lui și apelează din nou upload() cu același title. Noua încărcare o înlocuiește pe cea anterioară, iar joburile deja pornite nu sunt afectate.
Câmpuri precum arguments_schema și sizes_map își păstrează valorile stocate când le omiți din noua încărcare.
Pașii următori
- Definește intrările și ieșirile pentru a afla ce tipuri de argumente și rezultate acceptă un flux de lucru.
- Declară dependențele pentru a folosi mai multe pachete Python în fluxul tău de lucru.
- Rulează joburi cuantice dintr-un flux de lucru pentru a-ți rula circuitele pe un QPU, a raporta fiecare etapă și a urmări joburile QPU.
- Rulează un flux de lucru gestionat pentru a afla toate stările jobului, a depana un job eșuat și a găsi un job mai târziu.
- Pentru a porni de la cod funcțional, implementează unul dintre șabloanele Qiskit Function sau adaptează un șablon pentru propriul tău flux de lucru.