פרוס את זרימת העבודה המנוהלת הראשונה שלך
גרסאות חבילות
הקוד בעמוד הזה פותח עם הדרישות הבאות. מומלץ להשתמש בגרסאות האלה או בחדשות יותר.
qiskit[all]~=2.6.1
qiskit-serverless~=0.38.0
השתמש בעמוד הזה כדי להעלות זרימת עבודה, להריץ אותה ולקבל את התוצאה שלה. זרימת העבודה לדוגמה מבצעת אופטימיזציה וסימולציה של מעגל Qiskit. היא מדמה את המעגל על חומרה קלאסית, ולכן אינה משתמשת בזמן QPU.
לפני שמתחילים, התקן את חבילת הלקוח והתחבר.
כדי לפרוס קוד משלך בעזרת עוזר AI, השתמש ביכולות ה-AI ב-מאגר התבניות של 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")
כתיבת זרימת עבודה
יצירת מבנה התיקיות
זרימת עבודה מנוהלת היא תיקייה של קבצי Python עם קובץ נקודת כניסה אחד. זרימת עבודה מנוהלת מעלה את כל מה שבתיקייה, עד 50 MB, ומריצה את נקודת הכניסה כסקריפט. מכיוון שזרימת עבודה מעלה את התיקייה כולה, שמור את הקבצים המקומיים שלך, כמו deploy.ipynb, מחוץ לתיקייה. צור את המבנה הבא:
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
כתיבת נקודת הכניסה hello world
נקודת הכניסה קוראת מעגל, מבצעת לו אופטימיזציה וסימולציה, ושומרת את הספירות ואת העומק של שני קיוביטים. שמור את הקוד הבא בשם source_files/hello_world.py:
אם אתה קורא את העמוד הזה כמחברת, תא הקוד של hello_world.py מתחיל ב-פקודת הקסם %%writefile. כשאתה מריץ את התא הזה, הוא שומר את הקוד בקובץ במקום להריץ אותו.
# 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
נקודת הכניסה משתמשת בשלוש פונקציות מ-qiskit_serverless:
-
get_arguments()מחזירה כמילון את ארגומנטי ה-keyword שאתה מעביר ל-run(). כל ערך חייב להיות ניתן לסריאליזציה ל-JSON, או אובייקט שהלקוח יכול לקודד, כמוQuantumCircuit. אובייקטים מקודדים מגיעים כאותם אובייקטים שהעברת. -
update_status(Job.OPTIMIZING_HARDWARE)קובעת את הסטטוס המפורטRUNNING: OPTIMIZING_FOR_HARDWARE, שאפשר לראות בזמן שהמשימה רצה. ראה דיווח על התקדמות עם update_status(). -
save_result()שומרת ערך שניתן לסריאליזציה ל-JSON, שתקרא מאוחר יותר עםjob.result(). זרימת העבודה מחזירה את הספירות כמילון ואת העומק של שני קיוביטים של המעגל המותאם כמספר שלם.
כל מה שזרימת העבודה כותבת לפלט הסטנדרטי, כמו העומק של שני קיוביטים, נכנס ללוגים של המשימה. כדי להוסיף חותמות זמן ורמות לוג, השתמש במודול logging. ראה כתיבת לוגים וטיפול בשגיאות.
העלאת זרימת העבודה
במחברת המקומית שלך, הרץ את הקוד הבא מתוך התיקייה hello_world_project. הקוד מתחבר עם החשבון השמור שלך, מגדיר את זרימת העבודה ומעלה אותה. entrypoint הוא הקובץ שזרימת העבודה מריצה, ו-working_dir היא התיקייה שאתה מעלה:
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)
הרצת זרימת העבודה עם קלטים
בנה מעגל GHZ של שלושה קיוביטים כדי להעביר ל-hello_world כקלט:
from qiskit import QuantumCircuit
circuit = QuantumCircuit(3)
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.measure_all()
הרץ את hello_world עם המעגל ומספר ה-shots כארגומנטי keyword. שמות הארגומנטים תואמים למפתחות שנקודת הכניסה קוראת עם get_arguments():
job = hello_world.run(circuit=circuit, shots=1024)
print(job.job_id)
54705348-5117-44b7-935b-e6986ef182fa
run() מחזירה Job אחרי שזרימת העבודה מכניסה את המשימה לתור. היא לא ממתינה שהמשימה תרוץ. המשימה ממשיכה בענן גם אחרי שסוגרים את סשן ה-Python. כדי למצוא אותה שוב מאוחר יותר, הצג את המשימות האחרונות שלך עם client.jobs().
קבלת הסטטוס, התוצאה והלוגים
מיד אחרי שאתה קורא ל-run(), הסטטוס הוא בדרך כלל QUEUED:
job.status()
'QUEUED'
הסטטוס משתנה מ-QUEUED ל-INITIALIZING, RUNNING ואז DONE.
job.result() ממתינה עד שהמשימה מסתיימת, ואז מחזירה את הערך שזרימת העבודה העבירה ל-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"])
אפשר לקרוא את הלוגים בזמן שהמשימה רצה. זרימת העבודה מעלה שורות חדשות בערך כל 15 שניות. הלוגים כוללים את השורה שזרימת העבודה הדפיסה:
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()
עדכון זרימת העבודה
כדי לשנות זרימת עבודה, ערוך את הקבצים שלה וקרא שוב ל-upload() עם אותו title. ההעלאה החדשה מחליפה את הקודמת, ומשימות שכבר התחילו לא מושפעות.
שדות כמו arguments_schema ו-sizes_map שומרים על הערכים השמורים שלהם כשמשמיטים אותם בהעלאה החדשה.
השלבים הבאים
- הגדרת קלטים ופלטים כדי ללמוד אילו סוגי ארגומנטים ותוצאות זרימת עבודה תומכת בהם.
- הצהרה על תלויות כדי להשתמש ביותר חבילות Python בזרימת העבודה שלך.
- הרצת משימות קוונטיות מתוך זרימת עבודה כדי להריץ את המעגלים שלך על QPU, לדווח על כל שלב ולעקוב אחרי משימות ה-QPU.
- הרצת זרימת עבודה מנוהלת כדי ללמוד את כל סטטוסי המשימה, לנפות שגיאות במשימה שנכשלה ולמצוא משימה מאוחר יותר.
- כדי להתחיל מקוד עובד, פרוס אחת מ-תבניות Qiskit Function, או התאם תבנית לזרימת העבודה שלך.