Sari la conținutul principal

Rulează joburi într-o sesiune

Versiuni de pachete

Codul de pe această pagină a fost dezvoltat folosind cerințele de mai jos. Recomandăm utilizarea acestor versiuni sau a unora mai noi.

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

Utilizatorii planului Open nu pot trimite joburi de sesiune. Sarcinile de lucru trebuie rulate în modul job sau modul batch.

Folosește sesiunile atunci când ai nevoie de acces dedicat și exclusiv la QPU.

Configurare pentru utilizarea sesiunilor

Înainte de a porni o sesiune, 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 scipy
from qiskit_ibm_runtime import (
QiskitRuntimeService,
Session,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
)

service = QiskitRuntimeService()

Deschide o sesiune

Poți deschide o sesiune runtime folosind managerul de context with Session(...) sau inițializând clasa Session. Când pornești o sesiune, trebuie să specifici un QPU transmițând un obiect backend. Sesiunea începe când primul ei job intră în execuție.

notă

Dacă deschizi o sesiune, dar nu trimiți niciun job în ea timp de 30 de minute, sesiunea se închide automat.

Clasa Session

atenție

Blocul de cod următor va returna o eroare pentru utilizatorii planului Open, deoarece folosește sesiuni. Sarcinile de lucru pe planul Open pot rula numai în modul job sau modul batch.

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

Manager de context

Managerul de context deschide și închide sesiunea automat.

atenție

Blocul de cod următor va returna o eroare pentru utilizatorii planului Open, deoarece folosește sesiuni. Sarcinile de lucru pe planul Open pot rula numai în modul job sau modul batch.

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

Durata sesiunii

Durata maximă de viață a sesiunii (TTL) determină cât timp poate rula o sesiune. Poți seta această valoare cu parametrul max_time. Aceasta ar trebui să depășească timpul de execuție al celui mai lung job.

Acest cronometru pornește când începe sesiunea. Când valoarea este atinsă, sesiunea se închide. Joburile aflate în execuție vor termina, dar joburile încă în așteptare sunt eșuate.

atenție

Blocul de cod următor va returna o eroare pentru utilizatorii planului Open, deoarece folosește sesiuni. Sarcinile de lucru pe planul Open pot rula numai în modul job sau modul batch.

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

Există, de asemenea, o valoare a timpului interactiv de viață (interactive TTL) care nu poate fi configurată. Dacă niciun job din sesiune nu este pus în așteptare în acea fereastră de timp, sesiunea este dezactivată temporar.

Valori implicite:

Tip de instanță (planul Open sau Premium)TTL interactivTTL maxim
Planul Premium60 sec*8 h*
* Anumite instanțe ale planului Premium pot fi configurate să aibă o valoare diferită.

Pentru a determina TTL-ul maxim sau TTL-ul interactiv al unei sesiuni, urmează instrucțiunile din Determină detaliile sesiunii și caută valorile max_time sau interactive_timeout, respectiv.

Încheie o sesiune

O sesiune se încheie în următoarele circumstanțe:

  • Valoarea maximă de timeout (TTL) este atinsă, ceea ce duce la anularea tuturor joburilor din așteptare.
  • Sesiunea este anulată manual, ceea ce duce la anularea tuturor joburilor din așteptare.
  • Sesiunea este închisă manual. Sesiunea nu mai acceptă joburi noi, dar continuă să ruleze joburile din așteptare cu prioritate.
  • Dacă folosești Session ca manager de context, adică with Session(), sesiunea este închisă automat când contextul se încheie (același comportament ca folosirea session.close()).

Închide o sesiune

O sesiune se închide automat când iese din managerul de context. Când managerul de context al sesiunii este ieșit, sesiunea este pusă în starea „În progres, nu acceptă joburi noi". Aceasta înseamnă că sesiunea termină de procesat toate joburile care rulează sau sunt în așteptare până când valoarea maximă de timeout este atinsă. După ce toate joburile sunt finalizate, sesiunea este închisă imediat. Acest lucru permite planificatorului să ruleze jobul următor fără a aștepta timeout-ul interactiv al sesiunii, reducând astfel timpul mediu de așteptare al joburilor. Nu poți trimite joburi la o sesiune închisă.

atenție

Blocul de cod următor va returna o eroare pentru utilizatorii planului Open, deoarece folosește sesiuni. Sarcinile de lucru pe planul Open pot rula numai în modul job sau modul batch.

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

Dacă nu folosești un manager de context, închide manual sesiunea pentru a evita costuri nedorite. Poți închide o sesiune imediat ce ai terminat de trimis joburi în ea. Când o sesiune este închisă cu session.close(), nu mai acceptă joburi noi, dar joburile deja trimise vor rula în continuare până la finalizare și rezultatele lor pot fi recuperate.

atenție

Blocul de cod următor va returna o eroare pentru utilizatorii planului Open, deoarece folosește sesiuni. Sarcinile de lucru pe planul Open pot rula numai în modul job sau modul batch.

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

Verifică starea Session-ului

Poți interoga starea unui Session pentru a-i înțelege starea curentă folosind session.status() sau vizualizând pagina Workloads.

Starea Session-ului poate fi una dintre următoarele:

  • Pending: Session-ul nu a început sau a fost dezactivat. Următorul job din Session trebuie să aștepte în coadă ca orice alt job.
  • In progress, accepting new jobs: Session-ul este activ și acceptă joburi noi.
  • In progress, not accepting new jobs: Session-ul este activ, dar nu mai acceptă joburi noi. Trimiterea de joburi către Session este respinsă, însă joburile deja existente în Session vor rula până la finalizare. Session-ul se închide automat după ce toate joburile sunt terminate.
  • Closed: Valoarea maximă de timeout a Session-ului a fost atinsă sau Session-ul a fost închis în mod explicit.

Determină detaliile Session-ului

Pentru o prezentare completă a configurației și stării unui Session, folosește metoda session.details().

atenție

Blocul de cod următor va returna o eroare pentru utilizatorii cu planul Open, deoarece folosește sesiuni. Sarcinile de lucru pe planul Open pot rula doar în modul job sau modul batch.

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}

Tipare de utilizare

Session-urile sunt deosebit de utile pentru algoritmii care necesită comunicare frecventă între resursele clasice și cele cuantice.

Exemplu: Rulează o sarcină de lucru iterativă care folosește optimizatorul clasic SciPy pentru a minimiza o funcție de cost. În acest model, SciPy folosește rezultatul funcției de cost pentru a calcula următoarea sa intrare.

atenție

Blocul de cod următor va returna o eroare pentru utilizatorii cu planul Open, deoarece folosește sesiuni. Sarcinile de lucru pe planul Open pot rula doar în modul job sau modul batch.

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

Rulează doi algoritmi VQE într-un Session folosind threading

Poți obține mai mult dintr-un Session rulând mai multe sarcini de lucru simultan. Exemplul următor arată cum poți rula doi algoritmi VQE, fiecare folosind un optimizator clasic diferit, simultan în cadrul unui singur Session. Tag-urile de job sunt folosite și pentru a diferenția joburile din fiecare sarcină de lucru.

atenție

Blocul de cod următor va returna o eroare pentru utilizatorii cu planul Open, deoarece folosește sesiuni. Sarcinile de lucru pe planul Open pot rula doar în modul job sau modul batch.

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

Pași următori

Recomandări