Rulează joburi în batch
Package versions
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.5.2
qiskit-ibm-runtime~=0.47.0
Folosește batch mode 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 clientul IBM Quantum Compute și să îl inițializezi ca serviciu:
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "qiskit": "qiskit", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_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, Batch, Executor
# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Sampler, Estimator
# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_sampler import Sampler
from qiskit_ibm_runtime.executor_estimator import 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)
executor = Executor(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, Executor
# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Sampler, Estimator
# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_sampler import Sampler
from qiskit_ibm_runtime.executor_estimator import Estimator
backend = service.least_busy(operational=True, simulator=False)
with Batch(backend=backend):
estimator = Estimator()
sampler = Sampler()
executor = Executor()
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ătite | 8 ore |
| Open | 10 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, respectiv interactive_timeout.
Închide un batch
Un batch se închide automat când iese din context manager. La ieșirea din context manager-ul batch-ului, acesta trece în starea „În desfășurare, 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)
Pentru codul următor trebuie să furnizezi propriile informații, cum ar fi PUB-urile pentru Estimator și Sampler și 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()
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=156>), shape=(3, 2)), metadata={'circuit_metadata': {}})], metadata={'execution': {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-09-01 07:46:49', stop='2026-09-01 07:46:56', size=24576>)])}, 'version': 2})
Determină detaliile batch-ului
Pentru o prezentare completă a configurației și stării unui batch, inclusiv TTL-ul interactiv și maxim, folosește metoda batch.details() method.
from qiskit_ibm_runtime import QiskitRuntimeService, Batch
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
with Batch(backend=backend) as batch:
print(batch.details())
{'id': '947aa097-9055-42d4-9e58-ad1c2cdd9d5a', 'backend_name': 'ibm_marrakesh', '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.circuit.random import random_circuit
from qiskit_ibm_runtime import Batch
# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Sampler
# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_sampler import Sampler
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)
Dacă setezi backend=backend într-o primitivă, programul este rulat în job mode, 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
- Încearcă un exemplu în tutorialul Combină opțiunile de atenuare a erorilor cu primitiva Estimator.
- Consultă referința Batch API.
- Înțelege limitele joburilor când trimiți un job la un QPU IBM®.
- Consultă întrebările frecvente despre modurile de execuție.