Wdróż swój pierwszy zarządzany przepływ pracy
Wersje pakietów
Kod na tej stronie został opracowany przy użyciu następujących wymagań. Zalecamy używanie tych wersji lub nowszych.
qiskit[all]~=2.6.1
qiskit-serverless~=0.38.0
Na tej stronie dowiesz się, jak wysłać przepływ pracy, uruchomić go i pobrać jego wynik. Przykładowy przepływ pracy optymalizuje i symuluje obwód Qiskit. Symuluje obwód na sprzęcie klasycznym, więc nie zużywa czasu QPU.
Zanim zaczniesz, zainstaluj pakiet klienta i uwierzytelnij się.
Aby wdrożyć własny kod z pomocą asystenta AI, użyj umiejętności AI z repozytorium szablonów 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")
Napisz przepływ pracy
Utwórz strukturę folderów
Zarządzany przepływ pracy to folder plików Python z jednym plikiem punktu wejścia. Zarządzany przepływ pracy wysyła wszystko, co jest w folderze, do 50 MB, i uruchamia punkt wejścia jako skrypt. Ponieważ przepływ pracy wysyła cały folder, przechowuj swoje pliki lokalne, takie jak deploy.ipynb, poza tym folderem. Utwórz następujący układ:
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
Napisz punkt wejścia hello world
Punkt wejścia odczytuje obwód, optymalizuje go i symuluje, a następnie zapisuje zliczenia oraz głębokość dwukubitową. Zapisz poniższy kod jako source_files/hello_world.py:
Jeśli czytasz tę stronę jako notatnik, komórka kodu dla hello_world.py zaczyna się od polecenia magicznego %%writefile. Po uruchomieniu tej komórki kod zostaje zapisany do pliku zamiast być wykonany.
# 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
Punkt wejścia używa trzech funkcji z qiskit_serverless:
-
get_arguments()zwraca jako słownik argumenty nazwane, które przekazujesz dorun(). Każda wartość musi być serializowalna do JSON albo być obiektem, który klient potrafi zakodować, takim jakQuantumCircuit. Zakodowane obiekty docierają jako te same obiekty, które przekazałeś. -
update_status(Job.OPTIMIZING_HARDWARE)ustawia szczegółowy statusRUNNING: OPTIMIZING_FOR_HARDWARE, który możesz zobaczyć podczas działania zadania. Zobacz Raportowanie postępu za pomocą update_status(). -
save_result()zapisuje wartość serializowalną do JSON, którą później odczytujesz za pomocąjob.result(). Przepływ pracy zwraca zliczenia jako słownik, a głębokość dwukubitową zoptymalizowanego obwodu jako liczbę całkowitą.
Wszystko, co przepływ pracy zapisuje na standardowe wyjście, na przykład głębokość dwukubitowa, trafia do logów zadania. Aby dodać znaczniki czasu i poziomy logowania, użyj modułu logging. Zobacz Zapisywanie logów i obsługa błędów.
Wyślij przepływ pracy
W lokalnym notatniku uruchom poniższy kod z folderu hello_world_project. Kod łączy się z Twoim zapisanym kontem, definiuje przepływ pracy i go wysyła. entrypoint to plik, który uruchamia przepływ pracy, a working_dir to folder, który wysyłasz:
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)
Uruchom przepływ pracy z danymi wejściowymi
Zbuduj trzykubitowy obwód GHZ, który przekażesz do hello_world jako dane wejściowe:
from qiskit import QuantumCircuit
circuit = QuantumCircuit(3)
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.measure_all()
Uruchom hello_world, przekazując obwód i liczbę strzałów jako argumenty nazwane. Nazwy argumentów odpowiadają kluczom, które punkt wejścia odczytuje za pomocą get_arguments():
job = hello_world.run(circuit=circuit, shots=1024)
print(job.job_id)
54705348-5117-44b7-935b-e6986ef182fa
run() zwraca Job po tym, jak przepływ pracy umieści zadanie w kolejce. Nie czeka, aż zadanie się uruchomi. Zadanie działa dalej w chmurze po zamknięciu sesji Python. Aby znaleźć je później, wyświetl swoje ostatnie zadania za pomocą client.jobs().
Pobierz status, wynik i logi
Zaraz po wywołaniu run() status to zwykle QUEUED:
job.status()
'QUEUED'
Status zmienia się z QUEUED na INITIALIZING, RUNNING, a następnie DONE.
job.result() czeka, aż zadanie się zakończy, a następnie zwraca wartość, którą przepływ pracy przekazał do 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"])
Logi możesz czytać podczas działania zadania. Przepływ pracy wysyła nowe wiersze mniej więcej co 15 sekund. Logi zawierają wiersz, który wypisał przepływ pracy:
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()
Zaktualizuj przepływ pracy
Aby zmienić przepływ pracy, edytuj jego pliki i ponownie wywołaj upload() z tym samym title. Nowe wysłanie zastępuje wcześniejsze, a zadania, które już się rozpoczęły, nie są dotknięte.
Pola takie jak arguments_schema i sizes_map zachowują zapisane wartości, jeśli pominiesz je w nowym wysłaniu.
Następne kroki
- Zdefiniuj dane wejściowe i wyjściowe, aby dowiedzieć się, jakie typy argumentów i wyników obsługuje przepływ pracy.
- Zadeklaruj zależności, aby używać w przepływie pracy większej liczby pakietów Python.
- Uruchamiaj zadania kwantowe z przepływu pracy, aby uruchamiać obwody na QPU, raportować każdy etap i śledzić zadania QPU.
- Uruchom zarządzany przepływ pracy, aby poznać wszystkie statusy zadań, debugować nieudane zadanie i znaleźć zadanie później.
- Aby zacząć od działającego kodu, wdróż jeden z szablonów Qiskit Function lub dostosuj szablon do własnego przepływu pracy.