Skip to main contentIBM Quantum Documentation

Run jobs in a session

There are several ways to set up and use sessions. It is recommended that you do not run a session with a single job in it.

Important

The way sessions are started within Qiskit Runtime has changed. By 1 April 2024, upgrade to qiskit-ibm-runtime version 0.20.0 or later, or qiskit-ibm-provider version 0.10.0 or later. In addition, ensure you are using Qiskit version 0.45.0 or later. Starting 1 April, session calls made in earlier versions of these packages will fail.


Set up to use sessions

Before starting a session, you must set up Qiskit Runtime and initialize it as a service:

from qiskit_ibm_runtime import QiskitRuntimeService, Session, Sampler, Estimator
 
service = QiskitRuntimeService()

Open a session

You can open a runtime session by using the context manager with Session(...) or by initializing the Session class. The session starts when its first job begins execution.

Important

If the first session job is canceled, subsequent session jobs will all fail.

Session class

from qiskit_ibm_runtime import Session, Samplerv2 as Sampler, Estimatorv2 as Estimator
 
backend = service.least_busy(operational=True, simulator=False)
session = Session(service=service, backend=backend)
estimator = Estimator(session=session)
sampler = Sampler(session=session)

Context manager

The context manager automatically opens and closes the session.

backend = service.least_busy(operational=True, simulator=False)    
with Session(service=service, backend=backend):
  estimatorv2 = EstimatorV2()
  samplerv2 = SamplerV2()

When you start a session, you must specify a system. This can be done by specifying its name or by passing a backend object.

Specify a system by name

service = QiskitRuntimeService()
with Session(service=service, backend="ibm_sherbrooke"):
    ...

Pass a backend object

backend = service.least_busy(operational=True, simulator=False)
with Session(backend=backend):
  ...

Session length

You can define the maximum session timeout with the max_time parameter. This should exceed the longest job's execution time and be within the system's limits.

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

There is also an interactive timeout value (ITTL, or interactive time to live) that cannot be configured. If no session jobs are queued within that window, the session is temporarily deactivated. To determine a session's ITTL, follow the instructions in Determine session details and look for the interactive_timeout value.


Close a session

A session automatically closes when it exits the context manager. With qiskit-ibm-runtime 0.13 or later releases, when the session context manager is exited, the session is put into "In progress, not accepting new jobs" status. This means that the session finishes processing all running or queued jobs until the maximum timeout value is reached. After all jobs are completed, the session is immediately closed. This allows the scheduler to run the next job without waiting for the session interactive timeout, thereby reducing the average job queuing time. You cannot submit jobs to a closed session.

with Session(service=service, backend=backend) as session:
    estimator = Estimator()
    job1 = estimator.run(...)
    job2 = estimator.run(...)
    
# The session is no longer accepting jobs but the submitted job will run to completion.    
result = job1.result()
result2 = job2.result()

If you are not using a context manager, it's good practice to manually close the session once all the necessary results have been retrieved. With qiskit-ibm-runtime 0.13 or later releases, when a session is closed with session.close(), it no longer accepts new jobs, but the already submitted jobs will still run until completion and their results can be retrieved. Prior to qiskit-ibm-runtime 0.13, when a session is closed with session.close(), any jobs that are already running continue to run, but any queued jobs remaining in the session are put into a failed state.

session = Session(backend=backend)
estimator = Estimator(session=session)
job1 = estimator.run(...)
job2 = estimator.run(...)
print(f"Result1: {job1.result()}")
print(f"Result2: {job2.result()}")
 
# Manually close the session. Running and queued jobs will run to completion.
session.close()
When the root job is canceled

Note that when you cancel the root job in the session (the job which has the same ID as the session), the session closes and fails any remaining queued jobs in the session.


Cancel a session

Canceling a session immediately closes it, failing all queued jobs and preventing new submission. Use the session.cancel() method to cancel a session. Any jobs that are already running continue to run but queued jobs are put into a failed state and no further jobs can be submitted to the session. This is a convenient way to quickly fail all queued jobs within a session.

with Session(service=service, backend=backend) as session:
    estimator = Estimator()
    job1 = estimator.run(...)
    job2 = estimator.run(...)
    # You can use session.cancel() to fail all pending jobs, for example, 
    # if you realize you made a mistake.
    session.cancel()

Invoke multiple primitives in a session

A session can handle multiple primitives, allowing for various operations within a single session. The following example shows how you can create both an instance of the Sampler class and one of the Estimator class and invoke their run() methods within a session.

from qiskit_ibm_runtime import Session, SamplerV2 as Sampler, EstimatorV2 as Estimator
 
with Session(backend=backend):
    sampler = Sampler()
    estimator = Estimator()
 
    job = sampler.run([(sampler_circuit,)])
    result = job.result()
    print(f" > Counts: {result[0].data.meas.get_counts()}")
 
    job = estimator.run([(circuit, observable)])
    result = job.result()
    print(f" > Expectation value: {result[0].data.evs}")
    print(f" > Metadata: {result[0].metadata}")

Check session status

You can query a session's status to understand its current state by using session.status() or on the Jobs page for your channel.

Session status can be one of the following:

  • Pending: The session has not started or has been deactivated. The next session job needs to wait in the queue like other jobs.
  • In progress, accepting new jobs: The session is active and accepting new jobs.
  • In progress, not accepting new jobs: The session is active but not accepting new jobs. Job submission to the session is rejected, but outstanding session jobs will run to completion. The session is automatically closed once all jobs finish.
  • Closed: The session's maximum timeout value has been reached or the session was explicitly closed.

Determine session details

For a comprehensive overview of a session's configuration and status, use the session.details() method.

from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator
 
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
 
with Session(service=service, backend="backend") as session:
    estimator = Estimator()
    job = estimator.run([(circuit, observable)])
    print(session.details())

Next steps

Recommendations
Was this page helpful?