Skip to main content
IBM Quantum Platform

Comece com primitivas

Novo modelo de execução, agora em versão beta

A versão beta de um novo modelo de execução já está disponível. O modelo de execução direcionada oferece mais flexibilidade ao personalizar seu fluxo de trabalho de atenuação de erros. Consulte o guia do modelo de execução direcionada para obter mais informações.

Note

Embora esta documentação use as primitivas de Qiskit Runtime, que permitem que você use os backends de IBM®, as primitivas podem ser executadas em qualquer provedor usando as primitivas de backend. Além disso, você pode usar as primitivas de referência para executar em um simulador de vetor de estado local. Consulte Simulação exata com primitivos Qiskit para obter detalhes.

As etapas deste tópico descrevem como configurar primitivas, explorar as opções que podem ser usadas para configurá-las e invocá-las em um programa.

Uso de portas fracionárias

Para usar as novas portas fracionárias compatíveis, defina use_fractional_gates=True ao solicitar um backend de uma instância QiskitRuntimeService . Por exemplo:

service = QiskitRuntimeService()
fractional_gate_backend = service.least_busy(use_fractional_gates=True)

Observe que esse é um recurso experimental e pode mudar no futuro.

  • O código desta página foi desenvolvido usando os seguintes requisitos. Recomendamos o uso dessas versões ou de versões mais recentes.

    qiskit[all]~=2.3.1
    qiskit-ibm-runtime~=0.45.1
    

Comece a usar o Estimador

1. Inicialize a conta

Como o Qiskit Runtime Estimator é um serviço gerenciado, primeiro você precisa inicializar sua conta. Em seguida, você pode selecionar a QPU que deseja usar para calcular o valor de expectativa.

Siga as etapas no tópico Instalar e configurar se você ainda não tiver uma conta.

from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.least_busy(
    operational=True, simulator=False, min_num_qubits=127
)

print(backend.name)

Output:

ibm_fez

2. Crie um circuito e um observável

Você precisa de pelo menos um circuito e um observável como entradas para a primitiva Estimator.

from qiskit.circuit.library import qaoa_ansatz
from qiskit.quantum_info import SparsePauliOp

entanglement = [tuple(edge) for edge in backend.coupling_map.get_edges()]
observable = SparsePauliOp.from_sparse_list(
    [("ZZ", [i, j], 0.5) for i, j in entanglement],
    num_qubits=backend.num_qubits,
)
circuit = qaoa_ansatz(observable, reps=2)
# the circuit is parametrized, so we will define the parameter values for execution
param_values = [0.1, 0.2, 0.3, 0.4]

print(f">>> Observable: {observable.paulis}")

Output:

>>> Observable: ['IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...', ...]

O circuito e o observável precisam ser transformados para usar somente as instruções compatíveis com a QPU (chamadas de circuitos de arquitetura de conjunto de instruções (ISA) ). Usaremos o transpilador para fazer isso.

from qiskit.transpiler import generate_preset_pass_manager

pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
isa_circuit = pm.run(circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)
print(f">>> Circuit ops (ISA): {isa_circuit.count_ops()}")

Output:

>>> Circuit ops (ISA): OrderedDict([('rz', 4472), ('sx', 1884), ('cz', 1120)])

3. Inicializar um estimador d Qiskit Runtime

Ao inicializar o Estimador, use o mode parâmetro para especificar o modo em que deseja que ele seja executado. Os valores possíveis são batch, session, ou backend objetos para os modos de execução em lote, sessão e tarefa, respectivamente. Para obter mais informações, consulte Introdução aos modos de execução do Qiskit Runtime.

from qiskit_ibm_runtime import EstimatorV2 as Estimator

estimator = Estimator(mode=backend)

4. Invoque o Estimador e obtenha resultados

Em seguida, invoque o método run() para calcular os valores de expectativa para os circuitos de entrada e os observáveis. Os conjuntos de valores de parâmetros de circuito, observáveis e opcionais são inseridos como tuplas primitivas de bloco unificado ( PUB ).

job = estimator.run([(isa_circuit, isa_observable, param_values)])
print(f">>> Job ID: {job.job_id()}")
print(f">>> Job Status: {job.status()}")

Output:

>>> Job ID: d76cm768faus73f14eg0
>>> Job Status: QUEUED
result = job.result()
print(f">>> {result}")
print(f"  > Expectation value: {result[0].data.evs}")
print(f"  > Metadata: {result[0].metadata}")

Output:

>>> PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(), dtype=float64>), stds=np.ndarray(<shape=(), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(), dtype=float64>)), metadata={'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32})], metadata={'dynamical_decoupling': {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'}, 'twirling': {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'}, 'resilience': {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False}, 'version': 2})
  > Expectation value: 28.628978416256825
  > Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}

