Przejdź do głównej treści

Uruchamianie zadań w sesji

Wersje pakietów

Kod na tej stronie został opracowany przy użyciu następujących wymagań. Zalecamy korzystanie z tych wersji lub nowszych.

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

Użytkownicy planu Open Plan nie mogą przesyłać zadań sesji. Zadania muszą być uruchamiane w trybie zadań lub trybie wsadowym.

Używaj sesji, gdy potrzebujesz dedykowanego i wyłącznego dostępu do QPU.

Konfiguracja do korzystania z sesji

Przed uruchomieniem sesji musisz skonfigurować Qiskit Runtime i zainicjować go jako usługę:

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

Otwieranie sesji

Sesję runtime możesz otworzyć przy użyciu menedżera kontekstu with Session(...) lub przez zainicjowanie klasy Session. Przy uruchamianiu sesji musisz podać QPU, przekazując obiekt backend. Sesja startuje, gdy zaczyna się wykonywanie jej pierwszego zadania.

uwaga

Jeśli otworzysz sesję, ale nie prześlesz do niej żadnych zadań przez 30 minut, sesja automatycznie się zamknie.

Klasa Session

ostrożnie

Poniższy blok kodu zwróci błąd dla użytkowników planu Open Plan, ponieważ korzysta z sesji. Zadania w planie Open Plan mogą być uruchamiane wyłącznie w trybie zadań lub trybie wsadowym.

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

Menedżer kontekstu

Menedżer kontekstu automatycznie otwiera i zamyka sesję.

ostrożnie

Poniższy blok kodu zwróci błąd dla użytkowników planu Open Plan, ponieważ korzysta z sesji. Zadania w planie Open Plan mogą być uruchamiane wyłącznie w trybie zadań lub trybie wsadowym.

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

Czas trwania sesji

Maksymalny czas życia sesji (TTL) określa, jak długo sesja może działać. Możesz ustawić tę wartość za pomocą parametru max_time. Powinna ona przekraczać czas wykonywania najdłuższego zadania.

Ten licznik czasu startuje w momencie uruchomienia sesji. Po osiągnięciu wartości sesja jest zamykana. Zadania w trakcie wykonywania zostaną dokończone, natomiast zadania wciąż oczekujące w kolejce zakończą się błędem.

ostrożnie

Poniższy blok kodu zwróci błąd dla użytkowników planu Open Plan, ponieważ korzysta z sesji. Zadania w planie Open Plan mogą być uruchamiane wyłącznie w trybie zadań lub trybie wsadowym.

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

Istnieje również wartość interaktywnego czasu życia (interactive TTL), której nie można konfigurować. Jeśli w tym oknie czasowym nie zostaną ustawione w kolejce żadne zadania sesji, sesja zostanie tymczasowo dezaktywowana.

Wartości domyślne:

Typ instancji (plan Open lub Premium)Interaktywny TTLMaksymalny TTL
Plan Premium60 s*8 h*
* Niektóre instancje planu Premium mogą mieć skonfigurowane inne wartości.

Aby określić maksymalny TTL sesji lub interaktywny TTL, postępuj zgodnie z instrukcjami w sekcji Sprawdzanie szczegółów sesji i wyszukaj odpowiednio wartość max_time lub interactive_timeout.

Kończenie sesji

Sesja kończy się w następujących okolicznościach:

  • Osiągnięta zostaje maksymalna wartość limitu czasu (TTL), co powoduje anulowanie wszystkich zadań oczekujących w kolejce.
  • Sesja jest ręcznie anulowana, co powoduje anulowanie wszystkich zadań oczekujących w kolejce.
  • Sesja jest ręcznie zamykana. Sesja przestaje przyjmować nowe zadania, ale kontynuuje wykonywanie zadań z kolejki z priorytetem.
  • Jeśli używasz Session jako menedżera kontekstu, tzn. with Session(), sesja jest automatycznie zamykana po zakończeniu kontekstu (takie samo zachowanie jak przy użyciu session.close()).

Zamykanie sesji

