Sari la conținutul principal

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.

notă

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

notă

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

Recomandări
  • 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.