Aller au contenu principal
Ce projet est en phase bêta. Tu as trouvé un bug ? Ouvrir un ticket GitHub. Une question ou une idée ? Pose ta question dans Discussions — tes retours sont les bienvenus !
Quelle est la qualité de la traduction sur cette page ?

Exécuter des jobs dans une session

Versions des packages

Le code de cette page a été développé avec les dépendances suivantes. Nous recommandons d'utiliser ces versions ou des versions plus récentes.

qiskit[all]~=2.5.2
qiskit-ibm-runtime~=0.47.0
scipy~=1.17.1
Remarque

Les utilisateurs du plan Open ne peuvent pas soumettre de jobs en session. Les charges de travail doivent être exécutées en job mode ou en batch mode.

Utilise les sessions lorsque tu as besoin d'un accès dédié et exclusif au QPU.

Configurer l'utilisation des sessions​

Avant de démarrer une session, tu dois configurer le client IBM Quantum Compute et l'initialiser en tant que service :

# 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", "scipy": "scipy"}
_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, Session, 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()

Ouvrir une session​

Tu peux ouvrir une session runtime en utilisant le gestionnaire de contexte with Session(...) ou en instanciant la classe Session. Lorsque tu démarres une session, tu dois spécifier un QPU en passant un objet backend. La session démarre quand son premier job commence à s'exécuter.

remarque

Si tu ouvres une session sans y soumettre de jobs pendant 30 minutes, la session se ferme automatiquement.

Classe Session

attention

Le bloc de code suivant retournera une erreur pour les utilisateurs du plan Open car il utilise des sessions. Les charges de travail du plan Open ne peuvent s'exécuter qu'en job mode ou en batch mode.

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

Gestionnaire de contexte

Le gestionnaire de contexte ouvre et ferme automatiquement la session.

attention

Le bloc de code suivant retournera une erreur pour les utilisateurs du plan Open car il utilise des sessions. Les charges de travail du plan Open ne peuvent s'exécuter qu'en job mode ou en batch mode.

from qiskit_ibm_runtime import Session, 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 Session(backend=backend):
estimator = Estimator()
sampler = Sampler()
executor = Executor()

Durée d'une session​

La durée de vie maximale d'une session (TTL) détermine combien de temps elle peut s'exécuter. Tu peux définir cette valeur avec le paramètre max_time. Elle doit dépasser le temps d'exécution du job le plus long.

Ce minuteur démarre au lancement de la session. Lorsque la valeur est atteinte, la session est fermée. Les jobs en cours d'exécution se terminent, mais les jobs encore en file d'attente échouent.

attention

Le bloc de code suivant retournera une erreur pour les utilisateurs du plan Open car il utilise des sessions. Les charges de travail du plan Open ne peuvent s'exécuter qu'en job mode ou en batch mode.

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

Il existe également une valeur de durée de vie interactive (TTL interactif) qui ne peut pas être configurée. Si aucun job de session n'est mis en file d'attente dans cette fenêtre, la session est temporairement désactivée.

Valeurs par défaut :

Type d'instance (plan Open ou Premium)TTL interactifTTL maximum
Plan Premium60 sec*8 h*

* Certaines instances du plan Premium peuvent être configurées avec une valeur différente.

Pour déterminer le TTL maximum ou le TTL interactif d'une session, suis les instructions de la section Consulter les détails d'une session et cherche respectivement les valeurs max_time ou interactive_timeout.

Terminer une session​

Une session se termine dans les circonstances suivantes :

  • La valeur maximale du délai d'expiration (TTL) est atteinte, entraînant l'annulation de tous les jobs en file d'attente.

  • La session est annulée manuellement, entraînant l'annulation de tous les jobs en file d'attente.

  • La session est fermée manuellement. Elle cesse d'accepter de nouveaux jobs mais continue à exécuter les jobs en file d'attente en priorité.

  • Si tu utilises Session comme gestionnaire de contexte, c'est-à-dire with Session(), la session se ferme automatiquement à la fin du contexte (comportement identique à session.close()).

Fermer une session​

