最初のQiskit Serverlessプログラムを作成する
パッケージバージョン
このページのコードは、以下の要件を使用して開発されました。 これらのバージョン以降を使用することをお勧めします。
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はアップグレード中であり、その機能は急速に変化しています。 この開発フェーズでは、Qiskit Serverless GitHubページでリリースノートと最新ドキュメントを確認してください。
この例では、qiskit-serverlessツールを使用して並列トランスパイルプログラムを作成し、qiskit-ibm-catalogを実装してプログラムをIBM Quantum Platformに再利用可能なリモートサービスとしてアップロードする方法を示します。
ワークフローの概要
-
ローカルディレクトリと空のプログラムファイル(
./source_files/transpile_remote.py)を作成する -
アップロード時にQiskit Serverlessで回路をトランスパイルするコードをプログラムに追加する
-
qiskit-ibm-catalogを使用してQiskit Serverlessに認証する -
プログラムをQiskit Serverlessにアップロードする
プログラムをアップロードしたら、Run your first Qiskit Serverless workload remotelyガイドに従って回路をトランスパイルするために実行できます。
# 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にアップロードした際に、指定されたbackendとターゲットoptimization_levelに対してcircuitをトランスパイルするプログラムファイルの作成と追記手順を説明します。
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には3つの入力があります: 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上で実行されるコードの内部では、QiskitRuntimeService()を直接インスタンス化する代わりに、get_runtime_service()(qiskit_serverlessからインポート)を使用してランタイムサービスを作成します。
get_runtime_service()はQiskitRuntimeServiceのドロップイン・ラッパーを返し、起動するすべてのIBM QuantumプリミティブジョブとSessionを親のQiskit Serverlessジョブに対して登録します。この連携により、プラットフォームはServerlessジョブと、それが生成するQPUジョブおよびSessionを、ステータス追跡、ログ、使用状況・アカウンティングのために紐付けることができます。QiskitRuntimeServiceを直接使用して送信したジョブは、プラットフォームによってServerlessジョブに関連付けられることはないため、その連携は失われます。
すべての引数はオプションです。プログラムのソースコード内では、引数なしのget_runtime_service()という形式が推奨されます。これは環境から認証データを取得します。QiskitRuntimeServiceと同じオプションのchannel、token、instance、url引数を受け付けます。
以下のコードは、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)
トランスパイルするコードを追加する
最後に、以下のコードをプログラムファイルに追加します。このコードは渡されたすべてのcircuitsに対してtranspile_remote()を実行し、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を使用して、APIキーでQiskitServerlessに認証します(QiskitRuntimeServiceのAPIキーを使用するか、IBM Quantum Platformダッシュボードで新しいAPIキーを作成できます)。
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
次のステップ
- Run your first Qiskit Serverless workload remotelyトピックで、入力を渡してプログラムをリモートで実行する方法を学びましょう。