REST APIを使ったPrimitives
このトピックでは、REST APIを使ってprimitive ワークロードを実行・設定する手順を説明し、任意のプログラムからそれらを呼び出す方法を示します。
このドキュメントでは、Qiskit Runtime REST APIの説明にPythonのrequestsモジュールを使用しています。ただし、REST APIをサポートする任意の言語やフレームワークを使ってこのワークフローを実行することができます。詳細については、APIリファレンスドキュメントを参照してください。
REST APIを使ったEstimator primitive
1. アカウントの初期化
Qiskit Runtime Estimatorはマネージドサービスであるため、最初にアカウントを初期化する必要があります。その後、期待値の計算に使用するデバイスを選択できます。
アカウントの初期化方法、利用可能なバックエンドの確認方法、およびトークンの無効化方法については、このトピックを参照してください。
2. QASMサーキットの作成
Estimator primitiveへの入力として、少なくとも1つのサーキットが必要です。
QASMの量子サーキットを定義します。例:
qasm_string='''
OPENQASM 3;
include "stdgates.inc";
qreg q[2];
creg c[2];
x q[0];
cx q[0], q[1];
c[0] = measure q[0];
c[1] = measure q[1];
'''
以下のコードスニペットでは、qasm_stringが新しい文字列resulting_qasmにトランスパイルされていることを前提としています。
3. Estimator V2 APIを使った量子サーキットの実行
以下のジョブではQiskit Runtime V2 primitivesを使用しています。SamplerV2とEstimatorV2はどちらも、1つ以上のPrimitive Unified Bloc(PUB)を入力として受け取ります。各PUBは1つのサーキットと、そのサーキットにブロードキャストされるデータ(複数のオブザーバブルやパラメーターを含む場合があります)を格納したタプルです。各PUBは結果を1つ返します。
import requests
url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"
headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'estimator',
"backend": backend,
"params": {
"pubs": [ #primitive unified blocs (PUBs) containing one circuit each.
[resulting_qasm, # QASM circuit
{"IIZII": 1, "XIZZZ": 2.3}, # Observable
None # parameter values
]]
}}
response = requests.post(url, headers=headers, json=job_input)
if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")
4. ジョブのステータス確認と結果の取得
次に、job_idをAPIに渡します:
response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)
response_status_singlejob.json().get('state')
出力
>>> Job ID: 58223448-5100-4dec-a47a-942fb30edcad
>>> Job Status: JobStatus.RUNNING
ジョブの結果を取得します:
response_result= requests.get(url+'/'+job_id+'/results', headers=headers)
res_dict=response_result.json()
estimator_result=res_dict['results']
print(estimator_result)
出力
[{'data': {'evs': 0.7428980350102542, 'stds': 0.029884014518789213, 'ensemble_standard_error': 0.03261147170624149}, 'metadata': {'shots': 10016, 'target_precision': 0.01, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}}]
5. Runtimeオプションの利用
エラー軽減技術を使うと、実行時のデバイスノイズをモデル化することでサーキットのエラーを軽減できます。これにより、通常、モデルの学習に関連する量子前処理のオーバーヘッドと、生成されたモデルを使って生の結果のエラーを軽減するための古典後処理のオーバーヘッドが発生します。
primitiveに組み込まれたエラー軽減技術は、高度なレジリエンスオプションです。これらのオプションを指定するには、ジョブ投入時にresilience_levelオプションを使用してください。
以下の例では、ダイナミカルデカップリング、ツワーリング、TREX + ZNEのデフォルトオプションを示します。さらに多くのオプションと詳細については、エラー軽減・抑制技術のトピックを参照してください。
- TREX + ZNE
- Dynamical Decoupling
- Twirling
import requests
url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "BACKEND_NAME"
headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'estimator',
"backend": backend,
"params": {
"pubs": [ #primitive unified blocs (PUBs) containing one circuit each
[resulting_qasm, # QASM circuit
{"IIZII": 1, "XIZZZ": 2.3}, # Observable
None # parameter values
]]
"options": {
"resilience": {
"measure_mitigation": True,
"zne_mitigation": True,
"zne": {
"extrapolator":["exponential", "linear"],
"noise_factors":[1, 3, 5],
},
},
},
}
}
response = requests.post(url, headers=headers, json=job_input)
if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")
import requests
url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "BACKEND_NAME"
headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'estimator',
"backend": backend,
"params": {
"pubs": [ #primitive unified blocs (PUBs) containing one circuit each
[resulting_qasm, # QASM circuit
{"IIZII": 1, "XIZZZ": 2.3}, # Observable
None # parameter values
]]
"options": {
"dynamical_decoupling": {
"enable": True,
"sequence_type": 'XpXm',
"extra_slack_distribution": 'middle',
"scheduling_method": 'alap',
},
},
}
}
response = requests.post(url, headers=headers, json=job_input)
if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")
import requests
url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "BACKEND_NAME"
headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'estimator',
"backend": backend,
"params": {
"pubs": [ #primitive unified blocs (PUBs) containing one circuit each
[resulting_qasm, # QASM circuit
{"IIZII": 1, "XIZZZ": 2.3}, # Observable
None # parameter values
]]
"options": {
"twirling": {
"enable_gates": True,
"enable_measure": True,
"num_randomizations": "auto",
"shots_per_randomization": "auto",
"strategy": "active-accum",
},
},
}
}
response = requests.post(url, headers=headers, json=job_input)
if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")
REST API を使った Sampler プリミ ティブ
1. アカウントの初期化
Qiskit Runtime Sampler はマネージドサービスであるため、まずアカウントを初期化する必要があります。その後、計算を実行するデバイスを選択できます。
アカウントの初期化方法、利用可能なバックエンドの確認方法、およびトークンの無効化方法については、このトピックをご参照ください。
2. QASM 回路の作成
Sampler プリミティブへの入力として、少なくとも 1 つの回路が必要です。
QASM 量子回路を定義します。
qasm_string='''
OPENQASM 3;
include "stdgates.inc";
qreg q[2];
creg c[2];
x q[0];
cx q[0], q[1];
c[0] = measure q[0];
c[1] = measure q[1];
'''
以下のコードスニペットでは、qasm_string が新しい文字列 resulting_qasm にトランスパイルされていることを前提としています。
3. Sampler V2 API を使った量子回路の実行
以下のジョブでは Qiskit Runtime V2 プリミティブを使用しています。SamplerV2 と EstimatorV2 はどちらも、1 つ以上の primitive unified bloc(PUB)を入力として受け取ります。各 PUB は 1 つの回路と、その回路にブロードキャストされるデータ(複数のオブザーバブルやパラメーターなど)を含むタプルです。各 PUB は結果を 1 つ返します。
import requests
url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"
headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
"pubs": [[resulting_qasm],[resulting_qasm,None,500]] # primitive unified blocs (PUBs) containing one circuit each.
}}
response = requests.post(url, headers=headers, json=job_input)
if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")
4. ジョブステータスの確認と結果の取得
次に、job_id を API に渡します。
response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)
response_status_singlejob.json().get('state')
出力
>>> Job ID: 58223448-5100-4dec-a47a-942fb30edced
>>> Job Status: JobStatus.RUNNING
ジョブの結果を取得します。
response_result= requests.get(url+'/'+job_id+'/results', headers=headers)
res_dict=response_result.json()
# Get results for the first PUB
counts=res_dict['results'][0]['data']['c']['samples']
print(counts[:20])
出力
['0x3', '0x0', '0x2', '0x1', '0x0', '0x3', '0x0', '0x3', '0x1', '0x2', '0x2', '0x0', '0x2', '0x0', '0x3', '0x3', '0x2', '0x0', '0x1', '0x0']
5. Runtime オプションの活用
エラー緩和技術を使用すると、実行時のデバイスノイズをモデル化することで回路のエラーを軽減できます。これにより、通常はモデルトレーニングに関連する量子前処理のオーバーヘッドと、生成されたモデルを用いて生の結果のエラーを緩和するための古典後処理のオーバーヘッドが発生します。
プリミティブに組み込まれているエラー緩和技術は、高度なレジリエンスオプションです。これらのオプションを指定するには、ジョブ送信時に resilience_level オプションを使用します。
Sampler V2 はレジリエンスレベルの指定をサポートしていませんが、個々のエラー緩和・抑制メソッドのオン/オフを切り替えることができます。
以下の例は、ダイナミカルデカップリングおよびツワーリン グのデフォルトオプションを示しています。その他のオプションや詳細については、エラー緩和・抑制技術のトピックをご参照ください。
- Dynamical Decoupling
- Twirling
import requests
url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"
headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
"pubs": [[resulting_qasm]], # primitive unified blocs (PUBs) containing one circuit each.
"options": {
"dynamical_decoupling": {
"enable": True,
"sequence_type": 'XpXm',
"extra_slack_distribution": 'middle',
"scheduling_method": 'alap',
},
},
}
}
response = requests.post(url, headers=headers, json=job_input)
if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")
import requests
url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"
headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
"pubs": [[resulting_qasm]], # primitive unified blocs (PUBs) containing one circuit each.
"options": {
"twirling": {
"enable_gates": True,
"enable_measure": True,
"num_randomizations": "auto",
"shots_per_randomization": "auto",
"strategy": "active-accum",
},
},
}
}
response = requests.post(url, headers=headers, json=job_input)
if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")
REST API とパラメーター化回路を使った Sampler プリミティブ
1. アカウントの初期化
Qiskit Runtime はマネージドサービスであるため、まずアカウントを初期化する必要があります。その後、計算を実行するデバイスを選択できます。
アカウントの初期化方法、利用可能なバックエンドの確認方法、およびトークンの無効化方法については、このトピックをご参照ください。
2. パラメーターの定義
import requests
import qiskit_ibm_runtime
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.qasm3 import dumps
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit import transpile
service = QiskitRuntimeService(channel='ibm_quantum')
backend = service.backend("<SPECIFY BACKEND>")
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
theta = Parameter('theta')
phi = Parameter('phi')
parameter_values = {'theta': 1.57, 'phi': 3.14} # In case we want to pass a dictionary
3. 量子回路の作成とパラメーター化ゲートの追加
qc = QuantumCircuit(2)
# Add parameterized gates
qc.rx(theta, 0)
qc.ry(phi, 1)
qc.cx(0, 1)
qc.measure_all()
# Draw the original circuit
qc.draw('mpl')
# Get an ISA circuit
isa_circuit = pm.run(qc)
4. QASM 3 コードの生成
qasm_str = dumps(isa_circuit)
print("Generated QASM 3 code:")
print(qasm_str)
5. Sampler V2 API を使った量子回路の実行
以下のジョブでは Qiskit Runtime V2 プリミティブを使用しています。SamplerV2 と EstimatorV2 はどちらも、1 つ以上の primitive unified bloc(PUB) を入力として受け取ります。各 PUB は 1 つの回路と、その回路にブロードキャストされるデータ(複数のオブザーバブルやパラメーターなど)を含むタプルです。各 PUB は結果を 1 つ返します。
import requests
url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"
headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
# Choose one option: direct parameter transfer or through a dictionary
#"pubs": [[qasm_str,[1,2],500]], # primitive unified blocs (PUBs) containing one circuit each.
"pubs": [[qasm_str,parameter_values,500]], # primitive unified blocs (PUBs) containing one circuit each.
}}
response = requests.post(url, headers=headers, json=job_input)
if response.status_code == 200:
job_id = response.json().get('id')
print(f"Job created: {response.text}")
else:
print(f"Error: {response.status_code}")
print(response.text)
6. ジョブステータスの確認と結果の取得
次に、job_id を API に渡します。
response_status_singlejob = requests.get(f"{url}/{job_id}", headers=headers)
response_status_singlejob.json().get('state')
出力
{'status': 'Completed'}
ジョブの結果を取得します。
response_result = requests.get(f"{url}/{job_id}/results", headers=headers)
res_dict=response_result.json()
# Get results for the first PUB
counts=res_dict['results'][0]['data']['c']['samples']
print(counts[:20])
出力
['0x1', '0x2', '0x1', '0x2', '0x1', '0x2', '0x0', '0x2', '0x1', '0x1', '0x2', '0x2', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1']
次のステップ
- ワークロードの実行方法にはニーズに応じていくつかの方法があります。ジョブモード、セッションモード、バッチモードなどがあります。セッションモードおよびバッチモードの使用方法については、実行モードのトピックをご覧ください。なお、Open Plan のユーザーはセッションジョブを送信できません。
- REST API を使ったアカウントの初期化方法をご確認ください。
- V2 プリミティブへの移行をお読みください。
- IBM Quantum Learning のコスト関数レッスンでプリミティブを使った演習を行いましょう。
- トランスパイルセクションで、ローカルでのトランスパイル方法をご確認ください。
- Qiskit Runtime V2 プリミティブへの移行を行いましょう。