Primitiva s REST API
Kroky v tomto tématu popisují, jak spouštět a konfigurovat úlohy s primitivy pomocí REST API, a ukazují, jak je volat v libovolném programu dle tvého výběru.
Tato dokumentace využívá Python modul requests k demonstraci Qiskit Runtime REST API. Tento postup však lze provést v libovolném jazyce nebo frameworku, který podporuje práci s REST API. Podrobnosti najdeš v referenční dokumentaci API.
Primitivum Estimator s REST API
1. Inicializace účtu
Protože Qiskit Runtime Estimator je spravovaná služba, musíš nejprve inicializovat svůj účet. Poté můžeš vybrat zařízení, které chceš použít k výpočtu střední hodnoty.
Podrobnosti o inicializaci účtu, zobrazení dostupných backendů a zneplatnění tokenů najdeš v tomto tématu.
2. Vytvoření QASM Circuit
Jako vstup pro primitivum Estimator potřebuješ alespoň jeden Circuit.
Definuj kvantový Circuit v QASM. Například:
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];
'''
Následující ukázky kódu předpokládají, že byl qasm_string transpilován do nového řetězce resulting_qasm.
3. Spuštění kvantového Circuit pomocí Estimator V2 API
Následující úlohy používají Qiskit Runtime V2 primitiva. Jak SamplerV2, tak EstimatorV2 přijímají jako vstup jeden nebo více primitive unified bloků (PUBs). Každý PUB je tuple obsahující jeden Circuit a data vysílaná do tohoto Circuit, což mohou být různé observables a parametry. Každý PUB vrátí výsledek.
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. Kontrola stavu úlohy a získání výsledků
Dále předej job_id do API:
response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)
response_status_singlejob.json().get('state')
Výstup
>>> Job ID: 58223448-5100-4dec-a47a-942fb30edcad
>>> Job Status: JobStatus.RUNNING
Získání výsledků úlohy:
response_result= requests.get(url+'/'+job_id+'/results', headers=headers)
res_dict=response_result.json()
estimator_result=res_dict['results']
print(estimator_result)
Výstup
[{'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. Práce s Runtime možnostmi
Techniky zmírnění chyb umožňují uživatelům snížit chybovost Circuit tím, že modelují šum zařízení v době provádění. To obvykle vede k režijním nákladům na kvantové předzpracování spojeným s trénováním modelu a k režijním nákladům na klasické postprocessing, které slouží ke zmírnění chyb v surových výsledcích pomocí vygenerovaného modelu.
Techniky zmírnění chyb zabudované v primitivech jsou pokročilé možnosti odolnosti. Chceš-li tyto možnosti určit, použij při odesílání úlohy volbu resilience_level.
Následující příklady ukazují výchozí možnosti pro dynamical decoupling, twirling a TREX + ZNE. Další možnosti a podrobnosti najdeš v tématu Techniky zmírnění a potlačení chyb.
- 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}")
Sampler primitive s REST API
1. Inicializace účtu
Protože Qiskit Runtime Sampler je spravovaná služba, musíš nejprve inicializovat svůj účet. Poté si můžeš vybrat zařízení, na kterém chceš provádět výpočty.
Podrobnosti o tom, jak inicializovat účet, zobrazit dostupné backendy a zneplatnit tokeny, najdeš v tomto tématu.
2. Vytvoření QASM Circuit
Jako vstup pro Sampler primitive potřebuješ alespoň jeden Circuit.
Definuj QASM kvantový Circuit:
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];
'''
Níže uvedené ukázky kódu předpokládají, že qasm_string byl transpilován do nového řetězce resulting_qasm.
3. Spuštění kvantového Circuit pomocí Sampler V2 API
Níže uvedené úlohy používají Qiskit Runtime V2 primitives. Jak SamplerV2, tak EstimatorV2 přijímají jako vstup jeden nebo více primitive unified bloků (PUBs). Každý PUB je n-tice obsahující jeden Circuit a data vysílaná do tohoto Circuit, což může být více observables a parametrů. Každý PUB vrací výsledek.
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. Kontrola stavu úlohy a získání výsledků
Dále předej job_id do API:
response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)
response_status_singlejob.json().get('state')
Výstup
>>> Job ID: 58223448-5100-4dec-a47a-942fb30edced
>>> Job Status: JobStatus.RUNNING
Získej výsledky úlohy:
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])
Výstup
['0x3', '0x0', '0x2', '0x1', '0x0', '0x3', '0x0', '0x3', '0x1', '0x2', '0x2', '0x0', '0x2', '0x0', '0x3', '0x3', '0x2', '0x0', '0x1', '0x0']
5. Práce s Runtime možnostmi
Techniky zmírnění chyb umožňují uživatelům snížit chyby Circuit modelováním šumu zařízení v době provád ění. To obvykle vede k režii kvantového předzpracování související s trénováním modelu a k režii klasického následného zpracování určené ke zmírnění chyb v surových výsledcích pomocí vygenerovaného modelu.
Techniky zmírnění chyb zabudované do primitiv jsou pokročilé možnosti odolnosti. Chceš-li tyto možnosti specifikovat, použij při odesílání úlohy volbu resilience_level.
Sampler V2 nepodporuje specifikování úrovní odolnosti. Můžeš však zapínat nebo vypínat jednotlivé metody zmírnění či potlačení chyb.
Následující příklady ukazují výchozí možnosti pro dynamické oddělení (dynamical decoupling) a twirling. Další možnosti a podrobnosti najdeš v tématu Techniky zmírnění a potlačení chyb.
- Dynamické oddělení (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}")
Sampler primitive s REST API a parametrizovanými obvody
1. Inicializace účtu
Protože Qiskit Runtime je spravovaná služba, musíš nejprve inicializovat svůj účet. Poté můžeš vybrat zařízení, na kterém chceš provádět výpočty.
Podrobnosti o inicializaci účtu, zobrazení dostupných backendů a zneplatnění tokenů najdeš v tomto tématu.
2. Definování parametrů
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. Vytvoření kvantového Circuit a přidání parametrizovaných Gate
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. Generování kódu QASM 3
qasm_str = dumps(isa_circuit)
print("Generated QASM 3 code:")
print(qasm_str)
5. Spuštění kvantového Circuit pomocí Sampler V2 API
Následující úlohy využívají Qiskit Runtime V2 primitiva. Jak SamplerV2, tak EstimatorV2 přijímají jako vstup jeden nebo více primitive unified bloků (PUBs). Každý PUB je n-tice obsahující jeden Circuit a data rozesílaná do tohoto Circuit, což může být více observables a parametrů. Každý PUB vrátí jeden výsledek.
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. Kontrola stavu úlohy a získání výsledků
Dále předej job_id do API:
response_status_singlejob = requests.get(f"{url}/{job_id}", headers=headers)
response_status_singlejob.json().get('state')
Výstup
{'status': 'Completed'}
Získání výsledků úlohy:
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])
Výstup
['0x1', '0x2', '0x1', '0x2', '0x1', '0x2', '0x0', '0x2', '0x1', '0x1', '0x2', '0x2', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1']
Další kroky
- Existuje několik způsobů spouštění pracovních zátěží podle tvých potřeb: režim úlohy, režim Session a dávkový režim. Zjisti, jak pracovat s režimem Session a dávkovým režimem v tématu o režimech spouštění. Uživatelé plánu Open nemohou odesílat úlohy v Session.
- Zjisti, jak inicializovat svůj účet pomocí REST API.
- Přečti si Migrace na primitiva V2.
- Procvič si práci s primitivy v lekci Cost function v IBM Quantum Learning.
- Zjisti, jak transpilovat lokálně v sekci Transpiler.
- Migruj na primitiva Qiskit Runtime V2.