Zum Hauptinhalt springen
Dieses Projekt befindet sich in der Beta-Phase. Einen Fehler gefunden? GitHub Issue erstellen. Frage oder Idee? In Discussions fragen — wir freuen uns über dein Feedback!
Wie ist die Übersetzungsqualität auf dieser Seite?

Deinen ersten Managed Workflow bereitstellen

Paketversionen

Der Code auf dieser Seite wurde mit den folgenden Anforderungen entwickelt. Wir empfehlen, diese Versionen oder neuere zu verwenden.

qiskit[all]~=2.6.1
qiskit-serverless~=0.38.0

Verwende diese Seite, um einen Workflow hochzuladen, auszuführen und sein Ergebnis abzurufen. Der Beispiel-Workflow optimiert und simuliert einen Qiskit-Circuit. Er simuliert den Circuit auf klassischer Hardware und verbraucht daher keine QPU-Zeit.

Bevor du beginnst, installiere das Client-Paket und authentifiziere dich.

KI-Skills verwenden (optional)

Um deinen eigenen Code mit Hilfe eines KI-Assistenten bereitzustellen, verwende die KI-Skills im Qiskit-Function-Templates-Repository.

# 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")

Einen Workflow schreiben​

Die Ordnerstruktur erstellen​

Ein Managed Workflow ist ein Ordner mit Python-Dateien und einer Entrypoint-Datei. Ein Managed Workflow lädt alles im Ordner hoch, bis zu 50 MB, und führt den Entrypoint als Skript aus. Da ein Workflow den gesamten Ordner hochlädt, bewahre deine lokalen Dateien, wie deploy.ipynb, außerhalb des Ordners auf. Erstelle das folgende Layout:

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

Den Hello-World-Entrypoint schreiben​

Der Entrypoint liest einen Circuit, optimiert und simuliert ihn und speichert die Zählungen und die Zwei-Qubit-Tiefe. Speichere den folgenden Code als source_files/hello_world.py:

hinweis

Wenn du diese Seite als Notebook liest, beginnt die Codezelle für hello_world.py mit dem Magic Command %%writefile. Wenn du diese Zelle ausführst, speichert sie den Code in der Datei, anstatt ihn auszuführen.

# 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

Der Entrypoint verwendet drei Funktionen aus qiskit_serverless:

  • get_arguments() gibt die Schlüsselwortargumente, die du an run() übergibst, als Dictionary zurück. Jeder Wert muss JSON-serialisierbar sein oder ein Objekt, das der Client kodieren kann, etwa ein QuantumCircuit. Kodierte Objekte kommen als dieselben Objekte an, die du übergeben hast.

  • update_status(Job.OPTIMIZING_HARDWARE) setzt den detaillierten Status RUNNING: OPTIMIZING_FOR_HARDWARE, den du während der Ausführung des Jobs sehen kannst. Siehe Fortschritt mit update_status() melden.

  • save_result() speichert einen JSON-serialisierbaren Wert, den du später mit job.result() liest. Der Workflow gibt die Zählungen als Dictionary und die Zwei-Qubit-Tiefe des optimierten Circuits als Ganzzahl zurück.

Alles, was der Workflow in die Standardausgabe schreibt, etwa die Zwei-Qubit-Tiefe, landet in den Logs des Jobs. Um Zeitstempel und Log-Level hinzuzufügen, verwende das Modul logging. Siehe Logs schreiben und Fehler behandeln.

Den Workflow hochladen​

Führe in deinem lokalen Notebook den folgenden Code im Ordner hello_world_project aus. Der Code verbindet sich mit deinem gespeicherten Konto, definiert den Workflow und lädt ihn hoch. entrypoint ist die Datei, die der Workflow ausführt, und working_dir ist der Ordner, den du hochlädst:

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)

Den Workflow mit Eingaben ausführen​

Erstelle einen Drei-Qubit-GHZ-Circuit, den du als Eingabe an hello_world übergibst:

from qiskit import QuantumCircuit

circuit = QuantumCircuit(3)
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.measure_all()

Führe hello_world mit dem Circuit und der Anzahl der Shots als Schlüsselwortargumente aus. Die Argumentnamen entsprechen den Schlüsseln, die der Entrypoint mit get_arguments() liest:

job = hello_world.run(circuit=circuit, shots=1024)
print(job.job_id)
54705348-5117-44b7-935b-e6986ef182fa

run() gibt einen Job zurück, nachdem der Workflow den Job in die Warteschlange gestellt hat. Es wartet nicht darauf, dass der Job läuft. Der Job läuft in der Cloud weiter, nachdem du deine Python-Sitzung geschlossen hast. Um ihn später wiederzufinden, liste deine letzten Jobs mit client.jobs() auf.

Status, Ergebnis und Logs abrufen​

Unmittelbar nach dem Aufruf von run() ist der Status normalerweise QUEUED:

job.status()
'QUEUED'

Der Status wechselt von QUEUED zu INITIALIZING, RUNNING und dann DONE.

job.result() wartet, bis der Job endet, und gibt dann den Wert zurück, den der Workflow an save_result() übergeben hat:

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"])

Output of the previous code cell

Du kannst die Logs lesen, während der Job läuft. Der Workflow lädt etwa alle 15 Sekunden neue Zeilen hoch. Die Logs enthalten die Zeile, die der Workflow ausgegeben hat:

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()

Den Workflow aktualisieren​

Um einen Workflow zu ändern, bearbeite seine Dateien und rufe upload() erneut mit demselben title auf. Der neue Upload ersetzt den früheren, und bereits gestartete Jobs sind davon nicht betroffen.

Felder wie arguments_schema und sizes_map behalten ihre gespeicherten Werte, wenn du sie im neuen Upload weglässt.

Nächste Schritte​

Empfehlungen