Skip to main content
IBM Quantum Platform

Exemplo de uso da API REST

As etapas descritas neste tópico explicam como executar e configurar cargas de trabalho usando a API REST e mostram como invocá-las em qualquer programa de sua escolha.

Note

Esta documentação utiliza o módulo requestsPython para demonstrar a API REST Qiskit Runtime. No entanto, esse fluxo de trabalho pode ser executado usando qualquer linguagem ou estrutura que ofereça suporte ao trabalho com APIs REST. Consulte a documentação de referência da API para obter mais detalhes.


1. Inicializar a conta

Como o Sampler do Qiskit Runtime é um serviço gerenciado, você precisa primeiro configurar sua conta. Você pode então selecionar o dispositivo no qual deseja realizar seus cálculos.

Veja detalhes sobre como inicializar sua conta, visualizar os back-ends disponíveis e trabalhar com tokens na se ção “Configurar para usar o IBM Quantum Platform com a API REST”.


2. Criar um circuito QASM

É necessário ter pelo menos um circuito como entrada para a primitiva Sampler.

Defina um circuito quâ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];
'''

Os trechos de código apresentados abaixo pressupõem que o qasm_string tenha sido transpilado para uma nova string resulting_qasm.


3. Execute o circuito quântico usando a API do Sampler V2

Note

Os trabalhos a seguir utilizam as primitivas Qiskit Runtime V2. SamplerV2 recebe um ou mais blocos primitivos unificados (PUBs) como entrada. Cada PUB é uma tupla que contém um circuito e os dados transmitidos para esse circuito — que podem ser vários parâmetros — e retorna um 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 o status do trabalho e obter os resultados

Em seguida, passe o job_id para a API:

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

Saída

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

Veja os resultados da busca:

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

Saída

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

5. Trabalhar com as opções d Qiskit Runtime

As técnicas de mitigação de erros permitem que os usuários minimizem os erros de circuito por meio da modelagem do ruído do dispositivo no momento da execução. Isso geralmente resulta em uma sobrecarga de pré-processamento quântico relacionada ao treinamento do modelo e em uma sobrecarga de pós-processamento clássico para mitigar erros nos resultados brutos por meio do uso do modelo gerado.

As técnicas de mitigação de erros integradas às primitivas são opções avançadas de resiliência. Para definir essas opções, use a resilience_level opção ao enviar seu trabalho. O Sampler V2 não permite definir níveis de resiliência. No entanto, você pode ativar ou desativar métodos individuais de mitigação ou supressão de erros.

Os exemplos a seguir demonstram as opções padrão para desacoplamento dinâmico e twirling. Encontre mais opções e detalhes no tópico “Técnicas de mitigação e supressão de erros”.

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

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

Circuitos parametrizados

1. Inicializar a conta

Como o Qiskit Runtime é um serviço gerenciado, você precisa primeiro configurar sua conta. Você pode então selecionar o dispositivo no qual deseja realizar seus cálculos.

Veja neste tópico como inicializar sua conta, visualizar os back-ends disponíveis e invalidar tokens.

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. Crie um circuito quântico e adicione portas 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. Gerar código QASM 3

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

5. Execute o circuito quântico usando a API do 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 o status do trabalho e obter os resultados

Em seguida, passe o job_id para a API:

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

Saída

{'status': 'Completed'}

Veja os resultados da busca:

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

Saída

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

Próximas etapas

Recomendações
  • Existem várias maneiras de executar cargas de trabalho, dependendo das suas necessidades: modo de tarefa, modo de sessão e modo em lote. Saiba como trabalhar com o modo de sessão e o modo em lote no tópico sobre modos de execução. Observe que os usuários do Open Plan não podem enviar tarefas de sessão.
  • Saiba como configurar sua conta usando a API REST.
  • Pratique com primitivas seguindo a lição sobre a função Cost em IBM Quantum Learning.
  • Saiba como fazer a transpilagem localmente na seção Transpilagem.
Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.