Przejdź do głównej treści

Pisanie pierwszego programu Qiskit Serverless

Package versions

The code on this page was developed using the following requirements. We recommend using these versions or newer.

qiskit[all]~=1.3.1
qiskit-ibm-runtime~=0.34.0
qiskit-aer~=0.15.1
qiskit-serverless~=0.18.1
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
wskazówka

Qiskit Serverless jest aktualizowany, a jego funkcje zmieniają się szybko. W tej fazie rozwoju informacje o wydaniach oraz najnowszą dokumentację znajdziesz na stronie Qiskit Serverless GitHub.

Ten przykład pokazuje, jak używać narzędzi qiskit-serverless do tworzenia programu do równoległej transpilacji, a następnie implementować qiskit-ibm-catalog, aby wdrożyć program na IBM Quantum Platform do używania jako wielokrotny zdalny serwis.

Przegląd przepływu pracy

  1. Utwórz lokalny katalog i pusty plik programu (./source_files/transpile_remote.py)
  2. Dodaj kod do programu, który po wdrożeniu na Qiskit Serverless dokona transpilacji obwodu
  3. Użyj qiskit-ibm-catalog, aby uwierzytelnić się w Qiskit Serverless
  4. Prześlij program do Qiskit Serverless

Po przesłaniu programu możesz go uruchomić, aby dokonać transpilacji obwodu, postępując zgodnie z instrukcją Zdalne uruchamianie pierwszego zadania Qiskit Serverless.

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-catalog qiskit-ibm-runtime qiskit-serverless

Przykład: zdalna transpilacja z Qiskit Serverless

Ten przykład prowadzi przez tworzenie i rozbudowywanie pliku programu, który po wdrożeniu na Qiskit Serverless dokona transpilacji circuit względem danego backend i docelowego optimization_level.

wskazówka

Qiskit Serverless wymaga umieszczenia plików .py zadania w dedykowanym katalogu. Następująca struktura jest przykładem dobrej praktyki:

serverless_program
├── program_uploader.ipynb
└── source_files
├── transpile_remote.py
└── *.py

Serverless przesyła zawartość określonego katalogu (w tym przykładzie katalogu source_files) w celu zdalnego uruchomienia. Po skonfigurowaniu tych plików możesz dostosować transpile_remote.py, aby pobierało dane wejściowe i zwracało wyjścia.

Tworzenie katalogu i pustego pliku programu

Najpierw utwórz katalog o nazwie source_files, a następnie utwórz plik programu w tym katalogu, tak aby jego ścieżka wynosiła ./source_files/transpile_remote.py. To jest plik, który prześlesz do Qiskit Serverless.

Dodawanie kodu do pliku programu

Wypełnij plik programu poniższym kodem, a następnie go zapisz.

ostrożnie

Jeśli czytasz komórki kodu lokalnie w notatniku, zobaczysz polecenie magiczne %%writefile. Wykonanie komórek z tym poleceniem magicznym zapisuje je na dysku zamiast je uruchamiać.

# 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

Dodawanie kodu pobierającego argumenty programu

Teraz dodaj poniższy kod do pliku programu, który konfiguruje argumenty programu.

Twój początkowy transpile_remote.py ma trzy dane wejściowe: circuits, backend_name i optimization_level. Serverless jest obecnie ograniczony do przyjmowania wyłącznie danych wejściowych i wyjściowych, które można serializować. Z tego powodu nie możesz bezpośrednio przekazać backend, więc zamiast tego użyj backend_name jako ciągu znaków.

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

Dodawanie kodu wywołującego backend

Dodaj poniższy kod do pliku programu, który wywołuje Twój backend za pomocą QiskitRuntimeService.

Poniższy kod zakłada, że już wykonałeś procedurę zapisywania poświadczeń przy użyciu QiskitRuntimeService.save_account i załaduje Twoje domyślne zapisane konto, chyba że określisz inaczej. Więcej informacji znajdziesz w artykułach Zapisz swoje dane logowania i Inicjalizacja konta usługi Qiskit Runtime.

%%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_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.backend(backend_name)

Dodawanie kodu do transpilacji

Na koniec dodaj poniższy kod do pliku programu. Ten kod uruchamia transpile_remote() dla wszystkich przekazanych circuits i zwraca transpiled_circuits jako wynik:

%%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
})

Uwierzytelnianie w Qiskit Serverless

Użyj qiskit-ibm-catalog, aby uwierzytelnić się w QiskitServerless swoim kluczem API (możesz użyć klucza API QiskitRuntimeService lub utworzyć nowy klucz API na panelu IBM Quantum Platform).

from qiskit_ibm_catalog import QiskitServerless, QiskitFunction

# Authenticate to the remote cluster and submit the pattern for remote execution
serverless = QiskitServerless()

Uruchamianie kodu w celu przesłania

Uruchom poniższy kod, aby przesłać program. Qiskit Serverless kompresuje zawartość working_dir (w tym przypadku source_files) do archiwum tar, które jest przesyłane i czyszczone po zakończeniu. entrypoint identyfikuje główny plik wykonywalny programu, który Qiskit Serverless ma uruchomić.

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)

Weryfikacja przesłania

Aby sprawdzić, czy przesłanie się powiodło, użyj serverless.list(), jak w poniższym kodzie:

# 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

Kolejne kroki

Recommendations