Напиши свою першу програму Qiskit Serverless
Package versions
Код на цій сторінці розроблявся з використанням таких залежностей. Рекомендуємо використовувати ці або новіші версії.
qiskit[all]~=1.3.1
qiskit-ibm-runtime~=0.34.0
qiskit-aer~=0.15.1
qiskit-serverless~=0.27.0
qiskit-ibm-catalog~=0.2
qiskit-addon-sqd~=0.8.1
qiskit-addon-utils~=0.1.0
qiskit-addon-mpf~=0.2.0
qiskit-addon-aqc-tensor~=0.1.2
qiskit-addon-obp~=0.1.0
scipy~=1.15.0
pyscf~=2.8.0
Qiskit Serverless отримує оновлення, і його функції швидко змінюються. На цьому етапі розробки знаходь нотатки до релізів та найновішу документацію на сторінці GitHub Qiskit Serverless.
У цьому прикладі показано, як за допомогою інструментів qiskit-serverless створити програму паралельної транспіляції, а потім використати qiskit-ibm-catalog, щоб завантажити її на IBM Quantum Platform як багаторазовий віддалений сервіс.
Огляд робочого процесу
-
Створи локальний каталог і порожній файл програми (
./source_files/transpile_remote.py) -
Додай код до програми, яка після завантаження до Qiskit Serverless транспілюватиме схему
-
Використай
qiskit-ibm-catalogдля автентифікації в Qiskit Serverless -
Завантаж програму до Qiskit Serverless
Після завантаження програми можна запустити її для транспіляції схеми, дотримуючись інструкцій посібника Запусти своє перше робоче навантаження Qiskit Serverless віддалено.
# 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")
Приклад: Віддалена транспіляція з Qiskit Serverless
У цьому прикладі наведено кроки зі створення та наповнення файлу програми, який після завантаження до Qiskit Serverless транспілюватиме circuit для заданого backend і цільового optimization_level.
Qiskit Serverless вимагає організувати .py-файли робочого навантаження в окремий каталог. Ось приклад рекомендованої структури:
serverless_program
├── program_uploader.ipynb
└── source_files
├── transpile_remote.py
└── *.py
Serverless завантажує вміст конкретного каталогу (у цьому прикладі — каталогу source_files) для віддаленого запуску. Після налаштування можна скоригувати transpile_remote.py для отримання вхідних даних і повернення результатів.
Створи каталог і порожній файл програми
Спочатку створи каталог source_files, а потім файл програми в ньому так, щоб його шлях був ./source_files/transpile_remote.py. Це файл, який ти завантажиш до Qiskit Serverless.
Додай код до файлу програми
Заповни файл програми наведеним нижче кодом, а потім збережи його.
Якщо ти читаєш блоки коду локально в ноутбуці, ти побачиш магічну команду %%writefile. Виконання блоків з цією магічною командою зберігає їх на диск, а не виконує.
# This cell is hidden from users, it creates a new folder
from pathlib import Path
Path("./source_files").mkdir(exist_ok=True)
%%writefile ./source_files/transpile_remote.py
# If you include the preceding `%%writefile` command (visible only when you read this
# locally in a notebook), running this cell saves to disk rather than executing the code.
from qiskit.transpiler import generate_preset_pass_manager
def transpile_remote(circuit, optimization_level, backend):
"""Transpiles an abstract circuit into an ISA circuit for a given backend."""
pass_manager = generate_preset_pass_manager(
optimization_level=optimization_level,
backend=backend
)
isa_circuit = pass_manager.run(circuit)
return isa_circuit
Додай код для отримання аргументів програми
Тепер додай такий код до файлу програми, що налаштовує аргументи програми.
Початковий transpile_remote.py має три вхідні параметри: circuits, backend_name і optimization_level. Serverless наразі приймає лише серіалізовні вхідні й вихідні дані. З цієї причини не можна передати backend безпосередньо — замість цього використовуй backend_name як рядок.
%%writefile --append ./source_files/transpile_remote.py
# If you include the preceding `%%writefile` command (visible only when you read this
# locally in a notebook), running this cell saves to disk rather than executing the code.
from qiskit_serverless import get_arguments, save_result, distribute_task, get
# Get program arguments
arguments = get_arguments()
circuits = arguments.get("circuits")
backend_name = arguments.get("backend_name")
optimization_level = arguments.get("optimization_level")
Додай код для виклику бекенду
Додай такий код до файлу програми, що отримує службу виконання та використовує її для вибору бекенду.
У коді, що виконується в Qiskit Serverless, створюй службу виконання за допомогою get_runtime_service() (імпортованої з qiskit_serverless) замість безпосереднього створення екземпляра QiskitRuntimeService().
get_runtime_service() повертає обгортку-замінник для QiskitRuntimeService, яка прив'язує кожне запущене нею завдання й сесію примітиву IBM Quantum до батьківського завдання Qiskit Serverless. Саме цей зв'язок дозволяє платформі пов'язувати завдання Serverless із завданнями та сесіями QPU, які воно породжує, для відстеження статусу, журналів, а також обліку використання. Звичайний QiskitRuntimeService надсилає завдання, які платформа ніколи не пов'язує з твоїм завданням Serverless, тому цей зв'язок втрачається.
Усі аргументи є необов'язковими. Усередині коду програми рекомендованою формою є get_runtime_service() без аргументів, яка отримує дані автентифікації з середовища. Вона приймає ті самі необов'язкові аргументи channel, token, instance та url, що й QiskitRuntimeService.
Наведений нижче код передбачає, що ти вже виконав процедуру збереження облікових даних за допомогою QiskitRuntimeService.save_account, і завантажить твій обліковий запис за замовчуванням, якщо не вказано інше. Дивись Збережи свої облікові дані для входу і Ініціалізуй обліковий запис IBM Quantum Compute Service для отримання додаткової інформації.
%%writefile --append ./source_files/transpile_remote.py
# If you include the preceding `%%writefile` command (visible only when you read this
# locally in a notebook), running this cell saves to disk rather than executing the code.
from qiskit_serverless import get_runtime_service
service = get_runtime_service()
backend = service.backend(backend_name)
Додай код для транспіляції
Нарешті, додай такий код до файлу програми. Цей код запускає transpile_remote() для всіх переданих circuits і повертає transpiled_circuits як результат:
%%writefile --append ./source_files/transpile_remote.py
# If you include the preceding `%%writefile` command (visible only when you read this
# locally in a notebook), running this cell saves to disk rather than executing the code.
# Each circuit is being transpiled and will populate the array
results = [
transpile_remote(circuit, 1, backend)
for circuit in circuits
]
save_result({
"transpiled_circuits": results
})
Автентифікація в Qiskit Serverless
Використовуй qiskit-ibm-catalog для автентифікації в QiskitServerless за допомогою свого API-ключа (можна використовувати API-ключ QiskitRuntimeService або створити новий на дашборді IBM Quantum Platform).
from qiskit_ibm_catalog import QiskitServerless, QiskitFunction
# Authenticate to the remote cluster and submit the pattern for remote execution
serverless = QiskitServerless()
Запусти код для завантаження
Запусти наведений нижче код для завантаження програми. Qiskit Serverless стискає вміст working_dir (у цьому випадку source_files) у tar-архів, який завантажується, а після цього очищається. entrypoint визначає головний виконуваний файл програми для Qiskit Serverless.
transpile_remote_demo = QiskitFunction(
title="transpile_remote_serverless",
entrypoint="transpile_remote.py",
working_dir="./source_files/",
)
serverless.upload(transpile_remote_demo)
QiskitFunction(transpile_remote_serverless)
Перевір завантаження
Щоб перевірити успішність завантаження, використовуй serverless.list(), як у наведеному нижче коді:
# Get program from serverless.list() that matches the title of the one we uploaded
next(
program
for program in serverless.list()
if program.title == "transpile_remote_serverless"
)
QiskitFunction(transpile_remote_serverless)
# This cell is hidden from users, it checks the program uploaded correctly
assert _.title == "transpile_remote_serverless" # noqa: F821
# This cell is hidden from users, it checks the program executes correctly
from time import sleep
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
transpile_remote_serverless = serverless.load("transpile_remote_serverless")
job = transpile_remote_serverless.run(
circuits=[qc],
backend="ibm_sherbrooke",
optimization_level=1,
)
while True:
sleep(5)
status = job.status()
if status not in ["QUEUED", "INITIALIZING", "RUNNING", "DONE"]:
raise Exception(
f"Unexpected job status: '{status}'\n"
+ "Here are the logs:\n"
+ job.logs()
)
if status == "DONE":
break
Наступні кроки
- Дізнайся, як передавати вхідні дані та запускати програму віддалено, у темі Запусти своє перше робоче навантаження Qiskit Serverless віддалено.