Sesja zamyka się automatycznie po opuszczeniu menedżera kontekstu. Gdy menedżer kontekstu sesji jest opuszczany, sesja przechodzi w stan „W trakcie, nie przyjmuje nowych zadań". Oznacza to, że sesja kończy przetwarzanie wszystkich uruchomionych lub oczekujących w kolejce zadań do momentu osiągnięcia maksymalnej wartości limitu czasu. Po ukończeniu wszystkich zadań sesja jest natychmiast zamykana. Dzięki temu harmonogram może uruchomić kolejne zadanie bez czekania na interaktywny limit czasu sesji, co skraca średni czas oczekiwania zadań w kolejce. Nie możesz przesyłać zadań do zamkniętej sesji.

ostrożnie

Poniższy blok kodu zwróci błąd dla użytkowników planu Open Plan, ponieważ korzysta z sesji. Zadania w planie Open Plan mogą być uruchamiane wyłącznie w trybie zadań lub trybie wsadowym.

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()
wskazówka

Jeśli nie używasz menedżera kontekstu, ręcznie zamknij sesję, aby uniknąć niepożądanych kosztów. Możesz zamknąć sesję zaraz po zakończeniu przesyłania do niej zadań. Gdy sesja zostanie zamknięta przy użyciu session.close(), nie przyjmuje już nowych zadań, ale przesłane wcześniej zadania nadal będą wykonywane do zakończenia i ich wyniki będzie można pobrać.

ostrożnie

Poniższy blok kodu zwróci błąd dla użytkowników planu Open Plan, ponieważ korzysta z sesji. Zadania w planie Open Plan mogą być uruchamiane wyłącznie w trybie zadań lub trybie wsadowym.

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

Sprawdzanie statusu sesji

Możesz zapytać o status sesji, aby poznać jej bieżący stan, używając session.status() lub przeglądając stronę Workloads.

Status sesji może przyjmować jedną z następujących wartości:

  • Pending: Sesja nie została uruchomiona lub została dezaktywowana. Następne zadanie sesji musi czekać w kolejce jak inne zadania.
  • In progress, accepting new jobs: Sesja jest aktywna i przyjmuje nowe zadania.
  • In progress, not accepting new jobs: Sesja jest aktywna, ale nie przyjmuje nowych zadań. Przesyłanie zadań do sesji jest odrzucane, ale oczekujące zadania sesji będą wykonane do końca. Sesja zostaje automatycznie zamknięta po zakończeniu wszystkich zadań.
  • Closed: Osiągnięto maksymalną wartość limitu czasu sesji lub sesja została jawnie zamknięta.

Sprawdzanie szczegółów sesji

Aby uzyskać pełny przegląd konfiguracji i statusu sesji, użyj metody session.details().

ostrożnie

Poniższy blok kodu zwróci błąd dla użytkowników planu Open Plan, ponieważ korzysta z sesji. Zadania w planie Open Plan mogą być uruchamiane wyłącznie w trybie zadań lub trybie wsadowym.

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}

Wzorce użycia

Sesje są szczególnie przydatne w algorytmach wymagających częstej komunikacji między zasobami klasycznymi i kwantowymi.

Przykład: uruchom iteracyjne obciążenie robocze, które używa klasycznego optymalizatora SciPy do minimalizacji funkcji kosztu. W tym modelu SciPy wykorzystuje wynik funkcji kosztu do obliczenia następnego wejścia.

ostrożnie

Poniższy blok kodu zwróci błąd dla użytkowników planu Open Plan, ponieważ korzysta z sesji. Zadania w planie Open Plan mogą być uruchamiane wyłącznie w trybie zadań lub trybie wsadowym.

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

Uruchamianie dwóch algorytmów VQE w sesji przy użyciu wątków

Możesz efektywniej wykorzystać sesję, uruchamiając jednocześnie wiele obciążeń roboczych. Poniższy przykład pokazuje, jak można uruchomić dwa algorytmy VQE, każdy z innym klasycznym optymalizatorem, jednocześnie w ramach jednej sesji. Znaczniki zadań są również używane do rozróżniania zadań z poszczególnych obciążeń roboczych.

ostrożnie

Poniższy blok kodu zwróci błąd dla użytkowników planu Open Plan, ponieważ korzysta z sesji. Zadania w planie Open Plan mogą być uruchamiane wyłącznie w trybie zadań lub trybie wsadowym.

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

Następne kroki

Zalecenia