Skip to main content
IBM Quantum Platform

Estimador con la API REST

Versiones del paquete

El código de esta página se ha desarrollado teniendo en cuenta los siguientes requisitos. Recomendamos utilizar estas versiones o posteriores.

qiskit[all]~=2.3.0

Los pasos de este tema describen cómo ejecutar y configurar cargas de trabajo mediante la API REST, y muestran cómo invocarlas en cualquier programa que elijas.

Note

Esta documentación utiliza el módulo requests Python para mostrar el funcionamiento de la API REST. No obstante, este flujo de trabajo se puede ejecutar utilizando cualquier lenguaje o marco de trabajo que permita trabajar con API REST. Consulta la documentación de referencia de la API para obtener más detalles.


1. Inicializar la cuenta

Dado que Estimator es un servicio gestionado, primero debes configurar tu cuenta. A continuación, puedes seleccionar el dispositivo que quieras utilizar para calcular el valor esperado.

En este tema encontrarás información sobre cómo iniciar sesión en tu cuenta, ver los backends disponibles e invalidar tokens.


2. Crear un circuito QASM

Necesitas al menos un circuito como entrada para la primitiva Estimator.

Defina un circuito cuántico QASM. Por ejemplo:

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];
'''

Los siguientes fragmentos de código dan por hecho que se qasm_string ha compilado en una nueva cadena resulting_qasm.


3. Ejecuta el circuito cuántico utilizando la API « V2 » de Estimator

Note

Los siguientes trabajos utilizan las primitivas IBM Quantum y V2. Tanto SamplerV2 como EstimatorV2 toman como entrada uno o más bloques primitivos unificados (PUB). Cada « PUB » es una tupla que contiene un circuito y los datos transmitidos a dicho circuito, que pueden ser varios observables y parámetros. Cada PUB devuelve un resultado.

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. Comprueba el estado del trabajo y obtén los resultados

A continuación, pasa el job_id a la API:

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

Resultado

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

Ver resultados de empleo:

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

res_dict=response_result.json()

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

Resultado

[{'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. Trabajar con opciones

Las técnicas de mitigación de errores permiten a los usuarios mitigar los errores de los circuitos mediante la modelización del ruido del dispositivo en el momento de la ejecución. Esto suele traducirse en una sobrecarga de preprocesamiento cuántico relacionada con el entrenamiento del modelo, y en una sobrecarga de posprocesamiento clásico para mitigar los errores en los resultados brutos mediante el uso del modelo generado.

Las técnicas de mitigación de errores integradas en las primitivas son opciones avanzadas de resiliencia. Para especificar estas opciones, utiliza la resilience_level opción al enviar tu trabajo.

Los siguientes ejemplos muestran las opciones predeterminadas para el desacoplamiento dinámico, el twirling y TREX + ZNE. Encontrarás más opciones y detalles adicionales en el tema «Técnicas de mitigación y supresión de errores ».

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

Desacoplamiento dinámico

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

Girando

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

Circuitos parametrizados

1. Inicializar la cuenta

Primero tienes que activar tu cuenta. A continuación, puedes seleccionar el dispositivo en el que deseas realizar los cálculos.

En este tema encontrarás información sobre cómo iniciar sesión en tu cuenta, ver los backends disponibles e invalidar tokens.

2. Definir los parámetros

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. Crear un circuito cuántico y añadir puertas parametrizadas

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. Generar código QASM 3

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

5. Ejecuta el circuito cuántico mediante la API de Estimator 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. Comprueba el estado del trabajo y obtén los resultados

A continuación, pasa el job_id a la API:

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

Resultado

{'status': 'Completed'}

Ver resultados de empleo:

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

Resultado

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

Próximos pasos

Recomendaciones
  • Hay varias formas de ejecutar cargas de trabajo, según tus necesidades: modo de trabajo, modo de sesión y modo por lotes. Descubre cómo trabajar con el modo de sesión y el modo por lotes en el apartado sobre modos de ejecución. Ten en cuenta que los usuarios de Open Plan no pueden enviar trabajos de sesión.
  • Descubre cómo configurar tu cuenta mediante la API REST.
  • Practica con primitivas siguiendo la lección sobre la función «Cost» en IBM Quantum® Learning.
  • Descubre cómo realizar la transpilación de forma local en la sección «Transpilación ».
¿Le ha resultado útil esta página?
Informe de un error, de una errata o solicite contenido en GitHub.