Estimator cu REST API
Versiuni de pachete
Codul de pe această pagină a fost dezvoltat folosind cerințele următoare. Recomandăm să folosești aceste versiuni sau versiuni mai noi.
qiskit[all]~=2.3.0
Pașii din acest topic descriu cum să rulezi și să configurezi sarcini cu REST API și demonstrează cum să le invoci în orice program la alegerea ta.
Această documentație folosește modulul Python requests pentru a demonstra Qiskit Runtime REST API. Cu toate acestea, acest flux de lucru poate fi executat folosind orice limbaj sau framework care suportă lucrul cu REST API. Consultă documentația de referință a API pentru detalii.
1. Inițializează contul
Deoarece Qiskit Runtime Estimator este un serviciu gestionat, mai întâi trebuie să îți inițializezi contul. Poți apoi selecta dispozitivul pe care vrei să îl folosești pentru a calcula valoarea de așteptare.
Găsești detalii despre cum să îți inițializezi contul, să vizualizezi Backend-urile disponibile și să invalidezi token-urile în acest topic.
2. Creează un circuit QASM
Ai nevoie de cel puțin un circuit ca intrare pentru primitiva Estimator.
Definește un circuit cuantic QASM. De exemplu:
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];
'''
Fragmentele de cod următoare presupun că qasm_string a fost transpilat într-un nou șir resulting_qasm.
3. Rulează Circuit-ul cuantic folosind Estimator V2 API
Joburile următoare folosesc primitivele Qiskit Runtime V2. Atât SamplerV2, cât și EstimatorV2 primesc unul sau mai multe primitive unified blocs (PUBs) ca intrare. Fiecare PUB este un tuplu care conține un circuit și datele difuzate către acel circuit, care pot fi mai multe observabile și parametri. Fiecare PUB returnează un rezultat.
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. Verifică starea jobului și obține rezultatele
Apoi, transmite job_id către API:
response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)
response_status_singlejob.json().get('state')
Output
>>> Job ID: 58223448-5100-4dec-a47a-942fb30edcad
>>> Job Status: JobStatus.RUNNING
Obține rezultatele jobului:
response_result= requests.get(url+'/'+job_id+'/results', headers=headers)
res_dict=response_result.json()
estimator_result=res_dict['results']
print(estimator_result)
Output
[{'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. Lucrează cu opțiunile Runtime
Tehnicile de atenuare a erorilor le permit utilizatorilor să atenueze erorile de circuit prin modelarea zgomotului dispozitivului la momentul execuției. Aceasta duce de obicei la costuri suplimentare de pre-procesare cuantică legate de antrenarea modelului și la costuri suplimentare de post-procesare clasică pentru atenuarea erorilor din rezultatele brute, folosind modelul generat.
Tehnicile de atenuare a erorilor integrate în primitive sunt opțiuni avansate de reziliență. Pentru a specifica aceste opțiuni, folosește opțiunea resilience_level atunci când trimiți jobul.
Exemplele de mai jos demonstrează opțiunile implicite pentru decuplarea dinamică, twirling și TREX + ZNE. Găsești mai multe opțiuni și detalii suplimentare în topicul Tehnici de atenuare și suprimare a erorilor.
TREX + ZNE
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}")
Decuplare dinamică
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}")
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": {
"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}")
Circuite parametrizate
1. Inițializează contul
Deoarece Qiskit Runtime este un serviciu gestionat, mai întâi trebuie să îți inițializezi contul. Poți apoi selecta dispozitivul pe care vrei să îl folosești pentru a rula calculele.
Găsești detalii despre cum să îți inițializezi contul, să vizualizezi Backend-urile disponibile și să invalidezi token-urile în acest topic.
2. Definește parametrii
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. Creează un circuit cuantic și adaugă Gate-uri parametrizate
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. Generează cod QASM 3
qasm_str = dumps(isa_circuit)
print("Generated QASM 3 code:")
print(qasm_str)
5. Rulează Circuit-ul cuantic folosind Estimator V2 API
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": {
# 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. Verifică starea jobului și obține rezultatele
În continuare, transmite job_id către API:
response_status_singlejob = requests.get(f"{url}/{job_id}", headers=headers)
response_status_singlejob.json().get('state')
Output
{'status': 'Completed'}
Obține rezultatele jobului:
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])
Output
['0x1', '0x2', '0x1', '0x2', '0x1', '0x2', '0x0', '0x2', '0x1', '0x1', '0x2', '0x2', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1']
Pași următori
- Există mai multe modalități de a rula workload-uri, în funcție de nevoile tale: job mode, session mode și batch mode. Află cum să lucrezi cu session mode și batch mode în topicul despre moduri de execuție. Reține că utilizatorii planului Open nu pot trimite joburi de tip Session.
- Află cum să îți inițializezi contul cu REST API.
- Exersează cu primitive lucrând prin lecția despre funcții de cost din IBM Quantum® Learning.
- Află cum să transpilezi local în secțiunea Transpiler.