Saltar al contenido principal
Este proyecto está en fase beta. ¿Encontraste un error? Abre un issue en GitHub. ¿Tienes una pregunta o una idea? Pregunta en Discussions — ¡nos encantaría tu opinión!
¿Cómo es la calidad de la traducción en esta página?

Sampler con la API REST

Los pasos de este tema describen cómo ejecutar y configurar cargas de trabajo con la API REST, y demuestran cómo invocarlas en cualquier programa de tu elección.

nota

Esta documentación utiliza el módulo Python requests para demostrar la API REST de IBM Quantum Compute Service. Sin embargo, este flujo de trabajo puede ejecutarse usando cualquier lenguaje o framework que admita trabajar con APIs REST. Consulta la documentación de referencia de la API para más detalles.

1. Inicializar la cuenta​

Primero debes inicializar tu cuenta. Luego puedes seleccionar el dispositivo que quieres usar para ejecutar tus cálculos.

Encuentra detalles sobre cómo inicializar tu cuenta, ver los backends disponibles y trabajar con tokens en Configurar para usar IBM Quantum Platform con la API REST.

2. Crear un circuit QASM​

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

Define un circuit cuántico 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];
'''

Los fragmentos de código que se presentan a continuación asumen que el qasm_string ha sido transpilado a una nueva cadena resulting_qasm.

3. Ejecutar el circuito cuántico usando la API de Sampler​

nota

Los trabajos a continuación usan primitivos IBM Quantum. Sampler toma uno o más bloques unificados primitivos (PUBs) como entrada. Cada PUB es una tupla que contiene un circuito y los datos difundidos a ese circuito, que pueden ser múltiples parámetros, y devuelve un resultado por 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. Verificar el estado del trabajo y obtener 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')

Salida

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

Obtén los resultados del trabajo:

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

Salida

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

5. Trabajar con opciones de IBM Quantum Compute Service​

Las técnicas de mitigación de errores permiten a los usuarios mitigar errores del circuito modelando el ruido del dispositivo en el momento de la ejecución. Por lo general, esto conlleva una sobrecarga de preprocesamiento cuántico relacionada con el entrenamiento del modelo, y una sobrecarga de postprocesamiento clásico para mitigar errores en los resultados sin procesar usando el modelo generado.

Las técnicas de mitigación de errores integradas en los primitivos son opciones avanzadas de resiliencia. Para especificar estas opciones, usa la opción resilience_level al enviar tu trabajo. Sampler V2 no admite la especificación de niveles de resiliencia. Sin embargo, puedes activar o desactivar métodos individuales de mitigación/supresión de errores.

Los siguientes ejemplos muestran las opciones predeterminadas para el desacoplamiento dinámico y el twirling. Encuentra más opciones y detalles adicionales en el tema Técnicas de mitigación y supresión de errores.

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

Circuits parametrizados​

1. Inicializar la cuenta​

Primero debes inicializar tu cuenta. Luego puedes seleccionar el dispositivo que quieres usar para ejecutar tus cálculos.

Encuentra detalles sobre cómo inicializar tu cuenta, ver los backends disponibles e invalidar tokens en este tema.

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

3. Crear un circuit cuántico y agregar gates parametrizados​

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. Ejecutar el circuit cuántico usando la API Sampler 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': '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. Verificar el estado del trabajo y obtener 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')

Salida

{'status': 'Completed'}

Obtén los resultados del trabajo:

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

Salida

['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: job mode, session mode y batch mode. Aprende cómo trabajar con session mode y batch mode en el tema sobre modos de ejecución. Ten en cuenta que los usuarios del Plan Open no pueden enviar trabajos de sesión.
  • Aprende a inicializar tu cuenta con la API REST.
  • Practica con los primitivos trabajando en la lección de función de costo en IBM Quantum Learning.
  • Aprende a transpilar localmente en la sección Transpilar.