Sari la conținutul principal

Rulează joburi în batch

Versiuni de pachete

Codul de pe această pagină a fost dezvoltat folosind următoarele cerințe. Recomandăm să folosești aceste versiuni sau unele mai noi.

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

Folosește modul batch pentru a trimite mai multe joburi primitive simultan. Mai jos găsești exemple de lucru cu batch-uri.

Configurare pentru utilizarea batch-urilor

Înainte de a porni un batch, trebuie să configurezi Qiskit Runtime și să îl inițializezi ca serviciu:

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime import (
QiskitRuntimeService,
Batch,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
)

service = QiskitRuntimeService()

Deschide un batch

Poți deschide un batch de runtime folosind context manager-ul with Batch(...) sau prin inițializarea clasei Batch. Când pornești un batch, trebuie să specifici un QPU pasând un obiect backend. Batch-ul pornește când primul său job începe execuția.

Clasa Batch

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

Context manager

Context manager-ul deschide și închide automat batch-ul.

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

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

Durata batch-ului

Poți defini durata maximă de viață (TTL) a batch-ului cu parametrul max_time. Aceasta ar trebui să depășească timpul de execuție al celui mai lung job. Cronometrul pornește când pornește batch-ul. Când valoarea este atinsă, batch-ul este închis. Joburile care rulează vor termina, dar joburile încă în coadă vor eșua.

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

Există, de asemenea, o valoare TTL interactivă care nu poate fi configurată (1 minut pentru toate planurile). Dacă niciun job din batch nu este pus în coadă în acel interval, batch-ul este dezactivat temporar.

Valorile implicite pentru TTL maxim:

Tip instanțăTTL maxim implicit
Toate planurile plătite8 ore
Open10 minute

Pentru a determina TTL-ul maxim sau TTL-ul interactiv al unui batch, urmează instrucțiunile din Determină detaliile batch-ului și caută valoarea max_time sau interactive_timeout.

Închide un batch

Un batch se închide automat când iese din context manager. Când context manager-ul batch-ului este ieșit, batch-ul este pus în statusul „În progres, nu acceptă joburi noi". Aceasta înseamnă că batch-ul termină procesarea tuturor joburilor care rulează sau sunt în coadă până când se atinge valoarea TTL maximă. După ce toate joburile sunt finalizate, batch-ul este închis imediat. Nu poți trimite joburi unui batch închis.

from qiskit.quantum_info import SparsePauliOp
from qiskit.circuit import QuantumCircuit, Parameter
from qiskit.transpiler import generate_preset_pass_manager
import numpy as np

# This cell is hidden from users
service = QiskitRuntimeService()
backend = service.least_busy()

# Define two circuits, each with one parameter with two parameters.
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.ry(Parameter("a"), 0)
circuit.cx(0, 1)
circuit.h(0)
circuit.measure_all()

pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
transpiled_circuit = pm.run(circuit)
transpiled_circuit_sampler = transpiled_circuit
transpiled_circuit_sampler.measure_all()

params = np.random.uniform(size=(2, 3)).T
observables = [
[
SparsePauliOp(["XX", "IY"], [0.5, 0.5]).apply_layout(
transpiled_circuit.layout
)
],
[SparsePauliOp("XX").apply_layout(transpiled_circuit.layout)],
[SparsePauliOp("IY").apply_layout(transpiled_circuit.layout)],
]

sampler_pub = (transpiled_circuit_sampler, params)
estimator_pub = (transpiled_circuit_sampler, observables, params)
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()
sfat

Dacă nu folosești un context manager, închide manual batch-ul. Dacă lași batch-ul deschis și trimiți mai multe joburi mai târziu, este posibil ca TTL-ul maxim să fie atins înainte ca joburile ulterioare să înceapă să ruleze, provocând anularea acestora. Poți închide un batch imediat ce ai terminat de trimis joburi. Când un batch este închis cu batch.close(), acesta nu mai acceptă joburi noi, dar joburile deja trimise vor rula în continuare până la finalizare, iar rezultatele lor pot fi recuperate.

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()
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-01-15 07:47:58', stop='2026-01-15 07:48:05', size=24576>)])}, 'version': 2})

Determină detaliile batch-ului

Pentru o prezentare completă a configurației și statusului unui batch, inclusiv TTL-ul interactiv și maxim, folosește metoda batch.details().

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())
{'id': 'ce8cf08d-b18e-4d56-ab51-eaff0b8190f4', '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}

Reconfigurează joburile pentru procesare paralelă

Există mai multe moduri de a-ți reconfigura joburile pentru a profita de procesarea paralelă oferită de batch-uri. Exemplul următor arată cum poți împărți o listă lungă de Circuit-uri în mai multe joburi și să le rulezi ca batch pentru a profita de procesarea paralelă.

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)
atenție

Dacă setezi backend=backend într-o primitivă, programul este rulat în modul job, chiar dacă se află în interiorul unui context batch sau Session. Setarea backend=backend este deprecată începând cu Qiskit Runtime v0.24.0. În schimb, folosește parametrul mode.

Pași următori

Recomandări