Comece a usar o Sampler

1. Inicialize a conta

Como o Qiskit Runtime Sampler é um serviço gerenciado, primeiro você precisa inicializar sua conta. Em seguida, você pode selecionar a QPU que deseja usar para calcular o valor de expectativa.

Siga as etapas no tópico Instalar e configurar se você ainda não tiver uma conta configurada.

from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.least_busy(
    operational=True, simulator=False, min_num_qubits=127
)

2. Crie um circuito

Você precisa de pelo menos um circuito como entrada para o primitivo Sampler.

import numpy as np
from qiskit.circuit.library import efficient_su2

circuit = efficient_su2(127, entanglement="linear")
circuit.measure_all()
# The circuit is parametrized, so we will define the parameter values for execution
param_values = np.random.rand(circuit.num_parameters)

Use o transpilador para obter um circuito ISA.

from qiskit.transpiler import generate_preset_pass_manager

pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
isa_circuit = pm.run(circuit)
print(f">>> Circuit ops (ISA): {isa_circuit.count_ops()}")

Output:

>>> Circuit ops (ISA): OrderedDict([('sx', 3088), ('rz', 3036), ('cz', 1089), ('measure', 127), ('barrier', 1)])

3. Inicialize o Sampler do Qiskit Runtime

Ao inicializar o Sampler, use o mode parâmetro para especificar o modo em que deseja que ele seja executado. Os valores possíveis são batch, session, ou backend objetos para os modos de execução em lote, sessão e tarefa, respectivamente. Para obter mais informações, consulte Introdução aos modos de execução do Qiskit Runtime. Observe que os usuários do Open Plan não podem enviar trabalhos de sessão.

from qiskit_ibm_runtime import SamplerV2 as Sampler

sampler = Sampler(mode=backend)

4. Invoque o Sampler e obtenha resultados

Em seguida, invoque o método run() para gerar a saída. O circuito e os conjuntos de valores de parâmetros opcionais são inseridos como tuplas primitivas de bloco unificado ( PUB ).

job = sampler.run([(isa_circuit, param_values)])
print(f">>> Job ID: {job.job_id()}")
print(f">>> Job Status: {job.status()}")

Output:

>>> Job ID: d76cmme8faus73f14fi0
>>> Job Status: QUEUED
result = job.result()

# Get results for the first (and only) PUB
pub_result = result[0]
print(
    f"First ten results for the 'meas' output register: {pub_result.data.meas.get_bitstrings()[:10]}"
)

Output:

First ten results for the 'meas' output register: ['1001101111100100101100100000100000001000110000010000011010111000000101100000110111010010100001010101011100110100100101000000011', '0000010001011111011000010001101100110010110001111010110001001000000100110111011111010011000001011100110111111010001010000000000', '0000100111000111110111110010000000101010100011110111110111000110101000100000100001000111000001110000000101000011111100100000000', '0100111111100001011101101101010010101100010001101110101010010100000011101100010100100011001000010011010101011010000000100010011', '1111000001001101001011010010000100010010010101010111001000100000100000010110111011010101000101011110001100101100011110000111110', '1100000111101011001001110010001000001000111111010101000011001000010101100001011000000100000000011010101001111110100110100010100', '1000111001100001100000111100101111100011100110101000100110001111010010111110011010010010010101010011100101001101111101000100000', '0111101010100001110000100010010100101010100010010101011010011001101100011001010000000100111010010001100011001010000000101001111', '0100001110000101111111101111010111000000000101011010100111001101001001001000101001100010101010000001001001000000100000101010101', '1101010100001000000100000110110101000000000000000100100001100100000000100000011101001100110110011100000001100111110010001011100']

Comece com os primitivos de back-end

Diferentemente das primitivas específicas do provedor, as primitivas de backend são implementações genéricas que podem ser usadas com um objeto arbitrário backend arbitrário, desde que ele implemente a Backend interface.

Alguns provedores implementam primitivas nativamente. Consulte a página do ecossistema Qiskit para obter detalhes.

Exemplo: BackendEstimator

from qiskit.primitives import BackendEstimatorV2
from <some_qiskit_provider> import QiskitProvider

provider = QiskitProvider()
backend = provider.get_backend('backend_name')
estimator = BackendEstimatorV2(backend)

Exemplo: BackendSampler

from qiskit.primitives import BackendSamplerV2
from <some_qiskit_provider> import QiskitProvider

provider = QiskitProvider()
backend = provider.get_backend('backend_name')
sampler = BackendSamplerV2(backend)

Semelhanças e diferenças entre primitivas de backend e Runtime


Próximas etapas

Recomendações
Esta página foi útil?
Informe um bug, erro de digitação ou solicite conteúdo em GitHub .