Sampler con la REST API
I passaggi in questo argomento descrivono come eseguire e configurare i carichi di lavoro con la REST API e mostrano come invocarli in qualsiasi programma a tua scelta.
Questa documentazione utilizza il modulo Python requests per illustrare la REST API di Qiskit Runtime. Tuttavia, questo flusso di lavoro può essere eseguito usando qualsiasi linguaggio o framework che supporti le REST API. Consulta la documentazione di riferimento API per i dettagli.
1. Inizializza l'account
Poiché Qiskit Runtime Sampler è un servizio gestito, devi prima inizializzare il tuo account. Poi puoi selezionare il dispositivo su cui vuoi eseguire i tuoi calcoli.
Trova i dettagli su come inizializzare il tuo account, visualizzare i Backend disponibili e lavorare con i token in Configura IBM Quantum Platform con la REST API.
2. Crea un circuito QASM
Hai bisogno di almeno un circuito come input per la primitiva Sampler.
Definisci un circuito quantistico 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];
'''
I frammenti di codice riportati di seguito assumono che qasm_string sia stato transpilato in una nuova stringa resulting_qasm.
3. Esegui il circuito quantistico usando la Sampler V2 API
I job seguenti usano le primitive Qiskit Runtime V2. SamplerV2 accetta uno o più blocchi unificati primitivi (PUB) come input. Ogni PUB è una tupla che contiene un circuito e i dati trasmessi a quel Circuit, che possono essere più parametri, e restituisce un risultato per PUB.
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": {
# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[resulting_qasm],[resulting_qasm,None,500]]
}}
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. Controlla lo stato del job e ottieni i risultati
Successivamente, passa il job_id all'API:
response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)
response_status_singlejob.json().get('state')
Output
>>> Job ID: 58223448-5100-4dec-a47a-942fb30edced
>>> Job Status: JobStatus.RUNNING
Ottieni i risultati del job:
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])
Output
['0x3', '0x0', '0x2', '0x1', '0x0', '0x3', '0x0', '0x3', '0x1', '0x2', '0x2', '0x0', '0x2', '0x0', '0x3', '0x3', '0x2', '0x0', '0x1', '0x0']
5. Lavora con le opzioni di Qiskit Runtime
Le tecniche di mitigazione degli errori consentono agli utenti di mitigare gli errori del circuito modellando il rumore del dispositivo al momento dell'esecuzione. Questo comporta tipicamente un overhead di pre-elaborazione quantistica legato all'addestramento del modello, e un overhead di post-elaborazione classica per mitigare gli errori nei risultati grezzi usando il modello generato.
Le tecniche di mitigazione degli errori integrate nelle primitive sono opzioni di resilienza avanzate. Per specificare queste opzioni, usa l'opzione resilience_level quando invii il tuo job.
Sampler V2 non supporta la specifica dei livelli di resilienza. Tuttavia, puoi attivare o disattivare singoli metodi di mitigazione / soppressione degli errori.
I seguenti esempi mostrano le opzioni predefinite per il decoupling dinamico e il twirling. Trova ulteriori opzioni e dettagli nell'argomento Tecniche di mitigazione e soppressione degli errori.
Decoupling dinamico
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": {
# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[resulting_qasm]],
"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': 'sampler',
"backend": backend,
"params": {
# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[resulting_qasm]],
"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}")
Circuit parametrizzati
1. Inizializza l'account
Poiché Qiskit Runtime è un servizio gestito, devi prima inizializzare il tuo account. Poi puoi selezionare il dispositivo su cui vuoi eseguire i tuoi calcoli.
Trova i dettagli su come inizializzare il tuo account, visualizzare i Backend disponibili e invalidare i token in questo argomento.
2. Definisci i parametri
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')
# In case we want to pass a dictionary:
parameter_values = {'theta': 1.57, 'phi': 3.14}
3. Crea un circuito quantistico e aggiungi gate parametrizzati
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. Genera il codice QASM 3
qasm_str = dumps(isa_circuit)
print("Generated QASM 3 code:")
print(qasm_str)
5. Esegui il circuito quantistico usando la Sampler 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': 'sampler',
"backend": backend,
"params": {
# Choose one option: direct parameter transfer or through a dictionary
# # primitive unified blocs (PUBs) containing one circuit each:
#"pubs": [[qasm_str,[1,2],500]],
# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[qasm_str,parameter_values,500]],
}}
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. Controlla lo stato del job e ottieni i risultati
Successivamente, passa il job_id all'API:
response_status_singlejob = requests.get(f"{url}/{job_id}", headers=headers)
response_status_singlejob.json().get('state')
Output
{'status': 'Completed'}
Ottieni i risultati del job:
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']
Passi successivi
- Ci sono diversi modi per eseguire i carichi di lavoro, a seconda delle tue esigenze: modalità job, modalità sessione e modalità batch. Scopri come lavorare con la modalità sessione e la modalità batch nell'argomento sulle modalità di esecuzione. Nota che gli utenti del piano Open non possono inviare job in sessione.
- Scopri come inizializzare il tuo account con la REST API.
- Esercitati con le primitive lavorando attraverso la lezione sulle funzioni di costo in IBM Quantum Learning.
- Scopri come eseguire la trasposizione localmente nella sezione Transpile.