Comece com primitivas
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.
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.
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.
- A primitiva Sampler pode ser executada com qualquer provedor usando
qiskit.primitives.BackendSamplerV2. - A primitiva do Estimator pode ser executada com qualquer provedor usando
qiskit.primitives.BackendEstimatorV2.
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
-
As entradas e saídas de
qiskit.primitives.BackendSamplerV2eqiskit.primitives.BackendEstimatorV2seguem o mesmo formato de PUB que as primitivas em Qiskit Runtime. Consulte Entradas e saídas primitivas para obter detalhes. No entanto, pode haver diferenças nos campos dos metadados retornados. -
A classe
qiskit.primitives.BackendEstimatorV2a classe não oferece implementações de medição ou mitigação de erro de porta prontas para uso, pois as primitivas de backend são projetadas para serem executadas localmente na máquina do usuário. -
A classe
qiskit.primitives.BackendSamplerV2requer um backend compatível com a opçãomemory. -
As interfaces primitivas de backend expõem
SamplerV2eEstimatorV2Optionsque são diferentes das implementações de tempo de execução.
Próximas etapas
- Saiba como testar localmente antes de executar em computadores quânticos.
- Revise exemplos detalhados de primitivas.
- Pratique com primitivos trabalhando na lição sobre função de custo em IBM Quantum Learning.
- Saiba como transpilar localmente na seção Transpilar.
- Experimente o guia Comparar configurações do transpiler.
- Aprenda a usar as opções primitivas.
- Veja a API para as opções Sampler e Estimator.
- Leia Migrar para V2 primitives.