Saltar al contenido principal
Este proyecto está en fase beta. ¿Encontraste un error? Abre un issue en GitHub. ¿Tienes una pregunta o una idea? Pregunta en Discussions — ¡nos encantaría tu opinión!
¿Cómo es la calidad de la traducción en esta página?

Ejecutar trabajos en una sesión

Versiones de paquetes

El código de esta página fue desarrollado con los siguientes requisitos. Recomendamos usar estas versiones o más recientes.

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

Los usuarios del Plan Abierto no pueden enviar trabajos de sesión. Los workloads deben ejecutarse en job mode o batch mode.

Usa sesiones cuando necesites acceso dedicado y exclusivo al QPU.

Configuración para usar sesiones​

Antes de iniciar una sesión, debes configurar el cliente de IBM Quantum Compute e inicializarlo como servicio:

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

Abrir una sesión​

Puedes abrir una sesión de runtime usando el gestor de contexto with Session(...) o inicializando la clase Session. Al iniciar una sesión, debes especificar un QPU pasando un objeto backend. La sesión comienza cuando su primer trabajo empieza a ejecutarse.

nota

Si abres una sesión pero no envías ningún trabajo durante 30 minutos, la sesión se cierra automáticamente.

Clase Session

precaución

El siguiente bloque de código devolverá un error para los usuarios del Plan Abierto porque usa sesiones. Los workloads del Plan Abierto solo pueden ejecutarse en job mode o 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()

Gestor de contexto

El gestor de contexto abre y cierra la sesión automáticamente.

precaución

El siguiente bloque de código devolverá un error para los usuarios del Plan Abierto porque usa sesiones. Los workloads del Plan Abierto solo pueden ejecutarse en job mode o 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()

Duración de la sesión​

El tiempo de vida máximo (TTL) de la sesión determina cuánto tiempo puede ejecutarse una sesión. Puedes establecer este valor con el parámetro max_time. Este valor debe superar el tiempo de ejecución del trabajo más largo.

Este temporizador comienza cuando la sesión se inicia. Cuando se alcanza ese valor, la sesión se cierra. Los trabajos que estén en ejecución terminarán, pero los trabajos aún en cola fallarán.

precaución

El siguiente bloque de código devolverá un error para los usuarios del Plan Abierto porque usa sesiones. Los workloads del Plan Abierto solo pueden ejecutarse en job mode o batch mode.

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

También existe un valor de tiempo de vida interactivo (TTL interactivo) que no se puede configurar. Si no se encolan trabajos de sesión dentro de esa ventana, la sesión se desactiva temporalmente.

Valores predeterminados:

Tipo de instancia (Plan Abierto o Premium)TTL interactivoTTL máximo
Plan Premium60 seg*8 h*

* Ciertas instancias del Plan Premium pueden estar configuradas con un valor diferente.

Para determinar el TTL máximo o el TTL interactivo de una sesión, sigue las instrucciones en Determinar detalles de la sesión y busca los valores max_time o interactive_timeout, respectivamente.

Finalizar una sesión​

Una sesión termina en las siguientes circunstancias:

  • Se alcanza el valor máximo de tiempo de espera (TTL), lo que provoca la cancelación de todos los trabajos en cola.

  • La sesión se cancela manualmente, lo que provoca la cancelación de todos los trabajos en cola.

  • La sesión se cierra manualmente. La sesión deja de aceptar nuevos trabajos, pero continúa ejecutando los trabajos en cola con prioridad.

  • Si usas Session como gestor de contexto, es decir, with Session(), la sesión se cierra automáticamente cuando el contexto termina (el mismo comportamiento que usar session.close()).

Cerrar una sesión​

Una sesión se cierra automáticamente cuando sale del gestor de contexto. Cuando se sale del gestor de contexto de la sesión, la sesión pasa al estado "En progreso, no acepta nuevos trabajos". Esto significa que la sesión termina de procesar todos los trabajos en ejecución o en cola hasta que se alcanza el valor máximo de tiempo de espera. Una vez completados todos los trabajos, la sesión se cierra inmediatamente. Esto permite al planificador ejecutar el siguiente trabajo sin esperar el tiempo de espera interactivo de la sesión, lo que reduce el tiempo promedio de espera en cola. No puedes enviar trabajos a una sesión cerrada.

precaución

El siguiente bloque de código devolverá un error para los usuarios del Plan Abierto porque usa sesiones. Los workloads del Plan Abierto solo pueden ejecutarse en job mode o 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()
consejo

Si no estás usando un gestor de contexto, cierra la sesión manualmente para evitar costos no deseados. Puedes cerrar una sesión en cuanto termines de enviar trabajos. Cuando una sesión se cierra con session.close(), ya no acepta nuevos trabajos, pero los trabajos ya enviados seguirán ejecutándose hasta completarse y sus resultados podrán recuperarse.

precaución

El siguiente bloque de código devolverá un error para los usuarios del Plan Abierto porque usa sesiones. Los workloads del Plan Abierto solo pueden ejecutarse en job mode o 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})

Verificar el estado de la sesión​

Puedes consultar el estado de una sesión para entender su estado actual usando session.status() o visitando la página de Workloads.

El estado de la sesión puede ser uno de los siguientes:

  • Pending (Pendiente): La sesión no ha comenzado o ha sido desactivada. El siguiente trabajo de la sesión debe esperar en la cola como cualquier otro trabajo.

  • In progress, accepting new jobs (En progreso, aceptando nuevos trabajos): La sesión está activa y acepta nuevos trabajos.

  • In progress, not accepting new jobs (En progreso, no acepta nuevos trabajos): La sesión está activa pero no acepta nuevos trabajos. El envío de trabajos a la sesión es rechazado, pero los trabajos pendientes se ejecutarán hasta completarse. La sesión se cierra automáticamente una vez que todos los trabajos terminen.

  • Closed (Cerrada): Se alcanzó el valor máximo de tiempo de espera de la sesión o la sesión fue cerrada explícitamente.

Determinar los detalles de la sesión​

Para obtener una visión general completa de la configuración y el estado de una sesión, usa el método session.details() method.

precaución

El siguiente bloque de código devolverá un error para los usuarios del Plan Abierto porque usa sesiones. Los workloads del Plan Abierto solo pueden ejecutarse en job mode o 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}

Patrones de uso​

Las sesiones son especialmente útiles para algoritmos que requieren comunicación frecuente entre recursos clásicos y cuánticos.

Ejemplo: ejecuta un workload iterativo que usa el optimizador clásico SciPy para minimizar una función de costo. En este modelo, SciPy usa la salida de la función de costo para calcular su siguiente entrada.

precaución

El siguiente bloque de código devolverá un error para los usuarios del Plan Abierto porque usa sesiones. Los workloads del Plan Abierto solo pueden ejecutarse en job mode o 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()

Ejecutar dos algoritmos VQE en una sesión usando threading​

Puedes aprovechar mejor una sesión ejecutando múltiples workloads simultáneamente. El siguiente ejemplo muestra cómo ejecutar dos algoritmos VQE, cada uno con un optimizador clásico diferente, de forma simultánea dentro de una única sesión. También se usan etiquetas de trabajo para diferenciar los trabajos de cada workload.

precaución

El siguiente bloque de código devolverá un error para los usuarios del Plan Abierto porque usa sesiones. Los workloads del Plan Abierto solo pueden ejecutarse en job mode o 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()

Próximos pasos​

Recomendaciones