diff --git a/docs/run/run-jobs-in-session.mdx b/docs/run/run-jobs-in-session.mdx
index a0c2534fa4a..5d07c88b661 100644
--- a/docs/run/run-jobs-in-session.mdx
+++ b/docs/run/run-jobs-in-session.mdx
@@ -30,7 +30,7 @@ backend to run on. This topic describes the most commonly used options.
For the full list, see the [Sessions API documentation](../api/qiskit-ibm-runtime/qiskit_ibm_runtime.Session#session).
- Data from the first session job is cached and used by subsequent jobs. Therefore, if the first job is canceled, subsequent session jobs will all fail.
+ If the first session job is canceled, subsequent session jobs will all fail.
@@ -70,8 +70,8 @@ There are two ways to specify a backend in a session:
**Directly specify a string with the backend name.** Example:
``` python
-backend = "ibmq_qasm_simulator"
-with Session(backend=backend):
+service = QiskitRuntimeService()
+with Session(service=service, backend="ibmq_qasm_simulator"):
...
```
@@ -121,13 +121,31 @@ closed session.
This behavior exists in `qiskit-ibm-runtime` 0.13 or later releases only. Previously, `session.close()` **canceled** the session.
+Example: The session is automatically closed when the context manager is exited.
+
``` python
with Session(service=service, backend=backend) as session:
estimator = Estimator()
- job = estimator.run(...)
+ job1 = estimator.run(...)
+ job2 = estimator.run(...)
-# The session is no longer accepting jobs but the submitted job will run to completion
-result = job.result()
+# The session is no longer accepting jobs but the submitted job will run to completion.
+result = job1.result()
+result2 = job2.result()
+```
+
+Example: The session is manually closed because we didn't use a context manager.
+
+``` python
+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()
```
diff --git a/docs/run/sessions.mdx b/docs/run/sessions.mdx
index 6caeb5a3df5..7c316612e7e 100644
--- a/docs/run/sessions.mdx
+++ b/docs/run/sessions.mdx
@@ -37,7 +37,7 @@ There are several benefits to using sessions:
- The queuing time does not decrease for the first job submitted within a session. Therefore, a session does not provide any benefits if you only need to run a single job.
- - Since data from the first session job is cached and used by subsequent jobs, if the first job is canceled, subsequent session jobs will all fail.
+ - If the first session job is canceled, subsequent session jobs will all fail.
@@ -142,7 +142,7 @@ Sessions can be used for iterative or batch execution.
Any session job submitted within the interactive timeout, also known as interactive time to live (ITTL), is processed immediately. This allows some time for variational algorithms, such as VQE, to perform classical post-processing.
-- The quantum device is locked to the session user unless the ITTL is reached.
+- When a session is active, its jobs get priority until ITTL or max timeout is reached.
- Post-processing could be done anywhere, such as a personal computer, cloud service, or an HPC environment.
![Iterative session execution diagram.](/images/run/iterative.png 'Figure 2: Iterative session execution')
@@ -151,14 +151,33 @@ Any session job submitted within the interactive timeout, also known as interact
There might be a limit imposed on the ITTL value depending on whether your hub is Premium, Open, and so on.
+This is an example of running an iterative workload that uses the classical SciPy optimizer to minimize a cost function. In this model, SciPy uses the output of the cost function to calculate its next input.
+
+```python
+ def cost_func(params, ansatz, hamiltonian, estimator):
+ # Return estimate of energy from estimator
+
+ energy = estimator.run(ansatz, hamiltonian, parameter_values=params).result().values[0]
+ return energy
+
+ x0 = 2 * np.pi * np.random.random(num_params)
+
+ session = Session(backend=backend)
+
+ estimator = Estimator(session=session, options={"shots": int(1e4)})
+ res = minimize(cost_func, x0, args=(ansatz, hamiltonian, estimator), method="cobyla")
+
+ # Close the session because we didn't use a context manager.
+ session.close()
+```
+
### Batch
Ideal for running experiments closely together to avoid device drifts,
that is, to maintain device characterization.
- Suitable for batching many jobs together.
-- Jobs that fit within the maximum session time run back-to-back on
- hardware.
+- The classical computation, such as compilation, of the jobs is run in parallel. This means running multiple jobs in a batch would be significantly faster than running them serially.
When batching, jobs are not guaranteed to run in the order they are submitted.
@@ -166,6 +185,21 @@ that is, to maintain device characterization.
![Batch session execution diagram.](/images/run/batch.png 'Figure 3: Batch session execution')
+The following example shows how you can divide up a long list of circuits into multiple jobs and run them as a batch to take advantage of the parallel processing.
+
+```python
+backend = service.backend("ibm_sherbrooke")
+
+with Session(backend=backend):
+ estimator = Estimator()
+ start_idx = 0
+ jobs = []
+ while start_idx < len(circuits):
+ end_idx = start_idx + backend.max_circuits
+ jobs.append(estimator.run(circuits[start_idx:end_idx], obs[start_idx:end_idx], params[start_idx:end_idx]))
+ start_idx = end_idx
+```
+
## Sessions and reservations
IBM Quantum Premium users can access both reservations and sessions on