Zum Hauptinhalt springen

Jobs in einer Session ausführen

Paketversionen

Der Code auf dieser Seite wurde mit den folgenden Anforderungen entwickelt. Wir empfehlen, diese oder neuere Versionen zu verwenden.

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
scipy~=1.16.3
Hinweis

Nutzer des Open Plans können keine Session-Jobs einreichen. Workloads müssen im Job-Modus oder im Batch-Modus ausgeführt werden.

Verwende Sessions, wenn du dedizierten und exklusiven Zugriff auf den QPU benötigst.

Einrichtung zur Verwendung von Sessions

Bevor du eine Session startest, musst du Qiskit Runtime einrichten und es als Service initialisieren:

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

service = QiskitRuntimeService()

Eine Session öffnen

Du kannst eine Runtime-Session öffnen, indem du den Context-Manager with Session(...) verwendest oder die Session-Klasse initialisierst. Wenn du eine Session startest, musst du einen QPU angeben, indem du ein backend-Objekt übergibst. Die Session startet, sobald ihr erster Job mit der Ausführung beginnt.

hinweis

Wenn du eine Session öffnest, aber 30 Minuten lang keine Jobs darin einreichst, wird die Session automatisch geschlossen.

Session-Klasse

vorsicht

Der folgende Codeblock gibt einen Fehler für Nutzer des Open Plans zurück, da er Sessions verwendet. Workloads im Open Plan können nur im Job-Modus oder im Batch-Modus ausgeführt werden.

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

Context-Manager

Der Context-Manager öffnet und schließt die Session automatisch.

vorsicht

Der folgende Codeblock gibt einen Fehler für Nutzer des Open Plans zurück, da er Sessions verwendet. Workloads im Open Plan können nur im Job-Modus oder im Batch-Modus ausgeführt werden.

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

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

Session-Länge

Die maximale Session-Lebensdauer (TTL) legt fest, wie lange eine Session laufen kann. Du kannst diesen Wert mit dem Parameter max_time festlegen. Dieser sollte die Ausführungszeit des längsten Jobs überschreiten.

Dieser Timer startet, wenn die Session beginnt. Sobald der Wert erreicht ist, wird die Session geschlossen. Alle laufenden Jobs werden abgeschlossen, aber noch in der Warteschlange befindliche Jobs schlagen fehl.

vorsicht

Der folgende Codeblock gibt einen Fehler für Nutzer des Open Plans zurück, da er Sessions verwendet. Workloads im Open Plan können nur im Job-Modus oder im Batch-Modus ausgeführt werden.

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

Es gibt auch einen interaktiven Lebensdauerwert (Interactive TTL), der nicht konfiguriert werden kann. Werden innerhalb dieses Zeitfensters keine Session-Jobs in die Warteschlange eingereiht, wird die Session vorübergehend deaktiviert.

Standardwerte:

Instanztyp (Open oder Premium Plan)Interaktive TTLMaximale TTL
Premium Plan60 Sek.*8 Std.*
* Bestimmte Premium-Plan-Instanzen können mit einem abweichenden Wert konfiguriert sein.

Um die maximale TTL oder die interaktive TTL einer Session zu ermitteln, folge den Anweisungen unter Session-Details ermitteln und suche nach dem Wert max_time bzw. interactive_timeout.

Eine Session beenden

Eine Session endet unter folgenden Umständen:

  • Der maximale Timeout-Wert (TTL) wird erreicht, was zur Stornierung aller Jobs in der Warteschlange führt.
  • Die Session wird manuell abgebrochen, was zur Stornierung aller Jobs in der Warteschlange führt.
  • Die Session wird manuell geschlossen. Die Session akzeptiert keine neuen Jobs mehr, führt aber Jobs in der Warteschlange mit Priorität weiter aus.
  • Wenn du Session als Context-Manager verwendest, also with Session(), wird die Session automatisch geschlossen, wenn der Kontext endet (gleiches Verhalten wie session.close()).

Eine Session schließen

