qiskit-documentation/docs/guides/run-jobs-session.ipynb

510 lines
20 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "b9fd7c5e-f3b8-4f0d-8632-821d601af52c",
"metadata": {},
"source": [
"# Run jobs in a session"
]
},
{
"cell_type": "markdown",
"id": "817c70e7-29dd-4f70-85ad-6487d7c4b010",
"metadata": {
"tags": [
"version-info"
]
},
"source": []
},
{
"cell_type": "markdown",
"id": "be06e0ee-e593-4fe7-aa98-4f6e0dcbaa9f",
"metadata": {},
"source": [
"<LegacyContent>\n",
"<Admonition type=\"note\" title=\"Notes\">\n",
"* This documentation is relevant to IBM Quantum&reg; Platform Classic. If you need the newer version, go to the new [IBM Quantum Platform documentation.](https://quantum.cloud.ibm.com/docs/guides/run-jobs-session)\n",
"* Session execution mode is not supported in the Open Plan. Jobs will run in job mode instead.\n",
"</Admonition>\n",
"</LegacyContent>\n",
"<CloudContent>\n",
"<Admonition type=\"note\" title=\"Notes\">\n",
"* This documentation is relevant to the new IBM Quantum&reg; Platform. If you need the previous version, return to the [IBM Quantum Platform Classic documentation.](https://docs.quantum.ibm.com/guides/run-jobs-session)\n",
"* Open Plan users cannot submit session jobs. Workloads must be run in [job mode](/docs/guides/execution-modes#job-mode) or [batch mode](/docs/guides/execution-modes#batch-mode).\n",
"</Admonition>\n",
"</CloudContent>\n",
"\n",
"Use sessions when you need dedicated and exclusive access to the QPU.\n",
"\n",
"## Set up to use sessions\n",
"\n",
"Before starting a session, you must [set up Qiskit Runtime](./install-qiskit) and initialize it as a service:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "117d0471-1f98-489c-906f-8aab836cd877",
"metadata": {},
"outputs": [],
"source": [
"from qiskit_ibm_runtime import (\n",
" QiskitRuntimeService,\n",
" Session,\n",
" SamplerV2 as Sampler,\n",
" EstimatorV2 as Estimator,\n",
")\n",
"\n",
"service = QiskitRuntimeService()"
]
},
{
"cell_type": "markdown",
"id": "1e1cd9a3-7f36-4f42-8924-7f4dac202788",
"metadata": {},
"source": [
"## Open a session\n",
"\n",
"You can open a runtime session by using the context manager `with Session(...)` or by initializing the `Session`\n",
"class. When you start a session, you must specify a QPU by passing a `backend` object. The session starts when its first job begins execution.\n",
"\n",
"<Admonition type=\"note\">\n",
"If you open a session but do not submit any jobs to it for 30 minutes, the session automatically closes.\n",
"</Admonition>\n",
"\n",
"\n",
"**Session class**\n",
"\n",
"<CloudContent>\n",
"<Admonition type=\"caution\">\n",
"The following code block will return an error for users on the Open Plan because it uses sessions. Workloads on the Open Plan can run only in [job mode](/docs/guides/execution-modes#job-mode) or [batch mode](/docs/guides/execution-modes#batch-mode).\n",
"</Admonition>\n",
"</CloudContent>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2694bd4c-2011-4671-9625-3e7e941dd381",
"metadata": {},
"outputs": [],
"source": [
"backend = service.least_busy(operational=True, simulator=False)\n",
"session = Session(backend=backend)\n",
"estimator = Estimator(mode=session)\n",
"sampler = Sampler(mode=session)\n",
"# Close the session because no context manager was used.\n",
"session.close()"
]
},
{
"cell_type": "markdown",
"id": "e0460f64-f5a8-4663-834a-a4c15c9ad82b",
"metadata": {},
"source": [
"**Context manager**\n",
"\n",
"The context manager automatically opens and closes the session.\n",
"\n",
"<CloudContent>\n",
"<Admonition type=\"caution\">\n",
"The following code block will return an error for users on the Open Plan because it uses sessions. Workloads on the Open Plan can run only in [job mode](/docs/guides/execution-modes#job-mode) or [batch mode](/docs/guides/execution-modes#batch-mode).\n",
"</Admonition>\n",
"</CloudContent>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "192e5e57-2f9d-4f8e-b3e7-1dd31907e8a6",
"metadata": {},
"outputs": [],
"source": [
"from qiskit_ibm_runtime import (\n",
" Session,\n",
" SamplerV2 as Sampler,\n",
" EstimatorV2 as Estimator,\n",
")\n",
"\n",
"backend = service.least_busy(operational=True, simulator=False)\n",
"with Session(backend=backend):\n",
" estimator = Estimator()\n",
" sampler = Sampler()"
]
},
{
"cell_type": "markdown",
"id": "e4219769-6348-4d0c-8e13-830177a4e7b8",
"metadata": {},
"source": [
"<span id=\"specify-length\"></span>\n",
"## Session length\n",
"\n",
"The maximum session time to live (TTL) determines how long a session can run. You can set this value with the `max_time` parameter. This should exceed the longest job's execution time.\n",
"\n",
"This timer starts when the session starts. When the value is reached, the session is closed. Any jobs that are running will finish, but jobs still queued are failed.\n",
"\n",
"<CloudContent>\n",
"<Admonition type=\"caution\">\n",
"The following code block will return an error for users on the Open Plan because it uses sessions. Workloads on the Open Plan can run only in [job mode](/docs/guides/execution-modes#job-mode) or [batch mode](/docs/guides/execution-modes#batch-mode).\n",
"</Admonition>\n",
"</CloudContent>\n",
"\n",
"```python\n",
"with Session(backend=backend, max_time=\"25m\"):\n",
" ...\n",
"```\n",
"\n",
"There is also an interactive time to live (interactive TTL) value that cannot be configured. If no session jobs are queued within that window, the session is temporarily deactivated.\n",
"\n",
"Default values:\n",
"<LegacyContent>\n",
"| Instance type (Open or Premium Plan) | Interactive TTL | Maximum TTL |\n",
"| --- | --- | --- |\n",
"| Premium Plan | 60 sec* | 8 h* |\n",
"| Open Plan | sessions run in job mode | sessions run in job mode |\n",
"</LegacyContent>\n",
"<CloudContent>\n",
"| Instance type (Open or Premium Plan) | Interactive TTL | Maximum TTL |\n",
"| --- | --- | --- |\n",
"| Premium Plan | 60 sec* | 8 h* |\n",
"</CloudContent>\n",
"*\\* Certain Premium Plan instances might be configured to have a different value.*\n",
"\n",
"To determine a session's max TTL or interactive TTL, follow the instructions in [Determine session details](#session-details) and look for the `max_time`or `interactive_timeout` value, respectively.\n",
"\n",
"<span id=\"ends\"></span>\n",
"## End a session\n",
"\n",
"A session ends in the following circumstances:\n",
"\n",
"* The maximum timeout (TTL) value is reached, resulting in the cancellation of all queued jobs.\n",
"* The session is manually canceled, resulting in the cancellation of all queued jobs.\n",
"* The session is manually closed. The session stops accepting new jobs but continues to run queued jobs with priority.\n",
"* If you use Session as a context manager, that is, `with Session()`, the session is automatically closed when the context ends (the same behavior as using `session.close()`).\n",
"\n",
"<span id=\"close\"></span>\n",
"### Close a session\n",
"\n",
"A session automatically closes when it exits the context manager. 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.\n",
"\n",
"<CloudContent>\n",
"<Admonition type=\"caution\">\n",
"The following code block will return an error for users on the Open Plan because it uses sessions. Workloads on the Open Plan can run only in [job mode](/docs/guides/execution-modes#job-mode) or [batch mode](/docs/guides/execution-modes#batch-mode).\n",
"</Admonition>\n",
"</CloudContent>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c13875c9-7898-4aa7-83c9-48fae3f07377",
"metadata": {
"tags": [
"remove-cell"
]
},
"outputs": [],
"source": [
"from qiskit.quantum_info import SparsePauliOp\n",
"from qiskit.circuit import QuantumCircuit, Parameter\n",
"from qiskit.transpiler import generate_preset_pass_manager\n",
"import numpy as np\n",
"\n",
"# This cell is hidden from users\n",
"service = QiskitRuntimeService()\n",
"backend = service.least_busy()\n",
"\n",
"# Define two circuits, each with one parameter with two parameters.\n",
"circuit = QuantumCircuit(2)\n",
"circuit.h(0)\n",
"circuit.cx(0, 1)\n",
"circuit.ry(Parameter(\"a\"), 0)\n",
"circuit.cx(0, 1)\n",
"circuit.h(0)\n",
"circuit.measure_all()\n",
"\n",
"\n",
"pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n",
"transpiled_circuit = pm.run(circuit)\n",
"transpiled_circuit_sampler = transpiled_circuit\n",
"transpiled_circuit_sampler.measure_all()\n",
"\n",
"params = np.random.uniform(size=(2, 3)).T\n",
"observables = [\n",
" [SparsePauliOp([\"XX\", \"IY\"], [0.5, 0.5])],\n",
" [SparsePauliOp(\"XX\")],\n",
" [SparsePauliOp(\"IY\")],\n",
"]\n",
"\n",
"sampler_pub = (transpiled_circuit_sampler, params)\n",
"estimator_pub = (transpiled_circuit_sampler, observables, params)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c6646bed-3064-488f-b2ff-da9ba793775a",
"metadata": {},
"outputs": [],
"source": [
"with Session(backend=backend) as session:\n",
" estimator = Estimator()\n",
" sampler = Sampler()\n",
" job1 = estimator.run([estimator_pub])\n",
" job2 = sampler.run([sampler_pub])\n",
"\n",
"# The session is no longer accepting jobs but the submitted job will run to completion.\n",
"result = job1.result()\n",
"result2 = job2.result()"
]
},
{
"cell_type": "markdown",
"id": "20eb23f3-fc34-4f38-8ad7-85278ff4c823",
"metadata": {},
"source": [
"<Admonition type=\"tip\">\n",
"If you are not using a context manager, manually close the session to avoid unwanted cost. You can close a session as soon as you are done submitting jobs to it. 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.\n",
"</Admonition>\n",
"\n",
"<CloudContent>\n",
"<Admonition type=\"caution\">\n",
"The following code block will return an error for users on the Open Plan because it uses sessions. Workloads on the Open Plan can run only in [job mode](/docs/guides/execution-modes#job-mode) or [batch mode](/docs/guides/execution-modes#batch-mode).\n",
"</Admonition>\n",
"</CloudContent>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "861cf6b3-9695-41eb-9d3d-d5293880ca75",
"metadata": {},
"outputs": [],
"source": [
"session = Session(backend=backend)\n",
"\n",
"# If using qiskit-ibm-runtime earlier than 0.24.0, change `mode=` to `session=`\n",
"estimator = Estimator(mode=session)\n",
"estimator = Sampler(mode=session)\n",
"job1 = estimator.run([estimator_pub])\n",
"job2 = sampler.run([sampler_pub])\n",
"print(f\"Result1: {job1.result()}\")\n",
"print(f\"Result2: {job2.result()}\")\n",
"\n",
"# Manually close the session. Running and queued jobs will run to completion.\n",
"session.close()"
]
},
{
"cell_type": "markdown",
"id": "aad804ed-027f-49c3-9f7d-8851a4f3de3a",
"metadata": {},
"source": [
"<span id=\"session-status\"></span>\n",
"## Check session status\n",
"\n",
"<LegacyContent>\n",
"You can query a session's status to understand its current state by using `session.status()` or by viewing the Workloads page for your channel.\n",
"</LegacyContent>\n",
"<CloudContent>\n",
"You can query a session's status to understand its current state by using `session.status()` or by viewing the [Workloads](https://quantum.cloud.ibm.com/workloads) page.\n",
"</CloudContent>\n",
"\n",
"Session status can be one of the following:\n",
"\n",
"- `Pending`: The session has not started or has been deactivated. The next session job needs to wait in the queue like other jobs.\n",
"- `In progress, accepting new jobs`: The session is active and accepting new jobs.\n",
"- `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.\n",
"- `Closed`: The session's maximum timeout value has been reached or the session was explicitly closed.\n",
"\n",
"<span id=\"session-details\"></span>\n",
"## Determine session details\n",
"\n",
"For a comprehensive overview of a session's configuration and status, use the `session.details() method`.\n",
"\n",
"<CloudContent>\n",
"<Admonition type=\"caution\">\n",
"The following code block will return an error for users on the Open Plan because it uses sessions. Workloads on the Open Plan can run only in [job mode](/docs/guides/execution-modes#job-mode) or [batch mode](/docs/guides/execution-modes#batch-mode).\n",
"</Admonition>\n",
"</CloudContent>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "82a2599e-3e32-4e01-9a36-b77a56af7647",
"metadata": {},
"outputs": [],
"source": [
"from qiskit_ibm_runtime import (\n",
" QiskitRuntimeService,\n",
" Session,\n",
" EstimatorV2 as Estimator,\n",
")\n",
"\n",
"service = QiskitRuntimeService()\n",
"backend = service.least_busy(operational=True, simulator=False)\n",
"\n",
"with Session(backend=backend) as session:\n",
" print(session.details())"
]
},
{
"cell_type": "markdown",
"id": "7db97311-25cb-4b81-9dba-494264c554c6",
"metadata": {},
"source": [
"## Usage patterns\n",
"\n",
"Sessions are especially useful for algorithms that require frequent communication between classical and quantum resources.\n",
"\n",
"Example: Run 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.\n",
"\n",
"<CloudContent>\n",
"<Admonition type=\"caution\">\n",
"The following code block will return an error for users on the Open Plan because it uses sessions. Workloads on the Open Plan can run only in [job mode](/docs/guides/execution-modes#job-mode) or [batch mode](/docs/guides/execution-modes#batch-mode).\n",
"</Admonition>\n",
"</CloudContent>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "77cc7c96-e8c0-4970-b05e-361ddf74d707",
"metadata": {},
"outputs": [],
"source": [
"from scipy.optimize import minimize\n",
"from qiskit.circuit.library import efficient_su2\n",
"\n",
"\n",
"def cost_func(params, ansatz, hamiltonian, estimator):\n",
" # Return estimate of energy from estimator\n",
"\n",
" energy = (\n",
" estimator.run(ansatz, hamiltonian, parameter_values=params)\n",
" .result()\n",
" .values[0]\n",
" )\n",
" return energy\n",
"\n",
"\n",
"hamiltonian = SparsePauliOp.from_list(\n",
" [(\"YZ\", 0.3980), (\"ZI\", -0.3980), (\"ZZ\", -0.0113), (\"XX\", 0.1810)]\n",
")\n",
"su2_ansatz = efficient_su2(hamiltonian.num_qubits)\n",
"pm = generate_preset_pass_manager(backend=backend, optimization_level=3)\n",
"ansatz = pm.run(su2_ansatz)\n",
"\n",
"num_params = ansatz.num_parameters\n",
"x0 = 2 * np.pi * np.random.random(num_params)\n",
"\n",
"session = Session(backend=backend)\n",
"\n",
"\n",
"# If using qiskit-ibm-runtime earlier than 0.24.0, change `mode=` to `session=`\n",
"estimator = Estimator(mode=session, options={\"default_shots\": int(1e4)})\n",
"res = minimize(\n",
" cost_func, x0, args=(ansatz, hamiltonian, estimator), method=\"cobyla\"\n",
")\n",
"\n",
"# Close the session because no context manager was used.\n",
"session.close()"
]
},
{
"cell_type": "markdown",
"id": "8c03c721-f040-4066-a9d2-f2dd39777789",
"metadata": {},
"source": [
"<span id=\"two-vqe\"></span>\n",
"## Run two VQE algorithms in a session by using threading\n",
"\n",
"You can get more out of a session by running multiple workloads simultaneously. The following example shows how you can run two VQE algorithms, each using a different classical optimizer, simultaneously inside a single session. Job tags are also used to differentiate jobs from each workload.\n",
"\n",
"<CloudContent>\n",
"<Admonition type=\"caution\">\n",
"The following code block will return an error for users on the Open Plan because it uses sessions. Workloads on the Open Plan can run only in [job mode](/docs/guides/execution-modes#job-mode) or [batch mode](/docs/guides/execution-modes#batch-mode).\n",
"</Admonition>\n",
"</CloudContent>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e83f7d60-13f0-4df1-9766-6fa67c970362",
"metadata": {},
"outputs": [],
"source": [
"from concurrent.futures import ThreadPoolExecutor\n",
"from qiskit_ibm_runtime import EstimatorV2 as Estimator\n",
"\n",
"\n",
"def minimize_thread(estimator, method):\n",
" return minimize(\n",
" cost_func, x0, args=(ansatz, hamiltonian, estimator), method=method\n",
" )\n",
"\n",
"\n",
"with Session(backend=backend), ThreadPoolExecutor() as executor:\n",
" estimator1 = Estimator()\n",
" estimator2 = Estimator()\n",
"\n",
" # Use different tags to differentiate the jobs.\n",
" estimator1.options.environment.job_tags = [\"cobyla\"]\n",
" estimator2.options.environment.job_tags = [\"nelder-mead\"]\n",
"\n",
" # Submit the two workloads.\n",
" cobyla_future = executor.submit(minimize_thread, estimator1, \"cobyla\")\n",
" nelder_mead_future = executor.submit(\n",
" minimize_thread, estimator2, \"nelder-mead\"\n",
" )\n",
"\n",
" # Get workload results.\n",
" cobyla_result = cobyla_future.result()\n",
" nelder_mead_result = nelder_mead_future.result()"
]
},
{
"cell_type": "markdown",
"id": "0194fb4b-0917-45d7-aeb1-9fdff38cc5c5",
"metadata": {},
"source": [
"## Next steps\n",
"\n",
"<Admonition type=\"tip\" title=\"Recommendations\">\n",
" - Try an example in the [Quantum approximate optimization algorithm (QAOA)](https://learning.quantum.ibm.com/tutorial/quantum-approximate-optimization-algorithm) tutorial.\n",
" - Review the [Session API](/docs/api/qiskit-ibm-runtime/session) reference.\n",
" - Understand the [Job limits](/docs/guides/job-limits) when sending a job to an IBM&reg; QPU.\n",
"</Admonition>"
]
}
],
"metadata": {
"description": "How to run a quantum computing job in a Qiskit Runtime session.",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3"
},
"title": "Run jobs in a session"
},
"nbformat": 4,
"nbformat_minor": 4
}