Skip to main content
IBM Quantum Platform

Ejecutar trabajos por lotes

  • El código de esta página se ha desarrollado siguiendo los siguientes requisitos. Recomendamos utilizar estas versiones o posteriores.

    qiskit[all]~=2.3.0
    qiskit-ibm-runtime~=0.43.1
    

Utilice el modo por lotes para enviar varios trabajos primitivos simultáneamente. A continuación se ofrecen ejemplos de trabajo con lotes.


Configurar para usar lotes

Antes de iniciar un lote, debe configurar Qiskit Runtime e inicializarlo como servicio:

from qiskit_ibm_runtime import (
    QiskitRuntimeService,
    Batch,
    SamplerV2 as Sampler,
    EstimatorV2 as Estimator,
    Executor,
)


service = QiskitRuntimeService()

Abrir un lote

Puede abrir un lote en tiempo de ejecución utilizando el gestor de contexto with Batch(...) o inicializando la clase Batch clase Al iniciar un lote, debe especificar una QPU pasando un objeto backend . El lote se inicia cuando comienza la ejecución de su primer trabajo.

Clase de lote

backend = service.least_busy(operational=True, simulator=False)
batch = Batch(backend=backend)
estimator = Estimator(mode=batch)
sampler = Sampler(mode=batch)
executor = Executor(mode=batch)
# Close the batch because no context manager was used.
batch.close()

Gestor de contexto

El gestor contextual abre y cierra automáticamente el lote.

from qiskit_ibm_runtime import (
    Batch,
    SamplerV2 as Sampler,
    EstimatorV2 as Estimator,
    Executor,
)

backend = service.least_busy(operational=True, simulator=False)
with Batch(backend=backend):
    estimator = Estimator()
    sampler = Sampler()
    executor = Executor()

Longitud del lote

Puede definir el tiempo máximo de vida (TTL) del lote con el parámetro max_time . Esto debería superar el tiempo de ejecución del trabajo más largo. Este temporizador se inicia cuando comienza el lote. Cuando se alcanza el valor, se cierra el lote. Los trabajos que se estén ejecutando finalizarán, pero los trabajos que sigan en cola fallarán.

with Batch(backend=backend, max_time="25m"):
  ...

También hay un valor de tiempo de vida interactivo (TTL interactivo) que no se puede configurar (1 minuto para todos los planes). Si no hay trabajos por lotes en cola dentro de esa ventana, el lote se desactiva temporalmente.

Valores TTL máximos por defecto:

Tipo de instancia
TTL máximo predeterminado
Todos los planes de pago8 horas
Abrir10 minutos

Para determinar el TTL máximo o el TTL interactivo de un lote, siga las instrucciones de Determinar detalles del lote y busque el valor max_time o interactive_timeout , respectivamente.


Cerrar un lote

Un lote se cierra automáticamente cuando sale del gestor de contexto. Cuando se sale del gestor contextual de lotes, el lote pasa al estado "En curso, no acepta nuevos trabajos". Esto significa que el lote termina de procesar todos los trabajos en ejecución o en cola hasta que se alcanza el valor TTL máximo. Una vez finalizados todos los trabajos, el lote se cierra inmediatamente. No se pueden enviar trabajos a un lote cerrado.

Note

El siguiente código requiere que introduzcas tu propia información, como los PUB del estimador y del muestreador, así como un backend.

with Batch(backend=backend) as batch:
    estimator = Estimator()
    sampler = Sampler()
    job1 = estimator.run([estimator_pub])
    job2 = sampler.run([sampler_pub])

# The batch is no longer accepting jobs but the submitted job will run to completion.
result = job1.result()
result2 = job2.result()
Tip

Si no utiliza un gestor contextual, cierre manualmente el lote. Si deja el lote abierto y le envía más trabajos más tarde, es posible que se alcance el TTL máximo antes de que empiecen a ejecutarse los trabajos posteriores, lo que provocará que se cancelen. Puede cerrar un lote en cuanto haya terminado de enviarle trabajos. Cuando un lote se cierra con batch.close(), ya no acepta nuevos trabajos, pero los trabajos ya enviados seguirán ejecutándose hasta su finalización y se podrán recuperar sus resultados.

batch = Batch(backend=backend)

# If using qiskit-ibm-runtime earlier than 0.24.0, change `mode=` to `batch=`
estimator = Estimator(mode=batch)
sampler = Sampler(mode=batch)
job1 = estimator.run([estimator_pub])
job2 = sampler.run([sampler_pub])
print(f"Result1: {job1.result()}")
print(f"Result2: {job2.result()}")

# Manually close the batch. Running and queued jobs will run to completion.
batch.close()

Output:

Result1: PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(3, 2), dtype=float64>), stds=np.ndarray(<shape=(3, 2), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(3, 2), dtype=float64>), shape=(3, 2)), 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})
Result2: PrimitiveResult([SamplerPubResult(data=DataBin(meas=BitArray(<shape=(3, 2), num_shots=4096, num_bits=2>), meas0=BitArray(<shape=(3, 2), num_shots=4096, num_bits=133>), shape=(3, 2)), metadata={'circuit_metadata': {}})], metadata={'execution': {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-02-15 07:58:55', stop='2026-02-15 07:59:02', size=24576>)])}, 'version': 2})

Determinar los detalles del lote

Para obtener una visión general de la configuración y el estado de un lote, incluidos su TTL interactivo y máximo, utilice la página batch.details() method.

from qiskit_ibm_runtime import (
    QiskitRuntimeService,
    batch,
    SamplerV2 as Sampler,
)

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

with Batch(backend=backend) as batch:
    print(batch.details())

Output:

{'id': '970fe01d-d2cf-45f0-b32b-f886b987a462', 'backend_name': 'ibm_torino', 'interactive_timeout': 1, 'max_time': 28800, 'active_timeout': 28800, 'state': 'open', 'accepting_jobs': True, 'last_job_started': None, 'last_job_completed': None, 'started_at': None, 'closed_at': None, 'activated_at': None, 'mode': 'batch', 'usage_time': None}

Reconfigurar trabajos para el procesamiento paralelo

Existen múltiples formas de reconfigurar los trabajos para aprovechar el procesamiento paralelo que proporciona la dosificación. El siguiente ejemplo muestra cómo puede dividir una larga lista de circuitos en varios trabajos y ejecutarlos como un lote para aprovechar el procesamiento en paralelo.

from qiskit_ibm_runtime import SamplerV2 as Sampler, Batch
from qiskit.circuit.random import random_circuit

max_circuits = 100
circuits = [pm.run(random_circuit(5, 5)) for _ in range(5 * max_circuits)]
for circuit in circuits:
    circuit.measure_active()
all_partitioned_circuits = []
for i in range(0, len(circuits), max_circuits):
    all_partitioned_circuits.append(circuits[i : i + max_circuits])
jobs = []
start_idx = 0

with Batch(backend=backend):
    sampler = Sampler()
    for partitioned_circuits in all_partitioned_circuits:
        job = sampler.run(partitioned_circuits)
        jobs.append(job)
Caution

Si se establece backend=backend en una primitiva, el programa se ejecuta en modo trabajo, incluso si se encuentra dentro de un contexto por lotes o de sesión. La configuración backend=backend está obsoleta a partir de Qiskit Runtime v0.24.0. En su lugar, utilice el mode parámetro.


Próximos pasos

Recomendaciones
¿Le ha resultado útil esta página?
Informe de un error, de una errata o solicite contenido en GitHub.