Eine Session wird automatisch geschlossen, wenn sie den Context-Manager verlässt. Wenn der Session-Context-Manager beendet wird, erhält die Session den Status „In Bearbeitung, akzeptiert keine neuen Jobs". Das bedeutet, dass die Session alle laufenden oder in der Warteschlange befindlichen Jobs fertigstellt, bis der maximale Timeout-Wert erreicht ist. Nachdem alle Jobs abgeschlossen sind, wird die Session sofort geschlossen. Dies ermöglicht dem Scheduler, den nächsten Job auszuführen, ohne auf den interaktiven Session-Timeout zu warten, wodurch die durchschnittliche Job-Wartezeit reduziert wird. Du kannst keine Jobs an eine geschlossene Session übermitteln.

vorsicht

Der folgende Codeblock gibt einen Fehler für Nutzer des Open Plans zurück, da er Sessions verwendet. Workloads im Open Plan können nur im Job-Modus oder im Batch-Modus ausgeführt werden.

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()

# Create parameters and mapped observables to submit
params = np.random.uniform(size=(2, 3)).T
observables = [
SparsePauliOp(["XX", "IY"], [0.5, 0.5]),
SparsePauliOp("XX"),
SparsePauliOp("IY"),
]
mapped_observables = [
[observable.apply_layout(transpiled_circuit.layout)]
for observable in observables
]

sampler_pub = (transpiled_circuit_sampler, params)
estimator_pub = (transpiled_circuit_sampler, mapped_observables, params)
with Session(backend=backend) as session:
estimator = Estimator()
sampler = Sampler()
job1 = estimator.run([estimator_pub])
job2 = sampler.run([sampler_pub])

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

Wenn du keinen Context-Manager verwendest, schließe die Session manuell, um unerwünschte Kosten zu vermeiden. Du kannst eine Session schließen, sobald du alle Jobs darin eingereicht hast. Wenn eine Session mit session.close() geschlossen wird, akzeptiert sie keine neuen Jobs mehr, aber bereits eingereichte Jobs werden noch bis zum Abschluss ausgeführt und ihre Ergebnisse können abgerufen werden.

vorsicht

Der folgende Codeblock gibt einen Fehler für Nutzer des Open Plans zurück, da er Sessions verwendet. Workloads im Open Plan können nur im Job-Modus oder im Batch-Modus ausgeführt werden.

session = Session(backend=backend)

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

# Manually close the session. Running and queued jobs will run to completion.
session.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:53:15', stop='2026-01-15 07:53:21', size=24576>)])}, 'version': 2})

Session-Status prüfen

Du kannst den Status einer Session abfragen, um ihren aktuellen Zustand zu verstehen, indem du session.status() verwendest oder die Seite Workloads aufrufst.

Der Session-Status kann einer der folgenden sein:

  • Pending: Die Session hat noch nicht begonnen oder wurde deaktiviert. Der nächste Session-Job muss wie andere Jobs in der Warteschlange warten.
  • In progress, accepting new jobs: Die Session ist aktiv und akzeptiert neue Jobs.
  • In progress, not accepting new jobs: Die Session ist aktiv, akzeptiert aber keine neuen Jobs. Das Einreichen von Jobs in die Session wird abgelehnt, aber ausstehende Session-Jobs werden bis zum Abschluss ausgeführt. Die Session wird automatisch geschlossen, sobald alle Jobs abgeschlossen sind.
  • Closed: Der maximale Timeout-Wert der Session wurde erreicht oder die Session wurde explizit geschlossen.

Session-Details ermitteln

Für einen umfassenden Überblick über die Konfiguration und den Status einer Session verwendest du die Methode session.details().

vorsicht

Der folgende Codeblock gibt einen Fehler für Nutzer des Open Plans zurück, da er Sessions verwendet. Workloads im Open Plan können nur im Job-Modus oder im Batch-Modus ausgeführt werden.

from qiskit_ibm_runtime import (
QiskitRuntimeService,
Session,
EstimatorV2 as Estimator,
)

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