Une session se ferme automatiquement lorsqu'elle quitte le gestionnaire de contexte. À ce moment, elle passe au statut « En cours, n'accepte plus de nouveaux jobs ». Cela signifie qu'elle termine tous les jobs en cours d'exécution ou en file d'attente jusqu'à ce que la valeur maximale du délai d'expiration soit atteinte. Une fois tous les jobs terminés, la session est immédiatement fermée. Cela permet au planificateur d'exécuter le job suivant sans attendre le délai d'expiration interactif de la session, réduisant ainsi le temps moyen d'attente des jobs. Tu ne peux pas soumettre de jobs à une session fermée.

attention

Le bloc de code suivant retournera une erreur pour les utilisateurs du plan Open car il utilise des sessions. Les charges de travail du plan Open ne peuvent s'exécuter qu'en job mode ou en batch mode.

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

Si tu n'utilises pas de gestionnaire de contexte, ferme manuellement la session pour éviter des coûts inutiles. Tu peux fermer une session dès que tu as fini de lui soumettre des jobs. Lorsqu'une session est fermée avec session.close(), elle n'accepte plus de nouveaux jobs, mais les jobs déjà soumis continueront à s'exécuter jusqu'à leur terme et leurs résultats pourront être récupérés.

attention

Le bloc de code suivant retournera une erreur pour les utilisateurs du plan Open car il utilise des sessions. Les charges de travail du plan Open ne peuvent s'exécuter qu'en job mode ou en batch mode.

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=156>), shape=(3, 2)), metadata={'circuit_metadata': {}})], metadata={'execution': {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-09-01 08:34:17', stop='2026-09-01 08:34:24', size=24576>)])}, 'version': 2})

Vérifier le statut d'une session​

Tu peux interroger le statut d'une session pour comprendre son état actuel en utilisant session.status() ou en consultant la page Workloads.

Le statut d'une session peut être l'un des suivants :

  • Pending : La session n'a pas encore démarré ou a été désactivée. Le prochain job de session doit attendre dans la file d'attente comme les autres jobs.

  • In progress, accepting new jobs : La session est active et accepte de nouveaux jobs.

  • In progress, not accepting new jobs : La session est active mais n'accepte plus de nouveaux jobs. La soumission de jobs à la session est refusée, mais les jobs de session en cours seront exécutés jusqu'à leur terme. La session se ferme automatiquement une fois tous les jobs terminés.

  • Closed : La valeur maximale du délai d'expiration de la session a été atteinte ou la session a été explicitement fermée.

Consulter les détails d'une session​

Pour un aperçu complet de la configuration et du statut d'une session, utilise la méthode session.details() method.

attention

Le bloc de code suivant retournera une erreur pour les utilisateurs du plan Open car il utilise des sessions. Les charges de travail du plan Open ne peuvent s'exécuter qu'en job mode ou en batch mode.

from qiskit_ibm_runtime import QiskitRuntimeService, Session

# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Estimator

# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_estimator import Estimator

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

with Session(backend=backend) as session:
print(session.details())
{'id': 'ff7977a5-ae7b-4509-9c84-bd1d7ff9f619', 'backend_name': 'ibm_marrakesh', '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}

Modèles d'utilisation​

Les sessions sont particulièrement utiles pour les algorithmes nécessitant des échanges fréquents entre des ressources classiques et quantiques.

Exemple : exécute une charge de travail itérative qui utilise l'optimiseur classique SciPy pour minimiser une fonction de coût. Dans ce modèle, SciPy utilise la sortie de la fonction de coût pour calculer son prochain paramètre d'entrée.

attention

Le bloc de code suivant retournera une erreur pour les utilisateurs du plan Open car il utilise des sessions. Les charges de travail du plan Open ne peuvent s'exécuter qu'en job mode ou en batch mode.

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

Exécuter deux algorithmes VQE dans une session avec le threading​

Tu peux tirer davantage parti d'une session en exécutant plusieurs charges de travail simultanément. L'exemple suivant montre comment exécuter deux algorithmes VQE, chacun utilisant un optimiseur classique différent, simultanément dans une seule session. Des étiquettes de job sont également utilisées pour différencier les jobs de chaque charge de travail.

attention

Le bloc de code suivant retournera une erreur pour les utilisateurs du plan Open car il utilise des sessions. Les charges de travail du plan Open ne peuvent s'exécuter qu'en job mode ou en batch mode.

from concurrent.futures import ThreadPoolExecutor

# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Estimator

# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_estimator import 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()

Prochaines étapes​

Recommandations