Skip to main content
IBM Quantum Platform

Strumento di stima con l'API REST

Versioni del pacchetto

Il codice presente in questa pagina è stato sviluppato sulla base dei seguenti requisiti. Si consiglia di utilizzare queste versioni o quelle più recenti.

qiskit[all]~=2.3.0

I passaggi descritti in questa sezione spiegano come eseguire e configurare i carichi di lavoro tramite l'API REST e mostrano come richiamarli in qualsiasi programma a propria scelta.

Note

La presente documentazione utilizza il modulo requests Python per illustrare l'API REST. Tuttavia, questo flusso di lavoro può essere eseguito utilizzando qualsiasi linguaggio o framework che supporti l'utilizzo delle API REST. Per ulteriori dettagli, consultare la documentazione di riferimento dell'API.


1. Inizializza l'account

Poiché Estimator è un servizio gestito, devi prima configurare il tuo account. A questo punto è possibile selezionare il dispositivo che si desidera utilizzare per calcolare il valore atteso.

In questa sezione troverai informazioni su come configurare il tuo account, visualizzare i backend disponibili e invalidare i token.


2. Creare un circuito QASM

È necessario almeno un circuito come input per la primitiva Estimator.

Definire un circuito quantistico QASM. Ad esempio:

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 seguenti frammenti di codice presuppongono che sia qasm_string stato transpilato in una nuova stringa resulting_qasm.


3. Eseguire il circuito quantistico utilizzando l'API Estimator dell' V2

Note

Le seguenti operazioni utilizzano le primitive IBM Quantum V2. Sia SamplerV2 che EstimatorV2 accettano come input uno o più blocchi primitivi unificati (PUB). Ogni " PUB " è una tupla che contiene un circuito e i dati trasmessi a tale circuito, che possono essere più osservabili e parametri. Ogni PUB restituisce un risultato.

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. Controllare lo stato del lavoro e visualizzare i risultati

Successivamente, invia il dato job_id all'API:

response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)
response_status_singlejob.json().get('state')

Emissione

>>> Job ID: 58223448-5100-4dec-a47a-942fb30edcad
>>> Job Status: JobStatus.RUNNING

Visualizza i risultati di ricerca:

response_result= requests.get(url+'/'+job_id+'/results', headers=headers)

res_dict=response_result.json()

estimator_result=res_dict['results']
print(estimator_result)

Emissione

[{'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. Utilizzo delle opzioni

Le tecniche di mitigazione degli errori consentono agli utenti di ridurre gli errori di circuito modellando il rumore del dispositivo al momento dell'esecuzione. Ciò comporta solitamente un sovraccarico di elaborazione quantistica nella fase di addestramento del modello e un sovraccarico di elaborazione classica nella fase di post-elaborazione, al fine di correggere gli errori presenti nei risultati grezzi utilizzando il modello generato.

Le tecniche di mitigazione degli errori integrate nelle primitive rappresentano opzioni avanzate di resilienza. Per specificare queste opzioni, utilizza resilience_level l'opzione al momento dell'invio del lavoro.

Gli esempi seguenti illustrano le opzioni predefinite per il disaccoppiamento dinamico, il twirling e TREX + ZNE. Per ulteriori opzioni e dettagli, consultare l'argomento " Tecniche di mitigazione e soppressione degli errori ".

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}")

Disaccoppiamento 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': '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}")

Girare

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}")

Circuiti parametrizzati

1. Inizializza l'account

Per prima cosa devi configurare il tuo account. A questo punto puoi selezionare il dispositivo su cui desideri eseguire i calcoli.

In questa sezione troverai informazioni su come configurare il tuo account, visualizzare i backend disponibili e invalidare i token.

2. Definire 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')
parameter_values = {'theta': 1.57, 'phi': 3.14}   # In case we want to pass a dictionary

3. Creare un circuito quantistico e aggiungere porte parametrizzate

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. Generare codice QASM 3

qasm_str = dumps(isa_circuit)
print("Generated QASM 3 code:")
print(qasm_str)

5. Eseguire il circuito quantistico utilizzando l'API Estimator dell' V2

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. Controllare lo stato del lavoro e visualizzare i risultati

Successivamente, invia il dato job_id all'API:

response_status_singlejob = requests.get(f"{url}/{job_id}", headers=headers)
response_status_singlejob.json().get('state')

Emissione

{'status': 'Completed'}

Visualizza i risultati di ricerca:

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])

Emissione

['0x1', '0x2', '0x1', '0x2', '0x1', '0x2', '0x0', '0x2', '0x1', '0x1', '0x2', '0x2', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1']

Passi successivi

Suggerimenti
  • Esistono diversi modi per eseguire i carichi di lavoro, a seconda delle proprie esigenze: modalità job, modalità sessione e modalità batch. Scopri come utilizzare la modalità sessione e la modalità batch nell'argomento dedicato alle modalità di esecuzione. Si noti che gli utenti di Open Plan non possono inviare lavori di sessione.
  • Scopri come configurare il tuo account tramite l'API REST.
  • Esercitati con le primitive seguendo la lezione sulla funzione «Cost» disponibile su IBM Quantum® Learning.
  • Scopri come eseguire la transpilazione in locale nella sezione " Transpilazione ".
Questa pagina è stata utile?
Segnala un bug, un errore di battitura o richiedi contenuti su GitHub.