with Session(backend=backend) as session:
print(session.details())
{'id': 'be84569d-86b5-4a7f-be5e-7d33e80dc220', 'backend_name': 'ibm_torino', 'interactive_timeout': 60, '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': 'dedicated', 'usage_time': None}

Verwendungsmuster

Sessions sind besonders nützlich für Algorithmen, die häufige Kommunikation zwischen klassischen und Quantenressourcen erfordern.

Beispiel: Führe eine iterative Workload aus, die den klassischen SciPy-Optimizer verwendet, um eine Kostenfunktion zu minimieren. In diesem Modell verwendet SciPy die Ausgabe der Kostenfunktion, um seine nächste Eingabe zu berechnen.

vorsicht

Der folgende Codeblock gibt einen Fehler für Nutzer des Open Plans zurück, da er Sessions verwendet. Workloads im Open Plan können nur im Job-Modus oder im Batch-Modus ausgeführt werden.

from scipy.optimize import minimize
from qiskit.circuit.library import efficient_su2

def cost_func(params, ansatz, hamiltonian, estimator):
# Return estimate of energy from estimator

energy = sum(
estimator.run([(ansatz, hamiltonian, params)]).result()[0].data.evs
)
return energy

hamiltonian = SparsePauliOp.from_list(
[("YZ", 0.3980), ("ZI", -0.3980), ("ZZ", -0.0113), ("XX", 0.1810)]
)
su2_ansatz = efficient_su2(hamiltonian.num_qubits)
pm = generate_preset_pass_manager(backend=backend, optimization_level=3)
ansatz = pm.run(su2_ansatz)
mapped_hamiltonian = [
operator.apply_layout(ansatz.layout) for operator in hamiltonian
]

num_params = ansatz.num_parameters
x0 = 2 * np.pi * np.random.random(num_params)

session = Session(backend=backend)

# If using qiskit-ibm-runtime earlier than 0.24.0, change `mode=` to `session=`
estimator = Estimator(mode=session, options={"default_shots": int(1e4)})
res = minimize(
cost_func,
x0,
args=(ansatz, mapped_hamiltonian, estimator),
method="cobyla",
options={"maxiter": 25},
)

# Close the session because no context manager was used.
session.close()

Zwei VQE-Algorithmen in einer Session mit Threading ausführen

Du kannst eine Session besser ausnutzen, indem du mehrere Workloads gleichzeitig ausführst. Das folgende Beispiel zeigt, wie du zwei VQE-Algorithmen, jeweils mit einem anderen klassischen Optimizer, gleichzeitig innerhalb einer einzigen Session ausführen kannst. Job-Tags werden ebenfalls verwendet, um Jobs aus verschiedenen Workloads zu unterscheiden.

vorsicht

Der folgende Codeblock gibt einen Fehler für Nutzer des Open Plans zurück, da er Sessions verwendet. Workloads im Open Plan können nur im Job-Modus oder im Batch-Modus ausgeführt werden.

from concurrent.futures import ThreadPoolExecutor
from qiskit_ibm_runtime import EstimatorV2 as Estimator

def minimize_thread(estimator, method):
return minimize(
cost_func,
x0,
args=(ansatz, mapped_hamiltonian, estimator),
method=method,
options={"maxiter": 25},
)

with Session(backend=backend), ThreadPoolExecutor() as executor:
estimator1 = Estimator()
estimator2 = Estimator()

# Use different tags to differentiate the jobs.
estimator1.options.environment.job_tags = ["cobyla"]
estimator2.options.environment.job_tags = ["nelder-mead"]

# Submit the two workloads.
cobyla_future = executor.submit(minimize_thread, estimator1, "cobyla")
nelder_mead_future = executor.submit(
minimize_thread, estimator2, "nelder-mead"
)

# Get workload results.
cobyla_result = cobyla_future.result()
nelder_mead_result = nelder_mead_future.result()

Nächste Schritte

Empfehlungen