diff --git a/docs/guides/DAG-representation.ipynb b/docs/guides/DAG-representation.ipynb index a73d1a6b2a5..1a9007167b4 100644 --- a/docs/guides/DAG-representation.ipynb +++ b/docs/guides/DAG-representation.ipynb @@ -465,8 +465,8 @@ "## Next steps\n", "\n", "\n", - " - Review the guide on creating a [custom transpiler pass](./custom-transpiler-pass)\n", - " - Learn how to [Create and transpile against custom backends](./custom-backend)\n", + " - Review the guide on creating a [custom transpiler pass](/docs/guides/custom-transpiler-pass)\n", + " - Learn how to [Create and transpile against custom backends](/docs/guides/custom-backend)\n", " - Try the [Compare transpiler settings](/docs/guides/circuit-transpilation-settings) guide.\n", " - Review the [DAG Circuit API documentation](/docs/api/qiskit/dagcircuit).\n", "" diff --git a/docs/guides/_toc.json b/docs/guides/_toc.json index a9ccdc1ae9e..12acb99a649 100644 --- a/docs/guides/_toc.json +++ b/docs/guides/_toc.json @@ -246,6 +246,10 @@ "title": "Exact and noisy simulation with Qiskit Aer primitives", "url": "/docs/guides/simulate-with-qiskit-aer" }, + { + "title": "Exact simulation with Qiskit SDK primitives", + "url": "/docs/guides/simulate-with-qiskit-sdk-primitives" + }, { "title": "Build noise models", "url": "/docs/guides/build-noise-models" @@ -483,6 +487,129 @@ } ] }, + { + "title": "Execute with primitives", + "children": [ + { + "title": "Introduction to primitives", + "url": "/docs/guides/primitives" + }, { + "title": "Introduction to options", + "url": "/docs/guides/runtime-options-overview" + }, + { + "title": "PUBs and broadcasting", + "url": "/docs/guides/pubs-broadcasting" + }, + { + "title": "Estimator", + "children": [ + { + "title": "Get started", + "url": "/docs/guides/get-started-with-estimator" + }, + { + "title": "Inputs and outputs", + "url": "/docs/guides/estimator-input-output" + }, + { + "title": "Broadcasting", + "url": "/docs/guides/estimator-broadcasting" + }, + { + "title": "Options", + "url": "/docs/guides/estimator-options" + }, + { + "title": "Examples", + "url": "/docs/guides/estimator-examples" + }, + { + "title": "REST API", + "url": "/docs/guides/estimator-rest-api" + } + ] + }, + { + "title": "Sampler", + "children": [ + { + "title": "Get started", + "url": "/docs/guides/get-started-with-sampler" + }, + { + "title": "Inputs and outputs", + "url": "/docs/guides/sampler-input-output" + }, + { + "title": "Options", + "url": "/docs/guides/sampler-options" + }, + { + "title": "Examples", + "url": "/docs/guides/sampler-examples" + }, + { + "title": "REST API", + "url": "/docs/guides/sampler-rest-api" + } + ] + }, + { + "title": "Executor", + "children": [ + { + "title": "Get started", + "url": "/docs/guides/get-started-with-executor" + }, + { + "title": "Inputs and outputs", + "url": "/docs/guides/executor-input-output" + }, + { + "title": "Broadcasting", + "url": "/docs/guides/executor-broadcasting" + }, + { + "title": "Options", + "url": "/docs/guides/executor-options" + }, + { + "title": "Examples", + "url": "/docs/guides/executor-examples" + } ] + }, + { + "title": "Manage noise", + "children": [ + { + "title": "Error mitigation and suppression", + "url": "/docs/guides/error-mitigation-and-suppression-techniques" + }, + { + "title": "Noise learning", + "url": "/docs/guides/noise-learning" + }, + { + "title": "Configure error mitigation", + "url": "/docs/guides/configure-error-mitigation" + }, + { + "title": "Configure error suppression", + "url": "/docs/guides/configure-error-suppression" + } + ] + }, + { + "title": "Directed execution model (beta)", + "url": "/docs/guides/directed-execution-model" + }, + { + "title": "Qiskit Runtime local testing mode", + "url": "/docs/guides/local-testing-mode" + } + ] + }, { "title": "Execute with primitives", "children": [ @@ -556,6 +683,10 @@ "title": "View backend details", "url": "/docs/guides/qpu-information" }, + { + "title": "Get backend information with Qiskit", + "url": "/docs/guides/get-qpu-information" + }, { "title": "Monitoring, calibrations, and benchmarking", "url": "/docs/guides/calibration-jobs" diff --git a/docs/guides/ai-transpiler-passes.ipynb b/docs/guides/ai-transpiler-passes.ipynb index 331f7f78f1a..c49df68d424 100644 --- a/docs/guides/ai-transpiler-passes.ipynb +++ b/docs/guides/ai-transpiler-passes.ipynb @@ -235,11 +235,11 @@ "\n", "## Limits\n", "\n", - "Refer to the [Qiskit Transpiler Service documentation](./qiskit-transpiler-service#limits-of-the-qiskit-transpiler-service) for more information about the limits that apply to the AI-powered transpiler passes.\n", + "Refer to the [Qiskit Transpiler Service documentation](/docs/guides/qiskit-transpiler-service#limits-of-the-qiskit-transpiler-service) for more information about the limits that apply to the AI-powered transpiler passes.\n", "\n", "## Citation\n", "\n", - "If you use any AI-powered feature from the Qiskit Transpiler Service in your research, use [the recommended citation](./qiskit-transpiler-service#citation)." + "If you use any AI-powered feature from the Qiskit Transpiler Service in your research, use [the recommended citation](/docs/guides/qiskit-transpiler-service#citation)." ] } ], diff --git a/docs/guides/algorithmiq-tem.ipynb b/docs/guides/algorithmiq-tem.ipynb index a1c941df197..473da11b5b9 100644 --- a/docs/guides/algorithmiq-tem.ipynb +++ b/docs/guides/algorithmiq-tem.ipynb @@ -292,7 +292,7 @@ "\n", "Name | Type | Description | Required | Default | Example\n", "-- | -- | -- | -- | -- | --\n", - "`pubs` | Iterable[EstimatorPubLike] | An iterable of PUB-like (primitive unified bloc) objects, such as tuples `(circuit, observables)` or `(circuit, observables, parameters, precision)`. See [Overview of PUBs](/docs/guides/primitive-input-output#overview-of-pubs) for more information. If a non-ISA circuit is passed, it will be transpiled with optimal settings. If an ISA circuit is passed, it will not be transpiled; in this case, the observable must be defined on the whole QPU. | Yes | N/A | (circuit, observables)\n", + "`pubs` | Iterable[EstimatorPubLike] | An iterable of PUB-like (primitive unified bloc) objects, such as tuples `(circuit, observables)` or `(circuit, observables, parameters, precision)`. See [Overview of PUBs](/docs/guides/pubs-broadcasting#pubs) for more information. If a non-ISA circuit is passed, it will be transpiled with optimal settings. If an ISA circuit is passed, it will not be transpiled; in this case, the observable must be defined on the whole QPU. | Yes | N/A | (circuit, observables)\n", "`backend_name` | str | Name of the backend to make the query.| No | If not provided, the least-busy backend will be used. | \"ibm_fez\"\n", "`options` | dict | Input options. See `Options` section for more details. | No | See `Options` section for more details.| \\{\"max_bond_dimension\": 100\\}\n", "\n", diff --git a/docs/guides/build-noise-models.ipynb b/docs/guides/build-noise-models.ipynb index fd603a8de53..0e655f04556 100644 --- a/docs/guides/build-noise-models.ipynb +++ b/docs/guides/build-noise-models.ipynb @@ -596,7 +596,7 @@ "source": [ "### Note on non-local qubit quantum error\n", "\n", - "`NoiseModel` does not support addition of non-local qubit quantum errors. They should be handled outside of `NoiseModel`. That suggests you should [write your own transpiler pass](./custom-transpiler-pass) (`TransformationPass`) and run the pass just before running the simulator if you need to insert your quantum errors into your circuit under your own conditions." + "`NoiseModel` does not support addition of non-local qubit quantum errors. They should be handled outside of `NoiseModel`. That suggests you should [write your own transpiler pass](/docs/guides/custom-transpiler-pass) (`TransformationPass`) and run the pass just before running the simulator if you need to insert your quantum errors into your circuit under your own conditions." ] }, { @@ -978,7 +978,7 @@ "## Next steps\n", "\n", "\n", - " - To simulate noisy circuits, see [Exact and noisy simulation with Qiskit Aer primitives](./simulate-with-qiskit-sdk-primitives).\n", + " - To simulate noisy circuits, see [Exact and noisy simulation with Qiskit Aer primitives](/docs/guides/simulate-with-qiskit-sdk-primitives).\n", " - Review the [Qiskit Aer noise module](https://qiskit.org/ecosystem/aer/apidocs/aer_noise.html) reference.\n", "" ] diff --git a/docs/guides/circuit-library.ipynb b/docs/guides/circuit-library.ipynb index 05bde9e8ae9..93715e78f85 100644 --- a/docs/guides/circuit-library.ipynb +++ b/docs/guides/circuit-library.ipynb @@ -492,7 +492,7 @@ "## Next steps\n", "\n", "\n", - " - Learn advanced methods for creating circuits in the [Construct circuits](./construct-circuits) topic.\n", + " - Learn advanced methods for creating circuits in the [Construct circuits](/docs/guides/construct-circuits) topic.\n", " - See an example of circuits being used in the [Grover's Algorithm](/docs/tutorials/grovers-algorithm) tutorial.\n", " - Review the [circuit library API](/docs/api/qiskit/circuit_library) reference.\n", "" diff --git a/docs/guides/cloud-setup-invited.mdx b/docs/guides/cloud-setup-invited.mdx index 5a43a944968..f16118ed201 100644 --- a/docs/guides/cloud-setup-invited.mdx +++ b/docs/guides/cloud-setup-invited.mdx @@ -12,7 +12,7 @@ If you do not have an invitation from an administrator to join an account that a You can run workloads on IBM® quantum processing units (QPUs) by setting up an account on IBM Cloud®. You will also need to [install and set up Qiskit and Qiskit Runtime](/docs/guides/install-qiskit#local). -Your user account is associated with one or more [instances](./instances), identified by _Cloud Resource Names_ (CRNs) that give access to IBM Quantum services. Additionally, a unique API token (also called a key) is assigned to each account, allowing for IBM Quantum access from Qiskit. For instructions to choose a specific instance, see [Connect to an instance](./instances#connect-instance). +Your user account is associated with one or more [instances](/docs/guides/instances), identified by _Cloud Resource Names_ (CRNs) that give access to IBM Quantum services. Additionally, a unique API token (also called a key) is assigned to each account, allowing for IBM Quantum access from Qiskit. For instructions to choose a specific instance, see [Connect to an instance](/docs/guides/instances#connect-instance). The [IBM Quantum Platform dashboard](https://quantum.cloud.ibm.com) and the [Instances page](https://quantum.cloud.ibm.com/instances) list the instances that you can access. diff --git a/docs/guides/compute-services.mdx b/docs/guides/compute-services.mdx index 4944db1b497..cebdf6aec9d 100644 --- a/docs/guides/compute-services.mdx +++ b/docs/guides/compute-services.mdx @@ -8,7 +8,7 @@ In addition to the open-source tools of the Qiskit SDK, Qiskit addons, and other ## Qiskit Runtime -Qiskit Runtime is the cloud-based service for executing quantum computations on IBM Quantum hardware. The `qiskit-ibm-runtime` package is a client for that service, and is the successor to the Qiskit IBM Provider. The Qiskit Runtime service streamlines quantum computations and provides optimal implementations of Qiskit primitives for IBM Quantum hardware. To get started with primitives, visit the [documentation](/docs/guides/get-started-with-primitives). +Qiskit Runtime is the cloud-based service for executing quantum computations on IBM Quantum hardware. The `qiskit-ibm-runtime` package is a client for that service, and is the successor to the Qiskit IBM Provider. The Qiskit Runtime service streamlines quantum computations and provides optimal implementations of Qiskit primitives for IBM Quantum hardware. To get started with primitives, visit the [documentation](/docs/guides/primitives). Qiskit Runtime is designed to use additional classical and quantum compute resources, including techniques such as error suppression and error mitigation, to return a higher-quality result from executing quantum circuits on quantum processors. Examples include dynamical decoupling for error suppression, and readout mitigation and zero-noise extrapolation (ZNE) for error mitigation. Learn how to configure these options on the [Configure error mitigation](/docs/guides/configure-error-mitigation) page. diff --git a/docs/guides/configure-error-mitigation.ipynb b/docs/guides/configure-error-mitigation.ipynb index 0a3a85cf724..0952743ada2 100644 --- a/docs/guides/configure-error-mitigation.ipynb +++ b/docs/guides/configure-error-mitigation.ipynb @@ -200,8 +200,8 @@ "You can turn on and off individual error mitigation and suppression methods, including dynamical decoupling, gate and measurement twirling, measurement error mitigation, PEC, and ZNE. See [Error mitigation and suppression techniques](error-mitigation-and-suppression-techniques) for an explanation of each.\n", "\n", "\n", - "- Not all options are available for both primitives. See the [available options table](runtime-options-overview#options-table) for the list of available options.\n", - "- Not all methods work together on all types of circuits. See the [feature compatibility table](runtime-options-overview#options-compatibility-table) for details.\n", + "- Not all options are available for all primitives. See each primitive's \"options\" page for its list of available options.\n", + "- Not all methods work together on all types of circuits. See the feature compatibility table for [Estimator](estimator-options#options-compatibility-table) or [Sampler](sampler-options#options-compatibility-table) for details.\n", "\n", "\n", "\n", @@ -246,15 +246,17 @@ "\n", "## Turn off all error mitigation\n", "\n", - "For instructions to turn off all error mitigation, see the [Turn off all error suppression and mitigation](specify-runtime-options#no-error-mitigation) section.\n", + "For instructions to turn off all error mitigation when using Estimator, see the [Turn off all error suppression and mitigation](estimator-options#no-error-mitigation) section in the Estimator options guide.\n", "\n", "## Next steps\n", "\n", "\n", " - Walk through an example that uses error mitigation in the [Cost function lesson](/learning/courses/variational-algorithm-design/cost-functions) in IBM Quantum Learning.\n", - " - Learn more about [error mitigation and error suppression techniques](error-mitigation-and-suppression-techniques).\n", - " - [Configure error suppression](configure-error-suppression).\n", - " - Explore other [options](runtime-options-overview).\n", + " - Learn more about [error mitigation and error suppression techniques.](error-mitigation-and-suppression-techniques)\n", + " - [Configure error suppression.](configure-error-suppression)\n", + " - Explore Sampler [options.](/docs/guides/sampler-options)\n", + " - Explore Estimator [options.](/docs/guides/estimator-options)\n", + " - Explore Executor [options.](/docs/guides/executor-options)\n", " - Decide what [execution mode](execution-modes) to run your job in.\n", "" ] diff --git a/docs/guides/configure-error-suppression.ipynb b/docs/guides/configure-error-suppression.ipynb index f7d1220e9ed..40c58fb17e4 100644 --- a/docs/guides/configure-error-suppression.ipynb +++ b/docs/guides/configure-error-suppression.ipynb @@ -62,7 +62,7 @@ "\n", "Primitives support a number of error suppression techniques, including [dynamical decoupling](/docs/api/qiskit-ibm-runtime/options-dynamical-decoupling-options#dynamicaldecouplingoptions) and [Pauli twirling](/docs/api/qiskit-ibm-runtime/options-twirling-options). See [Error mitigation and suppression techniques](error-mitigation-and-suppression-techniques) for an explanation of each. When using primitives, you can turn on or off individual methods. See the [Advanced error suppression options](#transpilation-table) section for details.\n", "\n", - "Estimator employs error suppression and mitigation by default. If you don't want any processing done to your input circuits, follow the instructions in the [Turn off all error mitigation and error suppression](specify-runtime-options#no-error-mitigation) section.\n", + "Estimator employs error suppression and mitigation by default. If you don't want any processing done to your input circuits, follow the instructions in the [Turn off all error mitigation and error suppression](estimator-options#no-error-mitigation) section.\n", "\n", "\n", "## Advanced error suppression options\n", @@ -70,8 +70,10 @@ "In the primitives, you can explicitly enable and disable individual error mitigation and suppression methods, such as dynamical decoupling.\n", "\n", "\n", - "- Not all options are available for both primitives. See the [available options](runtime-options-overview#options-table) table for the list of available options.\n", - "- Not all methods work together on all types of circuits. See the [feature compatibility](runtime-options-overview#options-compatibility-table) table for details.\n", + "- Not all options are available for both primitives. \n", + "- Not all methods work together on all types of circuits. \n", + "\n", + "See the [Estimator options](/docs/guides/estimator-options) or [Sampler options](/docs/guides/sampler-options) guide for full details.\n", "" ] }, @@ -115,20 +117,23 @@ "\n", "\n", "## Turn off all error suppression\n", "\n", - "For instructions to turn off all error suppression, see the [Turn off all error suppression and mitigation](specify-runtime-options#no-error-mitigation) section.\n", + "For instructions to turn off all error suppression, see the [Turn off all error suppression and mitigation](estimator-options#no-error-mitigation) section.\n", "\n", "## Next steps\n", "\n", "\n", - " - Learn more about [error mitigation and error suppression techniques](error-mitigation-and-suppression-techniques).\n", - " - [Configure error mitigation](configure-error-mitigation).\n", - " - Explore other [options](runtime-options-overview).\n", + " - Learn more about [error mitigation and error suppression techniques.](error-mitigation-and-suppression-techniques)\n", + " - [Configure error mitigation.](configure-error-mitigation)\n", + " - Explore other [options.](runtime-options-overview)\n", + " - Explore Sampler [options.](/docs/guides/sampler-options)\n", + " - Explore Estimator [options.](/docs/guides/estimator-options)\n", + " - Explore Executor [options.](/docs/guides/executor-options)\n", " - Decide what [execution mode](execution-modes) to run your job in.\n", "" ] diff --git a/docs/guides/considerations-set-up-runtime.mdx b/docs/guides/considerations-set-up-runtime.mdx index 42868ff3aa1..518b6ed80bf 100644 --- a/docs/guides/considerations-set-up-runtime.mdx +++ b/docs/guides/considerations-set-up-runtime.mdx @@ -101,9 +101,9 @@ The steps of this guide can be automated for consistent and repeatable managemen * See [Configure IBM Quantum Platform for an organization](/docs/guides/quickstart-steps-org) for the steps to set up IBM Quantum Platform. - * [Understand available plans](/docs/guides/plans-overview). - * [Create instances](/docs/guides/instances). - * [Understand the IBM Cloud structure](/docs/guides/cloud-account-structure). - * [Create policies and access groups](/docs/guides/access-groups). - * [Manage users](/docs/guides/invite-and-manage-users). + * [Understand available plans.](/docs/guides/plans-overview) + * [Create instances.](/docs/guides/instances) + * [Understand the IBM Cloud structure.](/docs/guides/cloud-account-structure) + * [Create policies and access groups.](/docs/guides/access-groups) + * [Manage users.](/docs/guides/invite-and-manage-users) diff --git a/docs/guides/construct-circuits.ipynb b/docs/guides/construct-circuits.ipynb index 62c1a2e2c12..dc25bbf4d30 100644 --- a/docs/guides/construct-circuits.ipynb +++ b/docs/guides/construct-circuits.ipynb @@ -190,7 +190,7 @@ "id": "17a82d8a-b717-44b8-b3f8-ce89e2588261", "metadata": {}, "source": [ - "The easiest way to view this information is through the [`draw`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#draw) method, which returns a visualization of a circuit. See [Visualize circuits](./visualize-circuits) for different ways of displaying quantum circuits." + "The easiest way to view this information is through the [`draw`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#draw) method, which returns a visualization of a circuit. See [Visualize circuits](/docs/guides/visualize-circuits) for different ways of displaying quantum circuits." ] }, { @@ -454,7 +454,7 @@ "Measurements are used to sample the states of individual qubits and transfer the results to a classical register. Note that if you are submitting circuits to a Sampler [primitive](/docs/guides/primitives), measurements are required. However, if circuits submitted to an Estimator primitive contain measurements, the measurements are ignored.\n", "\n", "\n", - "Qubits can be measured using three methods: [`measure`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#qiskit.circuit.QuantumCircuit.measure), [`measure_all`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#measure_all) and [`measure_active`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#measure_active). To learn how to visualize measured results, see the [Visualize results](./visualize-results) page.\n", + "Qubits can be measured using three methods: [`measure`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#qiskit.circuit.QuantumCircuit.measure), [`measure_all`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#measure_all) and [`measure_active`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#measure_active). To learn how to visualize measured results, see the [Visualize results](/docs/guides/visualize-results) page.\n", "\n", "1. `QuantumCircuit.measure` : measures each qubit in the first argument onto the classical bit given as the second argument. This method allows full control over where the measurement result is stored.\n", "\n", diff --git a/docs/guides/custom-transpiler-pass.ipynb b/docs/guides/custom-transpiler-pass.ipynb index 9219aa8091d..64083829654 100644 --- a/docs/guides/custom-transpiler-pass.ipynb +++ b/docs/guides/custom-transpiler-pass.ipynb @@ -103,7 +103,7 @@ "source": [ "## Transpiler passes\n", "\n", - "Transpiler passes are classified either as an [`AnalysisPass`](../api/qiskit/qiskit.transpiler.AnalysisPass) or a [`TransformationPass`](../api/qiskit/qiskit.transpiler.TransformationPass). Passes in general work with the [DAG](../api/qiskit/qiskit.dagcircuit.DAGCircuit) and the `property_set`, a dictionary-like object for storing properties determined by analysis passes. Analysis passes work with both the DAG and its `property_set`. They cannot modify the DAG, but can modify the `property_set`. This contrasts with transformation passes, which do modify the DAG, and can read (but not write to) `property_set`. For example, transformation passes translate a circuit to its [ISA](./transpile#instruction-set-architecture) or perform routing passes to insert SWAP gates where needed." + "Transpiler passes are classified either as an [`AnalysisPass`](../api/qiskit/qiskit.transpiler.AnalysisPass) or a [`TransformationPass`](../api/qiskit/qiskit.transpiler.TransformationPass). Passes in general work with the [DAG](../api/qiskit/qiskit.dagcircuit.DAGCircuit) and the `property_set`, a dictionary-like object for storing properties determined by analysis passes. Analysis passes work with both the DAG and its `property_set`. They cannot modify the DAG, but can modify the `property_set`. This contrasts with transformation passes, which do modify the DAG, and can read (but not write to) `property_set`. For example, transformation passes translate a circuit to its [ISA](/docs/guides/transpile#instruction-set-architecture) or perform routing passes to insert SWAP gates where needed." ] }, { diff --git a/docs/guides/debugging-tools.mdx b/docs/guides/debugging-tools.mdx index a6e422478b6..eae31c72e22 100644 --- a/docs/guides/debugging-tools.mdx +++ b/docs/guides/debugging-tools.mdx @@ -26,10 +26,10 @@ For general quantum circuits, the following tools are available to test and debu Several factors impact how much memory quantum simulation requires, so there are no exact hardware requirements for simulation, but there are some guidelines you can follow. -- The only requirement to run Qiskit is a functioning Python environment. For details, see the [Operating system support](./install-qiskit#operating-system-support) section. +- The only requirement to run Qiskit is a functioning Python environment. For details, see the [Operating system support](/docs/guides/install-qiskit#operating-system-support) section. - Because the requirements for simulating quantum circuits scale exponentially with the number of qubits, the available hardware limits the number of qubits that can be simulated. For example, a system with 4GB RAM can simulate approximately 27 qubits. - More or less available memory will not result in more or less accurate results (assuming results are returned), although more memory might return results faster or let you simulate more qubits. -- To get the most benefit out of your hardware, use local stabilizer (Clifford) circuit simulation when possible. See [Clifford simulation with Qiskit Runtime local testing mode](local-testing-mode#clifford-simulation) or [Efficient simulation of stabilizer circuits with Qiskit Aer primitives](./simulate-stabilizer-circuits) for examples. +- To get the most benefit out of your hardware, use local stabilizer (Clifford) circuit simulation when possible. See [Clifford simulation with Qiskit Runtime local testing mode](local-testing-mode#clifford-simulation) or [Efficient simulation of stabilizer circuits with Qiskit Aer primitives](/docs/guides/simulate-stabilizer-circuits) for examples. - You can increase your computing power by following these instructions to [run with multiple GPUs, nodes, or both](https://qiskit.github.io/qiskit-aer/howtos/running_gpu.html). ## Next steps diff --git a/docs/guides/defaults-and-configuration-options.ipynb b/docs/guides/defaults-and-configuration-options.ipynb index 9b098274fbd..c8ddaffc07e 100644 --- a/docs/guides/defaults-and-configuration-options.ipynb +++ b/docs/guides/defaults-and-configuration-options.ipynb @@ -274,9 +274,9 @@ "\n", " - Learn how to [Set the optimization level](set-optimization).\n", " - Review more [Commonly used parameters](common-parameters).\n", - " - Learn how to [Set the optimization level when using Qiskit Runtime](./runtime-options-overview).\n", - " - Visit the [Transpile with pass managers](transpile-with-pass-managers) topic.\n", - " - For examples, see [Representing quantum computers](/docs/guides/represent-quantum-computers).\n", + " - Learn how to [Set the optimization level when using Qiskit Runtime.](/docs/guides/runtime-options-overview)\n", + " - Visit the [Transpile with pass managers](/docs/guides/transpile-with-pass-managers) topic.\n", + " - For examples, see [Representing quantum computers.](/docs/guides/represent-quantum-computers)\n", " - Learn [how to transpile circuits](/docs/guides/circuit-transpilation-settings) as part of the Qiskit patterns workflow using Qiskit Runtime.\n", " - Review the [Transpile API documentation](/docs/api/qiskit/transpiler).\n", "" diff --git a/docs/guides/directed-execution-model.mdx b/docs/guides/directed-execution-model.mdx index d3310d7f54f..3204d47654a 100644 --- a/docs/guides/directed-execution-model.mdx +++ b/docs/guides/directed-execution-model.mdx @@ -1,5 +1,5 @@ --- -title: Directed execution model (beta) +title: Directed execution model description: Use this composable, explicit execution model with your utility-scale experiments to fine-tune error mitigation and other techniques. --- @@ -26,7 +26,7 @@ To apply error mitigation to a circuit under the framework, your workflow will t 3. Build the template circuit and samplex from the boxed circuit. -4. Run the template circuit and samplex with the [Executor](#executor-primitive) primitive, which will generate and execute the circuit variants as instructed. +4. Run the template circuit and samplex with the [Executor](#executor) primitive, which will generate and execute the circuit variants as instructed. 5. Post-process execution results. For example, you can apply post-selection, or extrapolate mitigated expectation values from the execution results. @@ -35,28 +35,25 @@ To apply error mitigation to a circuit under the framework, your workflow will t The following tools can be used together to implement an error mitigation technique in the directed execution model. + ### Samplomatic [Samplomatic](https://github.com/Qiskit/samplomatic/) is a new open-source library that supports customized sampling randomizations. It uses the [box](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#box) construct to reason about collections of circuit operations that should be treated as having a stable noise context, and uses annotations on boxes to allow you to declare and configure intents. For example, you can stratify your circuit into boxes, add a twirling annotation to each box, and specify which twirling group to use, as shown in the following figure: ![Example of using boxes and twirling annotations](/docs/images/guides/directed-execution-model/execution-model.avif) -A circuit with annotated boxes can then be used to generate a *template circuit* and a *samplex*. The output template circuit is a parameterized circuit that will be executed without further alteration (other than having different parameter values assigned to it). The samplex, which is the core type of the Samplomatic library, represents a parametric probability distribution over the parameters of the template circuit and other array-valued fields. These fields can be used to post-process data collected from executing the bound template circuit. In other words, the template circuit and samplex pair tells the Executor primitive (described below) exactly what parameters to generate and what bound circuits to run. Because these two constructs are created on the client side, you can do local inspection and sampling to verify the outputs prior to sending it for hardware execution. +A circuit with annotated boxes can then be used to generate a *template circuit* and a *samplex*. The output template circuit is a parameterized circuit that will be executed without further alteration (other than having different parameter values assigned to it). The samplex, which is the core type of the Samplomatic library, represents a parametric probability distribution over the parameters of the template circuit and other array-valued fields. These fields can be used to post-process data collected from executing the bound template circuit. In other words, the template circuit and samplex pair tells the [Executor primitive](#executor) exactly what parameters to generate and what bound circuits to run. Because these two constructs are created on the client side, you can do local inspection and sampling to verify the outputs prior to sending it for hardware execution. To simplify the process of generating annotated boxes, the Samplomatic library also provides transpiler passes that automatically group circuit instructions into annotated boxes, based on the strategies you provide. To learn more about Samplomatic, visit the [guides](https://qiskit.github.io/samplomatic/guides/index.html) and [API reference](https://qiskit.github.io/samplomatic/) documentation. Feel free to submit feedback and report bugs in its [GitHub](https://github.com/Qiskit/samplomatic) repository. + ### Executor primitive Executor is a new Qiskit Runtime primitive that takes the template circuit and samplex pair as the input, generates and binds parameter values according to the samplex, executes the bound circuits on the hardware, and returns the execution results and metadata. It follows the directives of the input pair and does not make any implicit decisions for you, so that the process is transparent yet performant. -To access `Executor`, install the `executor_preview` branch from `qiskit-ibm-runtime`: - -```bash -pip install -U git+https://github.com/Qiskit/qiskit-ibm-runtime.git@executor_preview -``` -The inputs and output of the Executor primitive are very different from those of Sampler and Estimator. Refer to the [Executor API reference](https://qiskit.github.io/qiskit-ibm-runtime/stubs/qiskit_ibm_runtime.Executor.html) for more information. In addition, the [Executor quickstart guide](https://qiskit.github.io/qiskit-ibm-runtime/guides/executor_basic.html) provides an overview and code examples. +The inputs and output of the Executor primitive are very different from those of Sampler and Estimator. Refer to [Get started with Executor](/docs/guides/get-started-with-executor) for more information. ### NoiseLearnerV3 diff --git a/docs/guides/error-mitigation-and-suppression-techniques.ipynb b/docs/guides/error-mitigation-and-suppression-techniques.ipynb index f27bb11bb9f..e200a8c834a 100644 --- a/docs/guides/error-mitigation-and-suppression-techniques.ipynb +++ b/docs/guides/error-mitigation-and-suppression-techniques.ipynb @@ -98,7 +98,7 @@ "\n", "Dynamical decoupling can be enabled by setting `enable` to `True` in the [dynamical decoupling options](/docs/api/qiskit-ibm-runtime/options-dynamical-decoupling-options). The `sequence_type` option can be used to pick from several different pulse sequences. The default sequence type is `\"XX\"`.\n", "\n", - "The following code cell shows how to enable dynamical decoupling for the Estimator and choose a dynamical decoupling sequence." + "The following code cell shows how to enable dynamical decoupling for Estimator and choose a dynamical decoupling sequence." ] }, { @@ -149,7 +149,7 @@ "- `num_randomizations`: The number of circuit instances to draw from the ensemble of twirled circuits.\n", "- `shots_per_randomization`: The number of shots to sample from each circuit instance.\n", "\n", - "The following code cell shows how to enable Pauli twirling and set these options for the estimator. None of these options are required to be set explicitly." + "The following code cell shows how to enable Pauli twirling and set these options for Estimator. None of these options are required to be set explicitly." ] }, { @@ -188,7 +188,7 @@ "\n", "TREX can be enabled by setting `measure_mitigation` to `True` in the [Qiskit Runtime resilience options](/docs/api/qiskit-ibm-runtime/options-resilience-options-v2) for Estimator. Options for measurement noise learning are described [here](/docs/api/qiskit-ibm-runtime/options-measure-noise-learning-options). As with gate twirling, you can set the number of circuit randomizations and the number of shots per randomization.\n", "\n", - "The following code cell shows how to enable TREX and set these options for the estimator. None of these options are required to be set explicitly." + "The following code cell shows how to enable TREX and set these options for Estimator. None of these options are required to be set explicitly." ] }, { @@ -237,7 +237,7 @@ "- `noise_factors`: The noise factors to use for noise amplification.\n", "- `extrapolator`: The functional form to use for the extrapolation.\n", "\n", - "The following code cell shows how to enable ZNE and set these options for the estimator. None of these options are required to be set explicitly." + "The following code cell shows how to enable ZNE and set these options for Estimator. None of these options are required to be set explicitly." ] }, { @@ -317,7 +317,7 @@ "PEC can be enabled by setting `pec_mitigation` to `True` in the [Qiskit Runtime resilience options](/docs/api/qiskit-ibm-runtime/options-resilience-options-v2) for Estimator.\n", "The Qiskit Runtime options for PEC are described [here](/docs/api/qiskit-ibm-runtime/options-pec-options). A limit on the sampling overhead can be set using the `max_overhead` option. Note that limiting the sampling overhead can cause the precision of the result to exceed the requested precision. The default value of `max_overhead` is 100.\n", "\n", - "The following code cell shows how to enable PEC and set the `max_overhead` option for the estimator." + "The following code cell shows how to enable PEC and set the `max_overhead` option for Estimator." ] }, { diff --git a/docs/guides/estimate-job-run-time.ipynb b/docs/guides/estimate-job-run-time.ipynb index 3975aadfca6..fcc7020db6c 100644 --- a/docs/guides/estimate-job-run-time.ipynb +++ b/docs/guides/estimate-job-run-time.ipynb @@ -87,7 +87,7 @@ "\n", " - Review these tips: [Minimize job run time](minimize-time).\n", " - Set the [Maximum execution time](max-execution-time).\n", - " - Learn how to transpile locally in the [Transpile](./transpile/) section.\n", + " - Learn how to transpile locally in the [Transpile](/docs/guides/transpile/) section.\n", " - Try the [Compare transpiler settings](/docs/guides/circuit-transpilation-settings) guide.\n", "" ] diff --git a/docs/guides/estimator-broadcasting.mdx b/docs/guides/estimator-broadcasting.mdx new file mode 100644 index 00000000000..afee7b8028d --- /dev/null +++ b/docs/guides/estimator-broadcasting.mdx @@ -0,0 +1,93 @@ +--- +title: Broadcasting +description: How Estimator handles array inputs and outputs using broadcasting semantics + +--- + +# Estimator broadcasting semantics +When invoking an Estimator primitive's [`run()`](/docs/api/qiskit-ibm-runtime/estimator-v2#run) method, the main argument that is required is a tuple called a [PUB.](/docs/guides/pubs-broadcasting#pubs) The data provided to these tuples can be arranged in a variety of shapes to provide flexibility in a workload through [broadcasting.](/docs/guides/pubs-broadcasting#broadcasting) This guide explains how Estimator handles array inputs and outputs using broadcasting semantics. + +Following are some examples of common patterns expressed in terms of array broadcasting. Their accompanying visual representation is shown in the figure that follows: + + +Parameter value sets are represented by `n x m` arrays, and observable arrays are represented by one or more single-column arrays. For each example in the previous code, the parameter value sets are combined with their observable array to create the resulting expectation value estimates. + +- *Example 1*: (broadcast single observable) has a parameter value set that is a 5x1 array and a 1x1 observables array. The one item in the observables array is combined with each item in the parameter value set to create a single 5x1 array where each item is a combination of the original item in the parameter value set with the item in the observables array. + +- *Example 2*: (zip) has a 5x1 parameter value set and a 5x1 observables array. The output is a 5x1 array where each item is a combination of the $n^{th}$ item in the parameter value set with the $n^{th}$ item in the observables array. + +- *Example 3*: (outer/product) has a 1x6 parameter value set and a 4x1 observables array. Their combination results in a 4x6 array that is created by combining each item in the parameter value set with *every* item in the observables array, and thus each parameter value becomes an entire column in the output. + +- *Example 4*: (Standard `nd` generalization) has a 3x6 parameter value set array and two 3x1 observables array. These combine to create two 3x6 output arrays in a similar manner to the previous example. + +![This image illustrates several visual representations of array broadcasting](/docs/images/guides/pubs-broadcasting/broadcasting.avif "Visual representation of broadcasting") + +```python +# Broadcast single observable +parameter_values = np.random.uniform(size=(5,)) # shape (5,) +observables = SparsePauliOp("ZZZ") # shape () +# >> pub result has shape (5,) + +# Zip +parameter_values = np.random.uniform(size=(5,)) # shape (5,) +observables = [ + SparsePauliOp(pauli) for pauli in ["III", "XXX", "YYY", "ZZZ", "XYZ"] +] # shape (5,) +# >> pub result has shape (5,) + +# Outer/Product +parameter_values = np.random.uniform(size=(1, 6)) # shape (1, 6) +observables = [ + [SparsePauliOp(pauli)] for pauli in ["III", "XXX", "YYY", "ZZZ"] +] # shape (4, 1) +# >> pub result has shape (4, 6) + +# Standard `nd` generalization +parameter_values = np.random.uniform(size=(3, 6)) # shape (3, 6) +observables = [ + [ + [SparsePauliOp(["XII"])], + [SparsePauliOp(["IXI"])], + [SparsePauliOp(["IIX"])], + ], + [ + [SparsePauliOp(["ZII"])], + [SparsePauliOp(["IZI"])], + [SparsePauliOp(["IIZ"])], + ], +] # shape (2, 3, 1) +# >> pub result has shape (2, 3, 6) +``` + + +Each `SparsePauliOp` counts as a single element in this context, regardless of the number of Paulis contained in the `SparsePauliOp`. Thus, for the purpose of these broadcasting rules, all of the following elements have the same shape: + +```python +# shape () +a = SparsePauliOp("Z") + +# shape () +b = SparsePauliOp("IIIIZXYIZ") + +# shape () +c = SparsePauliOp.from_list(["XX", "XY", "IZ"]) +``` + +The following lists of operators, while equivalent in terms of information contained, have different shapes: + +```python +# shape () +list1 = SparsePauliOp.from_list(["XX", "XY", "IZ"]) + +# shape (3, ) +list2 = [SparsePauliOp("XX"), SparsePauliOp("XY"), SparsePauliOp("IZ")] +``` + + +## Next steps + + + - See the [broadcasting guide](/docs/guides/pubs-broadcasting#broadcasting) for an overview of broadcasting. + - Learn about [PUBs.](/docs/guides/pubs-broadcasting#pubs) + - Understand [Estimator inputs and outputs.](/docs/guides/estimator-input-output) + diff --git a/docs/guides/estimator-examples.ipynb b/docs/guides/estimator-examples.ipynb new file mode 100644 index 00000000000..73e2a19967b --- /dev/null +++ b/docs/guides/estimator-examples.ipynb @@ -0,0 +1,415 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1f4a2ec4-3595-4300-8f9e-092b0ef9b444", + "metadata": {}, + "source": [ + "---\n", + "title: Examples\n", + "description: Practical examples of using the Estimator primitive in Qiskit Runtime.\n", + "---\n", + "\n", + "\n", + "# Estimator examples" + ] + }, + { + "cell_type": "markdown", + "id": "b4121e48", + "metadata": { + "tags": [ + "version-info" + ] + }, + "source": [ + "{/*\n", + " DO NOT EDIT THIS CELL!!!\n", + " This cell's content is generated automatically by a script. Anything you add\n", + " here will be removed next time the notebook is run. To add new content, create\n", + " a new cell before or after this one.\n", + "*/}\n", + "\n", + "
\n", + "Package versions\n", + "\n", + "The code on this page was developed using the following requirements.\n", + "We recommend using these versions or newer.\n", + "\n", + "```\n", + "qiskit[all]~=2.3.0\n", + "qiskit-ibm-runtime~=0.43.1\n", + "```\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "bae32e60", + "metadata": {}, + "source": [ + "The examples in this section illustrate some common ways to use Estimator. Before running these examples, follow the instructions in [Install Qiskit.](install-qiskit)\n", + "\n", + "\n", + " These examples all use the primitives from Qiskit Runtime, but you could use the base primitives instead.\n", + "\n", + "\n", + "Efficiently calculate and interpret expectation values of the quantum operators required for many algorithms with Estimator. Explore uses in molecular modeling, machine learning, and complex optimization problems.\n", + "\n", + "## Run a single experiment\n", + "\n", + "Use Estimator to determine the expectation value of a single circuit-observable pair." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "24573866-7cf2-40e1-b61c-a2bdcecb759b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " > Expectation value: -0.13582342954159593\n", + " > Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import iqp\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "from qiskit.quantum_info import SparsePauliOp, random_hermitian\n", + "from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator\n", + "\n", + "n_qubits = 50\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=n_qubits\n", + ")\n", + "\n", + "mat = np.real(random_hermitian(n_qubits, seed=1234))\n", + "circuit = iqp(mat)\n", + "observable = SparsePauliOp(\"Z\" * 50)\n", + "\n", + "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", + "isa_circuit = pm.run(circuit)\n", + "isa_observable = observable.apply_layout(isa_circuit.layout)\n", + "\n", + "estimator = Estimator(mode=backend)\n", + "job = estimator.run([(isa_circuit, isa_observable)])\n", + "result = job.result()\n", + "\n", + "print(f\" > Expectation value: {result[0].data.evs}\")\n", + "print(f\" > Metadata: {result[0].metadata}\")" + ] + }, + { + "cell_type": "markdown", + "id": "63769604-ec9e-4ff3-823d-e60f4eb8a877", + "metadata": {}, + "source": [ + "## Run multiple experiments in a single job\n", + "\n", + "Use Estimator to determine the expectation values of multiple circuit-observable pairs." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "bf4668bd-aaaf-4b23-af4b-4df767bd6d1a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ">>> Expectation values for PUB 0: 0.4873096446700508\n", + ">>> Standard errors for PUB 0: 1.3528950031716114\n", + ">>> Expectation values for PUB 1: -0.00390625\n", + ">>> Standard errors for PUB 1: 0.015347884419435263\n", + ">>> Expectation values for PUB 2: -0.02001953125\n", + ">>> Standard errors for PUB 2: 0.013797455737635134\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import iqp\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "from qiskit.quantum_info import SparsePauliOp, random_hermitian\n", + "from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator\n", + "\n", + "n_qubits = 50\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=n_qubits\n", + ")\n", + "\n", + "rng = np.random.default_rng()\n", + "mats = [np.real(random_hermitian(n_qubits, seed=rng)) for _ in range(3)]\n", + "\n", + "pubs = []\n", + "circuits = [iqp(mat) for mat in mats]\n", + "observables = [\n", + " SparsePauliOp(\"X\" * 50),\n", + " SparsePauliOp(\"Y\" * 50),\n", + " SparsePauliOp(\"Z\" * 50),\n", + "]\n", + "\n", + "# Get ISA circuits\n", + "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n", + "\n", + "for qc, obs in zip(circuits, observables):\n", + " isa_circuit = pm.run(qc)\n", + " isa_obs = obs.apply_layout(isa_circuit.layout)\n", + " pubs.append((isa_circuit, isa_obs))\n", + "\n", + "estimator = Estimator(backend)\n", + "job = estimator.run(pubs)\n", + "job_result = job.result()\n", + "\n", + "for idx in range(len(pubs)):\n", + " pub_result = job_result[idx]\n", + " print(f\">>> Expectation values for PUB {idx}: {pub_result.data.evs}\")\n", + " print(f\">>> Standard errors for PUB {idx}: {pub_result.data.stds}\")" + ] + }, + { + "cell_type": "markdown", + "id": "60bf051a-40f8-47a9-b74d-38713bc15210", + "metadata": {}, + "source": [ + "## Run parameterized circuits\n", + "\n", + "Use Estimator to run three experiments in a single job, leveraging parameter values to increase circuit reusability." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "67dc98b8-499c-44d9-ada1-6abc9d6198c0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ">>> Expectation values: [[ 1.0455093 0.98152862 0.82113463 0.60354133 0.29572641 0.01149883\n", + " -0.33110743 -0.60560522 -0.83322315 -0.96531231 -1.0257549 -0.95853095\n", + " -0.81081517 -0.61091237 -0.30221293 0.0035381 0.31371176 0.61061753\n", + " 0.83646641 0.97091431 1.03135689]\n", + " [ 0.03390682 0.31194271 0.620937 0.87391133 0.96973494 1.03872794\n", + " 0.94260949 0.82378821 0.56344283 0.28688115 -0.04570049 -0.37474403\n", + " -0.64540887 -0.87803912 -0.97887504 -1.03577952 -0.97268336 -0.83970967\n", + " -0.59705481 -0.29867482 0.0380346 ]\n", + " [ 0.00265358 -0.32992806 -0.59646512 -0.80934096 -0.96737621 -1.00128302\n", + " -0.94673728 -0.82703147 -0.59705481 -0.31341692 -0.00117937 0.29985419\n", + " 0.59469607 0.78486908 0.93346939 0.97622146 0.94732696 0.81199454\n", + " 0.60914332 0.28393273 -0.00678136]\n", + " [ 0.99656555 0.93553328 0.78398456 0.55872536 0.29749546 -0.04511081\n", + " -0.33523522 -0.62889773 -0.82201916 -0.95351864 -1.02634458 -0.96796589\n", + " -0.82054495 -0.57553135 -0.30103356 0.00265358 0.3104685 0.59705481\n", + " 0.83322315 0.94437854 0.99214292]]\n", + ">>> Standard errors: [[0.014353 0.01441151 0.01620648 0.0195418 0.019762 0.01515649\n", + " 0.02102523 0.02112359 0.0148494 0.01119219 0.01576623 0.01245824\n", + " 0.01239832 0.01501273 0.01821305 0.01776286 0.01500156 0.01635231\n", + " 0.01577367 0.01315371 0.01089558]\n", + " [0.01352805 0.01627835 0.01247646 0.01287866 0.01570182 0.01060924\n", + " 0.01590468 0.01620303 0.01530626 0.01619973 0.01918078 0.01379676\n", + " 0.01564971 0.01377673 0.01454324 0.01242184 0.01252201 0.01396738\n", + " 0.01326188 0.0145736 0.01795044]\n", + " [0.02029376 0.01610892 0.0161542 0.0157785 0.01385665 0.01113743\n", + " 0.01375237 0.01380922 0.0145974 0.01759484 0.01594193 0.02111719\n", + " 0.01521368 0.01365888 0.01188512 0.01353009 0.01195674 0.01446547\n", + " 0.01660987 0.01511225 0.01880871]\n", + " [0.01105161 0.01164476 0.01329858 0.01439545 0.01888747 0.01629201\n", + " 0.01405852 0.01406643 0.01088709 0.01275198 0.01281432 0.01333301\n", + " 0.01268483 0.01443594 0.01495655 0.01715532 0.01822699 0.01508936\n", + " 0.01435528 0.01340555 0.01295649]]\n", + ">>> Metadata: {'shots': 10016, 'target_precision': 0.01, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "from qiskit.circuit import QuantumCircuit, Parameter\n", + "from qiskit.quantum_info import SparsePauliOp\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "# Step 1: Map classical inputs to a quantum problem\n", + "theta = Parameter(\"θ\")\n", + "\n", + "chsh_circuit = QuantumCircuit(2)\n", + "chsh_circuit.h(0)\n", + "chsh_circuit.cx(0, 1)\n", + "chsh_circuit.ry(theta, 0)\n", + "\n", + "number_of_phases = 21\n", + "phases = np.linspace(0, 2 * np.pi, number_of_phases)\n", + "individual_phases = [[ph] for ph in phases]\n", + "\n", + "ZZ = SparsePauliOp.from_list([(\"ZZ\", 1)])\n", + "ZX = SparsePauliOp.from_list([(\"ZX\", 1)])\n", + "XZ = SparsePauliOp.from_list([(\"XZ\", 1)])\n", + "XX = SparsePauliOp.from_list([(\"XX\", 1)])\n", + "ops = [ZZ, ZX, XZ, XX]\n", + "\n", + "# Step 2: Optimize problem for quantum execution.\n", + "\n", + "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", + "chsh_isa_circuit = pm.run(chsh_circuit)\n", + "isa_observables = [\n", + " operator.apply_layout(chsh_isa_circuit.layout) for operator in ops\n", + "]\n", + "\n", + "# Step 3: Execute using Qiskit primitives.\n", + "\n", + "# Reshape observable array for broadcasting\n", + "reshaped_ops = np.fromiter(isa_observables, dtype=object)\n", + "reshaped_ops = reshaped_ops.reshape((4, 1))\n", + "\n", + "estimator = Estimator(backend, options={\"default_shots\": int(1e4)})\n", + "job = estimator.run([(chsh_isa_circuit, reshaped_ops, individual_phases)])\n", + "# Get results for the first (and only) PUB\n", + "pub_result = job.result()[0]\n", + "print(f\">>> Expectation values: {pub_result.data.evs}\")\n", + "print(f\">>> Standard errors: {pub_result.data.stds}\")\n", + "print(f\">>> Metadata: {pub_result.metadata}\")" + ] + }, + { + "cell_type": "markdown", + "id": "793f0ed1-5682-4aa3-a4a0-7baba71650f9", + "metadata": {}, + "source": [ + "## Use sessions and advanced options\n", + "\n", + "Explore sessions and advanced options to optimize circuit performance on QPUs.\n", + "\n", + "\n", + "\n", + "The following code block will return an error for Open Plan users because it uses sessions. Open Plan workloads can run only in [job mode](/docs/guides/execution-modes#job-mode) or [batch mode](/docs/guides/execution-modes#batch-mode).\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "d007b547-8546-4ca3-aee6-9a4e3a82598d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " > Expectation value: 0.08045977011494253\n", + " > Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n", + " > Another Expectation value: 0.02127659574468085\n", + " > More Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import iqp\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "from qiskit.quantum_info import SparsePauliOp, random_hermitian\n", + "from qiskit_ibm_runtime import (\n", + " QiskitRuntimeService,\n", + " Session,\n", + " EstimatorV2 as Estimator,\n", + ")\n", + "\n", + "n_qubits = 50\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=n_qubits\n", + ")\n", + "\n", + "rng = np.random.default_rng(1234)\n", + "mat = np.real(random_hermitian(n_qubits, seed=rng))\n", + "circuit = iqp(mat)\n", + "mat = np.real(random_hermitian(n_qubits, seed=rng))\n", + "another_circuit = iqp(mat)\n", + "observable = SparsePauliOp(\"X\" * 50)\n", + "another_observable = SparsePauliOp(\"Y\" * 50)\n", + "\n", + "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n", + "isa_circuit = pm.run(circuit)\n", + "another_isa_circuit = pm.run(another_circuit)\n", + "isa_observable = observable.apply_layout(isa_circuit.layout)\n", + "another_isa_observable = another_observable.apply_layout(\n", + " another_isa_circuit.layout\n", + ")\n", + "\n", + "with Session(backend=backend) as session:\n", + " estimator = Estimator(mode=session)\n", + "\n", + " estimator.options.resilience_level = 1\n", + "\n", + " job = estimator.run([(isa_circuit, isa_observable)])\n", + " another_job = estimator.run(\n", + " [(another_isa_circuit, another_isa_observable)]\n", + " )\n", + " result = job.result()\n", + " another_result = another_job.result()\n", + "\n", + " # first job\n", + " print(f\" > Expectation value: {result[0].data.evs}\")\n", + " print(f\" > Metadata: {result[0].metadata}\")\n", + "\n", + " # second job\n", + " print(f\" > Another Expectation value: {another_result[0].data.evs}\")\n", + " print(f\" > More Metadata: {another_result[0].metadata}\")" + ] + }, + { + "cell_type": "markdown", + "id": "551e1894-a12a-4f6c-8347-020fdc9db74e", + "metadata": {}, + "source": [ + "## Next steps\n", + "\n", + "\n", + " - [Specify advanced runtime options.](runtime-options-overview)\n", + " - Practice with primitives by working through the [Cost function lesson](/learning/courses/variational-algorithm-design/cost-functions) in IBM Quantum® Learning.\n", + " - Learn how to transpile locally in the [Transpile](/docs/guides/transpile/) section.\n", + " - Try the [Compare transpiler settings](/docs/guides/circuit-transpilation-settings) guide.\n", + " - Read [Migrate to V2 primitives](/docs/guides/v2-primitives).\n", + " - Understand the [Job limits](/docs/guides/job-limits) when sending a job to an IBM® QPU.\n", + "" + ] + } + ], + "metadata": { + "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" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/guides/estimator-input-output.ipynb b/docs/guides/estimator-input-output.ipynb new file mode 100644 index 00000000000..01796ddbbc3 --- /dev/null +++ b/docs/guides/estimator-input-output.ipynb @@ -0,0 +1,387 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "dbb193c8-d927-434c-a199-48de57c99694", + "metadata": {}, + "source": [ + "---\n", + "title: Inputs and outputs\n", + "description: Understand the input and output format of the Estimator primitive\n", + "---\n", + "\n", + "\n", + "# Estimator inputs and outputs" + ] + }, + { + "cell_type": "markdown", + "id": "13bdfd0b-b5df-4dc8-9de5-f4ee382bc1d4", + "metadata": { + "tags": [ + "version-info" + ] + }, + "source": [ + "{/*\n", + " DO NOT EDIT THIS CELL!!!\n", + " This cell's content is generated automatically by a script. Anything you add\n", + " here will be removed next time the notebook is run. To add new content, create\n", + " a new cell before or after this one.\n", + "*/}\n", + "\n", + "
\n", + "Package versions\n", + "\n", + "The code on this page was developed using the following requirements.\n", + "We recommend using these versions or newer.\n", + "\n", + "```\n", + "qiskit[all]~=2.3.0\n", + "qiskit-ibm-runtime~=0.43.1\n", + "```\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "6962c44c-da86-45ac-a70f-bd4ceb2c262b", + "metadata": {}, + "source": [ + "This page gives an overview of the inputs and outputs of the Estimator primitive, which executes workloads on IBM Quantum® compute resources. Estimator lets you efficiently define vectorized workloads by using a data structure known as a [**Primitive Unified Bloc (PUB)**.](/docs/guides/pubs-broadcasting#pubs) They are used as inputs to the [`run()`](/docs/api/qiskit-ibm-runtime/estimator-v2#run) method for the Estimator primitive, which executes the defined workload as a job. Then, after the job has completed, the results are returned in a format that is dependent on both the PUBs used as well as the runtime options specified from the primitive." + ] + }, + { + "cell_type": "markdown", + "id": "9c77dcb7-6210-4883-99b6-c19c46a83efc", + "metadata": {}, + "source": [ + "## Inputs\n", + "\n", + "For the Estimator primitive, a PUB can contain at most four values:\n", + "- A single `QuantumCircuit`, which may contain one or more [`Parameter`](/docs/api/qiskit/qiskit.circuit.Parameter) objects\n", + "- A list of one or more observables, which specify the expectation values to estimate, arranged into an array (for example, a single observable represented as a 0-d array, a list of observables as a 1-d array, and so on). The data can be in any one of the `ObservablesArrayLike` format such as `Pauli`, `SparsePauliOp`, `PauliList`, or `str`.\n", + " \n", + " If you have two commuting observables in different PUBs but with the same circuit, they will not be estimated using the same measurement. Each PUB represents a different basis for measurement, and therefore, separate measurements are required for each PUB. To ensure that commuting observables are estimated using the same measurement, they must be grouped within the same PUB.\n", + " \n", + "- A collection of parameter values to bind the circuit against. This can be specified as a single array-like object where the last index is over circuit `Parameter` objects, or omitted (or equivalently, set to `None`) if the circuit has no `Parameter` objects.\n", + "- (Optionally) a target precision for expectation values to estimate" + ] + }, + { + "cell_type": "markdown", + "id": "0874f9bd-1ce1-44fe-9a8c-3abcc6bed806", + "metadata": {}, + "source": [ + "---\n", + "\n", + "The following code demonstrates an example set of vectorized inputs to the `Estimator` primitive and executes them on an IBM® backend as a single `RuntimeJobV2 ` object." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0fbd9fbd-be9c-4986-aac6-ba9f3b8ec3fd", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit.circuit import (\n", + " Parameter,\n", + " QuantumCircuit,\n", + ")\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "from qiskit.quantum_info import SparsePauliOp\n", + "\n", + "from qiskit_ibm_runtime import (\n", + " QiskitRuntimeService,\n", + " EstimatorV2 as Estimator,\n", + ")\n", + "\n", + "import numpy as np\n", + "\n", + "# Instantiate runtime service and get\n", + "# the least busy backend\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "# Define a circuit with two parameters.\n", + "circuit = QuantumCircuit(2)\n", + "circuit.h(0)\n", + "circuit.cx(0, 1)\n", + "circuit.ry(Parameter(\"a\"), 0)\n", + "circuit.rz(Parameter(\"b\"), 0)\n", + "circuit.cx(0, 1)\n", + "circuit.h(0)\n", + "\n", + "# Transpile the circuit\n", + "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n", + "transpiled_circuit = pm.run(circuit)\n", + "layout = transpiled_circuit.layout\n", + "\n", + "# Now define a sweep over parameter values, the last axis of dimension 2 is\n", + "# for the two parameters \"a\" and \"b\"\n", + "params = np.vstack(\n", + " [\n", + " np.linspace(-np.pi, np.pi, 100),\n", + " np.linspace(-4 * np.pi, 4 * np.pi, 100),\n", + " ]\n", + ").T\n", + "\n", + "# Define three observables. The inner length-1 lists cause this array of\n", + "# observables to have shape (3, 1), rather than shape (3,) if they were\n", + "# omitted.\n", + "observables = [\n", + " [SparsePauliOp([\"XX\", \"IY\"], [0.5, 0.5])],\n", + " [SparsePauliOp(\"XX\")],\n", + " [SparsePauliOp(\"IY\")],\n", + "]\n", + "# Apply the same layout as the transpiled circuit.\n", + "observables = [\n", + " [observable.apply_layout(layout) for observable in observable_set]\n", + " for observable_set in observables\n", + "]\n", + "\n", + "# Estimate the expectation value for all 300 combinations of observables\n", + "# and parameter values, where the pub result will have shape (3, 100).\n", + "#\n", + "# This shape is due to our array of parameter bindings having shape\n", + "# (100, 2), combined with our array of observables having shape (3, 1).\n", + "estimator_pub = (transpiled_circuit, observables, params)\n", + "\n", + "# Instantiate the new Estimator object, then run the transpiled circuit\n", + "# using the set of parameters and observables.\n", + "estimator = Estimator(mode=backend)\n", + "job = estimator.run([estimator_pub])\n", + "result = job.result()" + ] + }, + { + "cell_type": "markdown", + "id": "7a17dce0-1383-49c6-b9e4-46bf9a887fa6", + "metadata": {}, + "source": [ + "## Output\n", + "\n", + "Once one or more PUBs are sent to a QPU for execution and a job successfully completes, the data is returned as a [`PrimitiveResult`](/docs/api/qiskit/qiskit.primitives.PrimitiveResult) container object accessed by calling the `RuntimeJobV2.result()` method. The `PrimitiveResult` contains an iterable list of [`PubResult`](/docs/api/qiskit/qiskit.primitives.PubResult) objects that contain the execution results for each PUB. Depending on the primitive used, these data will be expectation values and their error bars.\n", + "\n", + "Each element of this list corresponds to each PUB submitted to the primitive's `run()` method (for example, a job submitted with 20 PUBs will return a `PrimitiveResult` object that contains a list of 20 `PubResults`, one corresponding to each PUB).\n", + "\n", + "Each of these `PubResult` objects possess both a `data` and a `metadata` attribute. The `data` attribute is a customized [`DataBin`](/docs/api/qiskit/qiskit.primitives.DataBin) that contains the actual measurement values, standard deviations, and so forth. This `DataBin` has various attributes depending on the shape or structure of the associated PUB as well as the error mitigation options specified by the primitive used to submit the job (for example, [ZNE](/docs/guides/error-mitigation-and-suppression-techniques#zero-noise-extrapolation-zne) or [PEC](/docs/guides/error-mitigation-and-suppression-techniques#probabilistic-error-cancellation-pec)). Meanwhile, the `metadata` attribute contains information about the runtime and error mitigation options used (explained later in the [Result metadata](#result-metadata) section of this page).\n", + "\n", + "The following is a visual outline of the `PrimitiveResult` data structure for the Estimator output:\n", + "\n", + " ```\n", + " └── PrimitiveResult\n", + " ├── PubResult[0]\n", + " │ ├── metadata\n", + " │ └── data ## In the form of a DataBin object\n", + " │ ├── evs\n", + " │ │ └── List of estimated expectation values in the shape\n", + " | | specified by the first pub\n", + " │ └── stds\n", + " │ └── List of calculated standard deviations in the\n", + " | same shape as above\n", + " ├── PubResult[1]\n", + " | ├── metadata\n", + " | └── data ## In the form of a DataBin object\n", + " | ├── evs\n", + " | │ └── List of estimated expectation values in the shape\n", + " | | specified by the second pub\n", + " | └── stds\n", + " | └── List of calculated standard deviations in the\n", + " | same shape as above\n", + " ├── ...\n", + " ├── ...\n", + " └── ...\n", + " ```\n", + "\n", + "Put simply, a single job returns a `PrimitiveResult` object and contains a list of one or more `PubResult` objects. These `PubResult` objects then store the measurement data for each PUB that was submitted to the job.\n", + "\n", + "\n", + "Each `PubResult` for the Estimator primitive contains at least an array of expectation values (`PubResult.data.evs`) and associated standard deviations (either `PubResult.data.stds` or `PubResult.data.ensemble_standard_error` depending on the `resilience_level` used), but can contain more data depending on the error mitigation options that were specified.\n", + "\n", + "The below code snippet describes the `PrimitiveResult` (and associated `PubResult`) format for the job created above." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "960a78c7-3602-4c69-bdfa-18fd8ba993b6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The result of the submitted job had 1 PUB and has a value:\n", + " PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(), stds=np.ndarray(), ensemble_standard_error=np.ndarray(), shape=(3, 100)), 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})\n", + "\n", + "The associated PubResult of this job has the following data bins:\n", + " DataBin(evs=np.ndarray(), stds=np.ndarray(), ensemble_standard_error=np.ndarray(), shape=(3, 100))\n", + "\n", + "And this DataBin has attributes: dict_keys(['evs', 'stds', 'ensemble_standard_error'])\n", + "Recall that this shape is due to our array of parameter binding sets having shape (100, 2) -- where 2 is the\n", + " number of parameters in the circuit -- combined with our array of observables having shape (3, 1). \n", + "\n", + "The expectation values measured from this PUB are: \n", + "[[ 0.00948597 0.12163221 0.29100944 0.40535344 0.46625814 0.54716103\n", + " 0.57690846 0.59809047 0.5784682 0.50924868 0.4579837 0.40035644\n", + " 0.37174056 0.32887613 0.25850853 0.26396412 0.25852429 0.26074166\n", + " 0.29282485 0.34388535 0.37368314 0.43562138 0.46912323 0.51955146\n", + " 0.54430185 0.55467261 0.5162183 0.52744696 0.47261781 0.42613541\n", + " 0.35400013 0.33217125 0.29600426 0.27561903 0.25307754 0.25672088\n", + " 0.28783701 0.36612701 0.40433263 0.44428286 0.51028376 0.55034507\n", + " 0.55979913 0.57160124 0.54127534 0.49753533 0.42942659 0.32552331\n", + " 0.20215918 0.04303087 -0.08115732 -0.18473659 -0.34015892 -0.44489319\n", + " -0.49112115 -0.54588034 -0.60601287 -0.55869218 -0.53353861 -0.51628053\n", + " -0.44978534 -0.38090252 -0.32481576 -0.28832245 -0.27057547 -0.26542929\n", + " -0.27054473 -0.29367389 -0.31531828 -0.38462352 -0.40276794 -0.47168997\n", + " -0.48548191 -0.5382924 -0.52716406 -0.53277032 -0.50776933 -0.48512907\n", + " -0.44335198 -0.38756463 -0.34438156 -0.29199194 -0.2729216 -0.24602918\n", + " -0.23527174 -0.3019153 -0.35159518 -0.38303379 -0.42434541 -0.47743033\n", + " -0.54652609 -0.5877912 -0.59175701 -0.57386895 -0.56416812 -0.48022381\n", + " -0.3853372 -0.2639702 -0.12030502 0.02081148]\n", + " [ 0.00581765 0.0552677 0.15998546 0.20725389 0.25452232 0.34178711\n", + " 0.39196437 0.47050268 0.50031815 0.527952 0.57231161 0.64066903\n", + " 0.72429779 0.77011181 0.78174711 0.86610308 0.88646487 0.91337151\n", + " 0.94245978 0.98100173 0.97372966 1.00936279 1.01881647 1.0544496\n", + " 1.01954368 1.03699664 0.99845469 1.03845105 1.00936279 1.00354513\n", + " 0.95409508 0.95264067 0.91264431 0.91846196 0.8355604 0.80283611\n", + " 0.77956549 0.74102354 0.69520953 0.64575948 0.58976457 0.53231524\n", + " 0.43996 0.3956004 0.32069812 0.27706572 0.22470684 0.16653032\n", + " 0.07272066 -0.00218162 -0.05817653 -0.06253977 -0.15853104 -0.25015908\n", + " -0.28506499 -0.34251432 -0.44359604 -0.44432324 -0.53158804 -0.60285429\n", + " -0.637033 -0.67630215 -0.71266249 -0.76793019 -0.81519862 -0.86464867\n", + " -0.90173621 -0.93155168 -0.9337333 -0.98245614 -0.99627307 -1.01518044\n", + " -1.01590764 -1.04863194 -1.00499955 -1.02827016 -1.01663485 -1.0108172\n", + " -1.02317971 -0.97518407 -0.96500318 -0.94682302 -0.901009 -0.87846559\n", + " -0.79556404 -0.84937733 -0.78101991 -0.73811472 -0.65521316 -0.57667485\n", + " -0.59921825 -0.49813653 -0.44577766 -0.36505772 -0.33524225 -0.25888556\n", + " -0.21161713 -0.12289792 -0.03781474 0.00654486]\n", + " [ 0.01315429 0.18799671 0.42203343 0.603453 0.67799397 0.75253494\n", + " 0.76185256 0.72567827 0.65661825 0.49054535 0.3436558 0.16004385\n", + " 0.01918334 -0.11235955 -0.26473006 -0.33817484 -0.36941628 -0.39188819\n", + " -0.35681008 -0.29323102 -0.22636339 -0.13812003 -0.08057002 -0.01534667\n", + " 0.06906002 0.07234859 0.03398191 0.01644286 -0.06412716 -0.15127432\n", + " -0.24609482 -0.28829816 -0.32063579 -0.3672239 -0.32940532 -0.28939435\n", + " -0.20389148 -0.00876953 0.11345574 0.24280625 0.43080296 0.5683749\n", + " 0.67963826 0.74760208 0.76185256 0.71800493 0.63414634 0.48451631\n", + " 0.3315977 0.08824335 -0.10413812 -0.30693341 -0.52178679 -0.6396273\n", + " -0.69717731 -0.74924637 -0.76842971 -0.67306111 -0.53548918 -0.42970677\n", + " -0.26253768 -0.08550288 0.06303097 0.19128528 0.27404768 0.33379008\n", + " 0.36064675 0.34420389 0.30309674 0.2132091 0.19073719 0.07180049\n", + " 0.04494382 -0.02795286 -0.04932858 -0.03727049 0.00109619 0.04055906\n", + " 0.13647575 0.20005481 0.27624007 0.36283913 0.3551658 0.38640723\n", + " 0.32502055 0.24554673 0.07782954 -0.02795286 -0.19347767 -0.3781858\n", + " -0.49383393 -0.67744588 -0.73773637 -0.78268019 -0.793094 -0.70156207\n", + " -0.55905728 -0.40504248 -0.20279529 0.0350781 ]]\n" + ] + } + ], + "source": [ + "print(\n", + " f\"The result of the submitted job had {len(result)} PUB and has a value:\\n {result}\\n\"\n", + ")\n", + "print(\n", + " f\"The associated PubResult of this job has the following data bins:\\n {result[0].data}\\n\"\n", + ")\n", + "print(f\"And this DataBin has attributes: {result[0].data.keys()}\")\n", + "print(\n", + " \"Recall that this shape is due to our array of parameter binding sets having shape (100, 2) -- where 2 is the\\n\\\n", + " number of parameters in the circuit -- combined with our array of observables having shape (3, 1). \\n\"\n", + ")\n", + "print(\n", + " f\"The expectation values measured from this PUB are: \\n{result[0].data.evs}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "389bd235-c6c7-4dc0-87c5-272b85cfaae0", + "metadata": {}, + "source": [ + "#### How the Estimator primitive calculates error\n", + "\n", + "In addition to the estimate of the mean of the observables passed in the input PUBs (the `evs` field of the `DataBin`), Estimator also attempts to deliver an estimate of the error associated with those expectation values. All Estimator queries will populate the `stds` field with a quantity like the standard error of the mean for each expectation value, but some error mitigation options produce additional information, such as `ensemble_standard_error`.\n", + "\n", + "Consider a single observable $\\mathcal{O}$. In the absence of [ZNE](/docs/guides/error-mitigation-and-suppression-techniques#zero-noise-extrapolation-zne), you can think of each shot of the Estimator execution as providing a point estimate of the expectation value $\\langle \\mathcal{O} \\rangle$. If the pointwise estimates are in a vector `Os`, then the value returned in `ensemble_standard_error` is equivalent to the following (in which $\\sigma_{\\mathcal{O}}$ is the [standard deviation of the expectation value](/docs/api/qiskit/qiskit.primitives.BackendEstimatorV2) estimate and $N_{shots}$ is the number of shots):\n", + "\n", + "$$\\frac{ \\sigma_{\\mathcal{O}} }{ \\sqrt{N_{shots}} },$$\n", + "\n", + "which treats all shots as part of a single ensemble. If you requested gate [twirling](/docs/guides/error-mitigation-and-suppression-techniques#pauli-twirling) (`twirling.enable_gates = True`), you can sort the pointwise estimates of $\\langle \\mathcal{O} \\rangle$ into sets that share a common twirl. Call these sets of estimates `O_twirls`, and there are `num_randomizations` (number of twirls) of them. Then `stds` is the standard error of the mean of `O_twirls`, as in\n", + "\n", + "$$\\frac{ \\sigma_{\\mathcal{O}} }{ \\sqrt{N_{twirls}} },$$\n", + "\n", + "where $\\sigma_{\\mathcal{O}}$ is the standard deviation of `O_twirls` and $N_{twirls}$ is the number of twirls. When you do not enable twirling, `stds` and `ensemble_standard_error` are equal.\n", + "\n", + "If you enable ZNE, then the `stds` described above become weights in a non-linear regression to an extrapolator model. What finally gets returned in the `stds` in this case is the uncertainty of the fit model evaluated at a noise factor of zero. When there is a poor fit, or large uncertainty in the fit, the reported `stds` can become very large. When ZNE is enabled, `pub_result.data.evs_noise_factors` and `pub_result.data.stds_noise_factors` are also populated, so that you can do your own extrapolation." + ] + }, + { + "cell_type": "markdown", + "id": "f5840476-04ec-4d3b-bdb9-d166ccd8cd11", + "metadata": {}, + "source": [ + "## Result metadata\n", + "\n", + "In addition to the execution results, both the `PrimitiveResult` and `PubResult` objects contain a metadata attribute about the job that was submitted. The metadata containing information for all submitted PUBs (such as the various [runtime options](/docs/api/qiskit-ibm-runtime/options) available) can be found in the `PrimitiveResult.metatada`, while the metadata specific to each PUB is found in `PubResult.metadata`.\n", + "\n", + "\n", + "In the metadata field, primitive implementations can return any information about execution that is relevant to them, and there are no key-value pairs that are guaranteed by the base primitive. Thus, the returned metadata might be different in different primitive implementations.\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "68268c70-d76a-47b9-af6d-5cfe7966abae", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The metadata of the PrimitiveResult is:\n", + "'execution' : {'execution_spans': ExecutionSpans([DoubleSliceSpan()])},\n", + "'version' : 2,\n", + "\n", + "The metadata of the PubResult result is:\n", + "'circuit_metadata' : {},\n" + ] + } + ], + "source": [ + "# Print out the results metadata\n", + "print(\"The metadata of the PrimitiveResult is:\")\n", + "for key, val in result.metadata.items():\n", + " print(f\"'{key}' : {val},\")\n", + "\n", + "print(\"\\nThe metadata of the PubResult result is:\")\n", + "for key, val in result[0].metadata.items():\n", + " print(f\"'{key}' : {val},\")" + ] + } + ], + "metadata": { + "celltoolbar": "Raw Cell Format", + "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" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/guides/estimator-options.ipynb b/docs/guides/estimator-options.ipynb new file mode 100644 index 00000000000..faf2b0a8104 --- /dev/null +++ b/docs/guides/estimator-options.ipynb @@ -0,0 +1,1068 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7acdb263-fde4-4ff3-a13d-c499a2ba77e4", + "metadata": {}, + "source": [ + "---\n", + "title: Options\n", + "description: Specify options when building with the Estimator primitive.\n", + "---\n", + "\n", + "\n", + "# Specify options" + ] + }, + { + "cell_type": "markdown", + "id": "73e3d6f4", + "metadata": { + "tags": [ + "version-info" + ] + }, + "source": [ + "{/*\n", + " DO NOT EDIT THIS CELL!!!\n", + " This cell's content is generated automatically by a script. Anything you add\n", + " here will be removed next time the notebook is run. To add new content, create\n", + " a new cell before or after this one.\n", + "*/}\n", + "\n", + "
\n", + "Package versions\n", + "\n", + "The code on this page was developed using the following requirements.\n", + "We recommend using these versions or newer.\n", + "\n", + "```\n", + "qiskit[all]~=2.3.0\n", + "qiskit-ibm-runtime~=0.43.1\n", + "```\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "8fdcbe4a", + "metadata": {}, + "source": [ + "You can use options to customize the Estimator primitive. While the interface of the primitives' `run()` method is common across all implementations, their options are not. Consult the API references for information about the [`qiskit.primitives.BaseEstimatorV2`](/docs/api/qiskit/qiskit.primitives.BaseEstimatorV2) and [`qiskit_aer.BaseEstimatorV2`](https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.primitives.EstimatorV2.html) options.\n", + "\n", + "Notes about specifying options in the Estimator primitives:\n", + "\n", + "- You can see the available options and update option values during or after Estimator initialization.\n", + "- Use the `update()` method to apply changes to the `options` attribute.\n", + "- If you do not specify a value for an option, it is given a special value of `Unset` and the server defaults are used.\n", + "- The `options` attribute is the `dataclass` Python type. You can use the built-in `asdict` method to convert it to a dictionary.\n", + "\n", + "\n", + "## Set Estimator options\n", + "\n", + "You can set options when initializing Estimator, after initializing Estimator, or (for `precision`) in the `run()` method.\n", + "\n", + "### Primitive initialization\n", + "\n", + "You can pass in an instance of the options class or a dictionary when initializing Estimator, which then makes a copy of those options. Thus, changing the original dictionary or options instance doesn't affect the options owned by the primitive.\n", + "\n", + "#### Options class\n", + "\n", + "When creating an instance of the `EstimatorV2` class, you can pass in an instance of the options class. Those options will then be applied when you use `run()` to perform the calculation. Specify the options in this format: `options.option.sub-option.sub-sub-option = choice`. For example: `options.dynamical_decoupling.enable = True`\n", + "\n", + "Example:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "4b40f0e5-2db0-4ccc-9c07-bdb71d2f5b91", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "from qiskit_ibm_runtime import EstimatorV2 as Estimator\n", + "from qiskit_ibm_runtime.options import EstimatorOptions\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "options = EstimatorOptions(\n", + " resilience_level=2,\n", + " resilience={\"zne_mitigation\": True, \"zne\": {\"noise_factors\": [1, 3, 5]}},\n", + ")\n", + "\n", + "# or...\n", + "options = EstimatorOptions()\n", + "options.resilience_level = 2\n", + "options.resilience.zne_mitigation = True\n", + "options.resilience.zne.noise_factors = [1, 3, 5]\n", + "\n", + "estimator = Estimator(mode=backend, options=options)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Options classes summary\n", + "\n", + " - [Dynamical decoupling](/docs/api/qiskit-ibm-runtime/options-dynamical-decoupling-options): Options for dynamical decoupling.\n", + " - [Environment](/docs/api/qiskit-ibm-runtime/options-environment-options): Execution environment options, such as the logging level to set and job tags to add.\n", + " - [Execution](/docs/api/qiskit-ibm-runtime/options-execution-options-v2): Primitive execution options, including whether to initialize qubits and the repetition delay.\n", + " - [Resilience](/docs/api/qiskit-ibm-runtime//options-resilience-options-v2): Advanced options for configuring error mitigation methods such as measurement error mitigation, ZNE, and PEC.\n", + " - [Simulator](/docs/api/qiskit-ibm-runtime/options-simulator-options): Simulator options, such as the basis gates, simulator seed, and coupling map. Applies to [local testing mode](/docs/guides/local-testing-mode) only.\n", + " - [Twirling](/docs/api/qiskit-ibm-runtime/options-twirling-options): Twirling options, such as whether to apply two-qubit gate twirling and the number of shots to run for each random sample.\n" + ] + }, + { + "cell_type": "markdown", + "id": "ba2f5146-2781-49da-9fa2-8a22647225d0", + "metadata": {}, + "source": [ + "#### Dictionary\n", + "\n", + "You can specify options as a dictionary when initializing Estimator." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0ee1eaf6-c221-437f-8ff8-40ec2aa937c0", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "from qiskit_ibm_runtime import EstimatorV2 as Estimator\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "# Setting options during initialization\n", + "estimator = Estimator(\n", + " backend,\n", + " options={\n", + " \"resilience_level\": 2,\n", + " \"resilience\": {\n", + " \"zne_mitigation\": True,\n", + " \"zne\": {\"noise_factors\": [1, 3, 5]},\n", + " },\n", + " },\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "fc9a759a-6d43-4372-bad2-87512d43b255", + "metadata": {}, + "source": [ + "### Update options after initialization\n", + "\n", + "You can specify the options in this format: `estimator.options.option.sub-option.sub-sub-option = choice` to take advantage of auto-complete, or use the `update()` method to make bulk updates.\n", + "\n", + "The `EstimatorV2` options class ([`EstimatorOptions`](/docs/api/qiskit-ibm-runtime/options-estimator-options)) does not need to be instantiated if you are setting options after initializing the primitive." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "71de6acf-77a5-460f-ac54-f88f7a4d2fa6", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "from qiskit_ibm_runtime import EstimatorV2 as Estimator\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "estimator = Estimator(mode=backend)\n", + "\n", + "# Setting options after initialization\n", + "# This uses auto-complete.\n", + "estimator.options.default_precision = 0.01\n", + "# This does bulk update.\n", + "estimator.options.update(\n", + " default_precision=0.02, resilience={\"zne_mitigation\": True}\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "fde8c5bf-d914-4806-b55e-1f33aa643204", + "metadata": {}, + "source": [ + "\n", + "### Run() method\n", + "\n", + "The only values you can pass to `run()` are those defined in the interface. That is, `precision` for Estimator. This overwrites any value set for `default_precision` for the current run." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2c12ead-4785-4d4f-bf4a-f015295d7083", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "from qiskit_ibm_runtime import EstimatorV2 as Estimator\n", + "from qiskit.circuit.library import random_iqp\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "circuit1 = random_iqp(3)\n", + "circuit1.measure_all()\n", + "circuit2 = random_iqp(3)\n", + "circuit2.measure_all()\n", + "\n", + "pass_manager = generate_preset_pass_manager(\n", + " optimization_level=3, backend=backend\n", + ")\n", + "\n", + "transpiled1 = pass_manager.run(circuit1)\n", + "transpiled2 = pass_manager.run(circuit2)\n", + "\n", + "estimator = Estimator(mode=backend)\n", + "# Default precision to use if not specified in run()\n", + "estimator.options.default_precision = 0.01\n", + "# Run two circuits, requiring a precision of .02 for both.\n", + "estimator.run([transpiled1, transpiled2], precision=0.02)\n", + "\n", + "# Run two circuits with different precision requirements.\n", + "estimator.run([(transpiled1, None, 0.01), (transpiled2, None, 0.02)])" + ] + }, + { + "cell_type": "markdown", + "id": "8be4bd84-9060-437a-85f4-3d996f3e581f", + "metadata": {}, + "source": [ + "### Special cases\n", + "\n", + "#### Resilience level\n", + "\n", + "The resilience level is not actually an option that directly impacts the primitive query, but specifies a base set of curated options as a starting point. In general, level 0 turns off all error mitigation, level 1 turns on options for measurement error mitigation, and level 2 turns on options for gate and measurement error mitigation.\n", + "\n", + "Any options you manually specify in addition to the resilience level are applied on top of the base set of options defined by the resilience level. Therefore, in principle, you could set the resilience level to 1, but then turn off measurement mitigation, although this is not advised.\n", + "\n", + "In the following example, setting the resilience level to 0 initially turns off `zne_mitigation`, but `estimator.options.resilience.zne_mitigation = True` overrides the relevant setup from `estimator.options.resilience_level = 0`." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "80c10c6d-a6df-460a-bf5f-a5bac3588c1f", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit_ibm_runtime import EstimatorV2, QiskitRuntimeService\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "estimator = EstimatorV2(backend)\n", + "\n", + "estimator.options.default_shots = 100\n", + "estimator.options.resilience_level = 0\n", + "estimator.options.resilience.zne_mitigation = True" + ] + }, + { + "cell_type": "markdown", + "id": "52024f25-74ef-445a-9df8-d76da4ec7a32", + "metadata": {}, + "source": [ + "#### Precision\n", + "\n", + "The `EstimatorV2.run` method accepts two arguments: a list of PUBs, each of which can specify a PUB-specific value for precision, and a precision keyword argument. These precision values are a part of the Executor execution interface, and are independent of the Runtime Executor's options. They take precedence over any values specified as options in order to comply with the Estimator abstraction.\n", + "\n", + "However, if `precision` is not specified by any PUB or in the run keyword argument (or if they are all `None`), then the precision value from the options is used, most notably `default_precision`.\n", + "\n", + "Note that Estimator options contain both `default_shots` and `default_precision`. However, because gate-twirling is enabled by default, the product of `num_randomizations` and `shots_per_randomization` takes precedence over those two options.\n", + "\n", + "Specifically, for any particular Estimator PUB:\n", + "\n", + "1. If the PUB specifies precision, use that value.\n", + "2. If the precision keyword argument is specified in `run`, use that value.\n", + "3. If `num_randomizations` and `shots_per_randomization` are specified as [`twirling` options](/docs/api/qiskit-ibm-runtime/options-twirling-options) (enabled by default), use their product to control the amount of data.\n", + "4. If `estimator.options.default_shots` is specified, use that value to control the amount of data.\n", + "5. If `estimator.options.default_precision` is specified, use that value.\n", + "\n", + "For example, if precision is specified in all four places, the one with highest precedence (precision specified in the PUB) is used.\n", + "\n", + "\n", + "Precision scales inversely with usage. That is, the lower the precision, the more QPU time it takes to run.\n", + "\n", + "\n", + "## Commonly used options\n", + "\n", + "Among the many available options, the following are the most commonly used:\n", + "\n", + "\n", + "### Shots\n", + "For some algorithms, setting a specific number of shots is a core part of their routines. Shots (or precision) can be specified in multiple places. They are prioritized as follows:\n", + "\n", + "For any Estimator PUB:\n", + "\n", + "1. Float-valued precision contained in the PUB\n", + "2. The `run(...,precision=val)` value\n", + "3. The `options.default_shots` value\n", + "4. The `options.default_precision` value\n", + "\n", + "Example:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43ed5d23-8d2e-43a7-82a9-b563de861ab1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "from qiskit_ibm_runtime import EstimatorV2 as Estimator\n", + "from qiskit.circuit.library import random_iqp\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "circuit1 = random_iqp(3)\n", + "circuit1.measure_all()\n", + "circuit2 = random_iqp(3)\n", + "circuit2.measure_all()\n", + "\n", + "pass_manager = generate_preset_pass_manager(\n", + " optimization_level=3, backend=backend\n", + ")\n", + "\n", + "transpiled1 = pass_manager.run(circuit1)\n", + "transpiled2 = pass_manager.run(circuit2)\n", + "\n", + "\n", + "# Setting precision during primitive initialization\n", + "estimator = Estimator(mode=backend, options={\"default_precision\": 0.01})\n", + "\n", + "# Setting options after primitive initialization\n", + "# This uses auto-complete.\n", + "estimator.options.default_precision = 0.01\n", + "\n", + "# This does bulk update. The value for default_precision is overridden if you specify precision with run() or in the PUB.\n", + "estimator.options.update(\n", + " default_precision=0.01, dynamical_decoupling={\"sequence_type\": \"XpXm\"}\n", + ")\n", + "\n", + "# Run two circuits to a precision of .02 each.\n", + "estimator.run([transpiled1, transpiled2], precision=0.02)" + ] + }, + { + "cell_type": "markdown", + "id": "81196237-227f-449e-a780-c21fb328a7df", + "metadata": {}, + "source": [ + "### Maximum execution time\n", + "\n", + "The maximum execution time (`max_execution_time`) limits how long a job can run. If a job exceeds this time limit, it is forcibly canceled. This value applies to single jobs, whether they are run in job, session, or batch mode.\n", + "\n", + "The value is set in seconds, based on quantum time (not wall clock time), which is the amount of time that the QPU is dedicated to processing your job. It is ignored when using [local testing mode](/docs/guides/local-testing-mode) because that mode does not use quantum time." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "31bd9edf-2c9e-44be-9e30-71a8415103aa", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "from qiskit_ibm_runtime import EstimatorV2 as Estimator\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "estimator = Estimator(mode=backend)\n", + "\n", + "estimator.options.max_execution_time = 2500" + ] + }, + { + "cell_type": "markdown", + "id": "eabb08cf-e67c-452a-8aa5-d028baee77e0", + "metadata": {}, + "source": [ + "\n", + "## Turn off all error mitigation and error suppression\n", + "\n", + "You can turn off all error mitigation and suppression if you are, for example, doing research on your own mitigation techniques. To accomplish this, set `resilience_level = 0`.\n", + "\n", + "Example:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9fe17f58-c273-49db-b35f-f698ab44319f", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit_ibm_runtime import EstimatorV2 as Estimator, QiskitRuntimeService\n", + "\n", + "# Define the service. This allows you to access an IBM QPU.\n", + "service = QiskitRuntimeService()\n", + "\n", + "# Get a backend\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "# Define Estimator\n", + "estimator = Estimator(backend)\n", + "\n", + "options = estimator.options\n", + "\n", + "# Turn off all error mitigation and suppression\n", + "options.resilience_level = 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Available options\n", + "\n", + "The following table documents options from the latest version of `qiskit-ibm-runtime`. To see older option versions, visit the [`qiskit-ibm-runtime` API reference](/docs/api/qiskit-ibm-runtime) and select a previous version.\n", + "\n", + "\n", + "\n", + "\n", + "The total number of shots to use per circuit per configuration.\n", + "\n", + "**Choices**: Integer >= 0\n", + "\n", + "**Default**: None\n", + "\n", + "[`default_shots` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#default_shots)\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "The default precision to use for any PUB or `run()` call that does not specify one.\n", + "\n", + "**Choices**: Float > 0\n", + "\n", + "**Default**: 0.015625 (1 / sqrt(4096))\n", + "\n", + "[`default_precision` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#default_precision)\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "Control dynamical decoupling error mitigation settings.\n", + "\n", + "[`dynamical_decoupling` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#dynamical_decoupling)\n", + "\n", + "\n", + "\n", + "**Choices**: `True`, `False`\n", + "\n", + "**Default**: `False`\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `middle`, `edges`\n", + "\n", + "**Default**: `middle`\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "Choices: `asap`, `alap`\n", + "Default: `alap`\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "Choices: `XX`, `XpXm`, `XY4`\n", + "Default: `XX`\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "Choices: `True`, `False`\n", + "Default: `False`\n", + " \n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "[`environment` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#environment)\n", + "\n", + "\n", + "\n", + "Callable function that receives the `Job ID` and `Job result`.\n", + "\n", + "**Choices**: None\n", + "\n", + "**Default**: None\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "List of tags.\n", + "\n", + "**Choices**: None\n", + "\n", + "**Default**: None\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: DEBUG, INFO, WARNING, ERROR, CRITICAL\n", + "\n", + "**Default**: WARNING\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `True`, `False`\n", + "\n", + "**Default**: `False`\n", + " \n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "[`execution` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#execution)\n", + "\n", + "\n", + "Whether to reset the qubits to the ground state for each shot.\n", + "\n", + "**Choices**: `True`, `False`\n", + "\n", + "**Default**: `True`\n", + " \n", + "\n", + "\n", + "\n", + "The delay between a measurement and the subsequent quantum circuit.\n", + "\n", + "**Choices**: Value in the range supplied by `backend.rep_delay_range`\n", + "\n", + "**Default**: Given by `backend.default_rep_delay`\n", + " \n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: Integer number of seconds in the range [1, 10800]\n", + "\n", + "**Default**: 10800 (3 hours)\n", + "\n", + "[`max_execution_time` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#max_execution_time)\n", + " \n", + "\n", + "\n", + "\n", + "Advanced resilience options to fine tune the resilience strategy.\n", + "\n", + "[`resilience` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#resilience)\n", + "\n", + "\n", + "\n", + "Options for learning layer noise.\n", + "\n", + "[`resilience.layer_noise_learning` API documentation](/docs/api/qiskit-ibm-runtime/options-layer-noise-learning-options)\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: list[int] of 2-10 values in the range [0, 200]\n", + "\n", + "**Default**: `(0, 1, 2, 4, 16, 32)`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: None, Integer >= 1\n", + "\n", + "**Default**: `4`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: Integer >= 1\n", + "\n", + "**Default**: `32`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: Integer >= 1\n", + "\n", + "**Default**: `128`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `NoiseLearnerResult`, `Sequence[LayerError]`\n", + "\n", + "**Default**: None\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `True`, `False`\n", + "\n", + "**Default**: `True`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Options for measurement noise learning.\n", + "\n", + "[`resilience.measure_noise_learning` API documentation](/docs/api/qiskit-ibm-runtime/options-measure-noise-learning-options)\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: Integer >= 1\n", + "\n", + "**Default**: `32`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: Integer, `auto`\n", + "\n", + "**Default**: `auto`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `True`, `False`\n", + "\n", + "**Default**: `False`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Probabilistic error cancellation mitigation options.\n", + "\n", + "[`resilience.pec` API documentation](/docs/api/qiskit-ibm-runtime/options-pec-options)\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `None`, Integer >= 1\n", + "\n", + "\n", + "**Default**: `100`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `auto`, float in the range [0, 1]\n", + "\n", + "**Default**: `auto`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `True`, `False`\n", + "\n", + "**Default**: `False`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "[`resilience.zne` API documentation](/docs/api/qiskit-ibm-runtime/options-zne-options)\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `gate_folding`, `gate_folding_front`, `gate_folding_back`, `pea`\n", + "\n", + "**Default**: `gate_folding`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: List of floats\n", + "\n", + "**Default**: `[0, *noise_factors]`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: One or more of: `exponential`, `linear`, `double_exponential`, `polynomial_degree_(1 <= k <= 7)`, `fallback`\n", + "\n", + "**Default**: `(exponential, linear)`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: List of floats; each float >= 1\n", + "\n", + "**Default**: `(1, 1.5, 2)` for `PEA`, and `(1, 3, 5)` otherwise\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "How much resilience to build against errors. Higher levels generate more accurate results at the expense of longer processing times.\n", + "\n", + "**Choices**: `0`, `1`, `2`\n", + "\n", + "**Default**: `1`\n", + "\n", + "[`resilience_level` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#resilience_level)\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: Integer\n", + "\n", + "**Default**: None\n", + "\n", + "[`seed_estimator`](/docs/api/qiskit-ibm-runtime/options-estimator-options#seed_estimator)\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "Options to pass when simulating a backend\n", + "\n", + "[`simulator` API documentation](/docs/api/qiskit-ibm-runtime/options-simulator-options)\n", + "\n", + "\n", + "\n", + "**Choices**: List of basis gate names to unroll to\n", + "\n", + "**Default**: The set of all basis gates supported by [Qiskit Aer simulator](https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.AerSimulator.html)\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: List of directed two-qubit interactions\n", + "\n", + "**Default**: None, which implies no connectivity constraints (full connectivity).\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: [Qiskit Aer NoiseModel](/docs/guides/build-noise-models), or its representation\n", + "\n", + "**Default**: None\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: Integer\n", + "\n", + "**Default**: None\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Twirling options\n", + "\n", + "[`twirling` API documentation](/docs/api/qiskit-ibm-runtime/options-twirling-options)\n", + "\n", + "\n", + "\n", + "**Choices**: True, False\n", + "\n", + "**Default**: False\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: True, False\n", + "\n", + "**Default**: True\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `auto`, Integer >= 1\n", + "\n", + "**Default**: `auto`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `auto`, Integer >= 1\n", + "\n", + "**Default**: `auto`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `active`, `active-circuit`, `active-accum`, `all`\n", + "\n", + "**Default**: `active-accum`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Experimental options, when available.\n", + "\n", + " \n", + "\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Feature compatibility\n", + "\n", + "Due to differences in the device compilation process, certain runtime features cannot be used together in a single job. Click the appropriate tab for a list of features that are incompatible with the selected feature:\n", + "\n", + "\n", + " \n", + " Incompatible with:\n", + " - Gate-folding ZNE\n", + " - PEA\n", + " - PEC\n", + " - Dynamical decoupling\n", + "\n", + " Other notes:\n", + " - Gate twirling can be applied to dynamic circuits, but only to gates not inside conditional blocks. Measurement twirling can only be applied to terminal measurements.\n", + " - Compatible with fractional gates when using `qiskit-ibm-runtime` v0.42.0 or later.\n", + "\n", + " \n", + " \n", + " Incompatible with dynamic circuits.\n", + "\n", + " \n", + "\n", + " \n", + " Incompatible with:\n", + " - Gate twirling\n", + " - PEA\n", + " - PEC\n", + "\n", + " Compatible with dynamic circuits when using `qiskit-ibm-runtime` v0.42.0 or later.\n", + "\n", + " \n", + "\n", + " \n", + " Incompatible with:\n", + " - Dynamic circuits\n", + " - PEA\n", + " - PEC\n", + "\n", + " Might not work when using custom gates.\n", + " \n", + " \n", + " Incompatible with fractional gates or with stretches.\n", + "\n", + " Other notes:\n", + " - Gate twirling can be applied to dynamic circuits, but only to gates not inside conditional blocks. Measurement twirling can only be applied to terminal measurements.\n", + " - Does not work with non-Clifford entanglers.\n", + "\n", + " \n", + "\n", + " \n", + " Incompatible with:\n", + " - Dynamic circuits\n", + " - Fractional gates\n", + " - Gate-folding ZNE\n", + " - PEC\n", + " \n", + "\n", + " \n", + " Incompatible with:\n", + " - Dynamic circuits\n", + " - Fractional gates\n", + " - Gate-folding ZNE\n", + " - PEA\n", + " \n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "9b86001b-718a-4d72-b3b5-4a67eabf0a45", + "metadata": {}, + "source": [ + "## Next steps\n", + "\n", + "\n", + " - Find more details about the `EstimatorV2` methods in the [Estimator API reference](/docs/api/qiskit-ibm-runtime/estimator-v2).\n", + " - Find details about how to configure [error suppression](configure-error-suppression) and [error mitigation](/docs/guides/configure-error-mitigation).\n", + " - Decide what [execution mode](/docs/guides/execution-modes) to run your job in.\n", + "" + ] + } + ], + "metadata": { + "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" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/guides/estimator-rest-api.ipynb b/docs/guides/estimator-rest-api.ipynb new file mode 100644 index 00000000000..58e60e8be16 --- /dev/null +++ b/docs/guides/estimator-rest-api.ipynb @@ -0,0 +1,469 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0998165a-381f-4561-a79a-bf584aed9687", + "metadata": {}, + "source": [ + "---\n", + "title: REST API\n", + "description: How to use the Estimator primitive with the Qiskit Runtime REST API.\n", + "---\n", + "\n", + "\n", + "{/* cspell:ignore IIZII, XIZZZ, accum */}\n", + "\n", + "# Estimator with the REST API" + ] + }, + { + "cell_type": "markdown", + "id": "da948b6b-2ead-4359-aed4-b824e43ccbfb", + "metadata": { + "tags": [ + "version-info" + ] + }, + "source": [ + "{/*\n", + " DO NOT EDIT THIS CELL!!!\n", + " This cell's content is generated automatically by a script. Anything you add\n", + " here will be removed next time the notebook is run. To add new content, create\n", + " a new cell before or after this one.\n", + "*/}\n", + "\n", + "
\n", + "Package versions\n", + "\n", + "The code on this page was developed using the following requirements.\n", + "We recommend using these versions or newer.\n", + "\n", + "```\n", + "qiskit[all]~=2.3.0\n", + "```\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "3d9ef591-91fd-4a49-a065-5e2cda4d41be", + "metadata": {}, + "source": [ + "The steps in this topic describe how to run and configure workloads with the REST API, and demonstrate how to invoke them in any program of your choice.\n", + "\n", + "\n", + " This documentation utilizes the Python `requests` module to demonstrate the Qiskit Runtime REST API. However, this workflow can be executed using any language or framework that supports working with REST APIs. Refer to the [API reference documentation](/docs/api/qiskit-ibm-runtime/tags/jobs) for details.\n", + "\n", + "\n", + "## 1. Initialize the account\n", + "\n", + "Because Qiskit Runtime Estimator is a managed service, you first need to initialize your account. You can then select the device you want to use to calculate the expectation value.\n", + "\n", + "\n", + "Find details on how to initialize your account, view available backends, and invalidate tokens in this [topic](/docs/guides/cloud-setup-rest-api).\n", + "\n", + "## 2. Create a QASM circuit\n", + "\n", + "You need at least one circuit as the input to the Estimator primitive.\n", + "\n", + "Define a QASM quantum circuit. For example:\n", + "\n", + "```python\n", + "qasm_string='''\n", + "OPENQASM 3;\n", + "include \"stdgates.inc\";\n", + "qreg q[2];\n", + "creg c[2];\n", + "x q[0];\n", + "cx q[0], q[1];\n", + "c[0] = measure q[0];\n", + "c[1] = measure q[1];\n", + "'''\n", + "```\n", + "\n", + "The following code snippets assume that the `qasm_string` has been transpiled to a new string `resulting_qasm`.\n", + "\n", + "## 3. Run the quantum circuit using the Estimator V2 API\n", + "\n", + "\n", + "\n", + " The following jobs use [Qiskit Runtime V2 primitives](/docs/guides/v2-primitives). Both `SamplerV2` and `EstimatorV2` take one or more primitive unified blocs (PUBs) as the input. Each PUB is a tuple that contains one circuit and the data broadcasted to that circuit, which can be multiple observables and parameters. Each PUB returns a result.\n", + "\n", + "\n", + "\n", + "\n", + "```python\n", + "import requests\n", + "\n", + "url = 'https://quantum.cloud.ibm.com/api/v1/jobs'\n", + "auth_id = \"Bearer \"\n", + "crn = \"\"\n", + "backend = \"\"\n", + "\n", + "headers = {\n", + " 'Content-Type': 'application/json',\n", + " 'Authorization':auth_id,\n", + " 'Service-CRN': crn\n", + " }\n", + "\n", + "job_input = {\n", + " 'program_id': 'estimator',\n", + " \"backend\": backend,\n", + " \"params\": {\n", + " \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each.\n", + " [resulting_qasm, # QASM circuit\n", + " {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n", + " None # parameter values\n", + " ]]\n", + "}}\n", + "\n", + "response = requests.post(url, headers=headers, json=job_input)\n", + "\n", + "if response.status_code == 200:\n", + " job_id = response.json().get('id')\n", + " print(\"Job created:\",response.text)\n", + "else:\n", + " print(f\"Error: {response.status_code}\")\n", + "```\n", + "\n", + "\n", + "\n", + "## 4. Check job status and get results\n", + "\n", + "Next, pass the `job_id` to the API:\n", + "\n", + "```python\n", + "response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)\n", + "response_status_singlejob.json().get('state')\n", + "```\n", + "Output\n", + "\n", + "```text\n", + ">>> Job ID: 58223448-5100-4dec-a47a-942fb30edcad\n", + ">>> Job Status: JobStatus.RUNNING\n", + "```\n", + "\n", + "Get job results:\n", + "```python\n", + "response_result= requests.get(url+'/'+job_id+'/results', headers=headers)\n", + "\n", + "res_dict=response_result.json()\n", + "\n", + "estimator_result=res_dict['results']\n", + "print(estimator_result)\n", + "```\n", + "Output\n", + "```text\n", + "[{'data': {'evs': 0.7428980350102542, 'stds': 0.029884014518789213, 'ensemble_standard_error': 0.03261147170624149}, 'metadata': {'shots': 10016, 'target_precision': 0.01, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}}]\n", + "```\n", + "\n", + "## 5. Work with Runtime options\n", + "\n", + "Error mitigation techniques allow users to mitigate circuit errors by modeling the device noise at the time of execution. This typically results in quantum pre-processing overhead related to model training, and classical post-processing overhead to mitigate errors in the raw results by using the generated model.\n", + "\n", + "The error mitigation techniques built in to primitives are advanced resilience options. To specify these options, use the `resilience_level` option when submitting your job.\n", + "\n", + "The following examples demonstrate the default options for dynamical decoupling, twirling, and TREX + ZNE. Find more options and further details in the [Error mitigation and suppression techniques](/docs/guides/error-mitigation-and-suppression-techniques) topic.\n", + "\n", + "### TREX + ZNE\n", + "\n", + "```python\n", + "import requests\n", + "\n", + "url = 'https://quantum.cloud.ibm.com/api/v1/jobs'\n", + "auth_id = \"Bearer \"\n", + "crn = \"\"\n", + "backend = \"BACKEND_NAME\"\n", + "\n", + "headers = {\n", + " 'Content-Type': 'application/json',\n", + " 'Authorization':auth_id,\n", + " 'Service-CRN': crn\n", + " }\n", + "job_input = {\n", + " 'program_id': 'estimator',\n", + " \"backend\": backend,\n", + " \"params\": {\n", + " \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each\n", + " [resulting_qasm, # QASM circuit\n", + " {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n", + " None # parameter values\n", + " ]]\n", + " \"options\": {\n", + " \"resilience\": {\n", + " \"measure_mitigation\": True,\n", + " \"zne_mitigation\": True,\n", + " \"zne\": {\n", + " \"extrapolator\":[\"exponential\", \"linear\"],\n", + " \"noise_factors\":[1, 3, 5],\n", + " },\n", + " },\n", + " },\n", + " }\n", + "}\n", + "\n", + "response = requests.post(url, headers=headers, json=job_input)\n", + "\n", + "if response.status_code == 200:\n", + " job_id = response.json().get('id')\n", + " print(\"Job created:\",response.text)\n", + "else:\n", + " print(f\"Error: {response.status_code}\")\n", + "```\n", + "\n", + "### Dynamical Decoupling\n", + "\n", + "```python\n", + "import requests\n", + "\n", + "url = 'https://quantum.cloud.ibm.com/api/v1/jobs'\n", + "auth_id = \"Bearer \"\n", + "crn = \"\"\n", + "backend = \"BACKEND_NAME\"\n", + "\n", + "headers = {\n", + " 'Content-Type': 'application/json',\n", + " 'Authorization':auth_id,\n", + " 'Service-CRN': crn\n", + " }\n", + "job_input = {\n", + " 'program_id': 'estimator',\n", + " \"backend\": backend,\n", + " \"params\": {\n", + " \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each\n", + " [resulting_qasm, # QASM circuit\n", + " {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n", + " None # parameter values\n", + " ]]\n", + " \"options\": {\n", + " \"dynamical_decoupling\": {\n", + " \"enable\": True,\n", + " \"sequence_type\": 'XpXm',\n", + " \"extra_slack_distribution\": 'middle',\n", + " \"scheduling_method\": 'alap',\n", + " },\n", + " },\n", + " }\n", + "}\n", + "\n", + "response = requests.post(url, headers=headers, json=job_input)\n", + "\n", + "if response.status_code == 200:\n", + " job_id = response.json().get('id')\n", + " print(\"Job created:\",response.text)\n", + "else:\n", + " print(f\"Error: {response.status_code}\")\n", + "```\n", + "\n", + "### Twirling\n", + "\n", + "```python\n", + "import requests\n", + "\n", + "url = 'https://quantum.cloud.ibm.com/api/v1/jobs'\n", + "auth_id = \"Bearer \"\n", + "crn = \"\"\n", + "backend = \"BACKEND_NAME\"\n", + "\n", + "headers = {\n", + " 'Content-Type': 'application/json',\n", + " 'Authorization':auth_id,\n", + " 'Service-CRN': crn\n", + " }\n", + "job_input = {\n", + " 'program_id': 'estimator',\n", + " \"backend\": backend,\n", + " \"params\": {\n", + " \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each\n", + " [resulting_qasm, # QASM circuit\n", + " {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n", + " None # parameter values\n", + " ]]\n", + " \"options\": {\n", + " \"twirling\": {\n", + " \"enable_gates\": True,\n", + " \"enable_measure\": True,\n", + " \"num_randomizations\": \"auto\",\n", + " \"shots_per_randomization\": \"auto\",\n", + " \"strategy\": \"active-accum\",\n", + " },\n", + " },\n", + " }\n", + "}\n", + "\n", + "response = requests.post(url, headers=headers, json=job_input)\n", + "\n", + "if response.status_code == 200:\n", + " job_id = response.json().get('id')\n", + " print(\"Job created:\",response.text)\n", + "else:\n", + " print(f\"Error: {response.status_code}\")\n", + "```\n", + "\n", + "## Parameterized circuits\n", + "\n", + "### 1. Initialize the account\n", + "\n", + "Because Qiskit Runtime is a managed service, you first need to initialize your account. You can then select the device you want to use to run your calculations on.\n", + "\n", + "\n", + "Find details on how to initialize your account, view available backends, and invalidate tokens in this [topic](/docs/guides/cloud-setup-rest-api).\n", + "\n", + "\n", + "### 2. Define parameters\n", + "\n", + "```python\n", + "import requests\n", + "import qiskit_ibm_runtime\n", + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "from qiskit.qasm3 import dumps\n", + "from qiskit import QuantumCircuit\n", + "from qiskit.circuit import Parameter\n", + "from qiskit import transpile\n", + "\n", + "service = QiskitRuntimeService(channel='ibm_quantum')\n", + "backend = service.backend(\"\")\n", + "\n", + "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", + "\n", + "theta = Parameter('theta')\n", + "phi = Parameter('phi')\n", + "parameter_values = {'theta': 1.57, 'phi': 3.14} # In case we want to pass a dictionary\n", + "```\n", + "\n", + "\n", + "### 3. Create a quantum circuit and add parameterized gates\n", + "\n", + "```python\n", + "qc = QuantumCircuit(2)\n", + "\n", + "# Add parameterized gates\n", + "qc.rx(theta, 0)\n", + "qc.ry(phi, 1)\n", + "qc.cx(0, 1)\n", + "qc.measure_all()\n", + "\n", + "# Draw the original circuit\n", + "qc.draw('mpl')\n", + "\n", + "# Get an ISA circuit\n", + "isa_circuit = pm.run(qc)\n", + "```\n", + "\n", + "### 4. Generate QASM 3 code\n", + "\n", + "```python\n", + "qasm_str = dumps(isa_circuit)\n", + "print(\"Generated QASM 3 code:\")\n", + "print(qasm_str)\n", + "```\n", + "\n", + "### 5. Run the quantum circuit using Estimator V2 API\n", + "\n", + "\n", + "```python\n", + "import requests\n", + "\n", + "url = 'https://quantum.cloud.ibm.com/api/v1/jobs'\n", + "auth_id = \"Bearer \"\n", + "crn = \"\"\n", + "backend = \"\"\n", + "\n", + "headers = {\n", + " 'Content-Type': 'application/json',\n", + " 'Authorization':auth_id,\n", + " 'Service-CRN': crn\n", + " }\n", + "\n", + "job_input = {\n", + " 'program_id': 'estimator',\n", + " \"backend\": backend,\n", + " \"params\": {\n", + " # Choose one option: direct parameter transfer or through a dictionary\n", + " #\"pubs\": [[qasm_str,[1,2],500]], # primitive unified blocs (PUBs) containing one circuit each.\n", + " \"pubs\": [[qasm_str,parameter_values,500]], # primitive unified blocs (PUBs) containing one circuit each.\n", + "}}\n", + "\n", + "response = requests.post(url, headers=headers, json=job_input)\n", + "\n", + "if response.status_code == 200:\n", + " job_id = response.json().get('id')\n", + " print(f\"Job created: {response.text}\")\n", + "else:\n", + " print(f\"Error: {response.status_code}\")\n", + "```\n", + "\n", + "```python\n", + "print(response.text)\n", + "```\n", + "\n", + "\n", + "### 6. Check job status and get results\n", + "\n", + "Next, pass the `job_id` to the API:\n", + "\n", + "```python\n", + "response_status_singlejob = requests.get(f\"{url}/{job_id}\", headers=headers)\n", + "response_status_singlejob.json().get('state')\n", + "```\n", + "\n", + "Output\n", + "\n", + "```text\n", + "{'status': 'Completed'}\n", + "```\n", + "\n", + "Get job results:\n", + "\n", + "```python\n", + "response_result = requests.get(f\"{url}/{job_id}/results\", headers=headers)\n", + "\n", + "res_dict=response_result.json()\n", + "\n", + "# Get results for the first PUB\n", + "counts=res_dict['results'][0]['data']['c']['samples']\n", + "\n", + "print(counts[:20])\n", + "```\n", + "\n", + "Output\n", + "\n", + "```text\n", + "['0x1', '0x2', '0x1', '0x2', '0x1', '0x2', '0x0', '0x2', '0x1', '0x1', '0x2', '0x2', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1']\n", + "```\n", + "\n", + "## Next steps\n", + "\n", + "\n", + "\n", + " - There are several ways to run workloads, depending on your needs: job mode, session mode, and batch mode. Learn how to work with session mode and batch mode in the [execution modes topic](/docs/guides/execution-modes-rest-api). Note that Open Plan users cannot submit session jobs.\n", + " - Learn how to [initialize your account](/docs/guides/cloud-setup-rest-api) with REST API.\n", + " - Practice with primitives by working through the [Cost function lesson](/learning/courses/variational-algorithm-design/cost-functions) in IBM Quantum® Learning.\n", + " - Learn how to transpile locally in the [Transpile](/docs/guides/transpile) section.\n", + "" + ] + } + ], + "metadata": { + "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" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/guides/execution-modes-rest-api.ipynb b/docs/guides/execution-modes-rest-api.ipynb index 24c1452af2f..25298e64869 100644 --- a/docs/guides/execution-modes-rest-api.ipynb +++ b/docs/guides/execution-modes-rest-api.ipynb @@ -22,7 +22,25 @@ "version-info" ] }, - "source": [] + "source": [ + "{/*\n", + " DO NOT EDIT THIS CELL!!!\n", + " This cell's content is generated automatically by a script. Anything you add\n", + " here will be removed next time the notebook is run. To add new content, create\n", + " a new cell before or after this one.\n", + "*/}\n", + "\n", + "
\n", + "Package versions\n", + "\n", + "The code on this page was developed using the following requirements.\n", + "We recommend using these versions or newer.\n", + "\n", + "```\n", + "qiskit[all]~=2.3.0\n", + "```\n", + "
" + ] }, { "cell_type": "markdown", @@ -37,11 +55,11 @@ "\n", "## Job mode with REST API\n", "\n", - "In job mode, a single primitive request of the Estimator or the Sampler is made without a context manager. See how to run a quantum circuit using [Estimator](primitives-rest-api#estimator-primitive-with-rest-api) and [Sampler](primitives-rest-api#sampler-primitive-with-rest-api) for some examples.\n", + "In job mode, a single primitive request of Estimator or Sampler is made without a context manager. See how to run a quantum circuit using [Estimator](/docs/guides/estimator-rest-api) and [Sampler](/docs/guides/sampler-rest-api) for some examples.\n", "\n", "## Session mode with REST API\n", "\n", - "A session is a Qiskit Runtime feature that lets you efficiently run multi-job iterative workloads on quantum computers. Using sessions helps avoid delays caused by queuing each job separately, which can be particularly useful for iterative tasks that require frequent communication between classical and quantum resources. More details about Sessions can be found in the [documentation](./execution-modes).\n", + "A session is a Qiskit Runtime feature that lets you efficiently run multi-job iterative workloads on quantum computers. Using sessions helps avoid delays caused by queuing each job separately, which can be particularly useful for iterative tasks that require frequent communication between classical and quantum resources. More details about Sessions can be found in the [documentation](/docs/guides/execution-modes).\n", "\n", "\n", "\n", @@ -116,7 +134,7 @@ "\n", "## Batch mode with REST API\n", "\n", - "Alternatively, you can submit a batch job by specifying the `mode` in the request payload. Batch mode can help shorten processing time if all jobs can be provided at the outset. Learn about batch mode in the [introduction to execution modes](./execution-modes#batch-mode) guide.\n", + "Alternatively, you can submit a batch job by specifying the `mode` in the request payload. Batch mode can help shorten processing time if all jobs can be provided at the outset. Learn about batch mode in the [introduction to execution modes](/docs/guides/execution-modes#batch-mode) guide.\n", "\n", "\n", "```python\n", @@ -278,10 +296,11 @@ "## Next steps\n", "\n", "\n", - " - Review detailed [Sampler and Estimator](primitives-rest-api) primitives examples using REST API.\n", + " - Review detailed [Sampler](/docs/guides/sampler-rest-api) primitives examples using REST API.\n", + " - Review detailed [Estimator](/docs/guides/estimator-rest-api) primitives examples using REST API.\n", " - Read [Migrate to V2 primitives](/docs/guides/v2-primitives).\n", " - Practice with primitives by working through the [Cost function lesson](/learning/courses/variational-algorithm-design/cost-functions) in IBM Quantum® Learning.\n", - " - Learn how to transpile locally in the [Transpile](./transpile) section.\n", + " - Learn how to transpile locally in the [Transpile](/docs/guides/transpile) section.\n", "" ] } diff --git a/docs/guides/execution-modes.mdx b/docs/guides/execution-modes.mdx index 3e7ddfedfcb..07e9d3503a1 100644 --- a/docs/guides/execution-modes.mdx +++ b/docs/guides/execution-modes.mdx @@ -9,7 +9,7 @@ When Qiskit Runtime was introduced, users could only execute circuits as individ ## Job mode -A single primitive request of the estimator or the sampler made without a context manager. Circuits and inputs are packaged as primitive unified blocs (PUBs) and submitted as an execution task on the quantum computer. To run in job mode, specify `mode=backend` when instantiating a primitive. See [Primitives examples](/docs/guides/primitives-examples) for usage. +A single primitive request of an Estimator or Sampler primitive made without a context manager. Circuits and inputs are packaged as primitive unified blocs (PUBs) and submitted as an execution task on the quantum computer. To run in job mode, specify `mode=backend` when instantiating a primitive. See [Estimator examples](/docs/guides/estimator-examples) or [Sampler examples](/docs/guides/sampler-examples) for usage. ## Batch mode diff --git a/docs/guides/executor-broadcasting.mdx b/docs/guides/executor-broadcasting.mdx new file mode 100644 index 00000000000..01c506d4407 --- /dev/null +++ b/docs/guides/executor-broadcasting.mdx @@ -0,0 +1,285 @@ +--- +title: Broadcasting +description: How the Executor handles array inputs and outputs using broadcasting semantics + +--- +{/* cspell:ignore broadcastable */} + +# Executor broadcasting semantics +The data provided to the Executor primitive can be arranged in a variety of shapes to provide flexibility in a workload through [broadcasting.](/docs/guides/pubs-broadcasting#broadcasting) This guide explains how the Executor handles array inputs and outputs using broadcasting semantics. Understanding these concepts will help you efficiently sweep over parameter values, combine +multiple experimental configurations, and interpret the shape of returned data. + +## Quick start example + +This example demonstrates the core idea. It creates a parametric circuit and and five different parameter configurations. The executor automatically runs all five configurations and returns data organized by configuration, with one result per classical register in each quantum program item. + +The rest of this guide explains how this works in detail and how to build more complex sweeps, including samplomatic-based randomization and inputs. + +```python +import numpy as np +from qiskit.circuit import Parameter, QuantumCircuit +from qiskit_ibm_runtime.quantum_program import QuantumProgram + +# A circuit with 3 parameters +circuit = QuantumCircuit(3) +circuit.rx(Parameter("a"), 0) +circuit.rx(Parameter("b"), 1) +circuit.rx(Parameter("c"), 2) +circuit.measure_all() + +# 5 different parameter configurations (shape: 5 configurations × 3 parameters) +parameter_values = np.linspace(0, np.pi, 15).reshape(5, 3) + +program = QuantumProgram(shots=1024) +program.append(circuit, circuit_arguments=parameter_values) + +# Run and get results +result = executor.run(program).result() + +# result is a list with one entry per program item +# result[0] is a dict mapping classical register names to data arrays +# Output bool arrays have shape (5, 1024, 3) +# 5 = number of parameter configurations +# 1024 = number of shots +# 3 = bits in the classical register +result[0]["meas"] +``` + +## Intrinsic and extrinsic axes + +Broadcasting only applies to _extrinsic_ axes. The intrinsic axes are always preserved as specified. + +- **Intrinsic axes** (rightmost): Determined by the data type. For example, if your circuit + has three parameters, then parameter values require three numbers, giving an intrinsic shape + of `(3,)`. + +- **Extrinsic axes** (leftmost): Your sweep dimensions. These define how many configurations you + want to run. + +| Input type | Intrinsic shape | Example full shape | +|:----------------------------------------:|:---------------:|:---------------------------------------------------:| +| Parameter values (n parameters) | (n,) | (5, 3) for five configurations and three parameters | +| Scalar inputs (for example, noise scale) | () | (4,) for four configurations | +| Observables (if applicable) | varies | Depends on observable type | + +### Example + +Consider a circuit with two parameters that you want to sweep over a 4x3 grid of configurations, varying both parameter values and a noise scale factor: + +```python +import numpy as np + +# Parameter values: 4 configurations along axis 0, intrinsic shape (2,) +# Full shape: (4, 1, 2) - the "1" allows broadcasting with noise_scale +parameter_values = np.array([ + [[0.1, 0.2]], + [[0.3, 0.4]], + [[0.5, 0.6]], + [[0.7, 0.8]], +]) # shape (4, 1, 2) + +# Noise scale: 3 configurations, intrinsic shape () (scalar) +# Full shape: (3,) +noise_scale = np.array([0.8, 1.0, 1.2]) # shape (3,) + +# Extrinsic shapes: (4, 1) and (3,) → broadcast to (4, 3) +# Result: 12 total configurations in a 4×3 grid + +program.append( + template, + samplex=samplex, + samplex_arguments={ + "parameter_values": parameter_values, + "noise_scale.mod_ref1": noise_scale, + }, +) +``` + +The shapes are as follows: + +| Input | Full shape | Extrinsic shape | Intrinsic shape | +|:------------------:|:----------:|:---------------:|:---------------:| +| `parameter_values` | (4, 1, 2) | (4, 1) | (2,) | +| `noise_scale` | (3,) | (3,) | () | +| Broadcast | None | (4, 3) | None | + +## Output array shapes + +Output arrays follow the same extrinsic/intrinsic pattern: + +- **Extrinsic shape:** Matches the broadcast shape of all inputs +- **Intrinsic shape:** Determined by the output type + +The most common output is bitstring data from measurements, which is +formatted as an array of boolean values: + +| Output type | Intrinsic shape | Description | +|:-----------------------:|:----------------------:|:--------------------------------:| +| Classical register data | (num_shots, creg_size) | Bitstring data from measurements | +| Expectation values | () or (n_obs,) | Scalar or per-observable | + +### Example + +If you provide inputs with extrinsic shapes `(4, 1)` and `(3,)`, the broadcast extrinsic +shape is `(4, 3)`. For a circuit with 1024 shots and a 3-bit classical register: + +```python +# Input extrinsic shapes: (4, 1) and (3,) → (4, 3) +# Output for classical register "meas": +# extrinsic: (4, 3) +# intrinsic: (1024, 3) - shots × bits +# full shape: (4, 3, 1024, 3) + +result = executor.run(program).result() +meas_data = result[0]["meas"] # result[0] for first program item +print(meas_data.shape) # (4, 3, 1024, 3) + +# Access a specific configuration +config_2_1 = meas_data[2, 1, :, :] # shape (1024, 3) +``` + + +Each configuration receives the full shot count specified in the quantum program. Shots are **not** divided among configurations. For example, if you request 1024 shots and have 10 configurations, each configuration runs 1024 shots (10,240 total shots executed). + + +## Randomization and the `shape` parameter + +When using a [samplex,](/docs/guides/directed-execution-model) each element of the extrinsic shape corresponds to an independent circuit +execution. The samplex typically injects randomness (for example, twirling gates) into each +execution, so even without explicitly requesting multiple randomizations, each element naturally +receives its own random realization. + +You can use the `shape` parameter to augment the extrinsic shape for the item, effectively +adding axes that correspond specifically to randomizing the same configuration many times. It must be +broadcastable from the shape implicit in your `samplex_arguments`. Axes where `shape` exceeds +the implicit shape enumerate additional independent randomizations. + +### No explicit randomization axes + +If you omit `shape` (or set it to match your input shapes), you get one execution per +input configuration. Each execution is still randomized by the samplex, but with only a +single random realization you don't benefit from averaging over multiple randomizations. + + +If you're accustomed to enabling twirling with a simple flag like `twirling=True`, +the Executor requires you to explicitly request multiple randomizations with the `shape` argument to +allow your post-processing routines to get the benefits of averaging over multiple +randomizations. A single randomization (the default when `shape` is omitted) applies +random gates but typically offers no advantage over running the base circuit without +randomization. + + +The following example demonstrates the default behavior: + +```python +program.append( + template, + samplex=samplex, + samplex_arguments={ + "parameter_values": np.random.rand(10, 3), # extrinsic (10,) + }, + # shape defaults to (10,) - one randomized execution per config +) +# Output shape for "meas": (10, num_shots, creg_size) +``` + +### Single randomization axis + +To run multiple randomizations per configuration, extend the shape with additional axes. +For example, the following code runs 20 randomizations for each of 10 parameter configurations: + +```python +program.append( + template, + samplex=samplex, + samplex_arguments={ + "parameter_values": np.random.rand(10, 3), # extrinsic (10,) + }, + shape=(20, 10), # 20 randomizations × 10 configurations +) +# Output shape for "meas": (20, 10, num_shots, creg_size) +``` + +### Multiple randomization axes + +You can organize randomizations into a multi-dimensional grid. This is useful for structured +analysis, for example, separating randomizations by type or grouping them for statistical processing. + +Here, the input extrinsic shape `(10,)` broadcasts to the requested shape `(2, 14, 10)`, +with axes 0 and 1 filled by independent randomizations. + +```python +program.append( + template, + samplex=samplex, + samplex_arguments={ + "parameter_values": np.random.rand(10, 3), # extrinsic (10,) + }, + shape=(2, 14, 10), # 2×14=28 randomizations per configuration, 10 configurations +) +# Output shape for "meas": (2, 14, 10, num_shots, creg_size) +``` + +### How `shape` and input shapes interact + +The `shape` parameter must be broadcastable *from* your input extrinsic shapes. This means: + +- Input shapes with size-1 dimensions can expand to match `shape`. +- Input shapes must align from the right with `shape`. +- Axes in `shape` that exceed the input dimensions enumerate randomizations. + +Note that `shape` can contain size-1 dimensions +that expand to match input dimensions, as is illustrated in the last row of the following table. + +Examples: + +| Input extrinsic | Shape | Result | +|:---------------:|:----------:|:-----------------------------------------------------------------:| +| (10,) | (10,) | 10 configurations, 1 randomization each | +| (10,) | (5, 10) | 10 configurations, 5 randomizations each | +| (10,) | (2, 3, 10) | 10 configurations, 2×3=6 randomizations each | +| (4, 1) | (4, 5) | 4 configurations, 5 randomizations each | +| (4, 3) | (2, 4, 3) | 4×3=12 configurations, 2 randomizations each | +| (4, 3) | (2, 1, 3) | 4×3=12 configurations, 2 randomizations each (the 1 expands to 4) | + + + +### Indexing into results + +With randomization axes, you can index into specific randomization/parameter combinations: + +```python +# Using shape=(2, 14, 10) with input extrinsic shape (10,) +result = executor.run(program).result() +meas_data = result[0]["meas"] # shape (2, 14, 10, 1024, 3) + +# Get all shots for randomization (0, 7) and parameter config 3 +specific = meas_data[0, 7, 3, :, :] # shape (1024, 3) + +# Average over all randomizations for parameter config 5 on bit 2 +averaged = meas_data[:, :, 5, :, 2].mean(axis=(0, 1)) +``` + +## Common patterns + +### Sweep a single parameter +To sweep one parameter while holding others fixed: + +```python + + # Circuit has 3 parameters, sweep first one over 20 values + sweep_values = np.linspace(0, 2*np.pi, 20) + fixed_values = [0.5, 0.3] + + parameter_values = np.column_stack([ + sweep_values, + np.full(20, fixed_values[0]), + np.full(20, fixed_values[1]), + ]) # shape (20, 3) +``` +## Next steps + + + - Review the [broadcasting](/docs/guides/pubs-broadcasting#broadcasting) overview. + - Understand [Executor inputs and outputs.](/docs/guides/executor-input-output) + diff --git a/docs/guides/executor-examples.mdx b/docs/guides/executor-examples.mdx new file mode 100644 index 00000000000..0a975291f82 --- /dev/null +++ b/docs/guides/executor-examples.mdx @@ -0,0 +1,360 @@ +--- +title: Examples +description: Practical examples of using the Executor primitive in Qiskit Runtime. + +--- +{/* cspell:ignore broadcastable */} + +The examples in this section illustrate some common ways to use the Executor primitive. Before running these examples, follow the instructions in [Install Qiskit](/docs/guides/install-qiskit) and [Get started with Executor.](/docs/guides/directed-execution-model) + +## Example: Parameterized circuit + +This example illustrates how to add circuit items with parameters, as well as how to add samplex items. + +The examples in this guide use the following circuit, which generates a three-qubit GHZ state, rotates +the qubits around the Pauli-Z axis, and measures the qubits in the computational basis. We show how +to add this circuit to a `QuantumProgram`, optionally randomizing its content with twirling +gates, and execute the program by using the `Executor` class. + +```python +from qiskit.circuit import Parameter, QuantumCircuit +from qiskit_ibm_runtime import QiskitRuntimeService, Executor +from qiskit_ibm_runtime.quantum_program import QuantumProgram +from qiskit.transpiler import generate_preset_pass_manager +import numpy as np +from samplomatic import build +from samplomatic.transpiler import generate_boxing_pass_manager + +# Generate the circuit +circuit = QuantumCircuit(3) +circuit.h(0) +circuit.h(1) +circuit.cz(0, 1) +circuit.h(1) +circuit.h(2) +circuit.cz(1, 2) +circuit.h(2) +circuit.rz(Parameter("theta"), 0) +circuit.rz(Parameter("phi"), 1) +circuit.rz(Parameter("lam"), 2) +circuit.measure_all() + +# Transpile the circuit +preset_pass_manager = generate_preset_pass_manager( + backend=backend, optimization_level=0 +) +isa_circuit = preset_pass_manager.run(circuit) + +# Initialize the service and choose a backend +service = QiskitRuntimeService() +backend = service.least_busy(operational=True, simulator=False) +``` + +### Define a `QuantumProgram` + +The input to Executor is a `QuantumProgram`. For full details, see [Executor input and output.](/docs/guides/executor-input-output#programs) Note that Samplomatic uses [`generate_boxing_pass_manager`](https://qiskit.github.io/samplomatic/guides/transpiler.html) for transpilation. + +```python +# Initialize an empty program +program = QuantumProgram(shots=1024) + + +# Append the circuit and the parameter values to the program +program.append_circuit_item( + isa_circuit, + circuit_arguments=np.random.rand(10, 3), # 10 sets of parameter values +) + +# Transpile the circuit, additionally grouping gates and measurements into annotated boxes +preset_pass_manager = generate_preset_pass_manager( + backend=backend, optimization_level=0 +) +preset_pass_manager.post_scheduling = generate_boxing_pass_manager( + enable_gates=True, + enable_measures=True, +) +boxed_circuit = preset_pass_manager.run(circuit) + +# Build the template and the samplex +template, samplex = build(boxed_circuit) + +# Append the template and samplex as a samplex item +program.append_samplex_item( + template, + samplex=samplex, + samplex_arguments={ + # the arguments required by the samplex.sample method + "parameter_values": np.random.rand(10, 3), + }, + shape=(2, 14, 10), +) +``` + +### Run the Executor job + +```python +# initialize an Executor with the default options +executor = Executor(backend) + +# Submit the job +job = executor.run(program) + +# Retrieve the result +result = job.result() +``` + +## Example: Perform PEC + +This example shows how to use a samplex item to perform probabilistic error cancellation ([PEC](/docs/guides/error-mitigation-and-suppression-techniques#pec)) for error mitigation. + +Consider a mirrored-version of a circuit with ten qubits and two unique layers of CX gates. These are the main tasks: +- Execute the circuit with twirling. +- Execute the circuit with PEC mitigation, as in [Probabilistic error cancellation with sparse Pauli-Lindblad models on noisy quantum processors](https://arxiv.org/abs/2201.09866). + +The pipeline consists of the following steps: +1. Setup: Generate the target circuit and group its operations into boxes. +2. Learning: Learn the noise of the instructions that we want to mitigate with PEC. +3. Execution: Run the circuit on a backend and analyze the results. + +### Set up the circuit + +Choose a backend and prepare a 10 qubit circuit. + +```python +from qiskit_ibm_runtime import QiskitRuntimeService + +token = "" +service = QiskitRuntimeService() + +backend = service.least_busy( + simulator=False, operational=True, min_num_qubits=100) + +# Prepare a circuit + +num_qubits = 10 +num_layers = 10 + +qubits = list(range(num_qubits)) +circuit = QuantumCircuit(num_qubits) + +for layer_idx in range(num_layers): + circuit.rx(Parameter(f"theta_{layer_idx}"), qubits) + for i in range(num_qubits // 2): + circuit.cz(qubits[2 * i], qubits[2 * i + 1]) + + circuit.rx(Parameter(f"phi_{layer_idx}"), qubits) + for i in range(num_qubits // 2 - 1): + circuit.cz(qubits[2 * i] + 1, qubits[2 * i + 1] + 1) + +circuit.draw("mpl", scale=0.35, fold=100) +``` + +Combine the circuit with its inverse to create a mirror circuit. + +```python +mirror_circuit = circuit.compose(circuit.inverse()) +mirror_circuit.measure_all() + +mirror_circuit.draw("mpl", scale=0.35, fold=100) +``` + +Set some parameter values: + +```python +import numpy as np + +parameter_values=np.random.rand(mirror_circuit.num_parameters) +``` + +Use the pass manager to transpile the circuit against our backend, and group gates and measurements into annotated boxes. Begin by creating a circuit with twirled-annotated boxes. + +```python +preset_pass_manager = generate_preset_pass_manager( + backend=backend, + initial_layout=list(range(40, 50)), # qubits 40 to 50 + optimization_level=0, +) + +# Run the boxing pass manager after the scheduling stage +preset_pass_manager.post_scheduling = generate_boxing_pass_manager( + enable_gates=True, + enable_measures=True, +) + +mirror_circuit_twirl = preset_pass_manager.run(mirror_circuit) +``` + +Next, generate a new boxed circuit with `Twirl` and `InjectNoise` annotations. + +```python +preset_pass_manager = generate_preset_pass_manager( + backend=backend, + initial_layout=list(range(40, 50)), + optimization_level=0, +) + +# Run the boxing pass manager after the scheduling stage +preset_pass_manager.post_scheduling = generate_boxing_pass_manager( + enable_gates=True, + enable_measures=True, + inject_noise_targets="gates", # no measurement mitigation + inject_noise_strategy="uniform_modification", +) + +mirror_circuit_pec = preset_pass_manager.run(mirror_circuit) +``` + +### Learn the noise + +To minimize the number of noise learning experiments, identify the unique instructions in the second circuit (the one with boxes annotated with `InjectNoise`). In defining uniqueness, two box instructions are equal if: +- Their content is equal, up to single-qubit gates. +- Their `Twirl` annotation is equal (every other annotation is disregarded). + +This leads to three unique instructions, namely the odd and even gate boxes, and the final measurement box. + +```python +from samplomatic.utils import find_unique_box_instructions + +unique_box_instructions = find_unique_box_instructions(mirror_circuit_pec.data) +assert len(unique_box_instructions) == 3 +``` + +Initialize a `NoiseLearnerV3`, choose the learning parameters by setting its options, and run a noise learning job. + +```python +from qiskit_ibm_runtime.noise_learner_v3 import NoiseLearnerV3 + +use_cached_results = True + +if use_cached_results: + learner_job = shared_service.job("d607atruf71s73cje640") +else: + learner = NoiseLearnerV3(backend) + + learner.options.shots_per_randomization = 128 + learner.options.num_randomizations = 32 + learner.options.layer_pair_depths = [0, 1, 2, 4, 16, 32] + + learner_job = learner.run(unique_box_instructions) + +learner_job.job_id() +learner_result = learner_job.result() +``` + +To convert `result` to the object required by the samplex, use the `result.to_dict` method. + +```python +noise_maps = learner_result.to_dict(instructions=unique_box_instructions, require_refs=False) +``` + +### Execute the circuits + +The `Executor` runs `QuantumProgram` objects. Each `QuantumProgram` is able to contain several *items*, which can be thought of as a template, samplex pair. + +Initialize an empty program, requesting `1000` shots for each of its items. + +```python +from qiskit_ibm_runtime.quantum_program import QuantumProgram + +# Generate a quantum program +program = QuantumProgram(shots=1000) +``` + +Next, append the template and samplex built for `mirror_circuit_twirl`, requesting `900` randomizations. This means that the samplex will produce `900` sets of parameters, and each set will be executed `1000` times in the QPU. + +```python +template_twirl, samplex_twirl = build(mirror_circuit_twirl) + +program.append_samplex_item( + template_twirl, + samplex=samplex_twirl, + samplex_arguments={"parameter_values": parameter_values}, + shape=(900,) +) +``` + +Similarly, append the template and samplex built for `mirror_circuit_pec`, requesting `900` randomizations. + +```python +template_pec, samplex_pec = build(mirror_circuit_pec) + +program.append_samplex_item( + template_pec, + samplex=samplex_pec, + samplex_arguments={ + "parameter_values": parameter_values, + "pauli_lindblad_maps": noise_maps, + "noise_scales": {ref: -1.0 for ref in noise_maps} # Set the scales to -1 for PEC + }, + shape=(900,) +) +``` + +Import `Executor` and submit a job. + +```python +from qiskit_ibm_runtime.executor import Executor + +use_cached_results = True + +if use_cached_results: + executor_job = shared_service.job("d607e2l7fc0s73aupsqg") +else: + executor = Executor(backend) + executor_job = executor.run(program) + +executor_job.job_id() + +executor_results = executor_job.result() +executor_results + +twirl_result = executor_results[0] + +print(f"Twirl result keys:\n {list(twirl_result.keys())}\n") +print(f"Shape of results: {twirl_result['meas'].shape}") + +pec_result = executor_results[1] + +print(f"PEC result keys:\n {list(pec_result.keys())}\n") +print(f"Shape of results: {pec_result['meas'].shape}") +``` + +### Analyze results + +Finally, post-process the results to estimate the expectation values of single-qubit Pauli-Z operators acting on each of the ten active qubits (expected value: `1.0`). + +```python +# Undo measurement twirling +twirl_result_unflipped = twirl_result["meas"] ^ twirl_result["measurement_flips.meas"] + +# Calculate the expectation values of single-qubit Z operators +exp_vals = 1 - 2 * twirl_result_unflipped.mean(axis=1).mean(axis=0) + +for qubit, val in enumerate(exp_vals): + print(f"Qubit {qubit} -> {np.round(val, 2)}") +``` + +```python +# Undo measurement twirling +pec_result_unflipped = pec_result["meas"] ^ pec_result["measurement_flips.meas"] + +# Calculate the signs for PEC mitigation +signs = np.prod((-1)**pec_result["pauli_signs"], axis=-1) +signs = signs.reshape((signs.shape[0], 1)) + +# Calculate the expectation values of single-qubit Z operators as required by +# PEC mitigation +exp_vals = 1 - (2 * pec_result_unflipped.mean(axis=1) * signs).mean(axis=0) + +for qubit, val in enumerate(exp_vals): + print(f"Qubit {qubit} -> {np.round(val, 2)}") +``` + +## Next steps + + + - Review the [broadcasting](/docs/guides/pubs-broadcasting#broadcasting) overview. + - Learn how to use [Executor options.](/docs/guides/executor-options) + - Understand the [directed execution model.](/docs/guides/directed-execution-model) + - Review the [Samplomatic documentation.](https://qiskit.github.io/samplomatic/) + diff --git a/docs/guides/executor-input-output.mdx b/docs/guides/executor-input-output.mdx new file mode 100644 index 00000000000..cc6c1396924 --- /dev/null +++ b/docs/guides/executor-input-output.mdx @@ -0,0 +1,147 @@ +--- +title: Inputs and outputs +description: Understand the inputs and outputs to the Executor primitive. + +--- + +# Executor inputs and outputs + +The inputs and output of the Executor primitive are very different from those of the Sampler and Estimator primitives. As part of the [directed execution model,](/docs/guides/directed-execution-model) the Executor primitive helps provide more flexibility when customizing your error mitigation workflow. This primitive takes a `QuantumProgram` as input, and outputs a Qiskit Runtime job, which is then run on an IBM® quantum computer. + + +## Inputs: Quantum programs + +The input to an Executor primitive is a [`QuantumProgram`](https://qiskit.github.io/qiskit-ibm-runtime/stubs/qiskit_ibm_runtime.quantum_program.QuantumProgram.html#qiskit_ibm_runtime.quantum_program.QuantumProgram), which is an iterable of a +[`qiskit_ibm_runtime.quantum_program.QuantumProgramItem`.](https://qiskit.github.io/qiskit-ibm-runtime/stubs/qiskit_ibm_runtime.quantum_program.QuantumProgramItem.html) Each of these items represents a +different task for Executor to perform. Typically, each item owns one of the following options: + +* A `qiskit.circuit.QuantumCircuit` with static, non-parametrized gates +* A parametrized `qiskit.circuit.QuantumCircuit` with an array of parameter values +* A parametrized `qiskit.circuit.QuantumCircuit` with a `samplomatic.samplex.Samplex` to generate randomized arrays of parameter values + +Each of these items, including instructions to add them to a `QuantumProgram`, is explained in more detail below. + +The following cell initializes a `QuantumProgram` and specifies that it should run 1024 shots for every configuration of each item in the program. Then it appends a version of the target circuit with set parameters, transpiled according to the backend's ISA. + +```python +from qiskit.transpiler import generate_preset_pass_manager +from qiskit_ibm_runtime.quantum_program import QuantumProgram +import numpy as np +from samplomatic import build +from samplomatic.transpiler import generate_boxing_pass_manager + +# Initialize an empty program +program = QuantumProgram(shots=1024) + +# Initialize and transpile a circuit +circuit = ... +... +isa_circuit = preset_pass_manager.run(circuit) + +# Append the circuit to the program +program.append_circuit_item(isa_circuit) +``` + +Next, append a second item that contains a parametrized `qiskit.circuit.QuantumCircuit` and an array containing 10 sets of parameter values. This amounts to a circuit task requiring a total of 10240 shots (1024 per set of parameter values). + +```python +# Append the circuit and the parameter values to the program +program.append_circuit_item( + parametrized_isa_circuit, + circuit_arguments=np.random.rand(10, 3), # 10 sets of parameter values +) +``` + +Finally, append a parametrized `qiskit.circuit.QuantumCircuit` and a `samplomatic.samplex.Samplex`, which is responsible for generating randomized sets of parameters for the given circuit. As part of the `samplomatic.samplex.Samplex` arguments, `10` sets of parameters for the parametric gates in the original circuit are provided. The `shape` request argument requests an extension of the implicit shape defined by the `samplomatic.samplex.Samplex` arguments. In particular, by setting `shape` +to `(2, 14, 10)` we request to randomize each of the `10` sets of parameters `28` times, and to arrange the randomized parameter sets in an array of shape `(2, 14, 10)`. + +See the samplomatic [API](https://github.com/Qiskit/samplomatic/) documentation for full details about `samplomatic.samplex.Samplex` and its arguments. + +```python +# Transpile the circuit, additionally grouping gates and measurements into annotated boxes +preset_pass_manager = generate_preset_pass_manager( + backend=backend, optimization_level=0 +) +preset_pass_manager.post_scheduling = generate_boxing_pass_manager( + enable_gates=True, + enable_measures=True, +) +boxed_circuit = preset_pass_manager.run(circuit) + +# Build the template and the samplex +template, samplex = build(boxed_circuit) + +# Append the template and samplex as a samplex item +program.append_samplex_item( + template, + samplex=samplex, + samplex_arguments={ + # the arguments required by the samplex.sample method + "parameter_values": np.random.rand(10, 3), + }, + shape=(2, 14, 10), +) +``` + +## Outputs + +Executor's output is a [`qiskit_ibm_runtime.quantum_program.QuantumProgramResult`,](https://qiskit.github.io/qiskit-ibm-runtime/stubs/qiskit_ibm_runtime.quantum_program.QuantumProgramResult.html#qiskit_ibm_runtime.quantum_program.QuantumProgramResult) which is an iterable. It contains one +item per circuit task, and the items are in the same order as those in the program. Each of +these items is a dictionary where the keys are strings and the values are of type `np.ndarray`, with elements of type `bool`. + +In the previous example, the result contains three items: + +### Result item 0 +The first item in `result` is the result of running the first task in the program, the circuit with static gates. + +It contains a single key, `'meas'`, corresponding to the name of the input circuit's +classical register, mapped to the results collected for this +classical register. The information is stored in an `np.ndarray` of shape `(shots, register bits)`, for the above example, `(1024, 3)`. + +The following code illustrates how to access this information: + +```python +# Access the results of the classical register of task #0 +result_0 = result[0]["meas"] +print(f"Result shape: {result_0.shape}") +``` + +### Result item 1 + +The second item contains the results of running the second task in the program, +the circuit with parametrized gates. + +It contains a single key, `'meas'`, mapped to an `np.ndarray` of shape `(shots, parameter sets, register bits)`, for the above example, `(1024, 10, 3)`. + +The following code illustrates how to access this information: + +```python +# Access the results of the classical register of task #1 +result_1 = result[1]["meas"] +print(f"Result shape: {result_1.shape}") +``` + +### Result item 2 +The third item contains the results of running the third task in the program. This item +contains multiple keys. In addition to the `'meas'` key (mapped to the array of results for +that classical register), it contains `'measurement_flips.meas'`, the bit-flip corrections to undo +the measurement twirling for the `'meas'` register, as follows: + +```python +# Access the results of the classical register of task #2 +result_2 = result[2]["meas"] +print(f"Result shape: {result_2.shape}") + +# Access the bit-flip corrections +flips_2 = result[2]["measurement_flips.meas"] +print(f"Bit-flip corrections: {result_2.flips_2}") + +# Undo the bit flips via classical XOR +unflipped_result_2 = result_2 ^ flips_2 +``` + +## Next steps + + + - Explore [examples](/docs/guides/executor-examples) that use Executor. + diff --git a/docs/guides/executor-options.mdx b/docs/guides/executor-options.mdx new file mode 100644 index 00000000000..6450d5551b7 --- /dev/null +++ b/docs/guides/executor-options.mdx @@ -0,0 +1,100 @@ +--- +title: Specify options +description: Specify options when building with the Qiskit Runtime Executor primitive. + +--- + +# Specify Executor options + +You can use options to customize the Executor primitive. This section focuses on how to specify Qiskit Runtime primitive options. Consult the API reference for information about the [`ExecutorOptions`](https://qiskit.github.io/qiskit-ibm-runtime/stubs/qiskit_ibm_runtime.options.ExecutorOptions.html) class. + +Notes about specifying options in the primitives: + +- You can see the available options and update option values during or after primitive initialization. +- Use the `update()` method to apply changes to the `options` attribute. +- The `options` attribute is the `dataclass` Python type. You can use the built-in `asdict` method to convert it to a dictionary. + + +## Set Executor options + +You can set options when initializing the primitive or after initializing the primitive. If an option is specified in both locations, the value set after initializing the primitive is used. + +### Primitive initialization + +You can pass in an instance of the options class or a dictionary when initializing Executor, which then makes a copy of those options. Thus, changing the original dictionary or options instance doesn't affect the options owned by the primitive. + +#### Options class + +When creating an instance of the `Executor` class, you can pass in an instance of the options class. Those options will then be applied when you use `run()` to perform the calculation. Specify the options in this format: `options.option.sub-option.sub-sub-option = choice`. For example: `options.log_level = INFO` + +See [`ExecutorOptions`](https://qiskit.github.io/qiskit-ibm-runtime/stubs/qiskit_ibm_runtime.options.ExecutorOptions.html) for full details about the options class. + +Example: + +```python +from qiskit_ibm_runtime import QiskitRuntimeService, Executor +from qiskit_ibm_runtime.options import ExecutorOptions + +service = QiskitRuntimeService() +backend = service.least_busy(operational=True, simulator=False) + +options = ExecutorOptions( + environment={"log_level": INFO}, + execution={"init_qubits": True}, +) + +# or... +options = ExecutorOptions() +options.environment.log_level = INFO +options.execution.init_qubits = True + +executor = Executor(mode=backend, options=options) +``` + +#### Dictionary + +You can specify options as a dictionary when initializing Executor. + +```python +from qiskit_ibm_runtime import QiskitRuntimeService, executor + +service = QiskitRuntimeService() +backend = service.least_busy(operational=True, simulator=False) + +# Setting options during primitive initialization +executor = Executor( + backend, + options={ + "environment"={"log_level": INFO}, + "execution"={"init_qubits": True}, + }, +) +``` + +### Update options after initialization + +You can specify the options in this format: `executor.options.option.sub-option.sub-sub-option = choice` to take advantage of auto-complete, or use the `update()` method to make bulk updates. + +Executor's options class ([`ExecutorOptions`](https://qiskit.github.io/qiskit-ibm-runtime/stubs/qiskit_ibm_runtime.options.ExecutorOptions.html)) does not need to be instantiated if you are setting options after initializing the primitive. + +```python +from qiskit_ibm_runtime import QiskitRuntimeService, Executor + +service = QiskitRuntimeService() +backend = service.least_busy(operational=True, simulator=False) + +executor = Executor(mode=backend) + +# Setting options after primitive initialization +# This uses auto-complete. +executor.options.environment.log_level = INFO +# This does bulk update. +executor.options.update(environment={"log_level": INFO} +) +``` +## Next steps + + + - Review the [ExecutionOptionsV2](/docs/api/qiskit-ibm-runtime/options-execution-options-v2) API documentation. + - Review the [EnvironmentOptions](/docs/api/qiskit-ibm-runtime/options-environment-options) API documentation. + diff --git a/docs/guides/fractional-gates.ipynb b/docs/guides/fractional-gates.ipynb index b184153f151..77dacdba920 100644 --- a/docs/guides/fractional-gates.ipynb +++ b/docs/guides/fractional-gates.ipynb @@ -66,7 +66,7 @@ "Internally, these fractional gates work by directly executing an $R_{ZZ}(\\theta)$ and $R_X(\\theta)$ rotation for an arbitrary angle. Use of the $R_X(\\theta)$ gate can reduce the duration and error for single-qubit rotations of arbitrary angle by up to a factor of two. The direct execution of the $R_{ZZ}(\\theta)$ gate rotation avoids decomposition into multiple `CZGate` objects, similarly reducing a circuit's duration and error. This is especially useful for circuits that contain many single- and two-qubit rotations, such as when simulating the dynamics of a quantum system or when using a variational ansatz with many parameters.\n", "\n", "\n", - "While these types of gates are in the [library of standard gates](./circuit-library) which a `QuantumCircuit` can possess, they can only be used on specific IBM Quantum QPUs, and which must be loaded with the flag `use_fractional_gates` set to `True` (shown below). This flag will ensure that fractional gates are included in the backend's `Target` for the transpiler.\n", + "While these types of gates are in the [library of standard gates](/docs/guides/circuit-library) which a `QuantumCircuit` can possess, they can only be used on specific IBM Quantum QPUs, and which must be loaded with the flag `use_fractional_gates` set to `True` (shown below). This flag will ensure that fractional gates are included in the backend's `Target` for the transpiler.\n", "\n", "```python\n", "service = QiskitRuntimeService()\n", diff --git a/docs/guides/function-template-chemistry-workflow.ipynb b/docs/guides/function-template-chemistry-workflow.ipynb index 547034d2792..f354e46c34c 100644 --- a/docs/guides/function-template-chemistry-workflow.ipynb +++ b/docs/guides/function-template-chemistry-workflow.ipynb @@ -699,7 +699,7 @@ "\n", "\n", "\n", - "- Review the guide on building a function template for [Hamiltonian simulation](./function-template-hamiltonian-simulation)\n", + "- Review the guide on building a function template for [Hamiltonian simulation](/docs/guides/function-template-hamiltonian-simulation)\n", "- Check out the source files for this template on [GitHub](https://github.com/qiskit-community/qiskit-function-templates/tree/main/chemistry/sqd_pcm)\n", "\n", "" diff --git a/docs/guides/functions.ipynb b/docs/guides/functions.ipynb index 11c0e659cb0..98dd97ed43a 100644 --- a/docs/guides/functions.ipynb +++ b/docs/guides/functions.ipynb @@ -81,7 +81,7 @@ "|----------------------------------------------------------------------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n", "| [Tensor-Network Error Mitigation](/docs/guides/algorithmiq-tem) | Algorithmiq | Workloads that have low-weight observables and loop-free circuits. | Reduces measurement overhead and variance, outperforming standard error mitigation baselines such as Zero Noise Extrapolation (ZNE) and Probabilistic Error Cancellation (PEC) for relevant circuit classes. |\n", "| [QESEM: Error Suppression and Error Mitigation](/docs/guides/qedma-qesem) | Qedma | Workloads that include circuits with fractional or parameterized gates, high-weight observables, and workflows that require unbiased expectation values and accurate runtime estimates. | Produces unbiased expectation values with lower variance and resource overhead, outperforming ZNE and PEC for relevant circuit classes. |\n", - "| [Performance Management](/docs/guides/q-ctrl-performance-management) | Q-CTRL | Workloads that contain parametric circuits, deep circuits, or require many circuit executions. | Automatically applies AI-driven error suppression to quantum algorithms, maximizing the performance of IBM devices to deliver accurate results while reducing the number of shots, compute time, and cost required.

Zero-overhead method that improves execution accuracy for the Sampler and the Estimator primitives, compatible with any weight of observables. |\n", + "| [Performance Management](/docs/guides/q-ctrl-performance-management) | Q-CTRL | Workloads that contain parametric circuits, deep circuits, or require many circuit executions. | Automatically applies AI-driven error suppression to quantum algorithms, maximizing the performance of IBM devices to deliver accurate results while reducing the number of shots, compute time, and cost required.

Zero-overhead method that improves execution accuracy for the Sampler and Estimator primitives, compatible with any weight of observables. |\n", "\n", "\n", "### Application functions\n", @@ -520,8 +520,8 @@ "\n", "\n", "\n", - "- [Explore circuit functions](./ibm-circuit-function) to build new algorithms and applications, without needing to manage transpilation or error handling.\n", - "- [Explore application functions](./q-ctrl-optimization-solver) to solve domain-specific tasks, with classical inputs and outputs.\n", + "- [Explore circuit functions](/docs/guides/ibm-circuit-function) to build new algorithms and applications, without needing to manage transpilation or error handling.\n", + "- [Explore application functions](/docs/guides/q-ctrl-optimization-solver) to solve domain-specific tasks, with classical inputs and outputs.\n", "\n", "" ] diff --git a/docs/guides/get-started-with-primitives.ipynb b/docs/guides/get-started-with-estimator.ipynb similarity index 84% rename from docs/guides/get-started-with-primitives.ipynb rename to docs/guides/get-started-with-estimator.ipynb index c38127c47c5..c308f940a36 100644 --- a/docs/guides/get-started-with-primitives.ipynb +++ b/docs/guides/get-started-with-estimator.ipynb @@ -6,17 +6,12 @@ "metadata": {}, "source": [ "---\n", - "title: Get started with primitives\n", - "description: How to use the Estimator and Sampler primitives in Qiskit Runtime.\n", + "title: Get started\n", + "description: How to use the Estimator primitive in Qiskit Runtime.\n", "---\n", "\n", "\n", - "# Get started with primitives\n", - "\n", - "\n", - "The beta release of a new execution model is now available. The directed execution model provides more flexibility when customizing your error mitigation workflow. See the [Directed execution model](/docs/guides/directed-execution-model) guide for more information.\n", - "\n", - "\n", + "# Get started with the Estimator primitive\n", "\n", "\n", "While this documentation uses the primitives from Qiskit Runtime, which allow you to use IBM® backends, the primitives can be run on any provider by using the [backend primitives](#backend) instead. Additionally, you can use the *reference* primitives to run on a local statevector simulator. See [Exact simulation with Qiskit primitives](/docs/guides/simulate-with-qiskit-sdk-primitives) for details.\n", @@ -31,7 +26,7 @@ "The steps in this topic describe how to set up primitives, explore the options you can use to configure them, and invoke them in a program.\n", "\n", "\n", - " To use the newly supported [fractional gates](./fractional-gates), set `use_fractional_gates=True` when requesting a backend from a `QiskitRuntimeService` instance. For example:\n", + " To use the newly supported [fractional gates](/docs/guides/fractional-gates), set `use_fractional_gates=True` when requesting a backend from a `QiskitRuntimeService` instance. For example:\n", " ```python\n", " service = QiskitRuntimeService()\n", " fractional_gate_backend = service.least_busy(use_fractional_gates=True)\n", @@ -76,16 +71,15 @@ "id": "bafa61f0-c049-4ee6-ac76-a0ed97e67caf", "metadata": {}, "source": [ - "\n", - "## Get started with Estimator\n", - "\n", "{/*Verified the v2 examples 2/29/24 - updated 10/29/24*/}\n", "\n", + "## Steps to use the Estimator primitive\n", + "\n", "### 1. Initialize the account\n", "\n", "Because Qiskit Runtime Estimator is a managed service, you first need to initialize your account. You can then select the QPU you want to use to calculate the expectation value.\n", "\n", - "Follow the steps in the [Install and set up topic](install-qiskit) if you don't already have an account." + "Follow the steps in the [Set up your IBM Cloud account](cloud-setup) if you don't already have an account." ] }, { @@ -202,7 +196,7 @@ "source": [ "### 3. Initialize Qiskit Runtime Estimator\n", "\n", - "When you initialize the Estimator, use the `mode` parameter to specify the mode you want it to run in. Possible values are `batch`, `session`, or `backend` objects for batch, session, and job execution mode, respectively. For more information, see [Introduction to Qiskit Runtime execution modes](execution-modes)." + "When you initialize Estimator, use the `mode` parameter to specify the mode you want it to run in. Possible values are `batch`, `session`, or `backend` objects for batch, session, and job execution mode, respectively. For more information, see [Introduction to Qiskit Runtime execution modes.](execution-modes)" ] }, { @@ -222,7 +216,7 @@ "id": "59b13a43-0c9f-4fdb-a379-af5115c153e1", "metadata": {}, "source": [ - "### 4. Invoke the Estimator and get results\n", + "### 4. Invoke Estimator and get results\n", "\n", "Next, invoke the `run()` method to calculate expectation values for the input circuits and observables. The circuit, observable, and optional parameter value sets are input as *primitive unified bloc* (PUB) tuples." ] @@ -452,13 +446,12 @@ "metadata": {}, "source": [ "\n", - "## Get started with the backend primitives\n", + "## Get started with the Estimator backend primitive\n", "\n", "Unlike provider-specific primitives, backend primitives are generic implementations that can be used with an arbitrary\n", "`backend` object, as long as it implements the [`Backend`](/docs/api/qiskit/qiskit.providers.Backend) interface.\n", "\n", - "- The Sampler primitive can be run with any provider by using [`qiskit.primitives.BackendSamplerV2`](/docs/api/qiskit/qiskit.primitives.BackendSamplerV2).\n", - "- The Estimator primitive can be run with any provider by using [`qiskit.primitives.BackendEstimatorV2`](../api/qiskit/qiskit.primitives.BackendEstimatorV2).\n", + "The Estimator primitive can be run with any provider by using [`qiskit.primitives.BackendEstimatorV2`](/docs/api/qiskit/qiskit.primitives.BackendEstimatorV2).\n", "\n", "Some providers implement primitives natively. See the [Qiskit Ecosystem page](https://qiskit.github.io/ecosystem#provider) for details." ] @@ -468,7 +461,7 @@ "id": "9d78f323-1c58-4360-8880-59179c8a14b7", "metadata": {}, "source": [ - "### Example: BackendEstimator\n", + "### Example:\n", "\n", "```python\n", "from qiskit.primitives import BackendEstimatorV2\n", @@ -477,17 +470,6 @@ "provider = QiskitProvider()\n", "backend = provider.get_backend('backend_name')\n", "estimator = BackendEstimatorV2(backend)\n", - "```\n", - "\n", - "### Example: BackendSampler\n", - "\n", - "```python\n", - "from qiskit.primitives import BackendSamplerV2\n", - "from import QiskitProvider\n", - "\n", - "provider = QiskitProvider()\n", - "backend = provider.get_backend('backend_name')\n", - "sampler = BackendSamplerV2(backend)\n", "```" ] }, @@ -498,16 +480,14 @@ "source": [ "### Similarities and differences between backend and Runtime primitives\n", "\n", - "- The inputs to and outputs from [`qiskit.primitives.BackendSamplerV2`](/docs/api/qiskit/qiskit.primitives.BackendSamplerV2) and [`qiskit.primitives.BackendEstimatorV2`](../api/qiskit/qiskit.primitives.BackendEstimatorV2)\n", - "follow the same PUB format as the primitives in Qiskit Runtime. See [Primitive inputs and outputs](primitive-input-output) for details.\n", + "- The inputs to and outputs from [`qiskit.primitives.BackendEstimatorV2`](/docs/api/qiskit/qiskit.primitives.BackendEstimatorV2)\n", + "follow the same PUB format as the primitives in Qiskit Runtime. See [PUBs](/docs/guides/pubs-broadcasting#pubs) for details.\n", "However, there can be differences in the fields of the returned metadata.\n", "\n", "- The [`qiskit.primitives.BackendEstimatorV2`](/docs/api/qiskit/qiskit.primitives.BackendEstimatorV2) class offers no measurement or gate error mitigation implementations out-of-the-box, as\n", "backend primitives are designed to run locally in the user's machine.\n", "\n", - "- The [`qiskit.primitives.BackendSamplerV2`](/docs/api/qiskit/qiskit.primitives.BackendSamplerV2) class requires a backend that supports the `memory` option.\n", - "\n", - "- The backend primitive interfaces expose custom [`SamplerV2`](/docs/api/qiskit/qiskit.primitives.BackendSamplerV2) and [`EstimatorV2`](/docs/api/qiskit/qiskit.primitives.BackendEstimatorV2) `Options` that are different from the Runtime implementations." + "- The backend primitive interfaces expose custom [`EstimatorV2`](/docs/api/qiskit/qiskit.primitives.BackendEstimatorV2) `Options` that are different from the Runtime implementations." ] }, { @@ -519,12 +499,12 @@ "\n", "\n", " - Learn how to [test locally](local-testing-mode) before running on quantum computers.\n", - " - Review detailed [primitives examples](/docs/guides/primitives-examples).\n", + " - Review detailed [examples.](/docs/guides/estimator-examples)\n", " - Practice with primitives by working through the [Cost function lesson](/learning/courses/variational-algorithm-design/cost-functions) in IBM Quantum Learning.\n", - " - Learn how to transpile locally in the [Transpile](transpile/) section.\n", + " - Learn how to transpile locally in the [Transpile](/docs/guides/transpile/) section.\n", " - Try the [Compare transpiler settings](/docs/guides/circuit-transpilation-settings#compare-transpiler-settings) guide.\n", - " - Learn how to [use the primitive options](runtime-options-overview).\n", - " - View the API for [Sampler](/docs/api/qiskit-ibm-runtime/options-sampler-options) and [Estimator](/docs/api/qiskit-ibm-runtime/options-estimator-options) options.\n", + " - Learn how to [use the primitive options.](runtime-options-overview)\n", + " - View the API for [Estimator](/docs/api/qiskit-ibm-runtime/options-estimator-options) options.\n", " - Read [Migrate to V2 primitives](/docs/guides/v2-primitives).\n", "" ] diff --git a/docs/guides/get-started-with-executor.mdx b/docs/guides/get-started-with-executor.mdx new file mode 100644 index 00000000000..20c06cc4bdf --- /dev/null +++ b/docs/guides/get-started-with-executor.mdx @@ -0,0 +1,45 @@ +--- +title: Get started +description: How to use the Executor primitive in Qiskit Runtime. + +--- + +# Get started with the Executor primitive +The Executor primitive is part of the directed execution model, which provides more flexibility when customizing your error mitigation workflow. See the [Directed execution model](/docs/guides/directed-execution-model) guide for more information. + +## Steps to get started with Executor + +There are three basic steps involved in using the Executor primitive: +1. Initialize a `QuantumProgram` with your workload. +2. Run the `QuantumProgram` on IBM® backends by using the `Executor` primitive. +3. Interpret the outputs. + +See [Executor examples](/docs/guides/executor-examples) for a full walkthrough. + +## Run an Executor job + +The following code shows how to initialize an Executor with the default options. See [Executor options](/docs/guides/executor-options) to learn about the available options. + +```python +from qiskit_ibm_runtime import Executor + +executor = Executor(backend) +``` +Next, use the `run()` method to submit the job. + +```python +job = executor.run(program) + +# Retrieve the result +result = job.result() +``` + +The result is of type [`QuantumProgramResult`.](https://qiskit.github.io/qiskit-ibm-runtime/stubs/qiskit_ibm_runtime.quantum_program.QuantumProgramResult.html#qiskit_ibm_runtime.quantum_program.QuantumProgramResult) See [Executor input and output](/docs/guides/executor-input-output) to learn about the result object. + +## Next steps + + + - Try some [Executor examples.](/docs/guides/executor-examples) + - Understand [Executor input and output.](/docs/guides/executor-input-output) + - Learn about [Executor broadcasting semantics.](/docs/guides/executor-broadcasting) + diff --git a/docs/guides/get-started-with-sampler.ipynb b/docs/guides/get-started-with-sampler.ipynb new file mode 100644 index 00000000000..301f58be89a --- /dev/null +++ b/docs/guides/get-started-with-sampler.ipynb @@ -0,0 +1,319 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "008d2ceb-f6fa-42f6-a7df-6bd604775278", + "metadata": {}, + "source": [ + "---\n", + "title: Get started\n", + "description: How to use the Sampler primitive in Qiskit Runtime.\n", + "---\n", + "\n", + "\n", + "# Get started with the Sampler primitive\n", + "\n", + "\n", + "While this documentation uses the primitives from Qiskit Runtime, which allow you to use IBM® backends, the primitives can be run on any provider by using the [backend primitives](#backend) instead. Additionally, you can use the *reference* primitives to run on a local statevector simulator. See [Exact simulation with Qiskit primitives](/docs/guides/simulate-with-qiskit-sdk-primitives) for details.\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "b7e96291-0925-4d7f-81a8-a7738549477c", + "metadata": {}, + "source": [ + "The steps in this topic describe how to set up primitives, explore the options you can use to configure them, and invoke them in a program.\n", + "\n", + "\n", + " To use the newly supported [fractional gates](/docs/guides/fractional-gates), set `use_fractional_gates=True` when requesting a backend from a `QiskitRuntimeService` instance. For example:\n", + " ```python\n", + " service = QiskitRuntimeService()\n", + " fractional_gate_backend = service.least_busy(use_fractional_gates=True)\n", + " ```\n", + "\n", + " Note that this is an experimental feature and might change in the future.\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "818a2b3d-3950-4a28-8e37-39959c56484b", + "metadata": { + "tags": [ + "version-info" + ] + }, + "source": [ + "{/*\n", + " DO NOT EDIT THIS CELL!!!\n", + " This cell's content is generated automatically by a script. Anything you add\n", + " here will be removed next time the notebook is run. To add new content, create\n", + " a new cell before or after this one.\n", + "*/}\n", + "\n", + "
\n", + "Package versions\n", + "\n", + "The code on this page was developed using the following requirements.\n", + "We recommend using these versions or newer.\n", + "\n", + "```\n", + "qiskit[all]~=2.3.0\n", + "qiskit-ibm-runtime~=0.43.1\n", + "```\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "64e2e09f-8528-4088-897b-1529b451ab1e", + "metadata": {}, + "source": [ + "## Steps to use the Sampler primitive\n", + "### 1. Initialize the account\n", + "\n", + "Because Qiskit Runtime Sampler is a managed service, you first need to initialize your account. You can then select the QPU you want to use to calculate the expectation value.\n", + "\n", + "Follow the steps in the [Set up your IBM Cloud account](/docs/guides/cloud-setup) topic if you don't already have an account set up." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "b40504d7-aee5-4b30-98b1-265e70bece8d", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=127\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "73374fbc-d3b6-4d2d-84c6-edf85b43ea25", + "metadata": {}, + "source": [ + "### 2. Create a circuit\n", + "\n", + "You need at least one circuit as the input to the Sampler primitive." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "dfe23a34-2ea9-48af-bd1d-c7e3185aa80c", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import efficient_su2\n", + "\n", + "circuit = efficient_su2(127, entanglement=\"linear\")\n", + "circuit.measure_all()\n", + "# The circuit is parametrized, so we will define the parameter values for execution\n", + "param_values = np.random.rand(circuit.num_parameters)" + ] + }, + { + "cell_type": "markdown", + "id": "6cf08ef6-34d3-42e6-8cb3-391b60217289", + "metadata": {}, + "source": [ + "Use the transpiler to get an ISA circuit." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "062bd89b-b13e-46d0-96b6-6c84b2131415", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ">>> Circuit ops (ISA): OrderedDict([('sx', 3089), ('rz', 3036), ('cz', 1092), ('measure', 127), ('barrier', 1)])\n" + ] + } + ], + "source": [ + "from qiskit.transpiler import generate_preset_pass_manager\n", + "\n", + "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n", + "isa_circuit = pm.run(circuit)\n", + "print(f\">>> Circuit ops (ISA): {isa_circuit.count_ops()}\")" + ] + }, + { + "cell_type": "markdown", + "id": "cf0f2c0a-8574-45c6-a43b-1a99eac81279", + "metadata": {}, + "source": [ + "### 3. Initialize the Qiskit Runtime Sampler\n", + "\n", + "When you initialize Sampler, use the `mode` parameter to specify the mode you want it to run in. Possible values are `batch`, `session`, or `backend` objects for batch, session, and job execution mode, respectively. For more information, see [Introduction to Qiskit Runtime execution modes.](execution-modes) Note that Open Plan users cannot submit session jobs." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "a2b80dca-dff8-49f9-8154-e2cb0b768507", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit_ibm_runtime import SamplerV2 as Sampler\n", + "\n", + "sampler = Sampler(mode=backend)" + ] + }, + { + "cell_type": "markdown", + "id": "f35972bf-17d3-40be-852b-9e56615c7c3c", + "metadata": {}, + "source": [ + "### 4. Invoke Sampler and get results\n", + "\n", + "Next, invoke the `run()` method to generate the output. The circuit and optional parameter value sets are input as *primitive unified bloc* (PUB) tuples." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "e52e6a96-dc23-4f76-8152-b54514a99dfb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ">>> Job ID: d5k96rsjt3vs73ds5tig\n", + ">>> Job Status: QUEUED\n" + ] + } + ], + "source": [ + "job = sampler.run([(isa_circuit, param_values)])\n", + "print(f\">>> Job ID: {job.job_id()}\")\n", + "print(f\">>> Job Status: {job.status()}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "4543fac5-abdc-4440-a1a2-d32aabe135d6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "First ten results for the 'meas' output register: ['0101001101010000011001110001011000010010001100001000100110011111011110000010110001101000110011101010000100011011000110101111000', '0100111000000100110001100100000101111000111001101000110111101110110010010100001101001111001010011101010000010011000110000010001', '0101111101111111010011010101000000110100000010000010011101100011100011001100000100100001000101000000100001010101010011001101100', '1100110101111111001110010000010100101010101010001000001100100110011111010000000010001000110111010000010101100000100000110111001', '0010000001111001111010100100010111101000101000100000101100001000011100000100011010110110100011100110001001110110111101010011000', '0101110000001000100100010010100100111000010100000000010010000000010110010010000110000001110110010100000111001110100100111101100', '0100011111101001000111110011011101101101110101110001010111011101111110011101001000000001110000011110000101010000001010000100000', '0001010101011000110100000100111111100001011000111110000011000111001101010000010001001100000110000000100000110101010010101110010', '0100011010001110011110000110100101100100101001001111010100100101010100010000000010100000101010110010000000001000010101011111110', '0000011000000111000001000101111111110110101100110000001100010010011101011100001010000100011010001010001101000000000000010001001']\n" + ] + } + ], + "source": [ + "result = job.result()\n", + "\n", + "# Get results for the first (and only) PUB\n", + "pub_result = result[0]\n", + "print(\n", + " f\"First ten results for the 'meas' output register: {pub_result.data.meas.get_bitstrings()[:10]}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "ec04840d-5fa1-4716-b585-48aa371f67d4", + "metadata": {}, + "source": [ + "\n", + "## Get started with the Sampler backend primitive\n", + "\n", + "Unlike provider-specific primitives, backend primitives are generic implementations that can be used with an arbitrary\n", + "`backend` object, as long as it implements the [`Backend`](/docs/api/qiskit/qiskit.providers.Backend) interface.\n", + "\n", + "The Sampler primitive can be run with any provider by using [`qiskit.primitives.BackendSamplerV2`](/docs/api/qiskit/qiskit.primitives.BackendSamplerV2).\n", + "\n", + "Some providers implement primitives natively. See the [Qiskit Ecosystem page](https://qiskit.github.io/ecosystem#provider) for details." + ] + }, + { + "cell_type": "markdown", + "id": "9d78f323-1c58-4360-8880-59179c8a14b7", + "metadata": {}, + "source": [ + "### Example:\n", + "\n", + "```python\n", + "from qiskit.primitives import BackendSamplerV2\n", + "from import QiskitProvider\n", + "\n", + "provider = QiskitProvider()\n", + "backend = provider.get_backend('backend_name')\n", + "sampler = BackendSamplerV2(backend)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "e620a7b2-233d-4e0d-8a42-ee4eda3ccd8d", + "metadata": {}, + "source": [ + "### Similarities and differences between backend and Runtime primitives\n", + "\n", + "- The inputs to and outputs from [`qiskit.primitives.BackendSamplerV2`](/docs/api/qiskit/qiskit.primitives.BackendSamplerV2)\n", + "follow the same PUB format as the primitives in Qiskit Runtime. See [PUBs](/docs/guides/pubs-broadcasting#pubs) for details.\n", + "However, there can be differences in the fields of the returned metadata.\n", + "\n", + "- The [`qiskit.primitives.BackendSamplerV2`](/docs/api/qiskit/qiskit.primitives.BackendSamplerV2) class requires a backend that supports the `memory` option.\n", + "\n", + "- The backend primitive interfaces expose custom [`SamplerV2`](/docs/api/qiskit/qiskit.primitives.BackendSamplerV2) `Options` that are different from the Runtime implementations." + ] + }, + { + "cell_type": "markdown", + "id": "d38dd409-e0d8-4749-bb22-58ae9a53d26a", + "metadata": {}, + "source": [ + "## Next steps\n", + "\n", + "\n", + " - Learn how to [test locally](local-testing-mode) before running on quantum computers.\n", + " - Review detailed [examples.](sampler-examples)\n", + " - Practice with primitives by working through the [Cost function lesson](/learning/courses/variational-algorithm-design/cost-functions) in IBM Quantum Learning.\n", + " - Learn how to transpile locally in the [Transpile](transpile/) section.\n", + " - Try the [Compare transpiler settings](/docs/guides/circuit-transpilation-settings#compare-transpiler-settings) guide.\n", + " - Learn how to [use the primitive options.](/docs/guides/runtime-options-overview)\n", + " - View the API for [Sampler](/docs/api/qiskit-ibm-runtime/options-sampler-options) options.\n", + " - Read [Migrate to V2 primitives](/docs/guides/v2-primitives).\n", + "" + ] + } + ], + "metadata": { + "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" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/guides/global-data-quantum-optimizer.ipynb b/docs/guides/global-data-quantum-optimizer.ipynb index aafc0dd07de..9651daaad3b 100644 --- a/docs/guides/global-data-quantum-optimizer.ipynb +++ b/docs/guides/global-data-quantum-optimizer.ipynb @@ -327,8 +327,8 @@ "source": [ "| Name | Type | Description | Required | Default | Example |\n", "|-------------------|--------|--------------------------------------------|----------|----------------------------|----------------------------|\n", - "| sampler_shots | int | Number of shots of the Sampler. | No | 100000 | - |\n", - "| estimator_shots | int | Number of shots of the Estimator. | No | 25000 | - |\n", + "| sampler_shots | int | Number of shots for Sampler. | No | 100000 | - |\n", + "| estimator_shots | int | Number of shots for Estimator. | No | 25000 | - |\n", "| estimator_precision | float | Desired precision of the expected value. If specified, the precision will be used instead of the `estimator_shots`. | No | `None` | 0.015625 · (1 / sqrt(4096)) |\n", "| max_time | int or str | Maximum amount of time a runtime session can remain open before being forcibly closed. Can be given in seconds (int) or as a string, like `\"2h 30m 40s\"`. Must be less than the system-imposed maximum. | No | `None` | `\"1h 15m\"` |" ] diff --git a/docs/guides/hello-world.ipynb b/docs/guides/hello-world.ipynb index b7d4ea4242f..be016006166 100644 --- a/docs/guides/hello-world.ipynb +++ b/docs/guides/hello-world.ipynb @@ -160,7 +160,7 @@ { "data": { "text/plain": [ - "\"Output" + "\"Output" ] }, "execution_count": 1, @@ -212,7 +212,7 @@ "id": "f3ef4248-7938-44c1-85f1-edc997f0edcd", "metadata": {}, "source": [ - "When creating quantum circuits, you must also consider what type of data you want returned after execution. Qiskit provides two ways to return data: you can obtain a probability distribution for a set of qubits you choose to measure, or you can obtain the expectation value of an observable. Prepare your workload to measure your circuit in one of these two ways with [Qiskit primitives](/docs/guides/get-started-with-primitives) (explained in detail in [Step 3](#step-3-execute-using-the-quantum-primitives)).\n", + "When creating quantum circuits, you must also consider what type of data you want returned after execution. Qiskit provides two ways to return data: you can obtain a probability distribution for a set of qubits you choose to measure, or you can obtain the expectation value of an observable. Prepare your workload to measure your circuit in one of these two ways with Qiskit primitives (explained in detail in [Step 3](#step-3-execute-using-the-quantum-primitives)).\n", "\n", "This example measures expectation values by using the `qiskit.quantum_info` submodule, which is specified by using operators (mathematical objects used to represent an action or process that changes a quantum state). The following code cell creates six two-qubit Pauli operators: `IZ`, `IX`, `ZI`, `XI`, `ZZ`, and `XX`." ] @@ -263,10 +263,22 @@ "id": "9a901271", "metadata": {}, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "qiskit_runtime_service.__init__:WARNING:2026-02-12 15:13:28,878: Instance was not set at service instantiation. Free and trial plan instances will be prioritized. Based on the following filters: (tags: None, region: us-east, eu-de), and available plans: (internal, premium), the available account instances are: Documentation premium fleet, Documentation internal fleet, Documentation premium fleet, Documentation internal fleet. If you need a specific instance set it explicitly either by using a saved account with a saved default instance or passing it in directly to QiskitRuntimeService().\n", + "qiskit_runtime_service.backends:WARNING:2026-02-12 15:13:30,477: Loading instance: Documentation premium fleet, plan: premium\n", + "qiskit_runtime_service.backends:WARNING:2026-02-12 15:13:32,148: Loading instance: Documentation internal fleet, plan: internal\n", + "qiskit_runtime_service.backends:WARNING:2026-02-12 15:13:32,814: Loading instance: Documentation premium fleet, plan: premium\n", + "qiskit_runtime_service.backends:WARNING:2026-02-12 15:13:35,878: Loading instance: Documentation internal fleet, plan: internal\n", + "qiskit_runtime_service.backends:WARNING:2026-02-12 15:13:43,207: Using instance: Documentation premium fleet, plan: premium\n" + ] + }, { "data": { "text/plain": [ - "\"Output" + "\"Output" ] }, "execution_count": 3, @@ -421,7 +433,7 @@ "\n", "The analyze step is typically where you might post-process your results using, for example, measurement error mitigation or zero noise extrapolation (ZNE). You might feed these results into another workflow for further analysis or prepare a plot of the key values and data. In general, this step is specific to your problem. For this example, plot each of the expectation values that were measured for our circuit.\n", "\n", - "The expectation values and standard deviations for the observables you specified to Estimator are accessed through the job result's `PubResult.data.evs` and `PubResult.data.stds` attributes. To obtain the results from Sampler, use the `PubResult.data.meas.get_counts()` function, which will return a `dict` of measurements in the form of bitstrings as keys and counts as their corresponding values. For more information, see [Get started with Sampler](/docs/guides/get-started-with-primitives#get-started-with-sampler)." + "The expectation values and standard deviations for the observables you specified to Estimator are accessed through the job result's `PubResult.data.evs` and `PubResult.data.stds` attributes. To obtain the results from Sampler, use the `PubResult.data.meas.get_counts()` function, which will return a `dict` of measurements in the form of bitstrings as keys and counts as their corresponding values. For more information, see [Get started with Sampler.](/docs/guides/get-started-with-sampler)" ] }, { @@ -435,7 +447,7 @@ { "data": { "text/plain": [ - "\"Output" + "\"Output" ] }, "metadata": {}, @@ -580,7 +592,20 @@ "execution_count": 11, "id": "428f05e7", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "qiskit_runtime_service.__init__:WARNING:2026-02-12 15:14:20,967: Instance was not set at service instantiation. Free and trial plan instances will be prioritized. Based on the following filters: (tags: None, region: us-east, eu-de), and available plans: (internal, premium), the available account instances are: Documentation premium fleet, Documentation internal fleet, Documentation premium fleet, Documentation internal fleet. If you need a specific instance set it explicitly either by using a saved account with a saved default instance or passing it in directly to QiskitRuntimeService().\n", + "qiskit_runtime_service.backends:WARNING:2026-02-12 15:14:22,654: Loading instance: Documentation premium fleet, plan: premium\n", + "qiskit_runtime_service.backends:WARNING:2026-02-12 15:14:24,066: Loading instance: Documentation internal fleet, plan: internal\n", + "qiskit_runtime_service.backends:WARNING:2026-02-12 15:14:24,842: Loading instance: Documentation premium fleet, plan: premium\n", + "qiskit_runtime_service.backends:WARNING:2026-02-12 15:14:27,405: Loading instance: Documentation internal fleet, plan: internal\n", + "qiskit_runtime_service.backends:WARNING:2026-02-12 15:14:33,485: Using instance: Documentation premium fleet, plan: premium\n" + ] + } + ], "source": [ "service = QiskitRuntimeService()\n", "\n", @@ -659,7 +684,7 @@ { "data": { "text/plain": [ - "\"Output" + "\"Output" ] }, "metadata": {}, diff --git a/docs/guides/ibm-circuit-function.ipynb b/docs/guides/ibm-circuit-function.ipynb index f92930fcb33..12cf8f0b4fd 100644 --- a/docs/guides/ibm-circuit-function.ipynb +++ b/docs/guides/ibm-circuit-function.ipynb @@ -35,7 +35,7 @@ "\n", "## Overview\n", "\n", - "The IBM® Circuit function takes [abstract PUBs](./primitive-input-output) as inputs, and returns mitigated expectation values as outputs. This circuit function includes an automated and customized pipeline to enable researchers to focus on algorithm and application discovery." + "The IBM® Circuit function takes [abstract PUBs](/docs/guides/pubs-broadcasting#pubs) as inputs, and returns mitigated expectation values as outputs. This circuit function includes an automated and customized pipeline to enable researchers to focus on algorithm and application discovery." ] }, { @@ -47,9 +47,9 @@ "\n", "After submitting your PUB, your abstract circuits and observables are automatically transpiled, executed on hardware, and post-processed to return mitigated expectation values. To do so, this combines the following tools:\n", "\n", - "- [Qiskit Transpiler Service](./qiskit-transpiler-service), including auto-selection of AI-driven and heuristic transpilation passes to translate your abstract circuits to hardware-optimized ISA circuits\n", - "- [Error suppression and mitigation required for utility-scale computation](./error-mitigation-and-suppression-techniques), including measurement and gate twirling, dynamical decoupling, Twirled Readout Error eXtinction (TREX), Zero-Noise Extrapolation (ZNE), and Probabilistic Error Amplification (PEA)\n", - "- [Qiskit Runtime Estimator](./get-started-with-primitives), to execute ISA PUBs on hardware and return mitigated expectation values\n", + "- [Qiskit Transpiler Service](/docs/guides/qiskit-transpiler-service), including auto-selection of AI-driven and heuristic transpilation passes to translate your abstract circuits to hardware-optimized ISA circuits\n", + "- [Error suppression and mitigation required for utility-scale computation](/docs/guides/error-mitigation-and-suppression-techniques), including measurement and gate twirling, dynamical decoupling, Twirled Readout Error eXtinction (TREX), Zero-Noise Extrapolation (ZNE), and Probabilistic Error Amplification (PEA)\n", + "- [Qiskit Runtime Estimator](/docs/guides/get-started-with-estimator), to execute ISA PUBs on hardware and return mitigated expectation values\n", "\n", "![IBM Circuit function](/docs/images/guides/ibm-circuit-function/ibm-circuit-function.svg)" ] @@ -153,7 +153,7 @@ "id": "eda36356", "metadata": {}, "source": [ - "The results have the same format as an [Estimator result](/docs/guides/primitive-input-output#estimator-output):" + "The results have the same format as an [Estimator result](/docs/guides/estimator-input-output):" ] }, { @@ -206,7 +206,7 @@ "| Name | Type | Description | Required | Default | Example |\n", "|-----------|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|--------------------------------------------------------------------------|------------------------------------------|\n", "| backend_name | str | Name of the backend to make the query. | Yes | N/A | `ibm_fez` |\n", - "| pubs | Iterable[EstimatorPubLike] | An iterable of abstract PUB-like (primitive unified bloc) objects, such as tuples `(circuit, observables)` or `(circuit, observables, parameter_values)`. See [Overview of PUBs](/docs/guides/primitive-input-output#overview-of-pubs) for more information. The circuits can be abstract (non-ISA). | Yes | N/A | (circuit, observables, parameter_values) |\n", + "| pubs | Iterable[EstimatorPubLike] | An iterable of abstract PUB-like (primitive unified bloc) objects, such as tuples `(circuit, observables)` or `(circuit, observables, parameter_values)`. See [Overview of PUBs](/docs/guides/pubs-broadcasting#pubs) for more information. The circuits can be abstract (non-ISA). | Yes | N/A | (circuit, observables, parameter_values) |\n", "| options | dict | Input options. See the **Options** section for more details. | No | See the **Options** section for details. | `{\"optimization_level\": 3}` |\n", "| instance | str | The cloud resource name of the instance to use in that format. | No | One is randomly picked if your account has access to multiple instances. | `CRN` |" ] diff --git a/docs/guides/interoperate-qiskit-qasm2.ipynb b/docs/guides/interoperate-qiskit-qasm2.ipynb index 0283793fa49..924f5ee5f42 100644 --- a/docs/guides/interoperate-qiskit-qasm2.ipynb +++ b/docs/guides/interoperate-qiskit-qasm2.ipynb @@ -440,7 +440,7 @@ "\n", " - Learn how to generate OpenQASM code in the [IBM Quantum Composer](/docs/guides/composer) guide.\n", " - See the [OpenQASM 2 Qiskit API](/docs/api/qiskit/qasm2) reference.\n", - " - Review the [Verify your program](./debugging-tools) topic.\n", + " - Review the [Verify your program](/docs/guides/debugging-tools) topic.\n", " - Visit the [OpenQASM Live Specification](https://openqasm.com/).\n", "" ] diff --git a/docs/guides/interoperate-qiskit-qasm3.ipynb b/docs/guides/interoperate-qiskit-qasm3.ipynb index 99ba4e72533..029b3862b17 100644 --- a/docs/guides/interoperate-qiskit-qasm3.ipynb +++ b/docs/guides/interoperate-qiskit-qasm3.ipynb @@ -225,7 +225,7 @@ "\n", " - Learn how to generate OpenQASM code in the [IBM Quantum Composer](/docs/guides/composer) guide.\n", " - Review the [OpenQASM 3 Qiskit API](/docs/api/qiskit/qasm3) reference.\n", - " - Visit the [Verify your program](./debugging-tools) topic.\n", + " - Visit the [Verify your program](/docs/guides/debugging-tools) topic.\n", " - Review the [OpenQASM Live Specification](https://openqasm.com/).\n", "" ] diff --git a/docs/guides/intro-to-patterns.mdx b/docs/guides/intro-to-patterns.mdx index 30f12acb0b8..034cd85cd61 100644 --- a/docs/guides/intro-to-patterns.mdx +++ b/docs/guides/intro-to-patterns.mdx @@ -20,7 +20,7 @@ Each step is detailed in the sections below. ## Map the problem to quantum circuits and operators -This step describes how a user starts with a classical problem and figures out how to map it to a quantum computer. For example, in applications such as chemistry and quantum simulation, this step generally involves constructing a quantum circuit representing the Hamiltonian you are attempting to solve. During this step, for certain problems, it might also be desirable to specify the mapping of the problem onto qubits in the heavy-hex (or gross) lattice of IBM® hardware from the outset if the structure of the problem lends itself to optimization earlier. It is also worth considering at this point what the outcome of the particular algorithm will be in preparation for the later execute step - for example, if the desired outcome involves inferring correlation functions using Hadamard tests, you might prepare to use Sampler, whereas specifying observables would use the Estimator and could provide many error mitigation options. +This step describes how a user starts with a classical problem and figures out how to map it to a quantum computer. For example, in applications such as chemistry and quantum simulation, this step generally involves constructing a quantum circuit representing the Hamiltonian you are attempting to solve. During this step, for certain problems, it might also be desirable to specify the mapping of the problem onto qubits in the heavy-hex (or gross) lattice of IBM® hardware from the outset if the structure of the problem lends itself to optimization earlier. It is also worth considering at this point what the outcome of the particular algorithm will be in preparation for the later execute step - for example, if the desired outcome involves inferring correlation functions using Hadamard tests, you might prepare to use Sampler, whereas specifying observables would use Estimator and could provide many error mitigation options. The output of this step is normally a collection of circuits or quantum operators that can be optimized for hardware in the next step. @@ -38,7 +38,7 @@ During this step, abstract circuits must be transpiled to Instruction Set Archit This step involves running your circuits on hardware and produces the outputs of the quantum computation. The ISA circuits produced in the previous step can be executed using either a Sampler or Estimator primitive from Qiskit Runtime, initialized locally on your computer or from a cluster or other heterogeneous compute environment. These can be executed in a Batch, which allows parallel transpilation for classical computational efficiency - or a Session, which allows iterative tasks to be implemented efficiently without queuing delays. During this step, there is also the option to configure certain error suppression and mitigation techniques provided by Qiskit Runtime. -Depending on whether you are using the Sampler or Estimator primitive, the outcome of this step will be different. If using the Sampler, the output will be per-shot measurements in the form of bitstrings. If using the Estimator, the output will be expectation values of observables corresponding to physical quantities or cost functions. +Depending on whether you are using the Sampler or Estimator primitive, the outcome of this step will be different. If using Sampler, the output will be per-shot measurements in the form of bitstrings. If using Estimator, the output will be expectation values of observables corresponding to physical quantities or cost functions. ## Post-process results diff --git a/docs/guides/local-simulators.mdx b/docs/guides/local-simulators.mdx index c6a486de8ed..9ef3a451150 100644 --- a/docs/guides/local-simulators.mdx +++ b/docs/guides/local-simulators.mdx @@ -97,7 +97,7 @@ qc.h(0) qc.cx(0, 1) qc.measure_all() -# Run the sampler job locally using FakeManilaV2 +# Run the Sampler job locally using FakeManilaV2 fake_manila = FakeManilaV2() pm = generate_preset_pass_manager(backend=fake_manila, optimization_level=1) isa_qc = pm.run(qc) @@ -137,7 +137,7 @@ qc.h(0) qc.cx(0, 1) qc.measure_all() -# Run the sampler job locally using AerSimulator. +# Run the Sampler job locally using AerSimulator. # Session syntax is supported but ignored because local mode doesn't support sessions. aer_sim = AerSimulator() pm = generate_preset_pass_manager(backend=aer_sim, optimization_level=1) @@ -171,7 +171,7 @@ qc.measure_all() real_backend = service.backend("ibm_brisbane") aer = AerSimulator.from_backend(real_backend) -# Run the sampler job locally using AerSimulator. +# Run the Sampler job locally using AerSimulator. pm = generate_preset_pass_manager(backend=aer, optimization_level=1) isa_qc = pm.run(qc) sampler = Sampler(mode=aer) diff --git a/docs/guides/local-testing-mode.ipynb b/docs/guides/local-testing-mode.ipynb index 71271225df5..ace8fb0ec6c 100644 --- a/docs/guides/local-testing-mode.ipynb +++ b/docs/guides/local-testing-mode.ipynb @@ -121,7 +121,7 @@ "qc.cx(0, 1)\n", "qc.measure_all()\n", "\n", - "# Run the sampler job locally using FakeManilaV2\n", + "# Run the Sampler job locally using FakeManilaV2\n", "fake_manila = FakeManilaV2()\n", "pm = generate_preset_pass_manager(backend=fake_manila, optimization_level=1)\n", "isa_qc = pm.run(qc)\n", @@ -161,7 +161,7 @@ "qc.cx(0, 1)\n", "qc.measure_all()\n", "\n", - "# Run the sampler job locally using AerSimulator.\n", + "# Run the Sampler job locally using AerSimulator.\n", "# Session syntax is supported but ignored because local mode doesn't support sessions.\n", "aer_sim = AerSimulator()\n", "pm = generate_preset_pass_manager(backend=aer_sim, optimization_level=1)\n", @@ -211,7 +211,7 @@ "real_backend = service.backend(\"ibm_fez\")\n", "aer = AerSimulator.from_backend(real_backend)\n", "\n", - "# Run the sampler job locally using AerSimulator.\n", + "# Run the Sampler job locally using AerSimulator.\n", "pm = generate_preset_pass_manager(backend=aer, optimization_level=1)\n", "isa_qc = pm.run(qc)\n", "sampler = Sampler(mode=aer)\n", diff --git a/docs/guides/max-execution-time.ipynb b/docs/guides/max-execution-time.ipynb index a8e7ad39d6e..479521e3709 100644 --- a/docs/guides/max-execution-time.ipynb +++ b/docs/guides/max-execution-time.ipynb @@ -46,7 +46,7 @@ "\n", "The `max_execution_time` value is based on _quantum time_, not wall clock time. Quantum time is the amount of time that the QPU is dedicated to processing your job.\n", "\n", - "Set the maximum execution time (in seconds) on the job options, as shown in the following example. See [Specify options](/docs/guides/specify-runtime-options) for information about setting options.\n", + "Set the maximum execution time (in seconds) on the job options, as shown in the following example. See the [Estimator options](/docs/guides/estimator-options), [Sampler options](/docs/guides/sampler-options), or [Executor options](/docs/guides/executor-options) guides for information about setting options.\n", "\n", "```python\n", "from qiskit_ibm_runtime import QiskitRuntimeService\n", diff --git a/docs/guides/metapackage-migration.mdx b/docs/guides/metapackage-migration.mdx index 7ef206cc0f7..5447ddce2fe 100644 --- a/docs/guides/metapackage-migration.mdx +++ b/docs/guides/metapackage-migration.mdx @@ -111,4 +111,4 @@ You may notice that the command `pip install qiskit` will no longer includes pac Before the release of the Qiskit SDK v1.0, Qiskit was comprised of many different Python distributions, such as `qiskit-terra`, the compiler core; `qiskit-aer`, the high-performance simulator; the original IBM Quantum® provider; and several now-obsolete packages providing particular exploratory algorithmic or experiment-running features. -If you want to install the packages that were previously included in the Qiskit metapackage, visit the [Qiskit ecosystem](https://www.ibm.com/quantum/ecosystem) to find a range of packages to suit your needs. You can also read the [v1.0 migration guide](./qiskit-1.0-installation) for more information about how to install the new distribution. +If you want to install the packages that were previously included in the Qiskit metapackage, visit the [Qiskit ecosystem](https://www.ibm.com/quantum/ecosystem) to find a range of packages to suit your needs. You can also read the [v1.0 migration guide](/docs/guides/qiskit-1.0-installation) for more information about how to install the new distribution. diff --git a/docs/guides/minimize-time.mdx b/docs/guides/minimize-time.mdx index b31795dd2d2..f144988eca9 100644 --- a/docs/guides/minimize-time.mdx +++ b/docs/guides/minimize-time.mdx @@ -12,10 +12,10 @@ There are several ways you can limit the amount of time spent processing and run - Set limits on execution time: You can limit how long each job, batch, or session runs. For details, see [Maximum execution time for Qiskit Runtime workloads](max-execution-time). -- Use only the necessary settings for error suppression and error mitigation, because higher values can cause your jobs to run longer. See [Introduction to options](./runtime-options-overview), [Configure error suppression](./configure-error-suppression), and [Configure error mitigation](configure-error-mitigation) for details. +- Use only the necessary settings for error suppression and error mitigation, because higher values can cause your jobs to run longer. See [Introduction to options](/docs/guides/runtime-options-overview), [Configure error suppression](/docs/guides/configure-error-suppression), and [Configure error mitigation](configure-error-mitigation) for details. - If you are running multiple jobs that contain the same (likely parameterized) circuits and are using an error mitigation method that requires noise models, such as PEA and PEC, consider using `NoiseLearner`. With this helper program, you can learn the noise model of a circuit once and reuse the model in subsequent Estimator queries. Note that a noise model becomes stale after a certain time, so this is only practical if there is no long delay between jobs (for example, within a session). See [Noise learning helper -](./noise-learning) for more details. +](/docs/guides/noise-learning) for more details. ## Next steps diff --git a/docs/guides/monitor-job.ipynb b/docs/guides/monitor-job.ipynb index ae1341e081f..ecae45b26a2 100644 --- a/docs/guides/monitor-job.ipynb +++ b/docs/guides/monitor-job.ipynb @@ -64,7 +64,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "ee0318b6-0bfd-4f0b-b980-4e233a2d5d7b", "metadata": { "tags": [ @@ -112,7 +112,7 @@ "\n", "sampler_pub = (transpiled_circuit, params)\n", "\n", - "# Instantiate the new estimator object, then run the transpiled circuit\n", + "# Instantiate the new Estimator object, then run the transpiled circuit\n", "# using the set of parameters and observables.\n", "sampler = SamplerV2(mode=backend)\n", "job = sampler.run([sampler_pub], shots=4)\n", @@ -226,7 +226,7 @@ "This timing information can be used to place upper and lower timestamp bounds on when particular shots were executed on the QPU.\n", "Shots are grouped into [`ExecutionSpan`](/docs/api/qiskit-ibm-runtime/execution-span-execution-span) objects, each of which indicates a start time, a stop time, and a specification of which shots were collected in the span.\n", "\n", - "An execution span specifies which data was executed during its window by providing an [`ExecutionSpan.mask`](/docs/api/qiskit-ibm-runtime/execution-span-execution-span#mask) method. This method, given any [Primitive Unified Block (PUB)](/docs/guides/primitive-input-output) index, returns a boolean mask that is `True` for all shots executed during its window. PUBs are indexed by the order in which they were given to the Sampler run call. If, for example, a PUB has shape `(2, 3)` and was run with four shots, then the mask's shape is `(2, 3, 4)`. See the [execution_span](/docs/api/qiskit-ibm-runtime/execution-span) API page for full details.\n", + "An execution span specifies which data was executed during its window by providing an [`ExecutionSpan.mask`](/docs/api/qiskit-ibm-runtime/execution-span-execution-span#mask) method. This method, given any [Primitive Unified Block (PUB)](/docs/guides/pubs-broadcasting#pubs) index, returns a boolean mask that is `True` for all shots executed during its window. PUBs are indexed by the order in which they were given to the Sampler run call. If, for example, a PUB has shape `(2, 3)` and was run with four shots, then the mask's shape is `(2, 3, 4)`. See the [execution_span](/docs/api/qiskit-ibm-runtime/execution-span) API page for full details.\n", "\n", "Example:" ] diff --git a/docs/guides/noise-learning.ipynb b/docs/guides/noise-learning.ipynb index 0d1088b0998..ad0a206f4cc 100644 --- a/docs/guides/noise-learning.ipynb +++ b/docs/guides/noise-learning.ipynb @@ -49,12 +49,12 @@ "id": "cabee439-d0f2-4079-a47d-b6d96ce78332", "metadata": {}, "source": [ - "The error mitigation techniques [PEA](./error-mitigation-and-suppression-techniques#probabilistic-error-amplification-pea) and [PEC](./error-mitigation-and-suppression-techniques#probabilistic-error-cancellation-pec) both utilize a noise learning component based on a [Pauli-Lindblad noise model](https://arxiv.org/abs/2201.09866), which is typically managed during execution after submitting one or more jobs through `qiskit-ibm-runtime` without any local access to the fitted noise model. However, as of `qiskit-ibm-runtime` 0.27.1, a [`NoiseLearner`](../api/qiskit-ibm-runtime/noise-learner) and associated [`NoiseLearnerOptions`](../api/qiskit-ibm-runtime/options-noise-learner-options) class have been created to obtain the results of these noise learning experiments. These results can then be stored locally as a `NoiseLearnerResult` and used as input in later experiments. This page provides an overview of its usage and the associated options available.\n", + "The error mitigation techniques [PEA](/docs/guides/error-mitigation-and-suppression-techniques#pea) and [PEC](/docs/guides/error-mitigation-and-suppression-techniques#pec) both utilize a noise learning component based on a [Pauli-Lindblad noise model](https://arxiv.org/abs/2201.09866), which is typically managed during execution after submitting one or more jobs through `qiskit-ibm-runtime` without any local access to the fitted noise model. However, as of `qiskit-ibm-runtime` 0.27.1, a [`NoiseLearner`](/docs/api/qiskit-ibm-runtime/noise-learner) and associated [`NoiseLearnerOptions`](/docs/api/qiskit-ibm-runtime/options-noise-learner-options) class have been created to obtain the results of these noise learning experiments. These results can then be stored locally as a `NoiseLearnerResult` and used as input in later experiments. This page provides an overview of its usage and the associated options available.\n", "\n", "\n", "## Overview\n", "\n", - "The `NoiseLearner` class performs experiments that characterize noise processes based on a Pauli-Lindblad noise model for one (or more) circuits. It possesses a `run()` method that executes the learning experiments and takes as input either a list of circuits or a [PUB](./primitive-input-output#overview-of-pubs), and returns a `NoiseLearnerResult` containing the learned noise channels and metadata about the job(s) submitted. Below is a code snippet demonstrating the usage of the helper program." + "The `NoiseLearner` class performs experiments that characterize noise processes based on a Pauli-Lindblad noise model for one (or more) circuits. It possesses a `run()` method that executes the learning experiments and takes as input either a list of circuits or a [PUB](/docs/guides/pubs-broadcasting), and returns a `NoiseLearnerResult` containing the learned noise channels and metadata about the job(s) submitted. Below is a code snippet demonstrating the usage of the helper program." ] }, { @@ -350,7 +350,6 @@ " - Read more about [configuring error mitigation](configure-error-mitigation).\n", " - Review the [EstimatorOptions API reference](/docs/api/qiskit-ibm-runtime/options-estimator-options) and [ResilienceOptionsV2 API reference](/docs/api/qiskit-ibm-runtime/options-resilience-options-v2).\n", " - Learn more about [Error mitigation and suppression techniques](error-mitigation-and-suppression-techniques) that are available through Qiskit Runtime.\n", - " - Review how to [Specify options](specify-runtime-options) for the Qiskit Runtime primitives.\n", " - Read [Migrate to V2 primitives](/docs/guides/v2-primitives).\n", "
" ] diff --git a/docs/guides/online-lab-environments.mdx b/docs/guides/online-lab-environments.mdx index a4f11e53710..44a663f5c97 100644 --- a/docs/guides/online-lab-environments.mdx +++ b/docs/guides/online-lab-environments.mdx @@ -26,10 +26,10 @@ OVHcloud AI notebooks are not available in some regions, such as the United Stat Follow these steps to get started: -1. [Create an IBM Cloud account](./cloud-setup). -1. [Set up an OVHcloud account](https://help.ovhcloud.com/csm/en-account-create-ovhcloud-account?id=kb_article_view&sysparm_article=KB0043022). -2. [Create an OVH Public Cloud project](https://support.us.ovhcloud.com/hc/en-us/articles/360002245784-Creating-Your-First-Public-Cloud-Project). -6. Follow the steps in [Launch your first AI Notebook](https://help.ovhcloud.com/csm/en-public-cloud-ai-notebooks-definition?id=kb_article_view&sysparm_article=KB0048270), selecting **Qiskit** for the framework. +1. [Create an IBM Cloud account.](/docs/guides/cloud-setup) +1. [Set up an OVHcloud account.](https://help.ovhcloud.com/csm/en-account-create-ovhcloud-account?id=kb_article_view&sysparm_article=KB0043022) +2. [Create an OVH Public Cloud project.](https://support.us.ovhcloud.com/hc/en-us/articles/360002245784-Creating-Your-First-Public-Cloud-Project) +6. Follow the steps in [Launch your first AI Notebook,](https://help.ovhcloud.com/csm/en-public-cloud-ai-notebooks-definition?id=kb_article_view&sysparm_article=KB0048270) selecting **Qiskit** for the framework. ### qBraid Lab diff --git a/docs/guides/operator-class.ipynb b/docs/guides/operator-class.ipynb index 511d787313f..6d341990945 100644 --- a/docs/guides/operator-class.ipynb +++ b/docs/guides/operator-class.ipynb @@ -48,7 +48,7 @@ "id": "eb4d8e3f-5efb-4223-a15b-d6ef541370dc", "metadata": {}, "source": [ - "This page shows how to use the [`Operator`](/docs/api/qiskit/qiskit.quantum_info.Operator) class. For a high-level overview of operator representations in Qiskit, including the `Operator` class and others, see [Overview of operator classes](./operators-overview)." + "This page shows how to use the [`Operator`](/docs/api/qiskit/qiskit.quantum_info.Operator) class. For a high-level overview of operator representations in Qiskit, including the `Operator` class and others, see [Overview of operator classes](/docs/guides/operators-overview)." ] }, { diff --git a/docs/guides/operators-overview.ipynb b/docs/guides/operators-overview.ipynb index d1f025ed15e..afe905e4370 100644 --- a/docs/guides/operators-overview.ipynb +++ b/docs/guides/operators-overview.ipynb @@ -523,9 +523,9 @@ "## Next steps\n", "\n", "\n", - " - Learn how to [specify observables in the Pauli basis](./specify-observables-pauli).\n", + " - Learn how to [specify observables in the Pauli basis](/docs/guides/specify-observables-pauli).\n", " - See an example of using operators in the [Combine error mitigation options with the Estimator primitive](/docs/tutorials/combine-error-mitigation-techniques) tutorial.\n", - " - Read more [in-depth coverage of the Operator class](./operator-class).\n", + " - Read more [in-depth coverage of the Operator class](/docs/guides/operator-class).\n", " - Explore the [Operator API](/docs/api/qiskit/qiskit.quantum_info.Operator#operator) reference.\n", "" ] diff --git a/docs/guides/primitives-rest-api.ipynb b/docs/guides/primitives-rest-api.ipynb deleted file mode 100644 index 7b44c264689..00000000000 --- a/docs/guides/primitives-rest-api.ipynb +++ /dev/null @@ -1,1132 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "0998165a-381f-4561-a79a-bf584aed9687", - "metadata": {}, - "source": [ - "---\n", - "title: Primitives with REST API\n", - "description: How to use the Sampler and Estimator primitives with Qiskit Runtime REST API.\n", - "---\n", - "\n", - "\n", - "{/* cspell:ignore IIZII, XIZZZ, accum, WQVY, urlencoded */}\n", - "\n", - "# Primitives with REST API" - ] - }, - { - "cell_type": "markdown", - "id": "da948b6b-2ead-4359-aed4-b824e43ccbfb", - "metadata": { - "tags": [ - "version-info" - ] - }, - "source": [] - }, - { - "cell_type": "markdown", - "id": "95673fe9-23fa-44a0-a9a5-aa968b146b30", - "metadata": {}, - "source": [ - "The steps in this topic describe how to run and configure primitive workloads with the Qiskit Runtime REST API, and demonstrate how to invoke them in any program of your choice.\n", - "\n", - "\n", - " This documentation utilizes the Python `requests` module to demonstrate the Qiskit Runtime REST API. However, this workflow can be executed using any language or framework that supports working with REST APIs. Refer to the [API reference documentation](/docs/api/qiskit-ibm-runtime/tags/jobs) for details.\n", - "\n", - "\n", - "\n", - "## Estimator primitive with REST API\n", - "\n", - "### 1. Initialize the account\n", - "\n", - "Because Qiskit Runtime Estimator is a managed service, you first need to initialize your account. You can then select the device you want to use to calculate the expectation value.\n", - "\n", - "You will also need a bearer token. This is a short-lived token (different from an API key) which is used to authenticate requests to the REST API. To generate one, call the [IAM Identity Services API](https://cloud.ibm.com/apidocs/iam-identity-token-api#create-api-key) as shown in the following sample request:\n", - "\n", - "\n", - "\n", - " \n", - " ```bash\n", - " curl -X POST 'https://iam.cloud.ibm.com/identity/token' \\\n", - " -H 'Content-Type: application/x-www-form-urlencoded' \\\n", - " -d 'grant_type=urn:ibm:params:oauth:grant-type:apikey&apikey=MY_APIKEY'\n", - " ```\n", - " Expected Response\n", - " ```text\n", - " {\n", - " \"access_token\": \"eyJhbGciOiJIUz......sgrKIi8hdFs\",\n", - " \"refresh_token\": \"SPrXw5tBE3......KBQ+luWQVY=\",\n", - " \"token_type\": \"Bearer\",\n", - " \"expires_in\": 3600,\n", - " \"expiration\": 1473188353\n", - " }\n", - " ```\n", - " \n", - "\n", - " \n", - " ```python\n", - " # Use 'service' to invoke operations.\n", - " import requests\n", - " import json\n", - "\n", - " url = 'https://iam.cloud.ibm.com/identity/token'\n", - " api_key = 'MY_APIKEY'\n", - " headers = {\n", - " 'Content-Type': 'application/x-www-form-urlencoded',\n", - " }\n", - " data = f'grant_type=urn:ibm:params:oauth:grant-type:apikey&apikey={api_key}'\n", - " response = requests.post(url, headers=headers, data=data)\n", - "\n", - " # Bearer token to authorize requests to the REST API\n", - " bearer_token = response.json()['access_token']\n", - " ```\n", - " \n", - "\n", - "\n", - "For other details on how to initialize your account, view available backends, and validate tokens, read this [topic](/docs/guides/cloud-setup-rest-api).\n", - "\n", - "### 2. Create a QASM circuit\n", - "\n", - "You need at least one circuit as the input to the Estimator primitive.\n", - "\n", - "Define a QASM quantum circuit. For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "14f31039-6726-47f2-91f2-c99644a9f8b1", - "metadata": {}, - "outputs": [], - "source": [ - "qasm_string = \"\"\"\n", - "OPENQASM 3.0;\n", - "include \"stdgates.inc\";\n", - "bit[2] meas;\n", - "rz(pi/2) $1;\n", - "sx $1;\n", - "rz(pi) $1;\n", - "x $2;\n", - "cz $2, $1;\n", - "sx $1;\n", - "rz(pi/2) $1;\n", - "\"\"\"" - ] - }, - { - "cell_type": "markdown", - "id": "5a7c5586-4fe6-4205-b35d-1a4a8a9df13d", - "metadata": {}, - "source": [ - "### 3. Run the quantum circuit using the Estimator V2 API\n", - "You'll need to replace `auth_id`, `crn`, and `backend` with the appropriate values.\n", - "\n", - "```python\n", - "\n", - "url = 'https://quantum.cloud.ibm.com/api/v1/jobs'\n", - "auth_id = \"Bearer \"\n", - "crn = \"\"\n", - "backend = \"\"\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7d9988ed-69da-4102-b43e-8fda4176543b", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# Code hidden from users to collect authentication credentials\n", - "import requests\n", - "import time\n", - "from qiskit_ibm_runtime import QiskitRuntimeService\n", - "\n", - "url = \"https://quantum.cloud.ibm.com/api/v1/jobs\"\n", - "service = QiskitRuntimeService()\n", - "crn = service.active_account()[\"instance\"]\n", - "token = service.active_account()[\"token\"]\n", - "backend = service.least_busy().name\n", - "\n", - "header = {\"Content-Type\": \"application/x-www-form-urlencoded\"}\n", - "data = \"grant_type=urn:ibm:params:oauth:grant-type:apikey&apikey=\" + token\n", - "\n", - "response = requests.post(\n", - " \"https://iam.cloud.ibm.com/identity/token\", headers=header, data=data\n", - ")\n", - "auth_id = \"Bearer \" + response.json()[\"access_token\"]\n", - "\n", - "\n", - "def wait_for_results(url, job_id, headers):\n", - " timeout = 600\n", - " start_time = time.time()\n", - " job_status = requests.get(url + \"/\" + job_id, headers=headers)\n", - " status = job_status.json().get(\"state\")[\"status\"]\n", - " while status != \"Completed\":\n", - " if time.time() - start_time > timeout:\n", - " break\n", - " time.sleep(10)\n", - " job_status = requests.get(url + \"/\" + job_id, headers=headers)\n", - " status = job_status.json().get(\"state\")[\"status\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "80a40f86-ba8e-4520-8127-eaf64d51b331", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Job created: {\"id\":\"d6147q3traac73bef6f0\",\"backend\":\"ibm_pittsburgh\"}\n" - ] - } - ], - "source": [ - "headers = {\n", - " \"Content-Type\": \"application/json\",\n", - " \"Authorization\": auth_id,\n", - " \"Service-CRN\": crn,\n", - "}\n", - "\n", - "job_input = {\n", - " \"program_id\": \"estimator\",\n", - " \"backend\": backend,\n", - " \"params\": {\n", - " \"version\": \"2\",\n", - " \"pubs\": [ # primitive unified blocs (PUBs) containing one circuit each.\n", - " [\n", - " qasm_string, # QASM circuit\n", - " {\"IZI\": 1, \"IXI\": 2.3}, # Observable\n", - " None, # parameter values\n", - " ]\n", - " ],\n", - " },\n", - "}\n", - "\n", - "response = requests.post(url, headers=headers, json=job_input)\n", - "\n", - "if response.status_code == 200:\n", - " job_id = response.json().get(\"id\")\n", - " print(\"Job created:\", response.text)\n", - "else:\n", - " print(f\"Error: {response.status_code}\")" - ] - }, - { - "cell_type": "markdown", - "id": "f4f6b217-ed78-4a56-8329-aa0387215b6f", - "metadata": {}, - "source": [ - "### 4. Check job status and get results\n", - "\n", - "Next, pass the `job_id` to the API:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "625431da-32b8-4517-823b-ab2c86ddbd9d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'status': 'Queued'}" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "response_status_singlejob = requests.get(url + \"/\" + job_id, headers=headers)\n", - "response_status_singlejob.json().get(\"state\")" - ] - }, - { - "cell_type": "markdown", - "id": "3814b809-3012-4498-adc8-efa1f1f5c959", - "metadata": {}, - "source": [ - "Once the job has completed, get job results:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "b233f6ef-2e16-4084-b6e3-f51368089300", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# Hide this cell for testing\n", - "\n", - "wait_for_results(url, job_id, headers)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "cb892f6f-755f-4d3d-aa7c-58192f34bd09", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[{'data': {'evs': -0.9374102500618965, 'stds': 0.030982815700848845, 'ensemble_standard_error': 0.03686001673650654}, 'metadata': {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}}]\n" - ] - } - ], - "source": [ - "response_result = requests.get(\n", - " url + \"/\" + job_id + \"/results\", headers=headers\n", - ")\n", - "\n", - "res_dict = response_result.json()\n", - "\n", - "estimator_result = res_dict[\"results\"]\n", - "print(estimator_result)" - ] - }, - { - "cell_type": "markdown", - "id": "9b00a981-26d6-4526-998b-e13a16a515f2", - "metadata": {}, - "source": [ - "### 5. Work with Runtime options\n", - "\n", - "Error mitigation techniques allow users to mitigate circuit errors by modeling the device noise at the time of execution. This typically results in quantum pre-processing overhead related to model training, and classical post-processing overhead to mitigate errors in the raw results by using the generated model.\n", - "\n", - "The error mitigation techniques built in to primitives are advanced resilience options. To specify these options, use the `resilience_level` option when submitting your job.\n", - "\n", - "The following examples demonstrate the default options for dynamical decoupling, twirling, and TREX + ZNE. Find more options and further details in the [Error mitigation and suppression techniques](/docs/guides/error-mitigation-and-suppression-techniques) topic.\n", - "\n", - "\n", - "\n", - "\n", - "\n", - " \n", - "\n", - "\n", - "\n", - "\n", - " \n", - "\n", - "\n", - "\n", - "\n", - " \n", - "\n", - "\n", - "" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "245d1cab-dd0f-4eff-a27f-a65e529a7fde", - "metadata": { - "tags": [ - "id-zne-options" - ] - }, - "outputs": [], - "source": [ - "job_input = {\n", - " \"program_id\": \"estimator\",\n", - " \"backend\": backend,\n", - " \"params\": {\n", - " \"pubs\": [ # primitive unified blocs (PUBs) containing one circuit each.\n", - " [\n", - " qasm_string, # QASM circuit\n", - " {\"IZI\": 1, \"IXI\": 2.3}, # Observable\n", - " None, # parameter values\n", - " ]\n", - " ],\n", - " \"version\": \"2\",\n", - " \"options\": {\n", - " \"resilience\": {\n", - " \"measure_mitigation\": True,\n", - " \"zne_mitigation\": True,\n", - " \"zne\": {\n", - " \"extrapolator\": [\"exponential\", \"linear\"],\n", - " \"noise_factors\": [1, 3, 5],\n", - " },\n", - " },\n", - " },\n", - " },\n", - "}\n", - "response = requests.post(url, headers=headers, json=job_input)\n", - "\n", - "if response.status_code == 200:\n", - " job_id = response.json().get(\"id\")\n", - " print(\"Job created:\", response.text)\n", - "else:\n", - " print(f\"Error: {response.status_code}\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e8b41557-bebb-4ada-979a-f187eea07b4d", - "metadata": { - "tags": [ - "id-dd-estimator-options" - ] - }, - "outputs": [], - "source": [ - "job_input = {\n", - " \"program_id\": \"estimator\",\n", - " \"backend\": backend,\n", - " \"params\": {\n", - " \"pubs\": [ # primitive unified blocs (PUBs) containing one circuit each.\n", - " [\n", - " qasm_string, # QASM circuit\n", - " {\"IZI\": 1, \"IXI\": 2.3}, # Observable\n", - " None, # parameter values\n", - " ]\n", - " ],\n", - " \"version\": \"2\",\n", - " \"options\": {\n", - " \"dynamical_decoupling\": {\n", - " \"enable\": True,\n", - " \"sequence_type\": \"XpXm\",\n", - " \"extra_slack_distribution\": \"middle\",\n", - " \"scheduling_method\": \"alap\",\n", - " },\n", - " },\n", - " },\n", - "}\n", - "response = requests.post(url, headers=headers, json=job_input)\n", - "\n", - "if response.status_code == 200:\n", - " job_id = response.json().get(\"id\")\n", - " print(\"Job created:\", response.text)\n", - "else:\n", - " print(f\"Error: {response.status_code}\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "839fe813-ff5f-4f86-abb6-0b58dc5fdb7e", - "metadata": { - "tags": [ - "id-twirling-estimator-options" - ] - }, - "outputs": [], - "source": [ - "job_input = {\n", - " \"program_id\": \"estimator\",\n", - " \"backend\": backend,\n", - " \"params\": {\n", - " \"pubs\": [ # primitive unified blocs (PUBs) containing one circuit each.\n", - " [\n", - " qasm_string, # QASM circuit\n", - " {\"IZI\": 1, \"IXI\": 2.3}, # Observable\n", - " None, # parameter values\n", - " ]\n", - " ],\n", - " \"version\": \"2\",\n", - " \"options\": {\n", - " \"twirling\": {\n", - " \"enable_gates\": True,\n", - " \"enable_measure\": True,\n", - " \"num_randomizations\": \"auto\",\n", - " \"shots_per_randomization\": \"auto\",\n", - " \"strategy\": \"active-accum\",\n", - " },\n", - " },\n", - " },\n", - "}\n", - "response = requests.post(url, headers=headers, json=job_input)\n", - "\n", - "if response.status_code == 200:\n", - " job_id = response.json().get(\"id\")\n", - " print(\"Job created:\", response.text)\n", - "else:\n", - " print(f\"Error: {response.status_code}\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "66ed7e3f-1cb7-437a-bf87-1afd29e099c5", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# Cancel job immediately after since the example doesn't use it\n", - "job = service.job(job_id)\n", - "job.cancel()" - ] - }, - { - "cell_type": "markdown", - "id": "5e27e5f9-f65c-4fc3-bb04-d36be4cdf982", - "metadata": {}, - "source": [ - "\n", - "## Sampler primitive with REST API\n", - "\n", - "### 1. Initialize the account\n", - "\n", - "Because Qiskit Runtime Sampler is a managed service, you first need to initialize your account. You can then select the device you want to use to run your calculations on.\n", - "\n", - "You will also need a bearer token, which can be generated using the [instructions above](#1-initialize-the-account). You can also find more information about generating bearer tokens in the [IAM Identity Services API](https://cloud.ibm.com/apidocs/iam-identity-token-api#create-api-key) documentation.\n", - "\n", - "For other details on how to initialize your account, view available backends, and validate tokens, read this [topic](/docs/guides/cloud-setup-rest-api).\n", - "\n", - "\n", - "### 2. Create a QASM circuit\n", - "\n", - "You need at least one circuit as the input to the Sampler primitive.\n", - "\n", - "\n", - "Define a QASM quantum circuit:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "b450d383-c708-4555-8c11-ec2480a5dd37", - "metadata": {}, - "outputs": [], - "source": [ - "qasm_string = \"\"\"\n", - "OPENQASM 3.0;\n", - "include \"stdgates.inc\";\n", - "bit[2] meas;\n", - "rz(pi/2) $1;\n", - "sx $1;\n", - "rz(pi) $1;\n", - "x $2;\n", - "cz $2, $1;\n", - "sx $1;\n", - "rz(pi/2) $1;\n", - "meas[0] = measure $1;\n", - "meas[1] = measure $2;\n", - "\"\"\"" - ] - }, - { - "cell_type": "markdown", - "id": "d5a41639-0087-4c1a-90dc-d3a1821cc7a7", - "metadata": {}, - "source": [ - "### 3. Run the quantum circuit using Sampler V2 API\n", - "\n", - "\n", - "\n", - " The jobs below use [Qiskit Runtime V2 primitives](/docs/guides/v2-primitives). Both `SamplerV2` and `EstimatorV2` take one or more primitive unified blocs (PUBs) as the input. Each PUB is a tuple that contains one circuit and the data broadcasted to that circuit, which can be multiple observables and parameters. Each PUB returns a result.\n", - "\n", - "\n", - "You'll need to replace `auth_id`, `crn`, and `backend` with the appropriate values.\n", - "\n", - "```python\n", - "\n", - "url = 'https://quantum.cloud.ibm.com/api/v1/jobs'\n", - "auth_id = \"Bearer \"\n", - "crn = \"\"\n", - "backend = \"\"\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "61bccee0-e7e2-4306-8bc9-d8f3f81460dd", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Job created: {\"id\":\"d6147vio8gvs73f0h130\",\"backend\":\"ibm_pittsburgh\"}\n" - ] - } - ], - "source": [ - "headers = {\n", - " \"Content-Type\": \"application/json\",\n", - " \"Authorization\": auth_id,\n", - " \"Service-CRN\": crn,\n", - "}\n", - "job_input = {\n", - " \"program_id\": \"sampler\",\n", - " \"backend\": backend,\n", - " \"params\": {\n", - " \"pubs\": [\n", - " [qasm_string],\n", - " [qasm_string, None, 500],\n", - " ], # primitive unified blocs (PUBs) containing one circuit each.\n", - " \"version\": \"2\",\n", - " },\n", - "}\n", - "\n", - "response = requests.post(url, headers=headers, json=job_input)\n", - "\n", - "if response.status_code == 200:\n", - " job_id = response.json().get(\"id\")\n", - " print(\"Job created:\", response.text)\n", - "else:\n", - " print(f\"Error: {response.status_code}\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3e853562-281f-4be5-b7d7-2d4513572d43", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# Cancel job immediately after since the example doesn't use it\n", - "job = service.job(job_id)\n", - "job.cancel()" - ] - }, - { - "cell_type": "markdown", - "id": "0ef29434-69c2-4d30-9038-fd79e510f719", - "metadata": {}, - "source": [ - "### 4. Check job status and get results\n", - "\n", - "Next, pass the `job_id` to the API:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "ed6b98fc-be32-4d09-a9e9-2a403e14fe2e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'status': 'Queued'}" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "response_status_singlejob = requests.get(url + \"/\" + job_id, headers=headers)\n", - "response_status_singlejob.json().get(\"state\")" - ] - }, - { - "cell_type": "markdown", - "id": "50f15367-d1df-4dc1-86e9-870e105ad033", - "metadata": {}, - "source": [ - "Once the job has completed, get job results:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "ecaf22cd-3bda-4eec-8e66-e4435cdcff38", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# Hide this cell\n", - "\n", - "wait_for_results(url, job_id, headers)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "eb522845-88a6-4b51-adda-33e63ba159e5", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['0x3', '0x3', '0x3', '0x3', '0x3', '0x3', '0x3', '0x3', '0x3', '0x3', '0x3', '0x3', '0x2', '0x3', '0x3', '0x3', '0x3', '0x3', '0x3', '0x3']\n" - ] - } - ], - "source": [ - "response_result = requests.get(\n", - " url + \"/\" + job_id + \"/results\", headers=headers\n", - ")\n", - "\n", - "res_dict = response_result.json()\n", - "\n", - "# Get results for the first PUB\n", - "counts = res_dict[\"results\"][0][\"data\"][\"meas\"][\"samples\"]\n", - "\n", - "print(counts[:20])" - ] - }, - { - "cell_type": "markdown", - "id": "07b7df2e-82fe-498e-8a27-3a96bf26c23c", - "metadata": {}, - "source": [ - "### 5. Work with Runtime options\n", - "\n", - "Error mitigation techniques allow users to mitigate circuit errors by modeling the device noise at the time of execution. This typically results in quantum pre-processing overhead related to model training, and classical post-processing overhead to mitigate errors in the raw results by using the generated model.\n", - "\n", - "The error mitigation techniques built in to primitives are advanced resilience options. To specify these options, use the `resilience_level` option when submitting your job.\n", - "Sampler V2 does not support specifying resilience levels. However, you can turn on or off individual error mitigation / suppression methods.\n", - "\n", - "The following examples demonstrate the default options for dynamical decoupling and twirling. Find more options and further details in the [Error mitigation and suppression techniques](/docs/guides/error-mitigation-and-suppression-techniques) topic.\n", - "\n", - "\n", - "\n", - "\n", - " \n", - "\n", - "\n", - "\n", - "\n", - " \n", - "\n", - "\n", - "" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0ffa3726-c490-431d-ae93-c5cd5b11293b", - "metadata": { - "tags": [ - "id-dd-options" - ] - }, - "outputs": [], - "source": [ - "headers = {\n", - " \"Content-Type\": \"application/json\",\n", - " \"Authorization\": auth_id,\n", - " \"Service-CRN\": crn,\n", - "}\n", - "job_input = {\n", - " \"program_id\": \"sampler\",\n", - " \"backend\": backend,\n", - " \"params\": {\n", - " \"pubs\": [\n", - " [qasm_string]\n", - " ], # primitive unified blocs (PUBs) containing one circuit each.\n", - " \"version\": \"2\",\n", - " \"options\": {\n", - " \"dynamical_decoupling\": {\n", - " \"enable\": True,\n", - " \"sequence_type\": \"XpXm\",\n", - " \"extra_slack_distribution\": \"middle\",\n", - " \"scheduling_method\": \"alap\",\n", - " },\n", - " },\n", - " },\n", - "}\n", - "\n", - "\n", - "response = requests.post(url, headers=headers, json=job_input)\n", - "\n", - "if response.status_code == 200:\n", - " job_id = response.json().get(\"id\")\n", - " print(\"Job created:\", response.text)\n", - "else:\n", - " print(f\"Error: {response.status_code}\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e5d00fb6-a4a2-422c-a26b-6958a37cfa4e", - "metadata": { - "tags": [ - "id-twirling-options" - ] - }, - "outputs": [], - "source": [ - "headers = {\n", - " \"Content-Type\": \"application/json\",\n", - " \"Authorization\": auth_id,\n", - " \"Service-CRN\": crn,\n", - "}\n", - "job_input = {\n", - " \"program_id\": \"sampler\",\n", - " \"backend\": backend,\n", - " \"params\": {\n", - " \"pubs\": [\n", - " [qasm_string]\n", - " ], # primitive unified blocs (PUBs) containing one circuit each.\n", - " \"version\": \"2\",\n", - " \"options\": {\n", - " \"twirling\": {\n", - " \"enable_gates\": True,\n", - " \"enable_measure\": True,\n", - " \"num_randomizations\": \"auto\",\n", - " \"shots_per_randomization\": \"auto\",\n", - " \"strategy\": \"active-accum\",\n", - " },\n", - " },\n", - " },\n", - "}\n", - "\n", - "\n", - "response = requests.post(url, headers=headers, json=job_input)\n", - "\n", - "if response.status_code == 200:\n", - " job_id = response.json().get(\"id\")\n", - " print(\"Job created:\", response.text)\n", - "else:\n", - " print(f\"Error: {response.status_code}\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d3ab882b-0945-4f7f-a9dd-c781cacaba7a", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# Cancel job immediately after since the example doesn't use it\n", - "job = service.job(job_id)\n", - "job.cancel()" - ] - }, - { - "cell_type": "markdown", - "id": "b4575de0-b2bf-45a8-98d7-5e370b45bca5", - "metadata": {}, - "source": [ - "\n", - "## Sampler primitive with REST API and parameterized circuits\n", - "\n", - "\n", - "### 1. Initialize the account\n", - "\n", - "Because Qiskit Runtime is a managed service, you first need to initialize your account. You can then select the device you want to use to run your calculations on.\n", - "\n", - "\n", - "Find details on how to initialize your account, view available backends, and invalidate tokens in this [topic](/docs/guides/cloud-setup-rest-api).\n", - "\n", - "\n", - "### 2. Define parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ce185ac5-506f-4b55-8da7-e689c127d76c", - "metadata": {}, - "outputs": [], - "source": [ - "from qiskit_ibm_runtime import QiskitRuntimeService\n", - "from qiskit.transpiler import generate_preset_pass_manager\n", - "from qiskit.qasm3 import dumps\n", - "from qiskit import QuantumCircuit\n", - "from qiskit.circuit import Parameter\n", - "\n", - "service = QiskitRuntimeService()\n", - "backend = service.least_busy()\n", - "\n", - "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", - "\n", - "theta = Parameter(\"theta\")\n", - "phi = Parameter(\"phi\")\n", - "parameter_values = {\n", - " \"theta\": 1.57,\n", - " \"phi\": 3.14,\n", - "} # In case we want to pass a dictionary" - ] - }, - { - "cell_type": "markdown", - "id": "1b888602-3155-4fdf-ba39-9b4961498958", - "metadata": {}, - "source": [ - "### 3. Create a quantum circuit and add parameterized gates" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "de811bfe-7836-44b1-affe-353c94a93069", - "metadata": {}, - "outputs": [], - "source": [ - "qc = QuantumCircuit(2)\n", - "\n", - "# Add parameterized gates\n", - "qc.rx(theta, 0)\n", - "qc.ry(phi, 1)\n", - "qc.cx(0, 1)\n", - "qc.measure_all()\n", - "\n", - "# Draw the original circuit\n", - "qc.draw(\"mpl\")\n", - "\n", - "# Get an ISA circuit\n", - "isa_circuit = pm.run(qc)" - ] - }, - { - "cell_type": "markdown", - "id": "a2aa333f-a0da-440d-9519-6f2d69758ffe", - "metadata": {}, - "source": [ - "### 4. Generate QASM 3 code" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "60e1a8b0-5f22-412a-bd7d-afc7c5c67382", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Generated QASM 3 code:\n", - "OPENQASM 3.0;\n", - "include \"stdgates.inc\";\n", - "input float[64] phi;\n", - "input float[64] theta;\n", - "bit[2] meas;\n", - "rz(pi/2) $0;\n", - "sx $0;\n", - "rz(pi + theta) $0;\n", - "sx $0;\n", - "rz(5*pi/2) $0;\n", - "sx $1;\n", - "rz(pi + phi) $1;\n", - "rz(-pi/2) $1;\n", - "sx $1;\n", - "cz $0, $1;\n", - "rz(pi/2) $1;\n", - "sx $1;\n", - "rz(pi/2) $1;\n", - "barrier $0, $1;\n", - "meas[0] = measure $0;\n", - "meas[1] = measure $1;\n", - "\n" - ] - } - ], - "source": [ - "qasm_str = dumps(isa_circuit)\n", - "print(\"Generated QASM 3 code:\")\n", - "print(qasm_str)" - ] - }, - { - "cell_type": "markdown", - "id": "3978ce10-3867-45e8-a75e-90812ce6deaa", - "metadata": {}, - "source": [ - "### 5. Run the quantum circuit using Sampler V2 API\n", - "\n", - "\n", - "\n", - " The following jobs use Qiskit Runtime V2 [primitives](/docs/guides/primitives). Both [`SamplerV2`](/docs/api/qiskit-ibm-runtime/sampler-v2) and [`EstimatorV2`](/docs/api/qiskit-ibm-runtime/estimator-v2) take one or more [primitive unified blocs (PUBs)](/docs/guides/primitive-input-output#pubs) as the input. Each PUB is a tuple that contains one circuit and the data broadcasted to that circuit, which can be multiple observables and parameters. Each PUB returns a result.\n", - "" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "2948dd67-1e7c-4bed-9fb7-074781dc0482", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Job created: {\"id\":\"d614873traac73bef6tg\",\"backend\":\"ibm_pittsburgh\"}\n" - ] - } - ], - "source": [ - "headers = {\n", - " \"Content-Type\": \"application/json\",\n", - " \"Authorization\": auth_id,\n", - " \"Service-CRN\": crn,\n", - "}\n", - "\n", - "job_input = {\n", - " \"program_id\": \"sampler\",\n", - " \"backend\": backend.name,\n", - " \"params\": {\n", - " # Choose one option: direct parameter transfer or through a dictionary\n", - " # \"pubs\": [[qasm_str,[1,2],500]], # primitive unified blocs (PUBs) containing one circuit each.\n", - " \"pubs\": [\n", - " [qasm_str, parameter_values, 500]\n", - " ], # primitive unified blocs (PUBs) containing one circuit each.\n", - " \"version\": \"2\",\n", - " },\n", - "}\n", - "\n", - "response = requests.post(url, headers=headers, json=job_input)\n", - "\n", - "if response.status_code == 200:\n", - " job_id = response.json().get(\"id\")\n", - " print(f\"Job created: {response.text}\")\n", - "else:\n", - " print(f\"Error: {response.status_code}\")" - ] - }, - { - "cell_type": "markdown", - "id": "a46a1ec4-4b1d-4ab0-aaef-d390de1bc96e", - "metadata": {}, - "source": [ - "### 6. Check job status and get results\n", - "Next, pass the `job_id` to the API:" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "e124546a-bf89-4ab8-91ca-927af5db3a31", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'status': 'Queued'}" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "response_status_singlejob = requests.get(f\"{url}/{job_id}\", headers=headers)\n", - "response_status_singlejob.json().get(\"state\")" - ] - }, - { - "cell_type": "markdown", - "id": "a05d7d8b-e588-4cb6-8faa-4c89226e3df7", - "metadata": {}, - "source": [ - "Once the job has completed, get job results:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "5ca0bc8c-72ac-41b8-ad74-c1226167035a", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# Hide this cell\n", - "\n", - "wait_for_results(url, job_id, headers)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "31bf7e5d-bbe7-482c-acbb-377d970dafd6", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['0x1', '0x2', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x2', '0x1', '0x1', '0x1', '0x1', '0x2', '0x2', '0x2', '0x2', '0x2', '0x2', '0x1']\n" - ] - } - ], - "source": [ - "response_result = requests.get(f\"{url}/{job_id}/results\", headers=headers)\n", - "\n", - "res_dict = response_result.json()\n", - "\n", - "# Get results for the first PUB\n", - "counts = res_dict[\"results\"][0][\"data\"][\"meas\"][\"samples\"]\n", - "\n", - "print(counts[:20])" - ] - }, - { - "cell_type": "markdown", - "id": "3d9ef591-91fd-4a49-a065-5e2cda4d41be", - "metadata": {}, - "source": [ - "## Next steps\n", - "\n", - "\n", - "\n", - " - There are several ways to run workloads, depending on your needs: job mode, session mode, and batch mode. Learn how to work with session mode and batch mode in the [execution modes topic](/docs/guides/execution-modes-rest-api). Note that Open Plan users cannot submit session jobs.\n", - " - Learn how to [initialize your account](/docs/guides/cloud-setup-rest-api) with REST API.\n", - " - Read [Migrate to V2 primitives](/docs/guides/v2-primitives).\n", - " - Practice with primitives by working through the [Cost function lesson](/learning/courses/variational-algorithm-design/cost-functions) in IBM Quantum Learning.\n", - " - Learn how to transpile locally in the [Transpile](/docs/guides/transpile) section.\n", - " - [Migrate to the Qiskit Runtime V2 primitives](/docs/guides/v2-primitives).\n", - "" - ] - } - ], - "metadata": { - "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" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/guides/primitives.ipynb b/docs/guides/primitives.ipynb index a7aa9d1c19b..f8a78d7094b 100644 --- a/docs/guides/primitives.ipynb +++ b/docs/guides/primitives.ipynb @@ -90,7 +90,11 @@ "\n", "## Primitive definition and implementations\n", "\n", - "There are two types of Qiskit primitives: the base classes, and their implementations. The Qiskit primitives are defined by open-source primitive base classes that live in the Qiskit SDK (in the [`qiskit.primitives`](/docs/api/qiskit/primitives) module). Providers (such as Qiskit Runtime) can use these base classes to derive their own Sampler and Estimator implementations. Most users will interact with provider implementations, not the base primitives.\n", + "There are two types of Qiskit primitives: the base classes, and their implementations. The Estimator and Sampler primitives are defined by open-source primitive base classes that live in the Qiskit SDK (in the [`qiskit.primitives`](/docs/api/qiskit/primitives) module). Providers (such as Qiskit Runtime) can use these base classes to derive their own Sampler and Estimator implementations. Most users will interact with provider implementations, not the base primitives.\n", + "\n", + "\n", + "There is not yet a base class for the Executor primitive.\n", + "\n", "\n", "### Base classes\n", "\n", @@ -124,6 +128,23 @@ "way to access your hardware features such as advanced post-processing techniques. It is therefore easier for your users to benefit from your hardware's best capabilities." ] }, + { + "cell_type": "markdown", + "id": "9aca0e26-ab6e-42be-af3e-c92f881b5fbb", + "metadata": {}, + "source": [ + "\n", + "### Executor (beta)\n", + "\n", + "The Executor Qiskit Runtime primitive takes a _program_ as input, generates and binds parameter values according to the _samplex_, executes the bound circuits on the hardware, and returns the execution results and metadata. It follows the directives of the input pair and does not make any implicit decisions for you, so that the process is transparent yet performant.\n", + "\n", + "The Executor primitive is part of the [directed execution model,](/docs/guides/directed-execution-model) which introduces some new terminology:\n", + "\n", + "- A **program** is a list of program items, where each item is either a circuit item or a samplex item.\n", + "- A **samplex item** is a pair that consists of a template circuit and a samplex pair.\n", + "- **Samplex** is the core type of the [Samplomatic library.](/docs/guides/directed-execution-model#samplomatic)" + ] + }, { "cell_type": "markdown", "id": "02dbbc7d-76e7-4a89-8739-ba7f3a5a05b8", diff --git a/docs/guides/pubs-broadcasting.mdx b/docs/guides/pubs-broadcasting.mdx new file mode 100644 index 00000000000..d2e5fd54ceb --- /dev/null +++ b/docs/guides/pubs-broadcasting.mdx @@ -0,0 +1,62 @@ +--- +title: Introduction to PUBs and broadcasting +description: Understand what PUBs are and how primitives handle array inputs and outputs using broadcasting semantics + +--- + +# Introduction to PUBs and broadcasting + + +## Introduction to PUBs + +The Estimator and Sampler primitives help you efficiently define vectorized workloads by using a data structure known as a _Primitive Unified Bloc (PUB)_. (Executor does not use PUBs.) These PUBs are the fundamental unit of work a QPU needs to execute these workloads. They are used as inputs to the `run()` method for the primitives, which execute the defined workload as a job. Then, after the job has completed, the results are returned in a format that is dependent on both the PUBs used as well as the runtime options specified from the Sampler or Estimator primitives. + +When invoking an Estimator or Sampler primitive's [`run()`](/docs/api/qiskit-ibm-runtime/estimator-v2#run) method, the main argument that is required is a `list` of one or more tuples -- one for each circuit being executed by the primitive. Each of these tuples is considered a PUB, and the required elements of each tuple in the list depends on the primitive used. The data provided to these tuples can also be arranged in a variety of shapes to provide flexibility in a workload through [broadcasting.](/docs/guides/pubs-broadcasting#broadcasting) + + +## Primitive broadcasting + +The Estimator and Executor primitives aggregate elements from multiple arrays (observables and parameter values) by following the same broadcasting rules as NumPy. (Sampler does not use broadcasting.) This section briefly summarizes those rules. For a detailed explanation, see the [NumPy broadcasting rules documentation](https://numpy.org/doc/stable/user/basics.broadcasting.html). + + +### Rules + +* Input arrays do not need to have the same number of dimensions. + * The resulting array will have the same number of dimensions as the input array with the largest dimension. + * The size of each dimension is the largest size of the corresponding dimension. + * Missing dimensions are assumed to have size one. +* Shape comparisons start with the rightmost dimension and continue to the left. +* Two dimensions are compatible if their sizes are equal or if one of them is one. + +Examples of array pairs that broadcast: + +```text +A1 (1d array): 1 +A2 (2d array): 3 x 5 +Result (2d array): 3 x 5 + + +A1 (3d array): 11 x 2 x 7 +A2 (3d array): 11 x 1 x 7 +Result (3d array): 11 x 2 x 7 +``` + +Examples of array pairs that do not broadcast: + +```text +A1 (1d array): 5 +A2 (1d array): 3 + +A1 (2d array): 2 x 1 +A2 (3d array): 6 x 5 x 4 # This would work if the middle dimension were 2, but it is 5. +``` + +The primitives return one value for each element of the broadcasted shape. + +## Next Steps + + +- Learn about [Estimator input and output](/docs/guides/estimator-input-output) in depth. +- Learn about [Sampler input and output](/docs/guides/sampler-input-output) in depth. +- Learn about [Executor input and output](/docs/guides/executor-input-output) in depth. + \ No newline at end of file diff --git a/docs/guides/q-ctrl-performance-management.ipynb b/docs/guides/q-ctrl-performance-management.ipynb index 844661f5aa1..67ad4813dca 100644 --- a/docs/guides/q-ctrl-performance-management.ipynb +++ b/docs/guides/q-ctrl-performance-management.ipynb @@ -64,7 +64,7 @@ "\n", "![Visualization of the improved runtime](/docs/images/guides/qctrl-performance-management/achieve_more.svg)\n", "\n", - "The Performance Management function can be used with any algorithm, and you can easily use it in place of the standard [Qiskit Runtime primitives](./primitives). Behind the scenes, multiple error suppression techniques work together to prevent errors from happening at runtime. All Fire Opal pipeline methods are pre-configured and algorithm-agnostic, meaning you always get the best performance out of the box.\n", + "The Performance Management function can be used with any algorithm, and you can easily use it in place of the standard [Qiskit Runtime primitives](/docs/guides/primitives). Behind the scenes, multiple error suppression techniques work together to prevent errors from happening at runtime. All Fire Opal pipeline methods are pre-configured and algorithm-agnostic, meaning you always get the best performance out of the box.\n", "\n", "To get access to Performance Management, [contact Q-CTRL](https://form.typeform.com/to/uOAVDnGg?typeform-source=q-ctrl.com)." ] @@ -89,7 +89,7 @@ "\n", "![Visualization of the error suppression pipeline](/docs/images/guides/qctrl-performance-management/error_suppression.svg)\n", "\n", - "The function offers two primitives, Sampler and Estimator, and the inputs and outputs of both extend the implemented spec for [Qiskit Runtime V2 primitives](/docs/guides/primitive-input-output)." + "The function offers two primitives, Sampler and Estimator, and the inputs and outputs of both extend the implemented spec for [Qiskit Runtime V2 primitives](/docs/guides/pubs-broadcasting#pubs)." ] }, { @@ -261,12 +261,12 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "26952e1f", "metadata": {}, "outputs": [], "source": [ - "# Run the circuit using the estimator\n", + "# Run the circuit using Estimator\n", "qctrl_estimator_job = perf_mgmt.run(\n", " primitive=\"estimator\",\n", " pubs=estimator_pubs,\n", @@ -279,7 +279,7 @@ "id": "c07af9d0", "metadata": {}, "source": [ - "You can use the familiar [Qiskit Serverless APIs](./serverless) to check your Qiskit Function workload's status:" + "You can use the familiar [Qiskit Serverless APIs](/docs/guides/serverless) to check your Qiskit Function workload's status:" ] }, { @@ -327,7 +327,7 @@ "id": "7375fcad", "metadata": {}, "source": [ - "The results have the same format as an [Estimator result](/docs/guides/primitive-input-output#estimator-output):" + "The results have the same format as an [Estimator result](/docs/guides/estimator-input-output):" ] }, { @@ -381,10 +381,10 @@ "| backend_name| `str` | The name of the backend | No | The least busy backend that your instance has access to | `\"ibm_fez\"` |\n", "| options| `dict` | Input options; see Options section for more details | No | See the Options section for details | `{\"default_shots\": 2048}` |\n", "\n", - "**`QctrlEstimatorPubLike` components (derived from the [Qiskit Runtime PUB definition](/docs/guides/primitive-input-output#estimator-pub)):**\n", + "**`QctrlEstimatorPubLike` components (derived from the [Qiskit Runtime PUB definition](/docs/guides/estimator-input-output)):**\n", "- A single circuit defined as a `QuantumCircuit` or in OpenQASM 2.0 or 3.0 string format.\n", "- One or more observables that specify the expectation values to estimate, in any of the formats denoted in the list \"Supported observables formats\".\n", - "- (Optional) A collection of parameter values to bind the circuit against, which follow the same [array broadcasting rules](./primitive-input-output#broadcasting-rules) as the `QiskitRuntime` primitives.\n", + "- (Optional) A collection of parameter values to bind the circuit against, which follow the same [array broadcasting rules](/docs/guides/pubs-broadcasting#broadcasting) as the `QiskitRuntime` primitives.\n", "- (Optional) A target precision for expectation values to estimate.\n", "- (Optional) A real number representing the precision, or a dictionary of run options containing the shot count. For example: `{\"shots\": }`.\n", "\n", @@ -522,12 +522,12 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "id": "2595df84", "metadata": {}, "outputs": [], "source": [ - "# Run the circuit using the sampler\n", + "# Run the circuit using Sampler\n", "qctrl_sampler_job = perf_mgmt.run(\n", " primitive=\"sampler\",\n", " pubs=sampler_pubs,\n", @@ -704,7 +704,7 @@ "| backend_name| `str` | The name of the backend | No | The least busy backend that your instance has access to | `\"ibm_fez\"` |\n", "| options| `dict` | Input options; see Options section for more details | No | See the Options section for details | `{\"default_shots\": 2048}` |\n", "\n", - "**`QctrlSamplerPubLike` components (derived from the [Qiskit Runtime PUB definition](/docs/guides/primitive-input-output#sampler-pub)):**\n", + "**`QctrlSamplerPubLike` components (derived from the [Qiskit Runtime PUB definition](/docs/guides/sampler-input-output)):**\n", "- A single circuit defined as a `QuantumCircuit` or in OpenQASM 2.0 or 3.0 string format.\n", "- (Optional) A collection of parameter values to bind the circuit against.\n", "- (Optional) An integer representing the shot count, or a dictionary of runtime options containing the shot count. For example: `(circ, None, 123)` or `(circ, None, {\"shots\": 123})`.\n", diff --git a/docs/guides/qasm-feature-table.mdx b/docs/guides/qasm-feature-table.mdx index fc977bda411..d83d3fb9b31 100644 --- a/docs/guides/qasm-feature-table.mdx +++ b/docs/guides/qasm-feature-table.mdx @@ -157,6 +157,6 @@ This includes features that cannot be loaded by Qiskit SDK from OpenQASM 3. - Learn how to generate OpenQASM code using [IBM Quantum Composer](/docs/guides/composer). - See the [OpenQASM 3 Qiskit API](/docs/api/qiskit/qasm3) reference. - See the [OpenQASM 2 Qiskit API](/docs/api/qiskit/qasm2) reference. - - Review the [Verify your program](./debugging-tools) topic. + - Review the [Verify your program](/docs/guides/debugging-tools) topic. - Visit the [OpenQASM Live Specification](https://openqasm.com/).
diff --git a/docs/guides/qedma-qesem.ipynb b/docs/guides/qedma-qesem.ipynb index 490ff026012..4e7a6b0eaab 100644 --- a/docs/guides/qedma-qesem.ipynb +++ b/docs/guides/qedma-qesem.ipynb @@ -244,7 +244,7 @@ "\n", "| Name | Type | Description | Required | Default | Example |\n", "| -----| ------| ------------| -------- | ------- | -------- |\n", - "| `pubs` | [EstimatorPubLike](/docs/guides/primitive-input-output) |This is the main input. The `Pub` contains 2-4 elements: a circuit, one or more observables, 0 or a single set of parameter values, and an optional precision. If a precision was not specified, then the `default_precision` from `options` will be used| Yes| N/A | `[(circuit, [obs1,obs2,obs3], parameter_values, 0.03)]` |\n", + "| `pubs` | [EstimatorPubLike](/docs/guides/pubs-broadcasting#pubs) |This is the main input. The `Pub` contains 2-4 elements: a circuit, one or more observables, 0 or a single set of parameter values, and an optional precision. If a precision was not specified, then the `default_precision` from `options` will be used| Yes| N/A | `[(circuit, [obs1,obs2,obs3], parameter_values, 0.03)]` |\n", "| `backend_name`| string|Name of the backend to use |No | QESEM will get least busy device reported by IBM| `\"ibm_fez\"`|\n", "| `instance` | string| The cloud resource name of the instance to use in that format | No | N/A | `“CRN”` |\n", "| `options` | dictionary |Input options. See **Options** section for more details. | No | See the **Options** section for details. | `{ default_precision = 0.03, \"max_execution_time\" = 3600, \"transpilation_level\" = 0}` |\n", diff --git a/docs/guides/qiskit-1.0-features.mdx b/docs/guides/qiskit-1.0-features.mdx index 077f26e3100..9f04a1bb943 100644 --- a/docs/guides/qiskit-1.0-features.mdx +++ b/docs/guides/qiskit-1.0-features.mdx @@ -335,7 +335,7 @@ sampler_v2 = StatevectorSampler()
1. `Sampler and Estimator`: The new V2 primitives are designed to accept **vectorized inputs**, where single circuits can be grouped with array-valued specifications. That is, one circuit can be executed - for arrays of `n` parameter sets, `n` observables, or both (in the case of the estimator). Each group is called a **primitive unified bloc (pub)**, and can be represented as a tuple: `(1 x circuit, [n x observables], [n x parameters])`. The V1 interface didn't allow for the same flexibility. Instead, the number of input circuits had to match the number of observables and + for arrays of `n` parameter sets, `n` observables, or both (in the case of Estimator). Each group is called a **primitive unified bloc (pub)**, and can be represented as a tuple: `(1 x circuit, [n x observables], [n x parameters])`. The V1 interface didn't allow for the same flexibility. Instead, the number of input circuits had to match the number of observables and parameter sets, as shown in the following examples (select a tab to see each example): @@ -409,7 +409,7 @@ sampler_v2 = StatevectorSampler() returns measurement outcome samples in the form of **bitstrings** or **counts**, instead of the quasi-probability distributions from the V1 interface. The bitstrings show the measurement outcomes, preserving the shot - order in which they were measured. The V2 sampler result objects organize + order in which they were measured. The V2 Sampler result objects organize data in terms of their input circuits' classical register names, for compatibility with dynamic circuits. @@ -436,7 +436,7 @@ sampler_v2 = StatevectorSampler()
```python - # Run using V1 sampler + # Run using V1 Sampler result = sampler_v1.run(circuit).result() quasi_dist = result.quasi_dists[0] print(f"The quasi-probability distribution is: {quasi_dist}") @@ -445,7 +445,7 @@ sampler_v2 = StatevectorSampler() The quasi-probability distribution is: {0: 0.5, 3: 0.5} ``` ```python - # Run using V2 sampler + # Run using V2 Sampler result = sampler_v2.run([circuit]).result() # Access result data for pub 0 data_pub = result[0].data diff --git a/docs/guides/qiskit-1.0-installation.mdx b/docs/guides/qiskit-1.0-installation.mdx index 60d94408a3e..cbbb8023438 100644 --- a/docs/guides/qiskit-1.0-installation.mdx +++ b/docs/guides/qiskit-1.0-installation.mdx @@ -21,7 +21,7 @@ This guide is divided into the following sections. You only need to review the * If you develop or maintain a package that depends on Qiskit, read the [For developers](#for-developers) section. * If you encounter problems installing or importing Qiskit 1.0, review the [Troubleshooting](#troubleshooting) section. -If you are interested in understanding the old package structure and why it changed, review the [overview of the breaking package changes](./metapackage-migration). +If you are interested in understanding the old package structure and why it changed, review the [overview of the breaking package changes](/docs/guides/metapackage-migration). ## For users diff --git a/docs/guides/qiskit-function-templates.mdx b/docs/guides/qiskit-function-templates.mdx index a2dd9ffcf45..1281a38ccc5 100644 --- a/docs/guides/qiskit-function-templates.mdx +++ b/docs/guides/qiskit-function-templates.mdx @@ -6,7 +6,7 @@ description: Learn how to use and build Qiskit Function templates. # Introduction to Qiskit Function templates -[Qiskit Function templates](https://github.com/qiskit-community/qiskit-function-templates) are an open-source collection of realistic code examples that give you access to some of the latest research workflows that leverage tools like the Qiskit SDK and [Qiskit addons](/docs/guides/addons). These pre-built workflows take information from practical experiments and package them in a way that you can customize and reuse in your own research so that you don't have to build from scratch. All templates are readily deployable to [Qiskit Serverless](./serverless) where you can easily leverage classical compute as part of your workflow. +[Qiskit Function templates](https://github.com/qiskit-community/qiskit-function-templates) are an open-source collection of realistic code examples that give you access to some of the latest research workflows that leverage tools like the Qiskit SDK and [Qiskit addons](/docs/guides/addons). These pre-built workflows take information from practical experiments and package them in a way that you can customize and reuse in your own research so that you don't have to build from scratch. All templates are readily deployable to [Qiskit Serverless](/docs/guides/serverless) where you can easily leverage classical compute as part of your workflow. There are two types of templates: @@ -18,23 +18,23 @@ There are two types of templates: Qiskit Function template implementations are organized by application area. Currently included in the collection is a physics template for Hamiltonian simulation using the [AQC-Tensor Qiskit addon](https://qiskit.github.io/qiskit-addon-aqc-tensor/) and a chemistry template for electronic structure with the implicit solvent model using the [SQD Qiskit addon](/docs/guides/qiskit-addons-sqd). Resources to get started with these two templates are available at the following links: -- Electronic structure simulation with implicit solvent model: [template source files](https://github.com/qiskit-community/qiskit-function-templates/tree/main/chemistry/sqd_pcm) and [guide](./function-template-chemistry-workflow) -- Hamiltonian simulation: [template source files](https://github.com/qiskit-community/qiskit-function-templates/tree/main/physics/hamiltonian_simulation) and [guide](./function-template-hamiltonian-simulation) +- Electronic structure simulation with implicit solvent model: [template source files](https://github.com/qiskit-community/qiskit-function-templates/tree/main/chemistry/sqd_pcm) and [guide](/docs/guides/function-template-chemistry-workflow) +- Hamiltonian simulation: [template source files](https://github.com/qiskit-community/qiskit-function-templates/tree/main/physics/hamiltonian_simulation) and [guide](/docs/guides/function-template-hamiltonian-simulation) ## Base templates The *base templates* are references for developing your own original Qiskit Function. They are designed to help you kickstart the development process by illustrating best practices in interface development, code formatting, I/O handling, error messages, checkpoints, unit testing, and more. The repository is exposed as a [GitHub template](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository) so that the CI/CD implementation can be easily extended. -There are currently two templates: a [circuit function template](https://github.com/qiskit-community/qiskit-function-templates/blob/main/base_templates/circuit_function_template.py) and an [application function template](https://github.com/qiskit-community/qiskit-function-templates/blob/main/base_templates/application_function_template.py). The circuit function template is built similarly to the [IBM Circuit Function](./ibm-circuit-function) and the application function template illustrates how to structure a typical application workflow. +There are currently two templates: a [circuit function template](https://github.com/qiskit-community/qiskit-function-templates/blob/main/base_templates/circuit_function_template.py) and an [application function template](https://github.com/qiskit-community/qiskit-function-templates/blob/main/base_templates/application_function_template.py). The circuit function template is built similarly to the [IBM Circuit Function](/docs/guides/ibm-circuit-function) and the application function template illustrates how to structure a typical application workflow. ## Next steps -- Review the guide on building a function template for [Hamiltonian simulation](./function-template-hamiltonian-simulation) -- Read through the guide on deploying the function template for a [chemistry workflow](./function-template-chemistry-workflow) +- Review the guide on building a function template for [Hamiltonian simulation](/docs/guides/function-template-hamiltonian-simulation) +- Read through the guide on deploying the function template for a [chemistry workflow](/docs/guides/function-template-chemistry-workflow) - Check out the [Qiskit Function templates repository](https://github.com/qiskit-community/qiskit-function-templates) on GitHub. diff --git a/docs/guides/repetition-rate-execution.ipynb b/docs/guides/repetition-rate-execution.ipynb index 962ed98a748..f7ffcae5747 100644 --- a/docs/guides/repetition-rate-execution.ipynb +++ b/docs/guides/repetition-rate-execution.ipynb @@ -108,7 +108,8 @@ "\n", "\n", " - Try an example in the [Quantum approximate optimization algorithm (QAOA)](/docs/tutorials/quantum-approximate-optimization-algorithm) tutorial.\n", - " - Review how to [get started with primitives](/docs/guides/get-started-with-primitives).\n", + " - Review how to [get started with Estimator.](/docs/guides/get-started-with-estimator)\n", + " - Review how to [get started with Sampler.](/docs/guides/get-started-with-sampler)\n", "" ] } diff --git a/docs/guides/run-jobs-batch.ipynb b/docs/guides/run-jobs-batch.ipynb index 9b1f88b3946..2474c3e4d8c 100644 --- a/docs/guides/run-jobs-batch.ipynb +++ b/docs/guides/run-jobs-batch.ipynb @@ -361,10 +361,10 @@ "## Next steps\n", "\n", "\n", - " - Try an example in the [Combine error mitigation options with the estimator primitive](/docs/tutorials/combine-error-mitigation-techniques) tutorial.\n", + " - Try an example in the [Combine error mitigation options with the Estimator primitive](/docs/tutorials/combine-error-mitigation-techniques) tutorial.\n", " - Review the [Batch API](/docs/api/qiskit-ibm-runtime/batch#batch) reference.\n", - " - Understand the [Job limits](/docs/guides/job-limits) when sending a job to an IBM QPU.\n", - " - Review [execution modes FAQs](/docs/guides/execution-modes-faq).\n", + " - Understand the [Job limits](/docs/guides/job-limits) when sending a job to an IBM® QPU.\n", + " - Review [execution modes FAQs.](/docs/guides/execution-modes-faq)\n", "" ] } diff --git a/docs/guides/run-jobs-session.ipynb b/docs/guides/run-jobs-session.ipynb index 3e75b1a638f..8807436b7f7 100644 --- a/docs/guides/run-jobs-session.ipynb +++ b/docs/guides/run-jobs-session.ipynb @@ -58,7 +58,7 @@ "\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:" + "Before starting a session, you must [set up Qiskit Runtime](/docs/guides/install-qiskit) and initialize it as a service:" ] }, { diff --git a/docs/guides/runtime-options-overview.mdx b/docs/guides/runtime-options-overview.mdx index 466f3d6b5d5..fc0cd09dcdb 100644 --- a/docs/guides/runtime-options-overview.mdx +++ b/docs/guides/runtime-options-overview.mdx @@ -1,7 +1,7 @@ --- title: Introduction to options description: Available options for building with Qiskit Runtime primitives -in_page_toc_min_heading_level: 2 +in_page_toc_min_heading_level: 1 in_page_toc_max_heading_level: 2 --- @@ -14,889 +14,25 @@ in_page_toc_max_heading_level: 2 ### Structure -When calling the primitives, you can pass in options by using an options class or a dictionary. Commonly-used options, such as `resilience_level`, are at the first level. Other options are grouped into different categories, such as `execution`. See the [Set primitive options](/docs/guides/specify-runtime-options#pass-options) section for full details. +When calling the primitives, you can pass in options by using an options class or a dictionary. Commonly-used options, such as `resilience_level`, are at the first level. Other options are grouped into different categories, such as `execution`. See [Estimator options,](/docs/guides/estimator-options) [Sampler options,](/docs/guides/sampler-options) and [Executor options](/docs/guides/executor-options) for full details. ### Defaults If you do not specify a value for an option, it is given a special value of `Unset` and the server default value is used. Thus, the default value will be the same regardless of your code version. -The tables in the [Options classes summary](#options-classes) section lists the default values. +The tables in the Options classes summary sections on each primitive's options guide lists the default values. ## Set options -Options can be defined before a primitive is constructed and passed to the primitive, which makes a copy of them. This can be done either as a nested dictionary, or by using the options classes. Additionally, after the primitive is constructed, its options can be changed. Use the workflow that works best for your application. See [Specify options](specify-runtime-options) for full details. - - -## Options classes summary - - - - - [Dynamical decoupling](/docs/api/qiskit-ibm-runtime/options-dynamical-decoupling-options): Options for dynamical decoupling. - - [Environment](/docs/api/qiskit-ibm-runtime/options-environment-options): Execution environment options, such as the logging level to set and job tags to add. - - [Execution](/docs/api/qiskit-ibm-runtime/options-execution-options-v2): Primitive execution options, including whether to initialize qubits and the repetition delay. - - [Resilience](/docs/api/qiskit-ibm-runtime//options-resilience-options-v2): Advanced options for configuring error mitigation methods such as measurement error mitigation, ZNE, and PEC. - - [Simulator](/docs/api/qiskit-ibm-runtime/options-simulator-options): Simulator options, such as the basis gates, simulator seed, and coupling map. Applies to [local testing mode](/docs/guides/local-testing-mode) only. - - [Twirling](/docs/api/qiskit-ibm-runtime/options-twirling-options): Twirling options, such as whether to apply two-qubit gate twirling and the number of shots to run for each random sample. - - - - - [Dynamical decoupling](/docs/api/qiskit-ibm-runtime/options-dynamical-decoupling-options): Options for dynamical decoupling. - - [Environment](/docs/api/qiskit-ibm-runtime/options-environment-options): Execution environment options, such as the logging level to set and job tags to add. - - [Execution](/docs/api/qiskit-ibm-runtime/options-execution-options-v2): Primitive execution options, including whether to initialize qubits and the repetition delay. - - [Simulator](/docs/api/qiskit-ibm-runtime/options-simulator-options): Simulator options, such as the basis gates, simulator seed, and coupling map. Applies to [local testing mode](/docs/guides/local-testing-mode) only. - - [Twirling](/docs/api/qiskit-ibm-runtime/options-twirling-options): Twirling options, such as whether to apply two-qubit gate twirling and the number of shots to run for each random sample. - - - - - -## Available options - -The following table documents options from the latest version of `qiskit-ibm-runtime`. To see older option versions, visit the [`qiskit-ibm-runtime` API reference](/docs/api/qiskit-ibm-runtime) and select a previous version. - - - - - - -The total number of shots to use per circuit per configuration. - -**Choices**: Integer >= 0 - -**Default**: None - -[`default_shots` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#default_shots) - - - - - -The default precision to use for any PUB or `run()` call that does not specify one. - -**Choices**: Float > 0 - -**Default**: 0.015625 (1 / sqrt(4096)) - -[`default_precision` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#default_precision) - - - - - -Control dynamical decoupling error mitigation settings. - -[`dynamical_decoupling` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#dynamical_decoupling) - - - -**Choices**: `True`, `False` - -**Default**: `False` - - - - - -**Choices**: `middle`, `edges` - -**Default**: `middle` - - - - - -Choices: `asap`, `alap` -Default: `alap` - - - - - -Choices: `XX`, `XpXm`, `XY4` -Default: `XX` - - - - - -Choices: `True`, `False` -Default: `False` - - - - - - - - - - -[`environment` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#environment) - - - -Callable function that receives the `Job ID` and `Job result`. - -**Choices**: None - -**Default**: None - - - - - -List of tags. - -**Choices**: None - -**Default**: None - - - - - -**Choices**: DEBUG, INFO, WARNING, ERROR, CRITICAL - -**Default**: WARNING - - - - - -**Choices**: `True`, `False` - -**Default**: `False` - - - - - - - - - - -[`execution` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#execution) - - -Whether to reset the qubits to the ground state for each shot. - -**Choices**: `True`, `False` - -**Default**: `True` - - - - -The delay between a measurement and the subsequent quantum circuit. - -**Choices**: Value in the range supplied by `backend.rep_delay_range` - -**Default**: Given by `backend.default_rep_delay` - - - - - - - - - -**Choices**: Integer number of seconds in the range [1, 10800] - -**Default**: 10800 (3 hours) - -[`max_execution_time` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#max_execution_time) - - - - -Advanced resilience options to fine tune the resilience strategy. - -[`resilience` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#resilience) - - - -Options for learning layer noise. - -[`resilience.layer_noise_learning` API documentation](/docs/api/qiskit-ibm-runtime/options-layer-noise-learning-options) - - - - - -**Choices**: list[int] of 2-10 values in the range [0, 200] - -**Default**: `(0, 1, 2, 4, 16, 32)` - - - - - - - -**Choices**: None, Integer >= 1 - -**Default**: `4` - - - - - - - -**Choices**: Integer >= 1 - -**Default**: `32` - - - - - - - -**Choices**: Integer >= 1 - -**Default**: `128` - - - - - - - -**Choices**: `NoiseLearnerResult`, `Sequence[LayerError]` - -**Default**: None - - - - - - - -**Choices**: `True`, `False` - -**Default**: `True` - - - - - - - -Options for measurement noise learning. - -[`resilience.measure_noise_learning` API documentation](/docs/api/qiskit-ibm-runtime/options-measure-noise-learning-options) - - - - - -**Choices**: Integer >= 1 - -**Default**: `32` - - - - - - - -**Choices**: Integer, `auto` - -**Default**: `auto` - - - - - - - -**Choices**: `True`, `False` - -**Default**: `False` - - - - - - - -Probabilistic error cancellation mitigation options. - -[`resilience.pec` API documentation](/docs/api/qiskit-ibm-runtime/options-pec-options) - - - - - -**Choices**: `None`, Integer >= 1 - - -**Default**: `100` - - - - - - - -**Choices**: `auto`, float in the range [0, 1] - -**Default**: `auto` - - - - - - - -**Choices**: `True`, `False` - -**Default**: `False` - - - - - - - -[`resilience.zne` API documentation](/docs/api/qiskit-ibm-runtime/options-zne-options) - - - - - -**Choices**: `gate_folding`, `gate_folding_front`, `gate_folding_back`, `pea` - -**Default**: `gate_folding` - - - - - - - -**Choices**: List of floats - -**Default**: `[0, *noise_factors]` - - - - - - - -**Choices**: One or more of: `exponential`, `linear`, `double_exponential`, `polynomial_degree_(1 <= k <= 7)`, `fallback` - -**Default**: `(exponential, linear)` - - - - - - - -**Choices**: List of floats; each float >= 1 - -**Default**: `(1, 1.5, 2)` for `PEA`, and `(1, 3, 5)` otherwise - - - - - - - - - - - - -How much resilience to build against errors. Higher levels generate more accurate results at the expense of longer processing times. - -**Choices**: `0`, `1`, `2` - -**Default**: `1` - -[`resilience_level` API documentation](/docs/api/qiskit-ibm-runtime/options-estimator-options#resilience_level) - - - - - -**Choices**: Integer - -**Default**: None - -[`seed_estimator`](/docs/api/qiskit-ibm-runtime/options-estimator-options#seed_estimator) - - - - - -Options to pass when simulating a backend - -[`simulator` API documentation](/docs/api/qiskit-ibm-runtime/options-simulator-options) - - - -**Choices**: List of basis gate names to unroll to - -**Default**: The set of all basis gates supported by [Qiskit Aer simulator](https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.AerSimulator.html) - - - - - - - -**Choices**: List of directed two-qubit interactions - -**Default**: None, which implies no connectivity constraints (full connectivity). - - - - - - - -**Choices**: [Qiskit Aer NoiseModel](/docs/guides/build-noise-models), or its representation - -**Default**: None - - - - - - - -**Choices**: Integer - -**Default**: None - - - - - - - - - - - - -Twirling options - -[`twirling` API documentation](/docs/api/qiskit-ibm-runtime/options-twirling-options) - - - -**Choices**: True, False - -**Default**: False - - - - - - - -**Choices**: True, False - -**Default**: True - - - - - - - -**Choices**: `auto`, Integer >= 1 - -**Default**: `auto` - - - - - - - -**Choices**: `auto`, Integer >= 1 - -**Default**: `auto` - - - - - - - -**Choices**: `active`, `active-circuit`, `active-accum`, `all` - -**Default**: `active-accum` - - - - - - - - - - - - -Experimental options, when available. - - - - - - - - - - - - - -The total number of shots to use per circuit per configuration. - -**Choices**: Integer >= 0 - -**Default**: None - -[`default_shots` API documentation](/docs/api/qiskit-ibm-runtime/options-sampler-options#default_shots) - - - - - -Control dynamical decoupling error mitigation settings. - -[`dynamical_decoupling` API documentation](/docs/api/qiskit-ibm-runtime/options-sampler-options#dynamical_decoupling) - - - -**Choices**: `True`, `False` - -**Default**: `False` - - - - - -**Choices**: `middle`, `edges` - -**Default**: `middle` - - - - - -Choices: `asap`, `alap` -Default: `alap` - - - - - -Choices: `XX`, `XpXm`, `XY4` -Default: `XX` - - - - - -Choices: `True`, `False` -Default: `False` - - - - - - - - - -[`environment` API documentation](/docs/api/qiskit-ibm-runtime/options-sampler-options#environment) - - - -List of tags. - -**Choices**: None - -**Default**: None - - - - - -**Choices**: DEBUG, INFO, WARNING, ERROR, CRITICAL - -**Default**: WARNING - - - - - -**Choices**: `True`, `False` - -**Default**: `False` - - - - - - - - - -[`execution` API documentation](/docs/api/qiskit-ibm-runtime/options-sampler-options#execution) - - -Whether to reset the qubits to the ground state for each shot. - -**Choices**: `True`, `False` - -**Default**: `True` - - - - -The delay between a measurement and the subsequent quantum circuit. - -**Choices**: Value in the range supplied by `backend.rep_delay_range` - -**Default**: Given by `backend.default_rep_delay` - - - - - -**Choices**: `classified`, `kerneled`, `avg_kerneled` - -**Default**: `classified` - - - - - - - - - -**Choices**: Integer number of seconds in the range [1, 10800] - -**Default**: 10800 (3 hours) - -[`max_execution_time` API documentation](/docs/api/qiskit-ibm-runtime/options-sampler-options#max_execution_time) - - - - - -Options to pass when simulating a backend - -[`simulator` API documentation](/docs/api/qiskit-ibm-runtime/options-simulator-options) - - - -**Choices**: List of basis gate names to unroll to - -**Default**: The set of all basis gates supported by [Qiskit Aer simulator](https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.AerSimulator.html) - - - - - - - -**Choices**: List of directed two-qubit interactions - -**Default**: None, which implies no connectivity constraints (full connectivity). - - - - - - - -**Choices**: [Qiskit Aer NoiseModel](/docs/guides/build-noise-models), or its representation - -**Default**: None - - - - - - - -**Choices**: Integer - -**Default**: None - - - - - - - - - - - - -Twirling options - -[`twirling` API documentation](/docs/api/qiskit-ibm-runtime/options-twirling-options) - - - -**Choices**: True, False - -**Default**: False - - - - - - - -**Choices**: True, False - -**Default**: False - - - - - - - -**Choices**: `auto`, Integer >= 1 - -**Default**: `auto` - - - - - - - -**Choices**: `auto`, Integer >= 1 - -**Default**: `auto` - - - - - - - -**Choices**: `active`, `active-circuit`, `active-accum`, `all` - -**Default**: `active-accum` - - - - - - - - - - - - -Experimental options, when available. - - - - - - - - - - - - -## Feature compatibility - -Due to differences in the device compilation process, certain runtime features cannot be used together in a single job. Click the appropriate tab for a list of features that are incompatible with the selected feature: - - - - Incompatible with: - - Gate-folding ZNE - - PEA - - PEC - - Dynamical decoupling - - Other notes: - - Gate twirling can be applied to dynamic circuits, but only to gates not inside conditional blocks. Measurement twirling can only be applied to terminal measurements. - - Compatible with fractional gates when using `qiskit-ibm-runtime` v0.42.0 or later. - - - - Incompatible with dynamic circuits. - - - - - Incompatible with: - - Gate twirling - - PEA - - PEC - - Compatible with dynamic circuits when using `qiskit-ibm-runtime` v0.42.0 or later. - - - - - Incompatible with: - - Dynamic circuits - - PEA - - PEC - - Might not work when using custom gates. - - - Incompatible with fractional gates or with stretches. - - Other notes: - - Gate twirling can be applied to dynamic circuits, but only to gates not inside conditional blocks. Measurement twirling can only be applied to terminal measurements. - - Does not work with non-Clifford entanglers. - - - - - Incompatible with: - - Dynamic circuits - - Fractional gates - - Gate-folding ZNE - - PEC - - - - Incompatible with: - - Dynamic circuits - - Fractional gates - - Gate-folding ZNE - - PEA - - - +Options can be defined before a primitive is constructed and passed to the primitive, which makes a copy of them. This can be done either as a nested dictionary, or by using the options classes. Additionally, after the primitive is constructed, its options can be changed. Use the workflow that works best for your application. ## Next steps - - Find more details about the `EstimatorV2` methods in the [Estimator API reference](/docs/api/qiskit-ibm-runtime/estimator-v2). - - Find more details about the `SamplerV2` methods in the [Sampler API reference](/docs/api/qiskit-ibm-runtime/sampler-v2). - Find details about how to configure [error suppression](configure-error-suppression) and [error mitigation](configure-error-mitigation). - - Learn how to [specify options](specify-runtime-options). + - Learn more about [Estimator options.](/docs/guides/estimator-options) + - Learn more about [Sampler options.](/docs/guides/sampler-options) + - Learn more about [Executor options.](/docs/guides/executor-options) diff --git a/docs/guides/sampler-examples.ipynb b/docs/guides/sampler-examples.ipynb new file mode 100644 index 00000000000..3e477b9d4e6 --- /dev/null +++ b/docs/guides/sampler-examples.ipynb @@ -0,0 +1,361 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1f4a2ec4-3595-4300-8f9e-092b0ef9b444", + "metadata": {}, + "source": [ + "---\n", + "title: Examples\n", + "description: Practical examples of using the Sampler primitive in Qiskit Runtime.\n", + "---\n", + "\n", + "\n", + "# Sampler examples" + ] + }, + { + "cell_type": "markdown", + "id": "b4121e48", + "metadata": { + "tags": [ + "version-info" + ] + }, + "source": [ + "{/*\n", + " DO NOT EDIT THIS CELL!!!\n", + " This cell's content is generated automatically by a script. Anything you add\n", + " here will be removed next time the notebook is run. To add new content, create\n", + " a new cell before or after this one.\n", + "*/}\n", + "\n", + "
\n", + "Package versions\n", + "\n", + "The code on this page was developed using the following requirements.\n", + "We recommend using these versions or newer.\n", + "\n", + "```\n", + "qiskit[all]~=2.3.0\n", + "qiskit-ibm-runtime~=0.43.1\n", + "```\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "12aea3c7-37a1-4a6b-b944-587669aa6611", + "metadata": {}, + "source": [ + "Generate entire error-mitigated quasi-probability distributions sampled from quantum circuit outputs. Leverage Sampler’s capabilities for search and classification algorithms like Grover’s and QVSM.\n", + "\n", + "## Run a single experiment\n", + "\n", + "Use Sampler to return the measurement outcome as bitstrings or counts of a single circuit." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "a5a561b3-3819-4f9e-bb64-4c27267e0e96", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " > First ten results: ['0101110000110001001111000101001111000110110100011000100101011101110011010010010101000110000111101010101000001010000100100000100', '0100010101111101010000100010011100110001010000011000000010001100010111000011001010000100100000100000000010000000010010101011110', '1101010111111111100010000011101010101010100100011001000000001001110010001000000010000010000101000111000100010010000001111000010', '1001110001100001001101111010111100000100010110010001001100111000110010111000001010001000000000000000100101101001110010101000110', '0001000000011011000011000111001000000000100110110011111110110100110000101010100010000010101011011000101011101000100000110000011', '1011100010011111010000001110110000111101000001110010011001100011111010001100100000110001000010001010110011100010000111000111010', '1101110000011000001011011000001111001110010111111111100100010001110100000010000001011000110000000011010011110100101001101000010', '0110100000110011000011001000110110110001000100100001111010001101000001010111000000101010101000001110100100001010110001000100101', '1000011010011011001111010010100000001110010010100000011010000110011010100000111000010010100111000001100101100010110010101001010', '1011011100111001010010101001000111000001110011110011001111010100100011101111011101011000000111011010000011100011010000001000000']\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import iqp\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "from qiskit.quantum_info import random_hermitian\n", + "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler\n", + "\n", + "n_qubits = 127\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=n_qubits\n", + ")\n", + "\n", + "mat = np.real(random_hermitian(n_qubits, seed=1234))\n", + "circuit = iqp(mat)\n", + "circuit.measure_all()\n", + "\n", + "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", + "isa_circuit = pm.run(circuit)\n", + "\n", + "sampler = Sampler(backend)\n", + "job = sampler.run([isa_circuit])\n", + "result = job.result()\n", + "\n", + "# Get results for the first (and only) PUB\n", + "pub_result = result[0]\n", + "\n", + "print(f\" > First ten results: {pub_result.data.meas.get_bitstrings()[:10]}\")" + ] + }, + { + "cell_type": "markdown", + "id": "c9ea6d3c-b03f-49e2-a8de-d32e58396e02", + "metadata": {}, + "source": [ + "## Run multiple experiments in a single job\n", + "\n", + "Use Sampler to return the measurement outcome as bitstrings or counts of multiple circuits in one job." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "e4534da8-9fe3-402b-8afc-f4bd9fbed497", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " > First ten results for pub 0: ['1000000101000100010111001010101010000001001010101011011001011110001000000110110101010000010000000000110001001000011111110000001', '1111101011011011110001011000001100001101100001000101111011101110000101111010001011111010001001000010111001110111000010001011010', '1100100101110010000110101011110010111001101010001101100010110100110110000110110010001110001000001010011100001000011011000111010', '1100010010000100100010110100011010011001010101101101101001100001001110011001011011111100011100100001000101010000111101110001101', '0011101011101100010011111001001110000101100110000110000001111000011010011110000110100000110011011000000010110001010000111000100', '0110101101110000010110100100010011000100100010000010010010110001111111110000101011000100010000000100100100110011010111101110111', '1101011000111100011000010110000010001100101011000001110010110001111101010101011110110010000100011101000001010110010101000000100', '0000101010010100000010111110111000001011000000001011000110100010110011111000110110010110011010111101001011000000001101001110110', '1100101000110001000011111110010001011000010110010101101000000101011110000100011011111011011010001001110011011101001101010100000', '0110011000101110101001010100110010101000010111100001000111011000110101011010010101110011001010101000001001001000110010100010101']\n", + " > First ten results for pub 1: ['1100100001011010010100000110101010100111101100110000100001011000100010001101010101101110000011010010011000010000010001000001000', '1100000011000000100110011000000110010000011111000000001010000101000010011001000001010000001000001010001000110010111000010000000', '0010000111101000111010101010101001010000001110100001011011100011000111000000010101001000010101001100000010100010011000000000010', '0010100100001000011100001010011000001010000010001000000001011100001010001110010110111101101000001101010101000000000011000100110', '0101101000011110111000100010000000101110100001010101110010001100001100001000111111110101001010100110000000010011111111000000010', '0101010111000000001110100110100011010111000111110100010010010001011010001000101001100001100110001001001000010010000011100100000', '0110010000001110111010010100010010010011010010110101001110010010001001101010111000010000000100011001001000001111010001100010010', '1100001100101011011010000110111110001101010100010100101100111000010000101101101010111011111011101100000000110000100101001000101', '0000111100001000000101101001010111110100011011011101101111000000001010001001100010110000100000000001010100110001001100110010000', '0100100001001011110000110001100001111011111100000001010111011011100010110111101110101111101010100101000000110111000110000000000']\n", + " > First ten results for pub 2: ['1000010100111010101010111110101000110101010001111110011110011001010100001100100000000001000111111011001101100001001110011101100', '1110100000111000000000110110010100000011110000011110000110100010000100001100010101101001100100010111000010100101011000001000000', '1000010111011000000001110111010101000111111010010011110100001010000000111111100100001111111101010100001001011100111101010000010', '0000111011110110010011100111001010001000011010010110010010101000101110011100000010000101011000101001001001000100111101010100100', '0100000100111101110000101111011000100111101011101110100001000001000010101111100100000111010001101001100001100011011110101101100', '0100001000110101010010010100100110000100001010100001110001110101010011000111100111001001100000010100110111010111010100010100100', '0011111000010001101100000110111001000000100111110100001100001100010010010101011000000111011011111010100010000100100000100000000', '1000010010101100110110110110100010100000111001101011110100001000011000001000000110010001001011100100000000100000000000000000000', '0001011100010011111110011110000001000000010100111111000000101010000011011110110000110001010010000010010001000101110001111100010', '1111010100011100010010010110000101110000010001100101011111001100010111100001011001000001011010111011100001000001100000000000110']\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import iqp\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "from qiskit.quantum_info import random_hermitian\n", + "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler\n", + "\n", + "n_qubits = 127\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=n_qubits\n", + ")\n", + "\n", + "rng = np.random.default_rng()\n", + "mats = [np.real(random_hermitian(n_qubits, seed=rng)) for _ in range(3)]\n", + "circuits = [iqp(mat) for mat in mats]\n", + "for circuit in circuits:\n", + " circuit.measure_all()\n", + "\n", + "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", + "isa_circuits = pm.run(circuits)\n", + "\n", + "sampler = Sampler(mode=backend)\n", + "job = sampler.run(isa_circuits)\n", + "result = job.result()\n", + "\n", + "for idx, pub_result in enumerate(result):\n", + " print(\n", + " f\" > First ten results for pub {idx}: {pub_result.data.meas.get_bitstrings()[:10]}\"\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "e3ce4f13-b772-4ee6-ba9d-d98da633ab5c", + "metadata": {}, + "source": [ + "## Run parameterized circuits\n", + "\n", + "Run several experiments in a single job, leveraging parameter values to increase circuit reusability." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "c63c9cb6-0650-433c-b3d6-dcde06e465e4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " >> First ten results for the meas output register: ['1100011011100001011000001001000001111110000001011100011110011100111110000111000100011100001111100010010111110001001111011000101', '1100011101010101010000100110110110010001100101011101001011101010111110000111110100000011111010101101011101101101001111011110011', '0000000011000011001101001000111110001100010010011011001111000101000000001111111101101011100111010110111101010111011001010001011', '0101010001101110100010001100111001011101101100001000100001011101110100001000011011001011110101000110010001001010011011100011101', '0110101110000010110000001000010101100010010001001001101000010100110001011111110001000001100110010001011111001010011001001000101', '0111011111110111010111100110101000010100101000001010001001011111010010100111110110000011100001100000110000111000011011100000000', '0110100111001000100100110110010001011110000000110111000011110000100111001000100110011100100001100000101111111100010111100111001', '0101101111010110000000001000010110100101001100001101110010101111010110001010000111010010001111000000011001001001111100111010110', '0100000110010101111011110111000010001101011110010000110010001111001101010010000011111100100101101000010000111100111010000000110', '0011110110011011000110000100100110111000000010010101111011111000111001100011110100001100010100100001110101110100011100110001100']\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import real_amplitudes\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler\n", + "\n", + "n_qubits = 127\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=n_qubits\n", + ")\n", + "\n", + "# Step 1: Map classical inputs to a quantum problem\n", + "circuit = real_amplitudes(num_qubits=n_qubits, reps=2)\n", + "circuit.measure_all()\n", + "\n", + "# Define three sets of parameters for the circuit\n", + "rng = np.random.default_rng(1234)\n", + "parameter_values = [\n", + " rng.uniform(-np.pi, np.pi, size=circuit.num_parameters) for _ in range(3)\n", + "]\n", + "\n", + "# Step 2: Optimize problem for quantum execution.\n", + "\n", + "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", + "isa_circuit = pm.run(circuit)\n", + "\n", + "# Step 3: Execute using Qiskit primitives.\n", + "sampler = Sampler(backend)\n", + "job = sampler.run([(isa_circuit, parameter_values)])\n", + "result = job.result()\n", + "# Get results for the first (and only) PUB\n", + "pub_result = result[0]\n", + "# Get counts from the classical register \"meas\".\n", + "print(\n", + " f\" >> First ten results for the meas output register: {pub_result.data.meas.get_bitstrings()[:10]}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "a8b00d2a-3c5d-4670-9774-d39cdb262552", + "metadata": {}, + "source": [ + "## Use sessions and advanced options\n", + "\n", + "Explore sessions and advanced options to optimize circuit performance on QPUs.\n", + "\n", + "\n", + "\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", + "" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "881fdac4-973b-4cef-a3da-c011d326ff54", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " > The first ten measurement results of job 1: ['1101100010101100001001110000100011110011000010110000010000001011000110000110010100011000101111011110010101101001000101010100010', '0010100100011100001011111101001010010000010010000100000011001010001110101011010000100011001010000101110101110110010000110001110', '1011000110110011011010001111001011111000011111111010010010011000000110000001000101001111001000010110000000011101010000111101101', '0101000010000101001011111010110011101000100101010011001000010000011010000010101000000001000100010100011100101001000101001011000', '1101010101011100000001100110111001000100110011110001110011000000110100011011100000010000001100001101011000000001010101001101001', '1111100011111010000000100011100110101000010101100100000110000110001011100000000101010110011110010010000100011110000010101010100', '1011011100110001000110100100110010101101110010100010011100001000001100010101101110010101100000001110000000111001001000000100010', '0100011011110111010010111011101010111010010011011110011001000010101110100100111010110001101100110001010100000101001000000111001', '0001110001110000001011101101010001001110000010100001000101100100110111001011100000101010011100011001110011100100000000010110001', '1010110110111000001100011100000100101000000001111110110010000110011100100100100010000101111110100110010010010101001011001000011']\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import iqp\n", + "from qiskit.quantum_info import random_hermitian\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "from qiskit_ibm_runtime import Session, SamplerV2 as Sampler\n", + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "\n", + "n_qubits = 127\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=n_qubits\n", + ")\n", + "\n", + "rng = np.random.default_rng(1234)\n", + "mat = np.real(random_hermitian(n_qubits, seed=rng))\n", + "circuit = iqp(mat)\n", + "circuit.measure_all()\n", + "mat = np.real(random_hermitian(n_qubits, seed=rng))\n", + "another_circuit = iqp(mat)\n", + "another_circuit.measure_all()\n", + "\n", + "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", + "isa_circuit = pm.run(circuit)\n", + "another_isa_circuit = pm.run(another_circuit)\n", + "\n", + "with Session(backend=backend) as session:\n", + " sampler = Sampler(mode=session)\n", + " job = sampler.run([isa_circuit])\n", + " another_job = sampler.run([another_isa_circuit])\n", + " result = job.result()\n", + " another_result = another_job.result()\n", + "\n", + "# first job\n", + "\n", + "print(\n", + " f\" > The first ten measurement results of job 1: {result[0].data.meas.get_bitstrings()[:10]}\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "40fe2a06-edfc-41a8-9054-7f31ab93a00c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " > The first ten measurement results of job 2: ['0100010001111001111010000100101010011010000100010110100100010010010110001010101010000000110000010000001100100011000110101000001', '1101000100010000011100110101001110101100001000000000101001110110110010110110010010011100010000010001011000011100100000100000000', '1111101010100011010100000100010101111110011000000000010000010000101001010001100000100000100010000001100111000000111000111010000', '0101111100000110010101101100101110101011010100001001110101100010111100110011100001110101000000001000000000101000100000001000000', '1101001000000000011000010100111110101111001001110011100001100100100100000011110001001000001000010101111100001001110010110011100', '1100001000110110000111110110010010000100001000001001100011110001111100100101110010010111010010101100001010101011100100001010010', '0001001100010000000101101101101111000011101100101000111010000000000010010111011000100000011010100000100011100010110010010000001', '1010101100000000011000111101000011100101000110110000111111000001100010001110000101111111110110000000000000001000000010001110000', '1111111001001001001100010000101110110100001011011100010001100000100001010100111011000110100011110000001010101000010000000011000', '1011011010101100010101100001001000000010110001101000100001111010000100011100000000100111001001000001001001101000001000100000000']\n" + ] + } + ], + "source": [ + "# second job\n", + "print(\n", + " \" > The first ten measurement results of job 2:\",\n", + " another_result[0].data.meas.get_bitstrings()[:10],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "551e1894-a12a-4f6c-8347-020fdc9db74e", + "metadata": {}, + "source": [ + "## Next steps\n", + "\n", + "\n", + " - [Specify advanced runtime options.](runtime-options-overview)\n", + " - Practice with primitives by working through the [Cost function lesson](/learning/courses/variational-algorithm-design/cost-functions) in IBM Quantum Learning.\n", + " - Learn how to transpile locally in the [Transpile](/docs/guides/transpile/) section.\n", + " - Try the [Compare transpiler settings](/docs/guides/circuit-transpilation-settings) guide.\n", + " - Read [Migrate to V2 primitives](/docs/guides/v2-primitives).\n", + " - Understand the [Job limits](/docs/guides/job-limits) when sending a job to an IBM® QPU.\n", + "" + ] + } + ], + "metadata": { + "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" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/guides/sampler-input-output.ipynb b/docs/guides/sampler-input-output.ipynb new file mode 100644 index 00000000000..f611753a51a --- /dev/null +++ b/docs/guides/sampler-input-output.ipynb @@ -0,0 +1,517 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "dbb193c8-d927-434c-a199-48de57c99694", + "metadata": {}, + "source": [ + "---\n", + "title: Inputs and outputs\n", + "description: Understand the input and output format of Sampler primitives\n", + "---\n", + "\n", + "\n", + "# Sampler inputs and outputs" + ] + }, + { + "cell_type": "markdown", + "id": "13bdfd0b-b5df-4dc8-9de5-f4ee382bc1d4", + "metadata": { + "tags": [ + "version-info" + ] + }, + "source": [ + "{/*\n", + " DO NOT EDIT THIS CELL!!!\n", + " This cell's content is generated automatically by a script. Anything you add\n", + " here will be removed next time the notebook is run. To add new content, create\n", + " a new cell before or after this one.\n", + "*/}\n", + "\n", + "
\n", + "Package versions\n", + "\n", + "The code on this page was developed using the following requirements.\n", + "We recommend using these versions or newer.\n", + "\n", + "```\n", + "qiskit[all]~=2.3.0\n", + "qiskit-ibm-runtime~=0.43.1\n", + "```\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This page gives an overview of the inputs and outputs of the Sampler primitive, which executes workloads on IBM Quantum® compute resources. Sampler lets you efficiently define vectorized workloads by using a data structure known as a [**Primitive Unified Bloc (PUB)**.](/docs/guides/pubs-broadcasting#pubs) They are used as inputs to the [`run()`](/docs/api/qiskit-ibm-runtime/sampler-v2#run) method for the Sampler primitive, which executes the defined workload as a job. Then, after the job has completed, the results are returned in a format that is dependent on both the PUBs used as well as the runtime options specified from the primitive." + ] + }, + { + "cell_type": "markdown", + "id": "61903cfe-d221-4137-8324-9f0d3c1b517d", + "metadata": {}, + "source": [ + "## Input\n", + "\n", + "For the Sampler primitive, a PUB can contain at most three values:\n", + "- A single `QuantumCircuit`, which may contain one or more [`Parameter`](/docs/api/qiskit/qiskit.circuit.Parameter) objects\n", + " *Note: These circuits should also include measurement instructions for each of the qubits to be sampled.*\n", + "- A collection of parameter values to bind the circuit against $\\theta_k$ (only needed if any `Parameter` objects are used that must be bound at runtime)\n", + "- (Optionally) a number of shots to measure the circuit with" + ] + }, + { + "cell_type": "markdown", + "id": "331708ea-5fbd-468f-940e-ea09c7aae46a", + "metadata": {}, + "source": [ + "---\n", + "\n", + "The following code demonstrates an example set of vectorized inputs to the `Sampler` primitive and executes them on an IBM® backend as a single `RuntimeJobV2 ` object." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "16409c22-5d8d-459a-908e-eb9f6178d075", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit.circuit import (\n", + " Parameter,\n", + " QuantumCircuit,\n", + " ClassicalRegister,\n", + " QuantumRegister,\n", + ")\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "from qiskit.quantum_info import SparsePauliOp\n", + "from qiskit.primitives.containers import BitArray\n", + "\n", + "from qiskit_ibm_runtime import (\n", + " QiskitRuntimeService,\n", + " SamplerV2 as Sampler,\n", + ")\n", + "\n", + "import numpy as np\n", + "\n", + "# Instantiate runtime service and get\n", + "# the least busy backend\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "# Define a circuit with two parameters.\n", + "circuit = QuantumCircuit(2)\n", + "circuit.h(0)\n", + "circuit.cx(0, 1)\n", + "circuit.ry(Parameter(\"a\"), 0)\n", + "circuit.rz(Parameter(\"b\"), 0)\n", + "circuit.cx(0, 1)\n", + "circuit.h(0)\n", + "circuit.measure_all()\n", + "\n", + "# Transpile the circuit\n", + "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n", + "transpiled_circuit = pm.run(circuit)\n", + "layout = transpiled_circuit.layout\n", + "\n", + "# Now define a sweep over parameter values, the last axis of dimension 2 is\n", + "# for the two parameters \"a\" and \"b\"\n", + "params = np.vstack(\n", + " [\n", + " np.linspace(-np.pi, np.pi, 100),\n", + " np.linspace(-4 * np.pi, 4 * np.pi, 100),\n", + " ]\n", + ").T\n", + "\n", + "sampler_pub = (transpiled_circuit, params)\n", + "\n", + "# Instantiate the new Sampler object, then run the transpiled circuit\n", + "# using the set of parameters and observables.\n", + "sampler = Sampler(mode=backend)\n", + "job = sampler.run([sampler_pub])\n", + "result = job.result()" + ] + }, + { + "cell_type": "markdown", + "id": "df8faff8-4558-4f72-bd80-8615ce1ce3c5", + "metadata": {}, + "source": [ + "## Output\n", + "\n", + "Once one or more PUBs are sent to a QPU for execution and a job successfully completes, the data is returned as a [`PrimitiveResult`](/docs/api/qiskit/qiskit.primitives.PrimitiveResult) container object accessed by calling the `RuntimeJobV2.result()` method. The `PrimitiveResult` contains an iterable list of [`PubResult`](/docs/api/qiskit/qiskit.primitives.PubResult) objects that contain the execution results for each PUB.These data will be samples of the circuit output\n", + "\n", + "Each element of this list corresponds to each PUB submitted to the primitive's `run()` method (for example, a job submitted with 20 PUBs will return a `PrimitiveResult` object that contains a list of 20 `PubResults`, one corresponding to each PUB).\n", + "\n", + "Each of these `PubResult` objects possess both a `data` and a `metadata` attribute. The `data` attribute is a customized [`DataBin`](/docs/api/qiskit/qiskit.primitives.DataBin) that contains the actual measurement values, standard deviations, and so forth. This `DataBin` has various attributes depending on the shape or structure of the associated PUB as well as the error mitigation options specified by the primitive used to submit the job (for example, [ZNE](/docs/guides/error-mitigation-and-suppression-techniques#zero-noise-extrapolation-zne) or [PEC](/docs/guides/error-mitigation-and-suppression-techniques#probabilistic-error-cancellation-pec)). Meanwhile, the `metadata` attribute contains information about the runtime and error mitigation options used (explained later in the [Result metadata](#result-metadata) section of this page).\n", + "\n", + "The following is a visual outline of the `PrimitiveResult` data structure:\n", + "\n", + "```\n", + " └── PrimitiveResult\n", + " ├── PubResult[0]\n", + " │ ├── metadata\n", + " │ └── data ## In the form of a DataBin object\n", + " │ ├── NAME_OF_CLASSICAL_REGISTER\n", + " │ │ └── BitArray of count data (default is 'meas')\n", + " | |\n", + " │ └── NAME_OF_ANOTHER_CLASSICAL_REGISTER\n", + " │ └── BitArray of count data (exists only if more than one\n", + " | ClassicalRegister was specified in the circuit)\n", + " ├── PubResult[1]\n", + " | ├── metadata\n", + " | └── data ## In the form of a DataBin object\n", + " | └── NAME_OF_CLASSICAL_REGISTER\n", + " | └── BitArray of count data for second pub\n", + " ├── ...\n", + " ├── ...\n", + " └── ...\n", + "```\n", + "\n", + "Put simply, a single job returns a `PrimitiveResult` object and contains a list of one or more `PubResult` objects. These `PubResult` objects then store the measurement data for each PUB that was submitted to the job.\n", + "\n", + "When a Sampler job is completed successfully, the returned [`PrimitiveResult`](/docs/api/qiskit/qiskit.primitives.PrimitiveResult) object contains a list of [`SamplerPubResult`](/docs/api/qiskit/qiskit.primitives.SamplerPubResult)s, one per PUB. The data bins of these `SamplerPubResult` objects are dict-like objects that contain one `BitArray` per `ClassicalRegister` in the circuit.\n", + "\n", + "The `BitArray` class is a container for ordered shot data. In more detail, it stores the sampled bitstrings as bytes inside a two-dimensional array. The left-most axis of this array runs over ordered shots, while the right-most axis runs over bytes.\n", + "\n", + "As a first example, let us look at the following ten-qubit circuit:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "5c787874-1125-4381-b55e-7663caa92ec8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Databin: DataBin(meas=BitArray())\n", + "\n", + "BitArray: BitArray()\n", + "\n", + "The shape of register `meas` is (4096, 2).\n", + "\n", + "The bytes in register `alpha`, shot by shot:\n", + "[[ 3 254]\n", + " [ 0 0]\n", + " [ 3 255]\n", + " ...\n", + " [ 0 0]\n", + " [ 3 255]\n", + " [ 0 0]]\n", + "\n" + ] + } + ], + "source": [ + "# generate a ten-qubit GHZ circuit\n", + "circuit = QuantumCircuit(10)\n", + "circuit.h(0)\n", + "circuit.cx(range(0, 9), range(1, 10))\n", + "\n", + "# append measurements with the `measure_all` method\n", + "circuit.measure_all()\n", + "\n", + "# transpile the circuit\n", + "transpiled_circuit = pm.run(circuit)\n", + "\n", + "# run the Sampler job and retrieve the results\n", + "sampler = Sampler(mode=backend)\n", + "job = sampler.run([transpiled_circuit])\n", + "result = job.result()\n", + "\n", + "# the data bin contains one BitArray\n", + "data = result[0].data\n", + "print(f\"Databin: {data}\\n\")\n", + "\n", + "# to access the BitArray, use the key \"meas\", which is the default name of\n", + "# the classical register when this is added by the `measure_all` method\n", + "array = data.meas\n", + "print(f\"BitArray: {array}\\n\")\n", + "print(f\"The shape of register `meas` is {data.meas.array.shape}.\\n\")\n", + "print(f\"The bytes in register `alpha`, shot by shot:\\n{data.meas.array}\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "c8f3cd8f-4f43-448b-b8bc-870c3b03797f", + "metadata": {}, + "source": [ + "It can sometimes be convenient to convert away from the bytes format in the `BitArray` to bitstrings. The `get_count` method returns a dictionary mapping bitstrings to the number of times that they occurred." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "d152f7ca-daf3-4c24-9595-10d077de8f08", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Counts: {'1111111110': 199, '0000000000': 1337, '1111111111': 1052, '1111111000': 33, '1110000000': 65, '1100100000': 2, '1100000000': 25, '0010001110': 1, '0000000011': 30, '1111111011': 58, '1111111010': 25, '0000000110': 7, '0010000001': 11, '0000000001': 179, '1110111110': 6, '1111110000': 33, '1111101111': 49, '1110111111': 40, '0000111010': 2, '0100000000': 35, '0000000010': 51, '0000100000': 31, '0110000000': 7, '0000001111': 22, '1111111100': 24, '1011111110': 5, '0001111111': 58, '0000111111': 24, '1111101110': 10, '0000010001': 5, '0000001001': 2, '0011111111': 38, '0000001000': 11, '1111100000': 34, '0111111111': 45, '0000000100': 18, '0000000101': 2, '1011111111': 11, '1110000001': 13, '1101111000': 1, '0010000000': 52, '0000010000': 17, '0000011111': 15, '1110100001': 1, '0111111110': 9, '0000000111': 19, '1101111111': 15, '1111110111': 17, '0011111110': 5, '0001101110': 1, '0111111011': 6, '0100001000': 2, '0010001111': 1, '1111011000': 1, '0000111110': 4, '0011110010': 1, '1110111100': 2, '1111000000': 8, '1111111101': 27, '0000011110': 6, '0001000000': 5, '1111010000': 3, '0000011011': 4, '0001111110': 9, '1111011110': 6, '1110001111': 2, '0100000001': 7, '1110111011': 3, '1111101101': 2, '1101111110': 5, '1110000010': 7, '0111111000': 1, '1110111000': 1, '0000100001': 2, '1110100000': 6, '1000000001': 2, '0001011111': 1, '0000010111': 1, '1011111100': 1, '0111110000': 5, '0110111111': 2, '0010000010': 1, '0001111100': 4, '0011111001': 2, '1111110011': 1, '1110000011': 5, '0000001011': 8, '0100000010': 3, '1111011111': 13, '0010111000': 2, '0100111110': 1, '1111101000': 2, '1110110000': 2, '1100000001': 1, '0001110000': 3, '1011101111': 2, '1111000001': 2, '1111110001': 8, '1111110110': 4, '1100000010': 3, '0011000000': 2, '1110011111': 3, '0011101111': 3, '0010010000': 2, '0000100010': 1, '1100001110': 1, '0001111011': 4, '1010000000': 3, '0000001110': 5, '0000001010': 2, '0011111011': 4, '0100100000': 2, '1111110100': 1, '1111100011': 3, '0000110110': 1, '0001111101': 2, '1111100001': 2, '1000000000': 5, '0010000011': 3, '0010011111': 3, '0100001111': 1, '0100000111': 1, '1011101110': 1, '0011110111': 1, '1100000111': 1, '1100111111': 3, '0001111010': 1, '1101111011': 1, '0111111100': 2, '0100000110': 2, '0100000011': 2, '0001101111': 3, '0001000001': 1, '1111110010': 1, '0010100000': 1, '0011100000': 4, '1010001111': 1, '0101111111': 2, '1111101001': 1, '1110111101': 1, '0000011101': 1, '1110001000': 2, '0001111001': 1, '0101000000': 1, '1111111001': 5, '0001110111': 2, '0000111001': 1, '0100001011': 1, '0000010011': 1, '1011110111': 1, '0011110001': 1, '0000001100': 2, '0111010111': 1, '0001101011': 1, '1110010000': 2, '1110000100': 1, '0010111111': 3, '0111011100': 1, '1010001000': 1, '0000101110': 1, '0011111100': 2, '0000111100': 2, '1110011110': 1, '0011111000': 2, '0110100000': 1, '1001101111': 1, '1011000000': 1, '1101000000': 1, '1110001011': 1, '1110110111': 1, '0110111110': 1, '0011011111': 1, '0111100000': 1, '0000110111': 1, '0000010010': 2, '1111101100': 2, '1111011101': 1, '1101100000': 1, '0010111110': 1, '1101101110': 1, '1111001111': 1, '1101111100': 1, '1011111010': 1, '0001100000': 1, '1101110111': 1, '1100001011': 1}\n" + ] + } + ], + "source": [ + "# optionally, convert away from the native BitArray format to a dictionary format\n", + "counts = data.meas.get_counts()\n", + "print(f\"Counts: {counts}\")" + ] + }, + { + "cell_type": "markdown", + "id": "514e0ac0-b42e-4f26-b608-c223dfed7915", + "metadata": {}, + "source": [ + "When a circuit contains more than one classical register, the results are stored in different `BitArray` objects. The following example modifies the previous snippet by splitting the classical register into two distinct registers:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "4602925e-c69d-45b2-9e06-fe8bffe0a797", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "BitArray for register 'alpha': BitArray()\n", + "BitArray for register 'beta': BitArray()\n" + ] + } + ], + "source": [ + "# generate a ten-qubit GHZ circuit with two classical registers\n", + "circuit = QuantumCircuit(\n", + " qreg := QuantumRegister(10),\n", + " alpha := ClassicalRegister(1, \"alpha\"),\n", + " beta := ClassicalRegister(9, \"beta\"),\n", + ")\n", + "circuit.h(0)\n", + "circuit.cx(range(0, 9), range(1, 10))\n", + "\n", + "# append measurements with the `measure_all` method\n", + "circuit.measure([0], alpha)\n", + "circuit.measure(range(1, 10), beta)\n", + "\n", + "# transpile the circuit\n", + "transpiled_circuit = pm.run(circuit)\n", + "\n", + "# run the Sampler job and retrieve the results\n", + "sampler = Sampler(mode=backend)\n", + "job = sampler.run([transpiled_circuit])\n", + "result = job.result()\n", + "\n", + "# the data bin contains two BitArrays, one per register, and can be accessed\n", + "# as attributes using the registers' names\n", + "data = result[0].data\n", + "print(f\"BitArray for register 'alpha': {data.alpha}\")\n", + "print(f\"BitArray for register 'beta': {data.beta}\")" + ] + }, + { + "cell_type": "markdown", + "id": "a65c6078-c5c2-4087-b57a-5680148ce333", + "metadata": {}, + "source": [ + "#### Leveraging `BitArray` objects for performant post-processing\n", + "\n", + "Since arrays generally offer better performance compared to dictionaries, it is advisable to perform any post-processing directly on the `BitArray` objects rather than on dictionaries of counts. The `BitArray` class offers a range of methods to perform some common post-processing operations:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "3802cf7e-4d71-4e1f-88f5-3beb294fc163", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The shape of register `alpha` is (4096, 1).\n", + "The bytes in register `alpha`, shot by shot:\n", + "[[1]\n", + " [1]\n", + " [1]\n", + " ...\n", + " [0]\n", + " [0]\n", + " [1]]\n", + "\n", + "The shape of register `beta` is (4096, 2).\n", + "The bytes in register `beta`, shot by shot:\n", + "[[ 0 135]\n", + " [ 0 247]\n", + " [ 1 247]\n", + " ...\n", + " [ 0 0]\n", + " [ 1 224]\n", + " [ 1 255]]\n", + "\n", + "The shape of `beta` after post-selection is (0, 2).\n", + "The bytes in `beta` after post-selection:\n", + "[]\n", + "The shape of `beta` after bit-wise slicing is (4096, 1).\n", + "The bytes in `beta` after bit-wise slicing:\n", + "[[7]\n", + " [7]\n", + " [7]\n", + " ...\n", + " [0]\n", + " [0]\n", + " [7]]\n", + "\n", + "The shape of `beta` after shot-wise slicing is (5, 2).\n", + "The bytes in `beta` after shot-wise slicing:\n", + "[[ 0 135]\n", + " [ 0 247]\n", + " [ 1 247]\n", + " [ 1 128]\n", + " [ 1 255]]\n", + "\n", + "Exp. val. for observable `SparsePauliOp(['ZZZZZZZZZ'],\n", + " coeffs=[1.+0.j])` is: 0.068359375\n", + "Exp. val. for observable `SparsePauliOp(['IIIIIIIIZ'],\n", + " coeffs=[1.+0.j])` is: 0.06396484375\n", + "\n", + "The shape of the merged results is (4096, 2).\n", + "The bytes of the merged results:\n", + "[[ 1 15]\n", + " [ 1 239]\n", + " [ 3 239]\n", + " ...\n", + " [ 0 0]\n", + " [ 3 192]\n", + " [ 3 255]]\n", + "\n" + ] + } + ], + "source": [ + "print(f\"The shape of register `alpha` is {data.alpha.array.shape}.\")\n", + "print(f\"The bytes in register `alpha`, shot by shot:\\n{data.alpha.array}\\n\")\n", + "\n", + "print(f\"The shape of register `beta` is {data.beta.array.shape}.\")\n", + "print(f\"The bytes in register `beta`, shot by shot:\\n{data.beta.array}\\n\")\n", + "\n", + "# post-select the bitstrings of `beta` based on having sampled \"1\" in `alpha`\n", + "mask = data.alpha.array == \"0b1\"\n", + "ps_beta = data.beta[mask[:, 0]]\n", + "print(f\"The shape of `beta` after post-selection is {ps_beta.array.shape}.\")\n", + "print(f\"The bytes in `beta` after post-selection:\\n{ps_beta.array}\")\n", + "\n", + "# get a slice of `beta` to retrieve the first three bits\n", + "beta_sl_bits = data.beta.slice_bits([0, 1, 2])\n", + "print(\n", + " f\"The shape of `beta` after bit-wise slicing is {beta_sl_bits.array.shape}.\"\n", + ")\n", + "print(f\"The bytes in `beta` after bit-wise slicing:\\n{beta_sl_bits.array}\\n\")\n", + "\n", + "# get a slice of `beta` to retrieve the bytes of the first five shots\n", + "beta_sl_shots = data.beta.slice_shots([0, 1, 2, 3, 4])\n", + "print(\n", + " f\"The shape of `beta` after shot-wise slicing is {beta_sl_shots.array.shape}.\"\n", + ")\n", + "print(\n", + " f\"The bytes in `beta` after shot-wise slicing:\\n{beta_sl_shots.array}\\n\"\n", + ")\n", + "\n", + "# calculate the expectation value of diagonal operators on `beta`\n", + "ops = [SparsePauliOp(\"ZZZZZZZZZ\"), SparsePauliOp(\"IIIIIIIIZ\")]\n", + "exp_vals = data.beta.expectation_values(ops)\n", + "for o, e in zip(ops, exp_vals):\n", + " print(f\"Exp. val. for observable `{o}` is: {e}\")\n", + "\n", + "# concatenate the bitstrings in `alpha` and `beta` to \"merge\" the results of the two\n", + "# registers\n", + "merged_results = BitArray.concatenate_bits([data.alpha, data.beta])\n", + "print(f\"\\nThe shape of the merged results is {merged_results.array.shape}.\")\n", + "print(f\"The bytes of the merged results:\\n{merged_results.array}\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "f5840476-04ec-4d3b-bdb9-d166ccd8cd11", + "metadata": {}, + "source": [ + "## Result metadata\n", + "\n", + "In addition to the execution results, both the `PrimitiveResult` and `PubResult` objects contain a metadata attribute about the job that was submitted. The metadata containing information for all submitted PUBs (such as the various [runtime options](/docs/api/qiskit-ibm-runtime/options) available) can be found in the `PrimitiveResult.metatada`, while the metadata specific to each PUB is found in `PubResult.metadata`.\n", + "\n", + "\n", + "In the metadata field, primitive implementations can return any information about execution that is relevant to them, and there are no key-value pairs that are guaranteed by the base primitive. Thus, the returned metadata might be different in different primitive implementations.\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "68268c70-d76a-47b9-af6d-5cfe7966abae", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The metadata of the PrimitiveResult is:\n", + "'execution' : {'execution_spans': ExecutionSpans([DoubleSliceSpan()])},\n", + "'version' : 2,\n", + "\n", + "The metadata of the PubResult result is:\n", + "'circuit_metadata' : {},\n" + ] + } + ], + "source": [ + "# Print out the results metadata\n", + "print(\"The metadata of the PrimitiveResult is:\")\n", + "for key, val in result.metadata.items():\n", + " print(f\"'{key}' : {val},\")\n", + "\n", + "print(\"\\nThe metadata of the PubResult result is:\")\n", + "for key, val in result[0].metadata.items():\n", + " print(f\"'{key}' : {val},\")" + ] + }, + { + "cell_type": "markdown", + "id": "2f26ff75-e1ba-45ef-97c1-c5dde36400cf", + "metadata": {}, + "source": [ + "You can also review the result metadata to understand when certain data was run; this is called the [_execution span._](monitor-job#execution-spans)" + ] + } + ], + "metadata": { + "celltoolbar": "Raw Cell Format", + "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" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/guides/sampler-options.ipynb b/docs/guides/sampler-options.ipynb new file mode 100644 index 00000000000..db80ff0ccd8 --- /dev/null +++ b/docs/guides/sampler-options.ipynb @@ -0,0 +1,731 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8bbb8d7d-bcd5-4092-9df1-9930c67b17bc", + "metadata": {}, + "source": [ + "---\n", + "title: Options\n", + "description: Specify options when building with the Sampler primitive.\n", + "---\n", + "\n", + "\n", + "# Sampler options" + ] + }, + { + "cell_type": "markdown", + "id": "73e3d6f4", + "metadata": { + "tags": [ + "version-info" + ] + }, + "source": [ + "{/*\n", + " DO NOT EDIT THIS CELL!!!\n", + " This cell's content is generated automatically by a script. Anything you add\n", + " here will be removed next time the notebook is run. To add new content, create\n", + " a new cell before or after this one.\n", + "*/}\n", + "\n", + "
\n", + "Package versions\n", + "\n", + "The code on this page was developed using the following requirements.\n", + "We recommend using these versions or newer.\n", + "\n", + "```\n", + "qiskit[all]~=2.3.0\n", + "qiskit-ibm-runtime~=0.43.1\n", + "```\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "8fdcbe4a", + "metadata": {}, + "source": [ + "You can use options to customize the Sampler primitive. This section focuses on how to specify Qiskit Runtime primitive options. While the interface of the primitives' `run()` method is common across all implementations, their options are not. Consult the corresponding API references for information about the [`qiskit.primitives.BackendSamplerV2`](/docs/api/qiskit/qiskit.primitives.BackendSamplerV2) and [`qiskit_aer.primitives.SamplerV2`](https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.primitives.SamplerV2.html) options.\n", + "\n", + "Notes about specifying options in the primitives:\n", + "\n", + "- You can see the available options and update option values during or after primitive initialization.\n", + "- Use the `update()` method to apply changes to the `options` attribute.\n", + "- If you do not specify a value for an option, it is given a special value of `Unset` and the server defaults are used.\n", + "- The `options` attribute is the `dataclass` Python type. You can use the built-in `asdict` method to convert it to a dictionary.\n", + "\n", + "\n", + "## Set Sampler options\n", + "\n", + "You can set options when initializing the primitive, after initializing the primitive, or (for `shots`) in the `run()` method.\n", + "\n", + "### Primitive initialization\n", + "\n", + "You can pass in an instance of the options class or a dictionary when initializing Sampler, which then makes a copy of those options. Thus, changing the original dictionary or options instance doesn't affect the options owned by the primitive.\n", + "\n", + "#### Options class\n", + "\n", + "When creating an instance of the `SamplerV2` class, you can pass in an instance of the options class. Those options will then be applied when you use `run()` to perform the calculation. Specify the options in this format: `options.option.sub-option.sub-sub-option = choice`. For example: `options.dynamical_decoupling.enable = True`\n", + "\n", + "See [`SamplerOptions`](/docs/api/qiskit-ibm-runtime/options-sampler-options) for full details about the options class." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4b40f0e5-2db0-4ccc-9c07-bdb71d2f5b91", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "from qiskit_ibm_runtime import SamplerV2 as Sampler\n", + "from qiskit_ibm_runtime.options import SamplerOptions\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "options = SamplerOptions(\n", + " resilience_level=2,\n", + " resilience={\"zne_mitigation\": True, \"zne\": {\"noise_factors\": [1, 3, 5]}},\n", + ")\n", + "\n", + "# or...\n", + "options = SamplerOptions()\n", + "options.resilience_level = 2\n", + "options.resilience.zne_mitigation = True\n", + "options.resilience.zne.noise_factors = [1, 3, 5]\n", + "\n", + "sampler = Sampler(mode=backend, options=options)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Options classes summary\n", + "\n", + " - [Dynamical decoupling](/docs/api/qiskit-ibm-runtime/options-dynamical-decoupling-options): Options for dynamical decoupling.\n", + " - [Environment](/docs/api/qiskit-ibm-runtime/options-environment-options): Execution environment options, such as the logging level to set and job tags to add.\n", + " - [Execution](/docs/api/qiskit-ibm-runtime/options-execution-options-v2): Primitive execution options, including whether to initialize qubits and the repetition delay.\n", + " - [Simulator](/docs/api/qiskit-ibm-runtime/options-simulator-options): Simulator options, such as the basis gates, simulator seed, and coupling map. Applies to [local testing mode](/docs/guides/local-testing-mode) only.\n", + " - [Twirling](/docs/api/qiskit-ibm-runtime/options-twirling-options): Twirling options, such as whether to apply two-qubit gate twirling and the number of shots to run for each random sample.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "ba2f5146-2781-49da-9fa2-8a22647225d0", + "metadata": {}, + "source": [ + "#### Dictionary\n", + "\n", + "You can specify options as a dictionary when initializing Sampler." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0ee1eaf6-c221-437f-8ff8-40ec2aa937c0", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "from qiskit_ibm_runtime import SamplerV2 as Sampler\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "# Setting options during primitive initialization\n", + "sampler = Sampler(\n", + " backend,\n", + " options={\n", + " \"resilience_level\": 2,\n", + " \"resilience\": {\n", + " \"zne_mitigation\": True,\n", + " \"zne\": {\"noise_factors\": [1, 3, 5]},\n", + " },\n", + " },\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "fc9a759a-6d43-4372-bad2-87512d43b255", + "metadata": {}, + "source": [ + "### Update options after initialization\n", + "\n", + "You can specify the options in this format: `sampler.options.option.sub-option.sub-sub-option = choice` to take advantage of auto-complete, or use the `update()` method to make bulk updates.\n", + "\n", + "The `SamplerV2` options class ([`SamplerOptions`](/docs/api/qiskit-ibm-runtime/options-sampler-options)) does not need to be instantiated if you are setting options after initializing the primitive." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "71de6acf-77a5-460f-ac54-f88f7a4d2fa6", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "from qiskit_ibm_runtime import SamplerV2 as Sampler\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "sampler = Sampler(mode=backend)\n", + "\n", + "# Setting options after primitive initialization\n", + "# This uses auto-complete.\n", + "sampler.options.default_shots = 4000\n", + "# This does bulk update.\n", + "sampler.options.update(\n", + " default_shots=4000, resilience={\"zne_mitigation\": True}\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "fde8c5bf-d914-4806-b55e-1f33aa643204", + "metadata": {}, + "source": [ + "\n", + "### Run() method\n", + "\n", + "The only values you can pass to `run()` are those defined in the interface. That is, `shots`. This overwrites any value set for `default_shots` for the current run." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "f2c12ead-4785-4d4f-bf4a-f015295d7083", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "from qiskit_ibm_runtime import SamplerV2 as Sampler\n", + "from qiskit.circuit.library import random_iqp\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "circuit1 = random_iqp(3)\n", + "circuit1.measure_all()\n", + "circuit2 = random_iqp(3)\n", + "circuit2.measure_all()\n", + "\n", + "pass_manager = generate_preset_pass_manager(\n", + " optimization_level=3, backend=backend\n", + ")\n", + "\n", + "transpiled1 = pass_manager.run(circuit1)\n", + "transpiled2 = pass_manager.run(circuit2)\n", + "\n", + "sampler = Sampler(mode=backend)\n", + "# Default shots to use if not specified in run()\n", + "sampler.options.default_shots = 500\n", + "# Sample two circuits at 128 shots each.\n", + "sampler.run([transpiled1, transpiled2], shots=128)\n", + "\n", + "# Sample two circuits with different numbers of shots.\n", + "# 100 shots is used for transpiled1 and 200 for transpiled.\n", + "sampler.run([(transpiled1, None, 100), (transpiled2, None, 200)])" + ] + }, + { + "cell_type": "markdown", + "id": "8be4bd84-9060-437a-85f4-3d996f3e581f", + "metadata": {}, + "source": [ + "### Special cases" + ] + }, + { + "cell_type": "markdown", + "id": "52024f25-74ef-445a-9df8-d76da4ec7a32", + "metadata": {}, + "source": [ + "#### Shots\n", + "\n", + "The `SamplerV2.run` method accepts two arguments: a list of PUBs, each of which can specify a PUB-specific value for shots, and a shots keyword argument. These shot values are a part of the Sampler execution interface, and are independent of the Runtime Sampler's options. They take precedence over any values specified as options in order to comply with the Sampler abstraction.\n", + "\n", + "However, if `shots` is not specified by any PUB or in the run keyword argument (or if they are all `None`), then the shots value from the options is used, most notably `default_shots`.\n", + "\n", + "To summarize, this is the order of precedence for specifying shots in the Sampler, for any particular PUB:\n", + "\n", + "1. If the PUB specifies shots, use that value.\n", + "2. If the `shots` keyword argument is specified in `run`, use that value.\n", + "3. If `num_randomizations` and `shots_per_randomization` are specified as `twirling` options, shots are the product of those values.\n", + "3. If `sampler.options.default_shots` is specified, use that value.\n", + "\n", + "Thus, if shots are specified in all possible places, the one with highest precedence (shots specified in the PUB) is used.\n", + "\n", + "## Commonly used options\n", + "\n", + "There are many available options, but the following are the most commonly used:\n", + "\n", + "\n", + "### Shots\n", + "For some algorithms, setting a specific number of shots is a core part of their routines. Shots (or precision) can be specified in multiple places. They are prioritized as follows:\n", + "\n", + "For any Sampler PUB:\n", + "\n", + "1. Integer-valued shots contained in the PUB\n", + "2. The `run(...,shots=val)` value\n", + "3. The `options.default_shots` value\n", + "\n", + "Example:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "43ed5d23-8d2e-43a7-82a9-b563de861ab1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "from qiskit_ibm_runtime import SamplerV2 as Sampler\n", + "from qiskit.circuit.library import random_iqp\n", + "from qiskit.transpiler import generate_preset_pass_manager\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "circuit1 = random_iqp(3)\n", + "circuit1.measure_all()\n", + "circuit2 = random_iqp(3)\n", + "circuit2.measure_all()\n", + "\n", + "pass_manager = generate_preset_pass_manager(\n", + " optimization_level=3, backend=backend\n", + ")\n", + "\n", + "transpiled1 = pass_manager.run(circuit1)\n", + "transpiled2 = pass_manager.run(circuit2)\n", + "\n", + "\n", + "# Setting shots during primitive initialization\n", + "sampler = Sampler(mode=backend, options={\"default_shots\": 4096})\n", + "\n", + "# Setting options after primitive initialization\n", + "# This uses auto-complete.\n", + "sampler.options.default_shots = 2000\n", + "\n", + "# This does bulk update. The value for default_shots is overridden if you specify shots with run() or in the PUB.\n", + "sampler.options.update(\n", + " default_shots=1024, dynamical_decoupling={\"sequence_type\": \"XpXm\"}\n", + ")\n", + "\n", + "# Sample two circuits at 128 shots each.\n", + "sampler.run([transpiled1, transpiled2], shots=128)" + ] + }, + { + "cell_type": "markdown", + "id": "81196237-227f-449e-a780-c21fb328a7df", + "metadata": {}, + "source": [ + "### Maximum execution time\n", + "\n", + "The maximum execution time (`max_execution_time`) limits how long a job can run. If a job exceeds this time limit, it is forcibly canceled. This value applies to single jobs, whether they are run in job, session, or batch mode.\n", + "\n", + "The value is set in seconds, based on quantum time (not wall clock time), which is the amount of time that the QPU is dedicated to processing your job. It is ignored when using [local testing mode](/docs/guides/local-testing-mode) because that mode does not use quantum time." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31bd9edf-2c9e-44be-9e30-71a8415103aa", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "from qiskit_ibm_runtime import SamplerV2 as Sampler\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "sampler = Sampler(mode=backend)\n", + "\n", + "sampler.options.max_execution_time = 2500" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Available options\n", + "\n", + "The following table documents options from the latest version of `qiskit-ibm-runtime`. To see older option versions, visit the [`qiskit-ibm-runtime` API reference](/docs/api/qiskit-ibm-runtime) and select a previous version.\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "The total number of shots to use per circuit per configuration.\n", + "\n", + "**Choices**: Integer >= 0\n", + "\n", + "**Default**: None\n", + "\n", + "[`default_shots` API documentation](/docs/api/qiskit-ibm-runtime/options-sampler-options#default_shots)\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "Control dynamical decoupling error mitigation settings.\n", + "\n", + "[`dynamical_decoupling` API documentation](/docs/api/qiskit-ibm-runtime/options-sampler-options#dynamical_decoupling)\n", + "\n", + "\n", + "\n", + "**Choices**: `True`, `False`\n", + "\n", + "**Default**: `False`\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `middle`, `edges`\n", + "\n", + "**Default**: `middle`\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "Choices: `asap`, `alap`\n", + "Default: `alap`\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "Choices: `XX`, `XpXm`, `XY4`\n", + "Default: `XX`\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "Choices: `True`, `False`\n", + "Default: `False`\n", + " \n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "[`environment` API documentation](/docs/api/qiskit-ibm-runtime/options-sampler-options#environment)\n", + "\n", + "\n", + "\n", + "List of tags.\n", + "\n", + "**Choices**: None\n", + "\n", + "**Default**: None\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: DEBUG, INFO, WARNING, ERROR, CRITICAL\n", + "\n", + "**Default**: WARNING\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `True`, `False`\n", + "\n", + "**Default**: `False`\n", + " \n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "[`execution` API documentation](/docs/api/qiskit-ibm-runtime/options-sampler-options#execution)\n", + "\n", + "\n", + "Whether to reset the qubits to the ground state for each shot.\n", + "\n", + "**Choices**: `True`, `False`\n", + "\n", + "**Default**: `True`\n", + " \n", + "\n", + "\n", + "\n", + "The delay between a measurement and the subsequent quantum circuit.\n", + "\n", + "**Choices**: Value in the range supplied by `backend.rep_delay_range`\n", + "\n", + "**Default**: Given by `backend.default_rep_delay`\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `classified`, `kerneled`, `avg_kerneled`\n", + "\n", + "**Default**: `classified`\n", + " \n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: Integer number of seconds in the range [1, 10800]\n", + "\n", + "**Default**: 10800 (3 hours)\n", + "\n", + "[`max_execution_time` API documentation](/docs/api/qiskit-ibm-runtime/options-sampler-options#max_execution_time)\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "Options to pass when simulating a backend\n", + "\n", + "[`simulator` API documentation](/docs/api/qiskit-ibm-runtime/options-simulator-options)\n", + "\n", + "\n", + "\n", + "**Choices**: List of basis gate names to unroll to\n", + "\n", + "**Default**: The set of all basis gates supported by [Qiskit Aer simulator](https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.AerSimulator.html)\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: List of directed two-qubit interactions\n", + "\n", + "**Default**: None, which implies no connectivity constraints (full connectivity).\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: [Qiskit Aer NoiseModel](/docs/guides/build-noise-models), or its representation\n", + "\n", + "**Default**: None\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: Integer\n", + "\n", + "**Default**: None\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Twirling options\n", + "\n", + "[`twirling` API documentation](/docs/api/qiskit-ibm-runtime/options-twirling-options)\n", + "\n", + "\n", + "\n", + "**Choices**: True, False\n", + "\n", + "**Default**: False\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: True, False\n", + "\n", + "**Default**: False\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `auto`, Integer >= 1\n", + "\n", + "**Default**: `auto`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `auto`, Integer >= 1\n", + "\n", + "**Default**: `auto`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "**Choices**: `active`, `active-circuit`, `active-accum`, `all`\n", + "\n", + "**Default**: `active-accum`\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Experimental options, when available.\n", + "\n", + " \n", + "\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Feature compatibility\n", + "\n", + "Due to differences in the device compilation process, certain runtime features cannot be used together in a single job. Click the appropriate tab for a list of features that are incompatible with the selected feature:\n", + "\n", + "\n", + " \n", + " Incompatible with:\n", + " - Dynamical decoupling\n", + "\n", + " Other notes:\n", + " - Gate twirling can be applied to dynamic circuits, but only to gates not inside conditional blocks. Measurement twirling can only be applied to terminal measurements.\n", + " - Compatible with fractional gates when using `qiskit-ibm-runtime` v0.42.0 or later.\n", + "\n", + " \n", + " \n", + " Incompatible with dynamic circuits.\n", + "\n", + " \n", + "\n", + " \n", + " Incompatible with:\n", + " - Gate twirling\n", + "\n", + " Compatible with dynamic circuits when using `qiskit-ibm-runtime` v0.42.0 or later.\n", + "\n", + " \n", + "\n", + " \n", + " Incompatible with fractional gates or with stretches.\n", + "\n", + " Other notes:\n", + " - Gate twirling can be applied to dynamic circuits, but only to gates not inside conditional blocks. Measurement twirling can only be applied to terminal measurements.\n", + " - Does not work with non-Clifford entanglers.\n", + "\n", + " \n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "9b86001b-718a-4d72-b3b5-4a67eabf0a45", + "metadata": {}, + "source": [ + "## Next steps\n", + "\n", + "\n", + " - Find more details about the `SamplerV2` methods in the [Sampler API reference](../api/qiskit-ibm-runtime/sampler-v2).\n", + " - Find details about how to configure [error suppression](configure-error-suppression) and [error mitigation](configure-error-mitigation).\n", + " - Decide what [execution mode](execution-modes) to run your job in.\n", + "" + ] + } + ], + "metadata": { + "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" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/guides/sampler-rest-api.mdx b/docs/guides/sampler-rest-api.mdx new file mode 100644 index 00000000000..1861cd0a341 --- /dev/null +++ b/docs/guides/sampler-rest-api.mdx @@ -0,0 +1,347 @@ +--- +title: REST API +description: How to use the Sampler primitive with the Qiskit Runtime REST API. +--- +{/* cspell:ignore IIZII, XIZZZ, accum */} + + +# Sampler with the REST API + +The steps in this topic describe how to run and configure workloads with the REST API, and demonstrate how to invoke them in any program of your choice. + + + This documentation utilizes the Python `requests` module to demonstrate the Qiskit Runtime REST API. However, this workflow can be executed using any language or framework that supports working with REST APIs. Refer to the [API reference documentation](/docs/api/qiskit-ibm-runtime/tags/jobs) for details. + + +## 1. Initialize the account + +Because Qiskit Runtime Sampler is a managed service, you first need to initialize your account. You can then select the device you want to use to run your calculations on. + + +Find details on how to initialize your account, view available backends, and work with tokens in [Set up to use IBM Quantum Platform with REST API.](/docs/guides/cloud-setup-rest-api) + + +## 2. Create a QASM circuit + +You need at least one circuit as the input to the Sampler primitive. + + +Define a QASM quantum circuit: + +```python +qasm_string=''' +OPENQASM 3; +include "stdgates.inc"; +qreg q[2]; +creg c[2]; +x q[0]; +cx q[0], q[1]; +c[0] = measure q[0]; +c[1] = measure q[1]; +''' +``` + + +The code snippets given below assume that the `qasm_string` has been transpiled to a new string `resulting_qasm`. + + +## 3. Run the quantum circuit using Sampler V2 API + + + + The jobs below use [Qiskit Runtime V2 primitives](/docs/guides/v2-primitives). `SamplerV2` takes one or more primitive unified blocs (PUBs) as the input. Each PUB is a tuple that contains one circuit and the data broadcasted to that circuit, which can be multiple parameters, and returns one result per PUB. + + + +```python +import requests + +url = 'https://quantum.cloud.ibm.com/api/v1/jobs' +auth_id = "Bearer " +crn = "" +backend = "" + +headers = { + 'Content-Type': 'application/json', + 'Authorization':auth_id, + 'Service-CRN': crn + } +job_input = { + 'program_id': 'sampler', + "backend": backend, + "params": { + "pubs": [[resulting_qasm],[resulting_qasm,None,500]] # primitive unified blocs (PUBs) containing one circuit each. +}} + +response = requests.post(url, headers=headers, json=job_input) + +if response.status_code == 200: + job_id = response.json().get('id') + print("Job created:",response.text) +else: + print(f"Error: {response.status_code}") +``` + + + +## 4. Check job status and get results + +Next, pass the `job_id` to the API: + +```python +response_status_singlejob= requests.get(url+'/'+job_id, headers=headers) +response_status_singlejob.json().get('state') +``` +Output + +```text +>>> Job ID: 58223448-5100-4dec-a47a-942fb30edced +>>> Job Status: JobStatus.RUNNING +``` + +Get job results: +```python +response_result= requests.get(url+'/'+job_id+'/results', headers=headers) + +res_dict=response_result.json() + +# Get results for the first PUB +counts=res_dict['results'][0]['data']['c']['samples'] + +print(counts[:20]) +``` +Output +```text +['0x3', '0x0', '0x2', '0x1', '0x0', '0x3', '0x0', '0x3', '0x1', '0x2', '0x2', '0x0', '0x2', '0x0', '0x3', '0x3', '0x2', '0x0', '0x1', '0x0'] +``` + +## 5. Work with Qiskit Runtime options + +Error mitigation techniques allow users to mitigate circuit errors by modeling the device noise at the time of execution. This typically results in quantum pre-processing overhead related to model training, and classical post-processing overhead to mitigate errors in the raw results by using the generated model. + +The error mitigation techniques built in to primitives are advanced resilience options. To specify these options, use the `resilience_level` option when submitting your job. +Sampler V2 does not support specifying resilience levels. However, you can turn on or off individual error mitigation / suppression methods. + +The following examples demonstrate the default options for dynamical decoupling and twirling. Find more options and further details in the [Error mitigation and suppression techniques](/docs/guides/error-mitigation-and-suppression-techniques) topic. + +### Dynamical decoupling +```python +import requests + +url = 'https://quantum.cloud.ibm.com/api/v1/jobs' +auth_id = "Bearer " +crn = "" +backend = "" + +headers = { + 'Content-Type': 'application/json', + 'Authorization':auth_id, + 'Service-CRN': crn + } +job_input = { + 'program_id': 'sampler', + "backend": backend, + "params": { + "pubs": [[resulting_qasm]], # primitive unified blocs (PUBs) containing one circuit each. + "options": { + "dynamical_decoupling": { + "enable": True, + "sequence_type": 'XpXm', + "extra_slack_distribution": 'middle', + "scheduling_method": 'alap', + }, + }, + } +} + +response = requests.post(url, headers=headers, json=job_input) + +if response.status_code == 200: + job_id = response.json().get('id') + print("Job created:",response.text) +else: + print(f"Error: {response.status_code}") +``` +### Twirling +```python +import requests + +url = 'https://quantum.cloud.ibm.com/api/v1/jobs' +auth_id = "Bearer " +crn = "" +backend = "" + +headers = { + 'Content-Type': 'application/json', + 'Authorization':auth_id, + 'Service-CRN': crn + } +job_input = { + 'program_id': 'sampler', + "backend": backend, + "params": { + "pubs": [[resulting_qasm]], # primitive unified blocs (PUBs) containing one circuit each. + "options": { + "twirling": { + "enable_gates": True, + "enable_measure": True, + "num_randomizations": "auto", + "shots_per_randomization": "auto", + "strategy": "active-accum", + }, + }, + } +} + +response = requests.post(url, headers=headers, json=job_input) + +if response.status_code == 200: + job_id = response.json().get('id') + print("Job created:",response.text) +else: + print(f"Error: {response.status_code}") +``` + + + +## Parameterized circuits + +### 1. Initialize the account + +Because Qiskit Runtime is a managed service, you first need to initialize your account. You can then select the device you want to use to run your calculations on. + + +Find details on how to initialize your account, view available backends, and invalidate tokens in this [topic](/docs/guides/cloud-setup-rest-api). + + +### 2. Define parameters + +```python +import requests +import qiskit_ibm_runtime +from qiskit_ibm_runtime import QiskitRuntimeService +from qiskit.transpiler import generate_preset_pass_manager +from qiskit.qasm3 import dumps +from qiskit import QuantumCircuit +from qiskit.circuit import Parameter +from qiskit import transpile + +service = QiskitRuntimeService(channel='ibm_quantum') +backend = service.backend("") + +pm = generate_preset_pass_manager(backend=backend, optimization_level=1) + +theta = Parameter('theta') +phi = Parameter('phi') +parameter_values = {'theta': 1.57, 'phi': 3.14} # In case we want to pass a dictionary +``` + + +### 3. Create a quantum circuit and add parameterized gates + +```python +qc = QuantumCircuit(2) + +# Add parameterized gates +qc.rx(theta, 0) +qc.ry(phi, 1) +qc.cx(0, 1) +qc.measure_all() + +# Draw the original circuit +qc.draw('mpl') + +# Get an ISA circuit +isa_circuit = pm.run(qc) +``` + +### 4. Generate QASM 3 code + +```python +qasm_str = dumps(isa_circuit) +print("Generated QASM 3 code:") +print(qasm_str) +``` + +### 5. Run the quantum circuit using Sampler V2 API + +```python +import requests + +url = 'https://quantum.cloud.ibm.com/api/v1/jobs' +auth_id = "Bearer " +crn = "" +backend = "" + +headers = { + 'Content-Type': 'application/json', + 'Authorization':auth_id, + 'Service-CRN': crn + } + +job_input = { + 'program_id': 'sampler', + "backend": backend, + "params": { + # Choose one option: direct parameter transfer or through a dictionary + #"pubs": [[qasm_str,[1,2],500]], # primitive unified blocs (PUBs) containing one circuit each. + "pubs": [[qasm_str,parameter_values,500]], # primitive unified blocs (PUBs) containing one circuit each. +}} + +response = requests.post(url, headers=headers, json=job_input) + +if response.status_code == 200: + job_id = response.json().get('id') + print(f"Job created: {response.text}") +else: + print(f"Error: {response.status_code}") +``` + +```python +print(response.text) +``` + + +### 6. Check job status and get results + +Next, pass the `job_id` to the API: + +```python +response_status_singlejob = requests.get(f"{url}/{job_id}", headers=headers) +response_status_singlejob.json().get('state') +``` + +Output + +```text +{'status': 'Completed'} +``` + +Get job results: + +```python +response_result = requests.get(f"{url}/{job_id}/results", headers=headers) + +res_dict=response_result.json() + +# Get results for the first PUB +counts=res_dict['results'][0]['data']['c']['samples'] + +print(counts[:20]) +``` + +Output + +```text +['0x1', '0x2', '0x1', '0x2', '0x1', '0x2', '0x0', '0x2', '0x1', '0x1', '0x2', '0x2', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1'] +``` + +## Next steps + + + + - There are several ways to run workloads, depending on your needs: job mode, session mode, and batch mode. Learn how to work with session mode and batch mode in the [execution modes topic](/docs/guides/execution-modes-rest-api). Note that Open Plan users cannot submit session jobs. + - Learn how to [initialize your account](/docs/guides/cloud-setup-rest-api) with REST API. + - Practice with primitives by working through the [Cost function lesson](/learning/courses/variational-algorithm-design/cost-functions) in IBM Quantum Learning. + - Learn how to transpile locally in the [Transpile](/docs/guides/transpile) section. + diff --git a/docs/guides/serverless-first-program.ipynb b/docs/guides/serverless-first-program.ipynb index 00c6005e845..0c1a9297c8e 100644 --- a/docs/guides/serverless-first-program.ipynb +++ b/docs/guides/serverless-first-program.ipynb @@ -428,7 +428,7 @@ "\n", "\n", "\n", - "- Learn how to pass inputs and run your program remotely in the [Run your first Qiskit Serverless workload remotely](./serverless-run-first-workload) topic.\n", + "- Learn how to pass inputs and run your program remotely in the [Run your first Qiskit Serverless workload remotely](/docs/guides/serverless-run-first-workload) topic.\n", "\n", "" ] diff --git a/docs/guides/serverless-manage-resources.ipynb b/docs/guides/serverless-manage-resources.ipynb index b07a6941e63..86a5087c2dc 100644 --- a/docs/guides/serverless-manage-resources.ipynb +++ b/docs/guides/serverless-manage-resources.ipynb @@ -135,7 +135,7 @@ "source": [ "## Parallel workflows\n", "\n", - "For classical tasks that can be parallelized, use the `@distribute_task` decorator to define compute requirements needed to perform a task. Start by recalling the `transpile_remote.py` example from the [Write your first Qiskit Serverless program](./serverless-first-program) topic with the following code.\n", + "For classical tasks that can be parallelized, use the `@distribute_task` decorator to define compute requirements needed to perform a task. Start by recalling the `transpile_remote.py` example from the [Write your first Qiskit Serverless program](/docs/guides/serverless-first-program) topic with the following code.\n", "\n", "The following code requires that you have already [saved your credentials](/docs/guides/cloud-setup)." ] @@ -649,7 +649,7 @@ "\n", "\n", "\n", - "- See a full example that [ports existing code to Qiskit Serverless](./serverless-port-code).\n", + "- See a full example that [ports existing code to Qiskit Serverless](/docs/guides/serverless-port-code).\n", "- Read a paper in which researchers used Qiskit Serverless and quantum-centric supercomputing to [explore quantum chemistry](https://arxiv.org/abs/2405.05068v1).\n", "\n", "" diff --git a/docs/guides/serverless-run-first-workload.ipynb b/docs/guides/serverless-run-first-workload.ipynb index 668452a98a7..12b3f8e127b 100644 --- a/docs/guides/serverless-run-first-workload.ipynb +++ b/docs/guides/serverless-run-first-workload.ipynb @@ -59,7 +59,7 @@ "source": [ "## List programs available\n", "\n", - "You can use `QiskitServerless.list()` to fetch a list of the available programs to run with Qiskit Serverless. This includes the previously uploaded [`transpile_remote_serverless`](./serverless-first-program)." + "You can use `QiskitServerless.list()` to fetch a list of the available programs to run with Qiskit Serverless. This includes the previously uploaded [`transpile_remote_serverless`](/docs/guides/serverless-first-program)." ] }, { @@ -441,7 +441,7 @@ "\n", "\n", "\n", - "- Explore [compute and data management tools](./serverless-manage-resources) available to your program, including parallelization.\n", + "- Explore [compute and data management tools](/docs/guides/serverless-manage-resources) available to your program, including parallelization.\n", "\n", "" ] diff --git a/docs/guides/set-optimization.ipynb b/docs/guides/set-optimization.ipynb index 60959e0188f..c2e4044dc0d 100644 --- a/docs/guides/set-optimization.ipynb +++ b/docs/guides/set-optimization.ipynb @@ -390,7 +390,7 @@ "jp-MarkdownHeadingCollapsed": true }, "source": [ - "Adjusting the optimization level can change other aspects of the circuit too, not just the number of ECR gates. For examples of how setting optimization level changes the layout, see [Representing quantum computers](./represent-quantum-computers).\n", + "Adjusting the optimization level can change other aspects of the circuit too, not just the number of ECR gates. For examples of how setting optimization level changes the layout, see [Representing quantum computers](/docs/guides/represent-quantum-computers).\n", "\n", "## Next steps\n", "\n", diff --git a/docs/guides/simulate-stabilizer-circuits.ipynb b/docs/guides/simulate-stabilizer-circuits.ipynb index ce3eb377444..9a36f3def21 100644 --- a/docs/guides/simulate-stabilizer-circuits.ipynb +++ b/docs/guides/simulate-stabilizer-circuits.ipynb @@ -254,7 +254,7 @@ "## Next steps\n", "\n", "\n", - " - To simulate circuits with Qiskit Aer, see [Exact and noisy simulation with Qiskit Aer primitives](./simulate-with-qiskit-sdk-primitives).\n", + " - To simulate circuits with Qiskit Aer, see [Exact and noisy simulation with Qiskit Aer primitives](/docs/guides/simulate-with-qiskit-sdk-primitives).\n", " - Review the [Qiskit Aer](https://qiskit.org/ecosystem/aer/) documentation.\n", "" ] diff --git a/docs/guides/simulate-with-qiskit-aer.ipynb b/docs/guides/simulate-with-qiskit-aer.ipynb index 41811b1423d..22ef7980e28 100644 --- a/docs/guides/simulate-with-qiskit-aer.ipynb +++ b/docs/guides/simulate-with-qiskit-aer.ipynb @@ -136,7 +136,7 @@ "id": "134d97a2-8420-4931-85b4-324679655e24", "metadata": {}, "source": [ - "Now, let's initialize a noise model that includes depolarizing error of 2% on every CX gate. In practice, the error arising from the two-qubit gates, which are CX gates here, are the dominant source of error when running a circuit. See [Build noise models](./build-noise-models) for an overview of constructing noise models in Qiskit Aer.\n", + "Now, let's initialize a noise model that includes depolarizing error of 2% on every CX gate. In practice, the error arising from the two-qubit gates, which are CX gates here, are the dominant source of error when running a circuit. See [Build noise models](/docs/guides/build-noise-models) for an overview of constructing noise models in Qiskit Aer.\n", "\n", "In the next cell, we construct an Estimator that incorporates this noise model and use it to compute the expectation value of the observable." ] diff --git a/docs/guides/simulate-with-qiskit-sdk-primitives.ipynb b/docs/guides/simulate-with-qiskit-sdk-primitives.ipynb index 0220cb9bfc2..66833cac3cf 100644 --- a/docs/guides/simulate-with-qiskit-sdk-primitives.ipynb +++ b/docs/guides/simulate-with-qiskit-sdk-primitives.ipynb @@ -50,7 +50,7 @@ "source": [ "The reference primitives in the Qiskit SDK perform local statevector simulations. These simulations do not support\n", "modeling device noise, but are useful for quickly prototyping algorithms before looking into more advanced simulation\n", - "techniques ([using Qiskit Aer](./simulate-stabilizer-circuits)) or running on real devices ([Qiskit Runtime primitives](primitives)).\n", + "techniques ([using Qiskit Aer](/docs/guides/simulate-stabilizer-circuits)) or running on real devices ([Qiskit Runtime primitives](primitives)).\n", "\n", "The Estimator primitive can compute expectation values of circuits, and the Sampler primitive can sample\n", "from output distributions of circuits.\n", @@ -64,7 +64,7 @@ "\n", "The following code prepares the inputs that will be used in the examples that follow. The expected input type for the\n", "observables is [`qiskit.quantum_info.SparsePauliOp`](../api/qiskit/qiskit.quantum_info.SparsePauliOp). Note that\n", - "the circuit in the example is parametrized, but you can also run the Estimator on non-parametrized circuits.\n", + "the circuit in the example is parametrized, but you can also run Estimator on non-parametrized circuits.\n", "\n", "\n", " Any circuit passed to an Estimator must **not** include any **measurements**.\n", @@ -252,14 +252,14 @@ "id": "d54f110f-004a-4337-8b4d-7d4287f22be9", "metadata": {}, "source": [ - "For a full example, see the [Primitives examples](primitives-examples#estimator-examples) page.\n", + "For a full example, see the [Estimator examples](/docs/guides/estimator-examples) page.\n", "\n", "## Use the reference Sampler\n", "\n", "The reference implementations of `SamplerV2` in `qiskit.primitives` is the [`StatevectorSampler`](../api/qiskit/qiskit.primitives.StatevectorSampler) class. It takes circuits and parameters as inputs and returns the results from sampling from the output probability distributions as a quasi-probability distribution of output states.\n", "\n", "The following code prepares the inputs used in the examples that follow. Note that\n", - "these examples run a single parametrized circuit, but you can also run the Sampler\n", + "these examples run a single parametrized circuit, but you can also run Sampler\n", "on non-parametrized circuits." ] }, @@ -462,7 +462,7 @@ "# Transpile circuit\n", "pm = generate_preset_pass_manager(optimization_level=1)\n", "isa_circuit = pm.run(circuit)\n", - "# Run using sampler\n", + "# Run using Sampler\n", "result = sampler.run([circuit]).result()\n", "# Access result data for PUB 0\n", "data_pub = result[0].data\n", @@ -519,7 +519,7 @@ "id": "1c0e76fe-4b5d-4fd4-9eec-da5332d76cfb", "metadata": {}, "source": [ - "For a full example, see the [Primitives examples](./primitives-examples#sampler-examples) page.\n", + "For a full example, see the [Sampler examples](/docs/guides/sampler-examples) page.\n", "## Next steps\n", "\n", "\n", diff --git a/docs/guides/synthesize-unitary-operators.ipynb b/docs/guides/synthesize-unitary-operators.ipynb index a5df9075582..5a3cbb07fbe 100644 --- a/docs/guides/synthesize-unitary-operators.ipynb +++ b/docs/guides/synthesize-unitary-operators.ipynb @@ -189,7 +189,7 @@ "\n", "\n", " - See an example of circuit decomposition in the [Grover's Algorithm](/docs/tutorials/grovers-algorithm) tutorial.\n", - " - For more information about the Qiskit transpiler, visit the [Transpile section](./transpile).\n", + " - For more information about the Qiskit transpiler, visit the [Transpile section](/docs/guides/transpile).\n", "" ] } diff --git a/docs/guides/tools-intro.mdx b/docs/guides/tools-intro.mdx index cb147966e81..07301088233 100644 --- a/docs/guides/tools-intro.mdx +++ b/docs/guides/tools-intro.mdx @@ -27,11 +27,11 @@ Some of the most useful features of the Qiskit SDK include: - **Transpiler** ([`qiskit.transpiler`](/docs/api/qiskit/transpiler)) - For transforming and adapting quantum circuits to suit specific device topology, and optimizing for execution on real quantum processing units (QPUs). -- **Primitives** ([`qiskit.primitives`](/docs/api/qiskit/primitives)) - The module that contains the base definitions and reference implementations of the Sampler and Estimator primitives, from which different quantum hardware providers can derive their own implementations. See more information about the Qiskit Runtime primitives [in the documentation](./primitives). +- **Primitives** ([`qiskit.primitives`](/docs/api/qiskit/primitives)) - The module that contains the base definitions and reference implementations of the Sampler and Estimator primitives, from which different quantum hardware providers can derive their own implementations. See more information about the Qiskit Runtime primitives [in the documentation](/docs/guides/primitives). ### Installation -For a more detailed introduction to installing the Qiskit SDK, check out the [installation page](./install-qiskit). If you're ready to install it now, simply run: +For a more detailed introduction to installing the Qiskit SDK, check out the [installation page](/docs/guides/install-qiskit). If you're ready to install it now, simply run: ```bash pip install qiskit diff --git a/docs/guides/transpiler-plugins.ipynb b/docs/guides/transpiler-plugins.ipynb index 92ce54ad341..6fcec3d2e26 100644 --- a/docs/guides/transpiler-plugins.ipynb +++ b/docs/guides/transpiler-plugins.ipynb @@ -425,7 +425,7 @@ "## Next steps\n", "\n", "\n", - " - [Create a transpiler plugin](./create-transpiler-plugin).\n", + " - [Create a transpiler plugin](/docs/guides/create-transpiler-plugin).\n", " - Check out the [tutorials](/docs/tutorials) for examples of transpiling and running quantum circuits.\n", "" ] diff --git a/docs/guides/transpiler-stages.ipynb b/docs/guides/transpiler-stages.ipynb index 980db4f196a..24709c80c17 100644 --- a/docs/guides/transpiler-stages.ipynb +++ b/docs/guides/transpiler-stages.ipynb @@ -83,7 +83,7 @@ "metadata": {}, "source": [ "## Layout stage\n", - "The next stage involves the layout or connectivity of the backend a circuit will be sent to. In general, quantum circuits are abstract entities whose qubits are \"virtual\" or \"logical\" representations of actual qubits used in computations. To execute a sequence of gates, a one-to-one mapping from the \"virtual\" qubits to the \"physical\" qubits in an actual quantum device is necessary. This mapping is stored as a `Layout` object and is part of the constraints defined within a backend's [instruction set architecture (ISA)](./transpile#instruction-set-architecture).\n", + "The next stage involves the layout or connectivity of the backend a circuit will be sent to. In general, quantum circuits are abstract entities whose qubits are \"virtual\" or \"logical\" representations of actual qubits used in computations. To execute a sequence of gates, a one-to-one mapping from the \"virtual\" qubits to the \"physical\" qubits in an actual quantum device is necessary. This mapping is stored as a `Layout` object and is part of the constraints defined within a backend's [instruction set architecture (ISA)](/docs/guides/transpile#instruction-set-architecture).\n", "\n", "\n", "![This image illustrates qubits being mapped from the wire representation to a diagram that represents how the qubits are connected on the QPU.](/docs/images/guides/transpiler-stages/layout-mapping.avif \"Qubit mapping\")\n", @@ -241,7 +241,7 @@ "source": [ "## Translation stage\n", "\n", - "When writing a quantum circuit, you are free to use any quantum gate (unitary operation) that you like, along with a collection of non-gate operations such as qubit measurement or reset instructions. However, most quantum devices only natively support a handful of quantum gate and non-gate operations. These native gates are part of the definition of a target's [ISA](./transpile#instruction-set-architecture) and this stage of the preset `PassManagers` translates (or *unrolls*) the gates specified in a circuit to the native basis gates of a specified backend. This is an important step, as it allows the circuit to be executed by the backend, but typically leads to an increase in the depth and number of gates.\n", + "When writing a quantum circuit, you are free to use any quantum gate (unitary operation) that you like, along with a collection of non-gate operations such as qubit measurement or reset instructions. However, most quantum devices only natively support a handful of quantum gate and non-gate operations. These native gates are part of the definition of a target's [ISA](/docs/guides/transpile#instruction-set-architecture) and this stage of the preset `PassManagers` translates (or *unrolls*) the gates specified in a circuit to the native basis gates of a specified backend. This is an important step, as it allows the circuit to be executed by the backend, but typically leads to an increase in the depth and number of gates.\n", "\n", "Two special cases are especially important to highlight, and help illustrate what this stage does.\n", "\n", diff --git a/docs/guides/upgrade-from-open.mdx b/docs/guides/upgrade-from-open.mdx index 35c5f9e5bb5..03c44e0e53a 100644 --- a/docs/guides/upgrade-from-open.mdx +++ b/docs/guides/upgrade-from-open.mdx @@ -8,11 +8,11 @@ description: upgrade from the IBM Quantum Open Plan to an IBM Cloud Pay-As-You-G This guide is for entities who want to upgrade from the IBM Quantum® Open Plan to an IBM Cloud® Pay-As-You-Go Plan. For instructions to set up a cloud account, set up a service instance, and work with users, follow these steps. -If you are an individual setting up the service for the first time or if you have been invited to an instance by an administrator, follow the steps in [Install Qiskit](./install-qiskit) instead. +If you are an individual setting up the service for the first time or if you have been invited to an instance by an administrator, follow the steps in [Install Qiskit](/docs/guides/install-qiskit) instead. ## Before you begin -If necessary, follow the steps in the [Set up to use IBM Cloud](./cloud-setup#cloud) section to complete the following: +If necessary, follow the steps in the [Set up to use IBM Cloud](/docs/guides/cloud-setup#cloud) section to complete the following: - Sign up for an IBM Cloud account. - Create an IBM Quantum instance. diff --git a/docs/guides/v2-primitives.mdx b/docs/guides/v2-primitives.mdx index dea326dddd0..eff26ce9855 100644 --- a/docs/guides/v2-primitives.mdx +++ b/docs/guides/v2-primitives.mdx @@ -215,7 +215,7 @@ The output is now in the [`PubResult`](/docs/api/qiskit/qiskit.primitives.PubRes - The V1 output format was a dictionary of bitstrings (as an int) as the key and quasi-probabilities as the value for each circuit. The V2 format has the same key (but as a string) and counts as the value. To convert the V2 format to V1, divide the counts by the number of shots, where the number of shots selected is described in the [Specify options](/docs/guides/specify-runtime-options#shots) guide. + The V1 output format was a dictionary of bitstrings (as an int) as the key and quasi-probabilities as the value for each circuit. The V2 format has the same key (but as a string) and counts as the value. To convert the V2 format to V1, divide the counts by the number of shots, where the number of shots selected is described in the [Sampler options](/docs/guides/sampler-options#shots) guide. ```python v2_result = sampler_v2_job.result() @@ -491,7 +491,7 @@ print(f"Job {job.job_id()} is still running: {job.status() is JobStatus.RUNNING} 1. You might need to reshape your arrays of observables or parameter sets if you want to apply their outer product. For example, an array of observables of shape (4, 1) and an array of parameter sets of shape (1, 6) will give you a result of (4, 6) expectation values. See the [Numpy broadcasting rules](https://numpy.org/doc/stable/user/basics.broadcasting.html) for more details. 2. You can optionally specify the precision you want for that specific PUB. -5. Update the estimator `run()` method to pass in the list of PUBs. For example, `run([(circuit1, observable1, parameter_set1)])`. +5. Update Estimator's `run()` method to pass in the list of PUBs. For example, `run([(circuit1, observable1, parameter_set1)])`. You can optionally specify a `precision` here, which would apply to all PUBs. 6. Estimator V2 job results are grouped by PUBs. You can see the expectation value and standard error for each PUB by indexing to it. For example: ```python @@ -878,7 +878,7 @@ print(f" > Expectation values job 2: {another_result.values}") 3. Review all the [supported options](/docs/api/qiskit-ibm-runtime/options) and make updates accordingly. 4. Group each circuit you want to run with the observables and parameter values you want to apply to the circuit in a tuple (a PUB). For example, use `(circuit1, parameter_set1)` if you want to run `circuit1` with `parameter_set1`. You can optionally specify the shots you want for that specific PUB. -5. Update the sampler `run()` method to pass in the list of PUBs. For example, `run([(circuit1, parameter_set1)])`. +5. Update Sampler's `run()` method to pass in the list of PUBs. For example, `run([(circuit1, parameter_set1)])`. You can optionally specify `shots` here, which would apply to all PUBs. 6. Sampler V2 job results are grouped by PUBs. You can see the output data for each PUB by indexing to it. While Sampler V2 returns unweighted samples, the result class has a convenience method to get counts instead. For example: ```python @@ -1206,7 +1206,7 @@ print(f" > Quasi-probability distribution job 2: {another_result.quasi_dists}") ## Next steps - - Learn more about setting options in the [Specify options](/docs/guides/specify-runtime-options) guide. - - Learn more details about [Primitive inputs and outputs](/docs/guides/primitive-input-output). + - Learn more about setting options in the [Sampler options,](/docs/guides/sampler-options) [Estimator options,](/docs/guides/estimator-options) and [Executor options](/docs/guides/executor-options) guides. + - Learn more details about [Primitive inputs and outputs.](/docs/guides/pubs-broadcasting#pubs) - Experiment with the [CHSH Inequality](/docs/tutorials/chsh-inequality) tutorial. diff --git a/docs/guides/view-cost.mdx b/docs/guides/view-cost.mdx index 20f8bcc59aa..e379f15fb39 100644 --- a/docs/guides/view-cost.mdx +++ b/docs/guides/view-cost.mdx @@ -26,5 +26,5 @@ To determine how much usage a specific workload incurred, open the [Workloads pa ## Next steps - - To learn how to limit costs, see [Manage costs](/docs/guides/manage-cost). + - To learn how to limit costs, see [Manage costs.](/docs/guides/manage-cost) \ No newline at end of file diff --git a/docs/tutorials/dc-hex-ising.ipynb b/docs/tutorials/dc-hex-ising.ipynb index 6eb81700f91..1356ed60b66 100644 --- a/docs/tutorials/dc-hex-ising.ipynb +++ b/docs/tutorials/dc-hex-ising.ipynb @@ -877,7 +877,7 @@ "metadata": {}, "source": [ "### Transpilation for dynamic circuits\n", - "First, we transpile the dynamic circuits, with and without adding the DD sequence. To ensure we use the same set of physical qubits in all circuits for more consistent results, we first transpile the circuit once, and then use its layout for all subsequent circuits, specified by [`initial_layout`](/docs/api/qiskit/qiskit.transpiler.TranspileLayout#initial_layout) in the pass manager. We then construct the [primitive unified blocs](/docs/guides/primitive-input-output) (PUBs) as the Sampler primitive input." + "First, we transpile the dynamic circuits, with and without adding the DD sequence. To ensure we use the same set of physical qubits in all circuits for more consistent results, we first transpile the circuit once, and then use its layout for all subsequent circuits, specified by [`initial_layout`](/docs/api/qiskit/qiskit.transpiler.TranspileLayout#initial_layout) in the pass manager. We then construct the [primitive unified blocs](/docs/guides/pubs-broadcasting) (PUBs) as the Sampler primitive input." ] }, { diff --git a/docs/tutorials/depth-reduction-with-circuit-cutting.ipynb b/docs/tutorials/depth-reduction-with-circuit-cutting.ipynb index 0403b82f367..d67caa5c64b 100644 --- a/docs/tutorials/depth-reduction-with-circuit-cutting.ipynb +++ b/docs/tutorials/depth-reduction-with-circuit-cutting.ipynb @@ -315,7 +315,7 @@ "source": [ "## Step 3: Execute using Qiskit primitives\n", "\n", - "Execute the target circuits (\"subexperiments\") with the Sampler Primitive.\n", + "Execute the target circuits (\"subexperiments\") with the Sampler primitive.\n", "\n", "* Input: Target circuits\n", "* Output: Quasi-probability distributions" diff --git a/docs/tutorials/error-mitigation-with-qiskit-functions.ipynb b/docs/tutorials/error-mitigation-with-qiskit-functions.ipynb index 238761a1c3d..cbe8ab07fa5 100644 --- a/docs/tutorials/error-mitigation-with-qiskit-functions.ipynb +++ b/docs/tutorials/error-mitigation-with-qiskit-functions.ipynb @@ -24,7 +24,7 @@ "id": "34260848-be4c-45f7-914f-9d9bcc2be504", "metadata": {}, "source": [ - "This tutorial walks through an example of building and running a workflow using the IBM Circuit function. This function takes [Primitive Unified Blocs](/docs/guides/primitive-input-output) (PUBs) as inputs and returns error-mitigated expectation values as outputs. It provides an automated and customized pipeline to optimize circuits and execute on quantum hardware so that researchers can focus on algorithm and application discovery.\n", + "This tutorial walks through an example of building and running a workflow using the IBM Circuit function. This function takes [Primitive Unified Blocs](/docs/guides/pubs-broadcasting) (PUBs) as inputs and returns error-mitigated expectation values as outputs. It provides an automated and customized pipeline to optimize circuits and execute on quantum hardware so that researchers can focus on algorithm and application discovery.\n", "\n", "Visit the documentation for an [introduction to Qiskit Functions](/docs/guides/functions) and learn how to get started with the [IBM Circuit function](/docs/guides/ibm-circuit-function)." ] @@ -420,7 +420,7 @@ "id": "e510ff6e-7022-48c6-b146-6e48611d7d12", "metadata": {}, "source": [ - "The result from running the function has the same format as the [Estimator](/docs/guides/primitive-input-output#estimator-output)." + "The result from running the function has the same format as the [Estimator](/docs/guides/estimator-input-output)." ] }, { diff --git a/docs/tutorials/ghz-spacetime-codes.ipynb b/docs/tutorials/ghz-spacetime-codes.ipynb index ce79d3bfac5..35323676e76 100644 --- a/docs/tutorials/ghz-spacetime-codes.ipynb +++ b/docs/tutorials/ghz-spacetime-codes.ipynb @@ -1673,14 +1673,14 @@ } ], "source": [ - "# Select the sampler options\n", + "# Select the Sampler options\n", "sampler = Sampler(mode=backend)\n", "sampler.options.default_shots = SHOTS\n", "sampler.options.dynamical_decoupling.enable = False\n", "sampler.options.execution.rep_delay = 0.00025\n", "\n", "# Submit the job\n", - "print(\"Submitting sampler job\")\n", + "print(\"Submitting Sampler job\")\n", "ghz_job = sampler.run([isa_circuit])\n", "\n", "print(ghz_job.job_id())" diff --git a/docs/tutorials/global-data-quantum-optimizer.ipynb b/docs/tutorials/global-data-quantum-optimizer.ipynb index 1ecd9661378..9791d449187 100644 --- a/docs/tutorials/global-data-quantum-optimizer.ipynb +++ b/docs/tutorials/global-data-quantum-optimizer.ipynb @@ -301,7 +301,7 @@ "id": "06608c0a-34ac-47b4-84c5-da98458e6dab", "metadata": {}, "source": [ - "The `optimizer_settings` dictionary configures the optimization process, including parameters such as `num_generations` for the number of iterations and `population_size` for the number of candidate solutions per generation. Other settings control aspects like the recombination rate, parallel jobs, batch size, and mutation range. Additionally, the primitive settings, such as `estimator_shots`, `estimator_precision`, and `sampler_shots`, define the quantum estimator and sampler configurations for the optimization process." + "The `optimizer_settings` dictionary configures the optimization process, including parameters such as `num_generations` for the number of iterations and `population_size` for the number of candidate solutions per generation. Other settings control aspects like the recombination rate, parallel jobs, batch size, and mutation range. Additionally, the primitive settings, such as `estimator_shots`, `estimator_precision`, and `sampler_shots`, define the quantum Estimator and Sampler configurations for the optimization process." ] }, { diff --git a/docs/tutorials/grovers-algorithm.ipynb b/docs/tutorials/grovers-algorithm.ipynb index d8cd56c06a3..b942ad84cdb 100644 --- a/docs/tutorials/grovers-algorithm.ipynb +++ b/docs/tutorials/grovers-algorithm.ipynb @@ -364,7 +364,7 @@ "\n", "Amplitude amplification is a sampling problem that is suitable for execution with the [`Sampler`](/docs/api/qiskit-ibm-runtime/sampler-v2) runtime primitive.\n", "\n", - "Note that the `run()` method of [Qiskit Runtime `SamplerV2`](/docs/api/qiskit-ibm-runtime/sampler-v2) takes an iterable of `primitive unified blocks (PUBs)`. For sampler, each PUB is an iterable in the format `(circuit, parameter_values)`. However, at a minimum, it takes a list of quantum circuit(s)." + "Note that the `run()` method of [Qiskit Runtime `SamplerV2`](/docs/api/qiskit-ibm-runtime/sampler-v2) takes an iterable of `primitive unified blocks (PUBs)`. For Sampler, each PUB is an iterable in the format `(circuit, parameter_values)`. However, at a minimum, it takes a list of quantum circuit(s)." ] }, { diff --git a/docs/tutorials/krylov-quantum-diagonalization.ipynb b/docs/tutorials/krylov-quantum-diagonalization.ipynb index 91751cad92a..d6b7f364347 100644 --- a/docs/tutorials/krylov-quantum-diagonalization.ipynb +++ b/docs/tutorials/krylov-quantum-diagonalization.ipynb @@ -1112,7 +1112,7 @@ "id": "794edf4c-d539-4864-865d-52a88a450b5c", "metadata": {}, "source": [ - "Execute circuits for $S$ and $\\tilde{H}$ with the Estimator" + "Execute circuits for $S$ and $\\tilde{H}$ with Estimator" ] }, { diff --git a/docs/tutorials/operator-back-propagation.ipynb b/docs/tutorials/operator-back-propagation.ipynb index a6bb9039c99..6f88b2add19 100644 --- a/docs/tutorials/operator-back-propagation.ipynb +++ b/docs/tutorials/operator-back-propagation.ipynb @@ -546,7 +546,7 @@ "id": "8b4487c1-b1e6-4ae8-b02d-c8bf980ad19b", "metadata": {}, "source": [ - "We create the Primitive Unified Bloc (PUB) for each of the three cases." + "We create the Primitive Unified Bloc (PUB) for each of the three cases." ] }, { diff --git a/docs/tutorials/quantum-approximate-optimization-algorithm.ipynb b/docs/tutorials/quantum-approximate-optimization-algorithm.ipynb index 86a7338199b..12364164513 100644 --- a/docs/tutorials/quantum-approximate-optimization-algorithm.ipynb +++ b/docs/tutorials/quantum-approximate-optimization-algorithm.ipynb @@ -499,7 +499,7 @@ "metadata": {}, "source": [ "#### Define backend and execution primitive\n", - "Use the **Qiskit Runtime primitives** to interact with IBM® backends. The two primitives are Sampler and Estimator, and the choice of primitive depends on what type of measurement you want to run on the quantum computer. For the minimization of $H_C$, use the Estimator since the measurement of the cost function is simply the expectation value of $\\langle H_C \\rangle$." + "Use the **Qiskit Runtime primitives** to interact with IBM® backends. The two primitives are Sampler and Estimator, and the choice of primitive depends on what type of measurement you want to run on the quantum computer. For the minimization of $H_C$, use Estimator since the measurement of the cost function is simply the expectation value of $\\langle H_C \\rangle$." ] }, { @@ -513,7 +513,7 @@ "\n", "![Illustration showing the behavior of Single job, Batch, and Session runtime modes.](/docs/images/tutorials/quantum-approximate-optimization-algorithm/runtime-modes.avif)\n", "\n", - "You can plug the sampler-based cost function into the SciPy minimizing routine to find the optimal parameters." + "You can plug the Sampler-based cost function into the SciPy minimizing routine to find the optimal parameters." ] }, { diff --git a/docs/tutorials/quantum-phase-estimation-qctrl.ipynb b/docs/tutorials/quantum-phase-estimation-qctrl.ipynb index feb77aaf891..8f58209727f 100644 --- a/docs/tutorials/quantum-phase-estimation-qctrl.ipynb +++ b/docs/tutorials/quantum-phase-estimation-qctrl.ipynb @@ -375,7 +375,7 @@ "metadata": {}, "outputs": [], "source": [ - "# Run the circuit using the sampler\n", + "# Run the circuit using Sampler\n", "fire_opal_job = perf_mgmt.run(\n", " primitive=\"sampler\",\n", " pubs=[qasm2.dumps(circuits_quantum_phase_estimation)],\n", diff --git a/docs/tutorials/sample-based-krylov-quantum-diagonalization.ipynb b/docs/tutorials/sample-based-krylov-quantum-diagonalization.ipynb index 60a4bc25c3f..24efffc9c49 100644 --- a/docs/tutorials/sample-based-krylov-quantum-diagonalization.ipynb +++ b/docs/tutorials/sample-based-krylov-quantum-diagonalization.ipynb @@ -406,7 +406,7 @@ "id": "a3304e1b-9c7c-4212-8744-d1c62292eced", "metadata": {}, "source": [ - "Now that we have created the circuits, we can optimize them for a target hardware. We pick the least busy QPU with at least 127 qubits. Check out the [Qiskit IBM® Runtime docs](/docs/guides/get-started-with-primitives#get-started-with-sampler) for more information." + "Now that we have created the circuits, we can optimize them for a target hardware. We pick the least busy QPU with at least 127 qubits. Check out the [Qiskit IBM® Runtime docs](/docs/guides/get-started-with-sampler) for more information." ] }, { diff --git a/docs/tutorials/sml-classification.ipynb b/docs/tutorials/sml-classification.ipynb index b9dec783737..b834280fcec 100644 --- a/docs/tutorials/sml-classification.ipynb +++ b/docs/tutorials/sml-classification.ipynb @@ -43,7 +43,7 @@ "What you will do here: prepare and balance the grid-stability dataset; establish a classical AdaBoost baseline; run several quantum configurations that vary ensemble width and regularization; execute on IBM® simulators or QPUs via Qiskit Serverless; and compare accuracy, precision, recall, and F1 across all runs. Along the way, you will use the function’s action pattern (`create`, `fit`, `predict`, `fit_predict`, `create_fit_predict`) and key controls:\n", "- Regularization types: `onsite` (λ) for direct sparsity and `alpha` for a ratio-based trade-off between interaction and onsite terms\n", "- Auto-regularization: set `regularization=\"auto\"` with a target selection ratio to adapt sparsity automatically\n", - "- Optimizer options: simulator versus QPU, repetitions, classical optimizer and its options, transpilation depth, and runtime sampler/estimator settings\n", + "- Optimizer options: simulator versus QPU, repetitions, classical optimizer and its options, transpilation depth, and Qiskit Runtime Sampler or Estimator settings\n", "\n", "Benchmarks in the documentation show that accuracy improves as the number of learners (qubits) increases on challenging problems, with the quantum classifier matching or exceeding a comparable classical ensemble. In this tutorial, you will reproduce the workflow end-to-end and examine when increasing ensemble width or switching to adaptive regularization yields better F1 at reasonable resource usage. The result is a grounded view of how a quantum optimization step can complement, rather than replace, classical ensemble learning in real applications." ] diff --git a/learning/courses/quantum-chem-with-vqe/geometry.ipynb b/learning/courses/quantum-chem-with-vqe/geometry.ipynb index f2f5ea0d0ad..0fdf43e9651 100644 --- a/learning/courses/quantum-chem-with-vqe/geometry.ipynb +++ b/learning/courses/quantum-chem-with-vqe/geometry.ipynb @@ -349,7 +349,7 @@ "source": [ "## Step 3: Execute using Qiskit primitives.\n", "\n", - "In the code block below, we set up an array to store our outputs from each step in our interatomic distance $x$. We have chosen the range of $x$ based on our knowledge of the experimental value for the equilibrium bond length: 0.74 Angstrom. We will run this first on a simulator, and will thus be importing our estimator (BackendEstimator) from `qiskit.primitives`. For each geometry step, we build the Hamiltonian and allow a certain number of optimization steps (here 500) using the optimizer \"cobyla\". At each geometry step, we store both the total energy and the electronic energy. Because of the high number of optimizer steps, this may take an hour or more. You may wish to modify the inputs below to reduce the required time." + "In the code block below, we set up an array to store our outputs from each step in our interatomic distance $x$. We have chosen the range of $x$ based on our knowledge of the experimental value for the equilibrium bond length: 0.74 Angstrom. We will run this first on a simulator, and will thus be importing our Estimator (BackendEstimator) from `qiskit.primitives`. For each geometry step, we build the Hamiltonian and allow a certain number of optimization steps (here 500) using the optimizer \"cobyla\". At each geometry step, we store both the total energy and the electronic energy. Because of the high number of optimizer steps, this may take an hour or more. You may wish to modify the inputs below to reduce the required time." ] }, { diff --git a/learning/courses/quantum-chem-with-vqe/ground-state.ipynb b/learning/courses/quantum-chem-with-vqe/ground-state.ipynb index 670b76f3d93..626d46a771c 100644 --- a/learning/courses/quantum-chem-with-vqe/ground-state.ipynb +++ b/learning/courses/quantum-chem-with-vqe/ground-state.ipynb @@ -313,7 +313,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "id": "dd54bb0e-c94b-4168-b1e7-2ca036d2c231", "metadata": {}, "outputs": [], @@ -321,7 +321,7 @@ "# We will start by using a local simulator\n", "from qiskit_aer import AerSimulator\n", "\n", - "# Import an estimator, this time from qiskit (we will import from Runtime for real hardware)\n", + "# Import Estimator, this time from Qiskit (we will import from Qiskit Runtime for real QPUs)\n", "from qiskit.primitives import BackendEstimatorV2\n", "\n", "# generate a simulator that mimics the real quantum system\n", diff --git a/learning/courses/quantum-computing-in-practice/running-quantum-circuits.ipynb b/learning/courses/quantum-computing-in-practice/running-quantum-circuits.ipynb index 47e711be47c..3d95f1aa6e4 100644 --- a/learning/courses/quantum-computing-in-practice/running-quantum-circuits.ipynb +++ b/learning/courses/quantum-computing-in-practice/running-quantum-circuits.ipynb @@ -17,7 +17,7 @@ "\n", "Watch the video on quantum circuits and primitives from Olivia Lanes, or open the video in a separate window on [YouTube.](https://youtube.com/watch?v=NTplT4WnNbk)\n", "\n", - "\n", + "\n", "\n", "## Lesson overview\n", "\n", @@ -55,7 +55,7 @@ "\n", "To turn your quantum problem into instructions for a quantum computer, you'll use Qiskit, the open-source software development kit designed for work on quantum computers developed by IBM. There's also the Qiskit Ecosystem — a collection of software tutorials and functions that build or extend upon the core functionalities of Qiskit — and Qiskit Runtime — a quantum computing service and programming model that allows users to design and optimize their quantum workloads and execute them efficiently by using Qiskit Runtime Primitives.\n", "\n", - "A primitive is a small building block that you can use to design a larger circuit or job. The two primitives that are most important to us are the sampler and the estimator, which we'll discuss in more depth shortly.\n", + "A primitive is a small building block that you can use to design a larger circuit or job. The two primitives that are most important to us are Sampler and Estimator, which we'll discuss in more depth shortly.\n", "\n", "With the recent release of Qiskit v1.0, Qiskit has become more performative and stable than ever before. So, for those of you just getting started, you came in at the perfect time! For those of you that are already familiar with Qiskit, you'll need to download and reinstall the newest version. For a full installation guide, visit [the Install Qiskit](/docs/guides/install-qiskit) guide.\n", "\n", @@ -151,7 +151,7 @@ "\n", "### Execute\n", "\n", - "Now we're ready to execute the quantum program. The Qiskit Runtime primitives provide an interface to IBM Quantum hardware, and they also abstract error suppression and mitigation away from the user. There are two primitives to choose from: the Sampler and the Estimator.\n", + "Now we're ready to execute the quantum program. The Qiskit Runtime primitives provide an interface to IBM Quantum hardware, and they also abstract error suppression and mitigation away from the user. There are two primitives to choose from: Sampler and Estimator.\n", "\n", "\n", "[Qiskit Runtime's Sampler](/docs/api/qiskit-ibm-runtime/sampler) runs the circuit multiple times on a quantum device, performing measurements on each run, and reconstructing the probability distribution from the recovered bit strings. The more runs (or shots) it performs, the more accurate the results will be, but this requires more time and quantum resources. Specifically, it calculates the probability of obtaining each possible standard basis state by measuring the state prepared by the circuit.\n", diff --git a/learning/courses/quantum-computing-in-practice/simulating-nature.ipynb b/learning/courses/quantum-computing-in-practice/simulating-nature.ipynb index 08e533648cf..8b2e28d7d43 100644 --- a/learning/courses/quantum-computing-in-practice/simulating-nature.ipynb +++ b/learning/courses/quantum-computing-in-practice/simulating-nature.ipynb @@ -200,7 +200,7 @@ "\n", "After completing the optimization step, we are ready to execute the circuit using a primitive. We are considering a simulation experiment in which the goal is to understand how certain properties of the system change over time. For this purpose, the Estimator primitive is the most appropriate choice, as it allows you to measure the expectation values of observables that correspond to these properties.\n", "\n", - "Next, we use options including [error suppression and mitigation techniques](/docs/guides/error-mitigation-and-suppression-techniques), to improve the Estimator's accuracy. Finally, we run the experiment to collect the results.\n", + "Next, we use options including [error suppression and mitigation techniques](/docs/guides/error-mitigation-and-suppression-techniques), to improve Estimator's accuracy. Finally, we run the experiment to collect the results.\n", "\n", "__7. Post-process__\n", "\n", @@ -327,7 +327,7 @@ "\n", "### Qiskit patterns step 3: Execute using primitives\n", "\n", - "Now, it is time to [run our circuit](/docs/tutorials/probabilistic-error-amplification#step-3-execute-using-qiskit-primitives). We will use the Estimator as our primary tool for this experiment because our goal is to measure the total magnetization of the system. The Estimator is specifically designed to estimate the expectation values of observables, making it the ideal choice here.\n", + "Now, it is time to [run our circuit](/docs/tutorials/probabilistic-error-amplification#step-3-execute-using-qiskit-primitives). We will use Estimator as our primary tool for this experiment because our goal is to measure the total magnetization of the system. The Estimator is specifically designed to estimate the expectation values of observables, making it the ideal choice here.\n", "At this stage, it is also essential to configure our error mitigation settings. We will apply Zero Noise Extrapolation (ZNE) to improve the accuracy of our results. In the tutorial, you will see that we specify two or more noise factor values at which to evaluate the extrapolated models, and we select “Probabilistic Error Amplification” (PEA) as our amplification method. PEA is preferred for this experiment because it scales significantly better than other options, which is crucial when working with systems of 100 or more qubits.\n", "\n", "This is all that is required to run the experiment.\n", diff --git a/learning/courses/quantum-computing-in-practice/utility-scale-qaoa.ipynb b/learning/courses/quantum-computing-in-practice/utility-scale-qaoa.ipynb index a8ed31ee7c0..87d7e91e202 100644 --- a/learning/courses/quantum-computing-in-practice/utility-scale-qaoa.ipynb +++ b/learning/courses/quantum-computing-in-practice/utility-scale-qaoa.ipynb @@ -181,7 +181,7 @@ "\n", "Now, we're almost ready to run the circuit — I promise! But first, it is important to note that you can send your job in a variety of different ways, which are called execution modes.\n", "\n", - "- Job mode: A single primitive request of the estimator or the sampler is made without a context manager. Circuits and inputs are packaged as primitive unified blocs (PUBs) and submitted as an execution task on the quantum computer.\n", + "- Job mode: A single primitive request of the Estimator or Sampler primitive is made without a context manager. Circuits and inputs are packaged as primitive unified blocs (PUBs) and submitted as an execution task on the quantum computer.\n", "\n", "- Batch mode: A multi-job manager for efficiently running an experiment that is comprised of bundle of independent jobs. Use batch mode to submit multiple primitive jobs simultaneously\n", "\n", diff --git a/learning/courses/quantum-diagonalization-algorithms/vqe.ipynb b/learning/courses/quantum-diagonalization-algorithms/vqe.ipynb index 925b4aa9046..b69b30510e1 100644 --- a/learning/courses/quantum-diagonalization-algorithms/vqe.ipynb +++ b/learning/courses/quantum-diagonalization-algorithms/vqe.ipynb @@ -29,11 +29,11 @@ "source": [ "## 1. What is VQE?\n", "\n", - "The variational quantum eigensolver is an algorithm that uses classical and quantum computing in conjunction to accomplish a task. There are 4 main components of a VQE calculation:\n", + "The variational quantum eigensolver is an algorithm that uses classical and quantum computing in conjunction to accomplish a task. There are four main components of a VQE calculation:\n", "\n", "* __An operator__: Often a Hamiltonian, which we’ll call $H$, that describes a property of your system that you wish to optimize. Another way of saying this is that you are seeking the eigenvector of this operator that corresponds to the minimum eigenvalue. We often call that eigenvector the “ground state”.\n", "* __An “ansatz”__ (a German word meaning “approach”): this is a quantum circuit that prepares a quantum state approximating the eigenvector you’re seeking. Really the ansatz is a family of quantum circuits, because some of the gates in the ansatz are parametrized, that is, they are fed a parameter which we can vary. This family of quantum circuits can prepare a family of quantum states approximating the ground state.\n", - "* __An estimator__: a means of estimating the expectation value of the operator $H$ over the current variational quantum state. Sometimes what we really care about is simply this expectation value, which we call a cost function. Sometimes, we care about a more complicated function that can still be written starting from one or more expectation values.\n", + "* __An Estimator__: a means of estimating the expectation value of the operator $H$ over the current variational quantum state. Sometimes what we really care about is simply this expectation value, which we call a cost function. Sometimes, we care about a more complicated function that can still be written starting from one or more expectation values.\n", "* __A classical optimizer__: an algorithm that varies parameters to try to minimize the cost function.\n", "\n", "Let's look at each of these components in more depth." @@ -207,7 +207,7 @@ "A common workflow (demonstrated in Section 3.3) is to use one of these algorithms as the method inside a minimizer like scipy's ```minimize``` function. This takes as its arguments:\n", "* Some function to be minimized. This is often the energy expectation value. But these are generally referred to as \"cost functions\".\n", "* A set of parameters from which to begin the search. Often called $x_0$ or $\\theta_0$.\n", - "* Arguments, including arguments of the cost function. In quantum computing with Qiskit, these arguments will include the ansatz, the Hamiltonian, and the estimator, which is discussed more in the next subsection.\n", + "* Arguments, including arguments of the cost function. In quantum computing with Qiskit, these arguments will include the ansatz, the Hamiltonian, and the Estimator primitive, which is discussed more in the next subsection.\n", "* A 'method' of minimization. This refers to the specific algorithm used to search the parameter space. This is where we would specify, for example, COBYLA or SLSQP.\n", "* Options. The options available may differ by method. But an example which practically all methods would include is the maximum number of iterations of the optimizer before ending the search: 'maxiter'.\n", "\n", @@ -351,7 +351,7 @@ "\n", "So we decompose our matrix $H$ into a sum of Paulis acting on different qubits. Some elements of that sum can be measured all at once; we call this a *group of commuting Paulis*. Depending on how many non-commuting terms there are, we may need many such groups. Call the number of such groups of commuting Pauli strings $N_\\text{GCP}$. If $N_\\text{GCP}$ is small, this could work well. If $H$ has millions of groups, this will not be useful.\n", "\n", - "The processes required for estimation of the expectation value are collected together in the Qiskit Runtime primitive called Estimator. To learn more about Estimator, see the [API reference](/docs/api/qiskit-ibm-runtime/estimator-v2) in IBM Quantum® Documentation. One can simply use Estimator directly, but Estimator returns much more than just the lowest energy eigenvalue. For example, it also returns information on ensemble standard error. Thus, in the context of minimization problems, one often sees Estimator inside a cost function. To learn more about Estimator inputs and outputs see this [guide](/docs/guides/primitive-input-output) on IBM Quantum Documentation.\n", + "The processes required for estimation of the expectation value are collected together in the Qiskit Runtime primitive called Estimator. To learn more about Estimator, see the [API reference](/docs/api/qiskit-ibm-runtime/estimator-v2) in IBM Quantum® Documentation. One can simply use Estimator directly, but Estimator returns much more than just the lowest energy eigenvalue. For example, it also returns information on ensemble standard error. Thus, in the context of minimization problems, one often sees Estimator inside a cost function. To learn more about Estimator inputs and outputs see this [guide](/docs/guides/pubs-broadcasting#pubs) on IBM Quantum Documentation.\n", "\n", "You record the expectation value (or the cost function) for the set of parameters $\\vec{\\theta_i}$ used in your state, and then you update the parameters. Over time, you could use the expectation values or cost-function values you’ve estimated to approximate a gradient of your cost function in the subspace of states sampled by your ansatz. Both gradient-based, and gradient-free classical optimizers exist. Both suffer from potential trainability issues, like multiple local minima, and large regions of parameter space with near-zero gradient, called *barren plateaus*.\n", "\n", @@ -636,18 +636,18 @@ "\n", "#### 3.3.1 Reporting out values\n", "\n", - "We define a cost function here that takes as arguments the structures we have built in previous steps: the parameters, the ansatz, and the Hamiltonian. It also uses the estimator which we have not yet defined. We include code to track the history of our cost function, so that we can check convergence behavior." + "We define a cost function here that takes as arguments the structures we have built in previous steps: the parameters, the ansatz, and the Hamiltonian. It also uses Estimator, which we have not yet defined. We include code to track the history of our cost function, so that we can check convergence behavior." ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "bb1d8999-77aa-4c1a-adae-8974eda9e63b", "metadata": {}, "outputs": [], "source": [ "def cost_func(params, ansatz, hamiltonian, estimator):\n", - " \"\"\"Return estimate of energy from estimator\n", + " \"\"\"Return estimate of energy from Estimator\n", "\n", " Parameters:\n", " params (ndarray): Array of ansatz parameters\n", @@ -948,7 +948,7 @@ "\n", "* Heuristic nature: VQE does not guarantee convergence to the correct ground state energy, as its performance depends on the choice of ansatz and optimization methods[\\[1-2\\]](#references). If a poor ansatz is chosen that lacks the requisite entanglement for the desired ground state, no classical optimizer can reach that ground state.\n", "* Potentially numerous parameters: A very expressive ansatz may have so many parameters that the minimization iterations are very time-consuming.\n", - "* High measurement overhead: In VQE, an estimator is used to estimate the expectation value of each term in the Hamiltonian. Most Hamiltonians of interest will have terms that cannot be simultaneously estimated. This can make VQE resource-intensive for large systems with complicated Hamiltonians[\\[1\\]](#references).\n", + "* High measurement overhead: In VQE, Estimator is used to estimate the expectation value of each term in the Hamiltonian. Most Hamiltonians of interest will have terms that cannot be simultaneously estimated. This can make VQE resource-intensive for large systems with complicated Hamiltonians[\\[1\\]](#references).\n", "* Effects of noise: When the classical optimizer is searching for a minimum, noisy calculations can confuse it and steer it away from the true minimum or delay its convergence. One possible solution for this is leveraging state-of-the-art error mitigation and error suppression techniques[\\[2-3\\]](#references) from IBM.\n", "* Barren plateaus: These regions of vanishing gradients[\\[2-3\\]](#references) exist even in the absence of noise, but noise makes them more troublesome since the change in expectation values due to noise could be larger than the change from updating parameters in these barren regions.\n", "\n", diff --git a/learning/courses/utility-scale-quantum-computing/variational-quantum-algorithms.ipynb b/learning/courses/utility-scale-quantum-computing/variational-quantum-algorithms.ipynb index 8cfcf3c57b6..f99e6becff3 100644 --- a/learning/courses/utility-scale-quantum-computing/variational-quantum-algorithms.ipynb +++ b/learning/courses/utility-scale-quantum-computing/variational-quantum-algorithms.ipynb @@ -1528,7 +1528,7 @@ "metadata": {}, "source": [ "#### Define backend and execution primitive\n", - "Use the **Qiskit Runtime primitives** to interact with IBM® backends. The two primitives are Sampler and Estimator, and the choice of primitive depends on what type of measurement you want to run on the quantum computer. For the minimization of $H_C$, use the Estimator since the measurement of the cost function is simply the expectation value of $\\langle H_C \\rangle$." + "Use the **Qiskit Runtime primitives** to interact with IBM® backends. The two primitives are Sampler and Estimator, and the choice of primitive depends on what type of measurement you want to run on the quantum computer. For the minimization of $H_C$, use Estimator since the measurement of the cost function is simply the expectation value of $\\langle H_C \\rangle$." ] }, { diff --git a/learning/modules/quantum-mechanics/exploring-uncertainty-with-qiskit.ipynb b/learning/modules/quantum-mechanics/exploring-uncertainty-with-qiskit.ipynb index f75ccc52593..8327b0bd1d8 100644 --- a/learning/modules/quantum-mechanics/exploring-uncertainty-with-qiskit.ipynb +++ b/learning/modules/quantum-mechanics/exploring-uncertainty-with-qiskit.ipynb @@ -267,7 +267,7 @@ "source": [ "### Step 3: Execute using Qiskit Runtime primitives\n", "\n", - "We can use sampler to collect statistics on the measurements. We will construct the Sampler primitive to run on a real quantum computer using ```mode = backend```. There are other modes for other workflows, and we will use one below. Sampler will be used by calling its run() method with a list of \"pubs\" (Primitive Unified Blocs). Each pub contains up to three values that, together, define a computation unit of work for the estimator to complete: circuits, observables, parameters. You can also provide a list of circuits, a list of observables, and a list of parameters. For more information, read the [Overview of PUBs.](/docs/guides/primitive-input-output#overview-of-pubs)\n", + "We can use sampler to collect statistics on the measurements. We will construct the Sampler primitive to run on a real quantum computer using ```mode = backend```. There are other modes for other workflows, and we will use one below. Sampler will be used by calling its run() method with a list of \"pubs\" (Primitive Unified Blocs). Each pub contains up to three values that, together, define a computation unit of work for the estimator to complete: circuits, observables, parameters. You can also provide a list of circuits, a list of observables, and a list of parameters. For more information, read the [Overview of PUBs.](/docs/guides/pubs-broadcasting#pubs)\n", "\n", "We want to run on a real quantum computer, so that we are carrying out a real quantum physics experiment. If you exhaust your allotted time on real quantum computers, you can comment out the code below for the quantum computer, and uncomment the code for running on a simulator." ] diff --git a/public/docs/images/guides/hello-world/extracted-outputs/87143fcc-0.avif b/public/docs/images/guides/hello-world/extracted-outputs/87143fcc-0.avif new file mode 100644 index 00000000000..fd83d254a4f Binary files /dev/null and b/public/docs/images/guides/hello-world/extracted-outputs/87143fcc-0.avif differ diff --git a/public/docs/images/guides/hello-world/extracted-outputs/930ca3b6-0.avif b/public/docs/images/guides/hello-world/extracted-outputs/930ca3b6-0.avif new file mode 100644 index 00000000000..6141b79cf04 Binary files /dev/null and b/public/docs/images/guides/hello-world/extracted-outputs/930ca3b6-0.avif differ diff --git a/public/docs/images/guides/hello-world/extracted-outputs/930ca3b6-0.svg b/public/docs/images/guides/hello-world/extracted-outputs/930ca3b6-0.svg deleted file mode 100644 index 01f34e0d6f0..00000000000 --- a/public/docs/images/guides/hello-world/extracted-outputs/930ca3b6-0.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/docs/images/guides/hello-world/extracted-outputs/9a901271-0.svg b/public/docs/images/guides/hello-world/extracted-outputs/9a901271-0.svg deleted file mode 100644 index ec3c0d3cce5..00000000000 --- a/public/docs/images/guides/hello-world/extracted-outputs/9a901271-0.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/docs/images/guides/hello-world/extracted-outputs/9a901271-1.avif b/public/docs/images/guides/hello-world/extracted-outputs/9a901271-1.avif new file mode 100644 index 00000000000..aed6814c479 Binary files /dev/null and b/public/docs/images/guides/hello-world/extracted-outputs/9a901271-1.avif differ diff --git a/public/docs/images/guides/hello-world/extracted-outputs/de91ebd0-0.avif b/public/docs/images/guides/hello-world/extracted-outputs/de91ebd0-0.avif new file mode 100644 index 00000000000..c8a3c02eaba Binary files /dev/null and b/public/docs/images/guides/hello-world/extracted-outputs/de91ebd0-0.avif differ diff --git a/public/docs/images/guides/primitive-input-output/broadcasting.svg b/public/docs/images/guides/primitive-input-output/broadcasting.svg deleted file mode 100644 index 533bb0ab40b..00000000000 --- a/public/docs/images/guides/primitive-input-output/broadcasting.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/docs/images/guides/pubs-broadcasting/broadcasting.avif b/public/docs/images/guides/pubs-broadcasting/broadcasting.avif new file mode 100644 index 00000000000..e1f059942c0 Binary files /dev/null and b/public/docs/images/guides/pubs-broadcasting/broadcasting.avif differ diff --git a/qiskit_bot.yaml b/qiskit_bot.yaml index 4e75e4ab0f9..696db6ee8b0 100644 --- a/qiskit_bot.yaml +++ b/qiskit_bot.yaml @@ -138,6 +138,14 @@ notifications: - "@jyu00" - "`@beckykd`" + "docs/guides/executor-options": + - "abbycross" + - "@jyu00" + - "@beckykd" + "docs/guides/get-started-with-executor": + - "abbycross" + - "@jyu00" + - "@beckykd" "docs/guides/fair-share-scheduler": - "`@lerongil`" - "@jyu00" @@ -146,34 +154,79 @@ notifications: - "@kaelynj" "docs/guides/measure-qubits": - "`@beckykd`" - "docs/guides/get-started-with-primitives": - - "@ElePT" - - "@jyu00" - "docs/guides/ha-dr": + "docs/guides/get-qpu-information": + - "@frankharkins" - "`@abbycross`" + - "`@mtreinish`" + "docs/guides/estimator-examples": + - "@abbycross" - "`@beckykd`" + - "@jyu00" + "docs/guides/estimator-input-output": + - "@abbycross" + - "@beckykd" + - "@jyu00" + "docs/guides/estimator-options": + - "@abbycross" + - "@beckykd" + - "@jyu00" + "docs/guides/executor-examples": + - "@abbycross" + - "@beckykd" + - "@jyu00" + "docs/guides/executor-input-output": + - "@abbycross" + - "@beckykd" + - "@jyu00" + "docs/guides/get-started-with-sampler": + - "@abbycross" + - "@beckykd" + - "@jyu00" + "docs/guides/pubs-broadcasting": + - "@abbycross" + - "@beckykd" + - "@jyu00" + "docs/guides/sampler-examples": + - "@abbycross" + - "@beckykd" + - "@jyu00" + "docs/guides/sampler-input-output": + - "@abbycross" + - "@beckykd" + - "@jyu00" + "docs/guides/sampler-options": + - "@abbycross" + - "@beckykd" + - "@jyu00" + "docs/guides/get-started-with-estimator": + - "@abbycross" + - "@beckykd" + - "@jyu00" + "docs/guides/ha-dr": + - "@abbycross" + - "@beckykd" "docs/guides/observability": - "`@abbycross`" - "`@beckykd`" "docs/guides/responsibilities": - - "`@abbycross`" - - "`@beckykd`" + - "@abbycross" + - "@beckykd" "docs/guides/hello-world": - - "`@abbycross`" - - "`@beckykd`" + - "@abbycross" + - "@beckykd" "docs/guides/allocation-limits": - "`@abbycross`" - "`@beckykd`" "docs/guides/qiskit-runtime-primitives": - - "`@abbycross`" - - "`@beckykd`" + - "@abbycross" + - "@beckykd" "docs/guides/install-c-api": - - "`@abbycross`" - - "`@beckykd`" + - "@abbycross" + - "@beckykd" - "@cryoris" "docs/guides/install-qiskit": - - "`@abbycross`" - - "`@beckykd`" + - "@abbycross" + - "@beckykd" - "`@mtreinish`" "docs/guides/install-qiskit-source": - "`@mtreinish`" @@ -267,14 +320,9 @@ notifications: - "@ElePT" - "`@beckykd`" - "`@abbycross`" - "docs/guides/primitives-examples": - - "@jyu00" - - "`@beckykd`" - - "`@abbycross`" - - "`@blakejohnson`" "docs/guides/processor-types": - "`@lerongil`" - - "`@abbycross`" + - "@abbycross" "docs/guides/qiskit-code-assistant": - "cbjuan" - "`@abbycross`" @@ -342,8 +390,6 @@ notifications: - "`@kevinsung`" "docs/guides/specify-observables-pauli": - "@Cryoris" - "docs/guides/specify-runtime-options": - - "`@beckykd`" "docs/guides/synthesize-unitary-operators": - "@Cryoris" "docs/guides/qpu-information": @@ -404,10 +450,26 @@ notifications: "docs/guides/v2-primitives": - "@jyu00" - "@ElePT" - - "`@beckykd`" - "docs/guides/primitive-input-output": + - "@beckykd" + "docs/guides/executor-broadcasting": + - "@born-2learn" + - "@HuangJunye" + - "@pacomf" + - "@Bagherpoor" + - "@kaelynj" + "docs/guides/estimator-broadcasting": + - "@born-2learn" + - "@HuangJunye" + - "@pacomf" + - "@Bagherpoor" + - "@kaelynj" + "docs/guides/sampler-rest-api": + - "@born-2learn" + - "@HuangJunye" + - "@pacomf" + - "@Bagherpoor" - "@kaelynj" - "docs/guides/primitives-rest-api": + "docs/guides/estimator-rest-api": - "@born-2learn" - "@HuangJunye" - "@pacomf" diff --git a/scripts/config/allowLists.ts b/scripts/config/allowLists.ts index c2f873b4eaf..d8adabf0ecf 100644 --- a/scripts/config/allowLists.ts +++ b/scripts/config/allowLists.ts @@ -22,6 +22,26 @@ export function ignoreTitleMismatch(filepath: string): boolean { } const IGNORE_TITLE_MISMATCHES: string[] = [ + "docs/guides/directed-execution-model.mdx", + "docs/guides/estimator-examples.ipynb", + "docs/guides/estimator-input-output.ipynb", + "docs/guides/estimator-options.ipynb", + "docs/guides/estimator-rest-api.ipynb", + "docs/guides/executor-examples.mdx", + "docs/guides/executor-options.mdx", + "docs/guides/executor-input-output.mdx", + "docs/guides/executor-broadcasting.mdx", + "docs/guides/estimator-broadcasting.mdx", + "docs/guides/broadcasting.mdx", + "docs/guides/executor-rest-api.mdx", + "docs/guides/get-started-with-sampler.ipynb", + "docs/guides/pubs.ipynb", + "docs/guides/sampler-examples.ipynb", + "docs/guides/sampler-rest-api.mdx", + "docs/guides/sampler-input-output.ipynb", + "docs/guides/sampler-options.ipynb", + "docs/guides/get-started-with-estimator.ipynb", + "docs/guides/get-started-with-executor.mdx", "docs/guides/external-providers-primitives-v2.mdx", "docs/guides/create-a-provider.mdx", "docs/guides/local-simulators.mdx", diff --git a/scripts/config/notebook-testing.toml b/scripts/config/notebook-testing.toml index a4b3dd8696c..3f008f472c4 100644 --- a/scripts/config/notebook-testing.toml +++ b/scripts/config/notebook-testing.toml @@ -36,6 +36,16 @@ notebooks = [ "docs/guides/operator-class.ipynb", "docs/guides/operators-overview.ipynb", "docs/guides/plot-quantum-states.ipynb", + "docs/guides/estimator-rest-api.ipynb", + "docs/guides/sampler-rest-api.ipynb", + "docs/guides/get-started-with-sampler.ipynb", + "docs/guides/sampler-input-output.ipynb", + "docs/guides/sampler-options.ipynb", + "docs/guides/estimator-examples.ipynb", + "docs/guides/sampler-examples.ipynb", + "docs/guides/estimator-input-output.ipynb", + "docs/guides/estimator-options.ipynb", + "docs/guides/get-started-with-estimator.ipynb", "docs/guides/quick-start.ipynb", "docs/guides/repetition-rate-execution.ipynb", "docs/guides/represent-quantum-computers.ipynb", @@ -60,7 +70,6 @@ test-strategies.ci = { patch = "qiskit-fake-provider", num_qubits = 6 } test-strategies.extended = { patch = "qiskit-fake-provider", num_qubits = 6 } test-strategies.hardware = { patch = "qiskit-ibm-runtime-open" } notebooks = [ - "docs/guides/specify-runtime-options.ipynb", "docs/guides/visualize-results.ipynb", ] @@ -97,10 +106,7 @@ notebooks = [ [groups.cron-job-only] test-strategies.hardware = { patch = "qiskit-ibm-runtime-open" } notebooks = [ - "docs/guides/primitives-rest-api.ipynb", "docs/guides/hello-world.ipynb", - # The following notebook takes >300s to run and should be executed in the - # cron job. Even though it does not use real hardware # The following notebooks don't seem to work with `test-eagle`, but I'm not # sure why. I've added them here to run on the next cron job so we can