Aller au contenu principal
Ce projet est en phase bêta. Tu as trouvé un bug ? Ouvrir un ticket GitHub. Une question ou une idée ? Pose ta question dans Discussions — tes retours sont les bienvenus !
Quelle est la qualité de la traduction sur cette page ?

Déploie ton premier workflow géré

Versions des paquets

Le code de cette page a été développé avec les prérequis suivants. Nous te recommandons d'utiliser ces versions ou des versions plus récentes.

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

Utilise cette page pour téléverser un workflow, l'exécuter et obtenir son résultat. Le workflow d'exemple optimise et simule un circuit Qiskit. Il simule le circuit sur du matériel classique, il n'utilise donc pas de temps QPU.

Avant de commencer, installe le paquet client et authentifie-toi.

Utiliser les compétences IA (facultatif)

Pour déployer ton propre code avec l'aide d'un assistant IA, utilise les compétences IA du dépôt de modèles 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")

Écrire un workflow​

Créer la structure de dossiers​

Un workflow géré est un dossier de fichiers Python avec un fichier de point d'entrée. Un workflow géré téléverse tout le contenu du dossier, jusqu'à 50 Mo, et exécute le point d'entrée comme un script. Comme un workflow téléverse tout le dossier, garde tes fichiers locaux, comme deploy.ipynb, en dehors du dossier. Crée l'arborescence suivante :

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

Écrire le point d'entrée hello world​

Le point d'entrée lit un circuit, l'optimise et le simule, puis enregistre les comptages et la profondeur à deux qubits. Enregistre le code suivant sous source_files/hello_world.py :

remarque

Si tu lis cette page sous forme de notebook, la cellule de code de hello_world.py commence par la commande magique %%writefile. Lorsque tu exécutes cette cellule, elle enregistre le code dans le fichier au lieu de l'exécuter.

# 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

Le point d'entrée utilise trois fonctions de qiskit_serverless :

  • get_arguments() renvoie sous forme de dictionnaire les arguments nommés que tu passes à run(). Chaque valeur doit être sérialisable en JSON, ou être un objet que le client peut encoder, comme un QuantumCircuit. Les objets encodés arrivent sous la forme des mêmes objets que ceux que tu as passés.

  • update_status(Job.OPTIMIZING_HARDWARE) définit le statut détaillé RUNNING: OPTIMIZING_FOR_HARDWARE, que tu peux voir pendant l'exécution du job. Consulte Signaler la progression avec update_status().

  • save_result() stocke une valeur sérialisable en JSON que tu lis ensuite avec job.result(). Le workflow renvoie les comptages sous forme de dictionnaire et la profondeur à deux qubits du circuit optimisé sous forme d'entier.

Tout ce que le workflow écrit sur la sortie standard, comme la profondeur à deux qubits, va dans les logs du job. Pour ajouter des horodatages et des niveaux de log, utilise le module logging. Consulte Écrire des logs et gérer les erreurs.

Téléverser le workflow​

Dans ton notebook local, exécute le code suivant depuis le dossier hello_world_project. Le code se connecte avec ton compte enregistré, définit le workflow et le téléverse. entrypoint est le fichier que le workflow exécute, et working_dir est le dossier que tu téléverses :

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)

Exécuter le workflow avec des entrées​

Construis un circuit GHZ à trois qubits à passer à hello_world comme entrée :

from qiskit import QuantumCircuit

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

Exécute hello_world avec le circuit et le nombre de shots comme arguments nommés. Les noms des arguments correspondent aux clés que le point d'entrée lit avec get_arguments() :

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

run() renvoie un Job une fois que le workflow a mis le job en file d'attente. Elle n'attend pas que le job s'exécute. Le job continue dans le cloud après la fermeture de ta session Python. Pour le retrouver plus tard, liste tes jobs récents avec client.jobs().

Obtenir le statut, le résultat et les logs​

Juste après l'appel à run(), le statut est généralement QUEUED :

job.status()
'QUEUED'

Le statut passe de QUEUED à INITIALIZING, RUNNING, puis DONE.

job.result() attend la fin du job, puis renvoie la valeur que le workflow a passée à 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"])

Output of the previous code cell

Tu peux lire les logs pendant l'exécution du job. Le workflow téléverse de nouvelles lignes environ toutes les 15 secondes. Les logs incluent la ligne que le workflow a affichée :

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

Mettre à jour le workflow​

Pour modifier un workflow, édite ses fichiers et appelle à nouveau upload() avec le même title. Le nouveau téléversement remplace le précédent, et les jobs déjà démarrés ne sont pas affectés.

Les champs comme arguments_schema et sizes_map conservent leurs valeurs enregistrées lorsque tu les omets dans le nouveau téléversement.

Prochaines étapes​

Recommandations