Inicio rápido con Executor
Versiones de paquetes
El código de esta página fue desarrollado con los siguientes requisitos. Recomendamos usar estas versiones o más recientes.
qiskit[all]~=2.6.1
qiskit-ibm-runtime~=0.50.0
samplomatic~=0.21.0
De manera similar al primitivo Sampler, Executor muestrea registros de salida de ejecuciones de circuitos cuánticos, pero no tiene supresión ni mitigación de errores integradas. En su lugar, forma parte del modelo de ejecución dirigida que proporciona los ingredientes para capturar las intenciones de diseño en el lado del cliente y desplaza la costosa generación de variantes de circuitos al lado del servidor. Executor sigue las directivas proporcionadas en las anotaciones y opciones del circuito, genera y vincula valores de parámetros, ejecuta los circuitos vinculados en el hardware y devuelve los resultados de ejecución y los metadatos. No toma ninguna decisión implícita por ti y te da control total y transparencia.
El paquete Qiskit aún no tiene una clase base para la primitiva Executor.
Antes de comenzar
Algunos de los ejemplos de código en esta página usan samplex, que forma parte del paquete Samplomatic. Por lo tanto, antes de ejecutar esos bloques de código, debes instalar Samplomatic, como se muestra en el siguiente bloque de código. Para más información, consulta la documentación de Samplomatic.
pip install samplomatic
# For visualization support, include the visualization dependencies.
# pip install samplomatic[vis]
Pasos para usar la primitiva Executor
1. Inicializar la cuenta
Dado que IBM Quantum Compute Service es un servicio gestionado, primero debes inicializar tu cuenta. Luego puedes seleccionar la QPU que quieres usar para calcular el valor esperado.
Sigue los pasos en Configurar tu cuenta de IBM Cloud® si aún no tienes una cuenta.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"qiskit": "qiskit", "qiskit_ibm_runtime": "qiskit-ibm-runtime", "samplomatic": "samplomatic"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
from qiskit_ibm_runtime import QiskitRuntimeService, Executor
from qiskit_ibm_runtime.quantum_program import QuantumProgram
from qiskit.circuit import QuantumCircuit
from qiskit.transpiler import generate_preset_pass_manager
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic import build
# Initialize the service and choose a backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
print(backend)
<IBMBackend('ibm_marrakesh')>
2. Crear y transpilar un circuit
Necesitas al menos un circuit para usar la primitiva Executor. Opcionalmente puede tener parámetros.
# Generate the circuit
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.h(1)
circuit.cz(0, 1)
circuit.h(1)
# Using `measure_all` automatically creates the necessary
# classical registers.
circuit.measure_all()
El circuit debe transformarse para usar solo instrucciones admitidas por la QPU (denominadas circuits de arquitectura de conjunto de instrucciones (ISA)). Usa el transpilador para hacer esto.
# Transpile the circuit
preset_pass_manager = generate_preset_pass_manager(
backend=backend, optimization_level=0
)
isa_circuit = preset_pass_manager.run(circuit)
3. Inicializar un QuantumProgram
Inicializa un QuantumProgram con tu carga de trabajo. Un QuantumProgram está compuesto de QuantumProgramItems. Por lo general, cada elemento consta de un circuito, un conjunto de valores de parámetros y posiblemente un samplex para aleatorizar el contenido del circuito. Para más detalles, consulta Entradas y salidas de Executor.
La siguiente celda inicializa un QuantumProgram y especifica realizar 25 shots. Luego, agrega el circuit transpilado objetivo.
# Initialize an empty program
program = QuantumProgram(shots=25)
# Append the circuit to the program
program.append_circuit_item(isa_circuit)
4. Opcional: Agrupar gates y mediciones en cajas anotadas
Agrupar instrucciones en cajas y anotarlas es la forma principal de especificar tu intención. En el siguiente ejemplo, usamos generate_boxing_pass_manager y sus parámetros de twirling para agrupar gates de dos qubits y mediciones en cajas y aplicar anotación de twirling.
# Generate a boxing pass manager to group gates
# and measurements into boxes and add
# a`Twirl` annotation.
boxes_pm = generate_boxing_pass_manager(
# Add gate twirling
enable_gates=True,
# Add measurement twirling
enable_measures=True,
)
boxed_circuit = boxes_pm.run(isa_circuit)
boxed_circuit.draw("mpl", idle_wires=False)
5. Opcional: Construir un circuit plantilla y un samplex, y agregarlos al programa
A continuación, usa el método build de Samplomatic para generar el par de circuito plantilla y samplex. El circuito plantilla es estructuralmente equivalente al circuito original. Sin embargo, sus puertas de un solo qubit se reemplazan por puertas parametrizadas para implementar las anotaciones prescritas (twirling de puertas y de mediciones, en este ejemplo). El samplex codifica toda la información necesaria para generar parámetros aleatorios para el circuito plantilla.
Después de generar el par de circuit plantilla y samplex, usa el método append_samplex_item para agregar el par al programa.
Consulta la documentación de la API de Samplomatic para obtener detalles completos sobre samplomatic.samplex.Samplex y sus argumentos.
# Build the template circuit and the samplex
template_circuit, samplex = build(boxed_circuit)
# Append the template circuit and samplex as a `samplex_item`
program.append_samplex_item(
template_circuit,
samplex=samplex,
shape=(num_randomizations := 20,),
)
6. Invocar Executor y obtener resultados
Ejecuta el QuantumProgram en un backend de IBM® usando la primitiva Executor con opciones predeterminadas. Consulta Opciones de Executor para aprender sobre las opciones disponibles.
# Initialize an Executor with the default options
executor = Executor(mode=backend)
# Submit the job
job = executor.run(program)
job
<RuntimeJobV2('dbjeahhkdqps7390ervg', 'executor')>
# Retrieve the result
result = job.result()
El resultado es de tipo QuantumProgramResult. Consulta Entrada y salida de Executor para aprender sobre el objeto de resultado.
Próximos pasos
- Prueba algunos ejemplos de Executor.
- Comprende la entrada y salida de Executor.
- Aprende sobre la semántica de difusión de Executor.