From f0a29e58648a523b6c1a8b0304174499e2c72501 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Mon, 25 Mar 2024 17:26:19 -0500 Subject: [PATCH 01/65] sampler supports twirling --- docs/api/migration-guides/v2-primitives.mdx | 3 +++ docs/run/configure-error-mitigation.mdx | 14 +++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/api/migration-guides/v2-primitives.mdx b/docs/api/migration-guides/v2-primitives.mdx index a7ecc6db6c9..b9dd9198522 100644 --- a/docs/api/migration-guides/v2-primitives.mdx +++ b/docs/api/migration-guides/v2-primitives.mdx @@ -309,6 +309,9 @@ sampler = Sampler(backend, options={"default_shots": 4096}) # Setting options after primitive initialization # This uses auto complete. sampler.options.dynamical_decoupling.enable = True +# Turn on gate twirling. Requires qiskit_ibm_runtime 0.23.0 or later. +options.twirling.enable_gates = True + # This does bulk update. The value for default_shots is overridden if you specify shots with run() or in the PUB. sampler.options.update(default_shots=1024, dynamical_decoupling={"sequence_type": "XpXm"}) diff --git a/docs/run/configure-error-mitigation.mdx b/docs/run/configure-error-mitigation.mdx index c48d67c014d..8d04d98addb 100644 --- a/docs/run/configure-error-mitigation.mdx +++ b/docs/run/configure-error-mitigation.mdx @@ -378,13 +378,13 @@ sampler = Sampler(backend, options=options) ``` -## Custom error settings +## Custom error settings (V2 primitives) -With Estimator V2, you can turn on and off individual error mitigation and suppression methods, including dynamical decoupling, gate and measurement twirling, measurement error mitigation, and ZNE. +With the V2 primitives, you can turn on and off individual error mitigation and suppression methods, including dynamical decoupling, gate and measurement twirling, measurement error mitigation, and ZNE. - -## Custom error settings (V2 primitives) -With the V2 primitives, you can turn on and off individual error mitigation and suppression methods. See the [API reference](/api/qiskit-ibm-runtime/options) for the list of available options. + +Not all options are available for both primitives. See the [API reference](/api/qiskit-ibm-runtime/options) for the list of available options. + @@ -415,8 +415,12 @@ from qiskit_ibm_runtime import SamplerV2 as Sampler, Options options = sampler.options options.dynamical_decoupling.enable = True +# Turn on gate twirling. Requires qiskit_ibm_runtime 0.23.0 or later. +options.twirling.enable_gates = True print(f">>> dynamical decoupling is turned on: {sampler.options.dynamical_decoupling.enable}") +print(f">>> gate twirling is turned on: {sampler.options.twirling.enable_gates}") + ``` From 3df2e39ffb6ec306ba41d9340e6e6141f3fdca68 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Mon, 25 Mar 2024 17:29:50 -0500 Subject: [PATCH 02/65] fix link --- docs/run/configure-error-mitigation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/run/configure-error-mitigation.mdx b/docs/run/configure-error-mitigation.mdx index 8d04d98addb..90e50d9a0df 100644 --- a/docs/run/configure-error-mitigation.mdx +++ b/docs/run/configure-error-mitigation.mdx @@ -15,7 +15,7 @@ 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. See the [Custom error settings](#advanced-options) section for details. +Sampler V2 does not support specifying resilience levels. However, you can turn on or off individual error mitigation / suppression methods. See the [Custom error settings](#advanced-error) section for details. The resilience level specifies how much resilience to build against errors. Higher levels generate more accurate results, at the expense of From 461bcc484cfb0a1bf1e1e3cc7f8017844abb9777 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Mon, 25 Mar 2024 17:31:30 -0500 Subject: [PATCH 03/65] link --- docs/run/configure-error-mitigation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/run/configure-error-mitigation.mdx b/docs/run/configure-error-mitigation.mdx index 90e50d9a0df..8f1509aa0aa 100644 --- a/docs/run/configure-error-mitigation.mdx +++ b/docs/run/configure-error-mitigation.mdx @@ -100,7 +100,7 @@ applied at each resilience level. ## Configure Estimator V2 with resilience levels -You can use resilience levels to specify error mitigation techniques, or you can set custom techniques individually as described in [Custom error settings with Estimator V2.](#advanced-options) You cannot specify resilience levels in Sampler V2. However, you can set custom techniques individually. +You can use resilience levels to specify error mitigation techniques, or you can set custom techniques individually as described in [Custom error settings with Estimator V2.](#advanced-error) You cannot specify resilience levels in Sampler V2. However, you can set custom techniques individually.
Resilience Level 0 From c44fd625cc760a5cdbed70405a59c5afec7eca34 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Tue, 26 Mar 2024 15:50:33 -0500 Subject: [PATCH 04/65] Updates round 1 --- docs/api/migration-guides/_toc.json | 10 +- .../migration-guides/qiskit-runtime-setup.mdx | 301 +++++++++++++++++ docs/api/migration-guides/qiskit-runtime.mdx | 307 +----------------- docs/api/migration-guides/v2-primitives.mdx | 2 +- 4 files changed, 321 insertions(+), 299 deletions(-) create mode 100644 docs/api/migration-guides/qiskit-runtime-setup.mdx diff --git a/docs/api/migration-guides/_toc.json b/docs/api/migration-guides/_toc.json index e934cf53ca6..9ce6eadf512 100644 --- a/docs/api/migration-guides/_toc.json +++ b/docs/api/migration-guides/_toc.json @@ -35,16 +35,16 @@ "title": "Migrate to Qiskit Runtime", "children": [ { - "title": "How to migrate", + "title": "Migrate from backend.run to primitives", "url": "/api/migration-guides/qiskit-runtime" }, { - "title": "Examples", - "url": "/api/migration-guides/qiskit-runtime-examples" + "title": "Migrate setup", + "url": "/api/migration-guides/qiskit-runtime-setup" }, { - "title": "qiskit_ibm_provider to qiskit_ibm_runtime", - "url": "/api/migration-guides/qiskit-runtime-from-provider" + "title": "Examples", + "url": "/api/migration-guides/qiskit-runtime-examples" } ] }, diff --git a/docs/api/migration-guides/qiskit-runtime-setup.mdx b/docs/api/migration-guides/qiskit-runtime-setup.mdx new file mode 100644 index 00000000000..f717f67fdda --- /dev/null +++ b/docs/api/migration-guides/qiskit-runtime-setup.mdx @@ -0,0 +1,301 @@ +--- +title: Migrate setup to qiskit-ibm-runtime +description: Migrate setup from using backend.run to using Qiskit Runtime primitives + + +in_page_toc_max_heading_level: 2 +--- + +# Migrate setup to qiskit-ibm-runtime + +This guide describes how to migrate code from the legacy IBMQ provider +`qiskit-ibmq-provider` package to use Qiskit Runtime +`qiskit-ibm-runtime`. + +## Changes in Class name and location + +The classes related to Qiskit Runtime that used to be included in +`qiskit-ibmq-provider` are now part of `qiskit-ibm-runtime`. Before, the +provider used to populate the `qiskit.providers.ibmq.runtime` namespace +with objects for Qiskit Runtime. These now live in the +`qiskit_ibm_runtime` module. + +The module from which the classes are imported has changed. The +following table contains example access patterns in +`qiskit.providers.ibmq.runtime` and their new form in +`qiskit_ibm_runtime`: + +| class in qiskit-ibmq-provider | class in qiskit-ibm-runtime | Notes | +|--------------------------------------------------|-------------------------------------------|----------------------------------------------------------------------------------------------------------------------| +| qiskit.providers.ibmq.runtime.IBMRuntimeService | qiskit_ibm_runtime.QiskitRuntimeService | IBMRuntimeService class was removed from qiskit-ibm-runtime 0.6 and replaced by the new class in qiskit-ibm-runtime. | +| qiskit.providers.ibmq.runtime.RuntimeJob | qiskit_ibm_runtime.RuntimeJob | +| qiskit.providers.ibmq.runtime.RuntimeProgram | | This class was used for custom programs, which are no longer supported. +| qiskit.providers.ibmq.runtime.UserMessenger | | This class was used for custom programs, which are no longer supported. | +| qiskit.providers.ibmq.runtime.ProgramBackend | | This class was used for custom programs, which are no longer supported. | +| qiskit.providers.ibmq.runtime.ResultDecoder | | This class was used for custom programs, which are no longer supported. | +| qiskit.providers.ibmq.runtime.RuntimeEncoder | qiskit_ibm_runtime.RuntimeEncoder | +| qiskit.providers.ibmq.runtime.RuntimeDecoder | qiskit_ibm_runtime.RuntimeDecoder | +| qiskit.providers.ibmq.runtime.ParameterNamespace | | This class was used for custom programs, which are no longer supported. +| qiskit.providers.ibmq.runtime.RuntimeOptions | qiskit_ibm_runtime.RuntimeOptions | + + +## Import path + +The import path has changed as follows: + + + +``` python +from qiskit_ibm_runtime import QiskitRuntimeService +``` + + + +``` python +from qiskit import IBMQ +``` + + + +## Save accounts + +Use the updated code to work save accounts. + + + +The new syntax accepts credentials for +Qiskit Runtime on IBM Cloud or IBM Quantum Platform. For more +information on retrieving account credentials, see [Install and set up](../../start/install). + +``` python +# IBM Cloud channel + +QiskitRuntimeService.save_account(channel="ibm_cloud", token="", instance="", overwrite=True) + +# IBM Quantum channel; set to default + +QiskitRuntimeService.save_account(channel="ibm_quantum", token="", overwrite=True, default=true) +``` + +Additionally, you can now name your saved credentials and load the credentials by name. + + +``` python +# Save different accounts for open and premium access + +QiskitRuntimeService.save_account(channel="ibm_quantum", token="", instance="h1/g1/p1", name="premium") +QiskitRuntimeService.save_account(channel="ibm_quantum", token="", instance="h2/g2/p2", name="open") + +# Load the "open" credentials + +service = QiskitRuntimeService(name="open") +``` + + + +``` python +IBMQ.save_account("", overwrite=True) +``` + + + + +## Load accounts + +Use the updated code to load accounts. + + + +The new syntax combines the functionality from `load_account()` and +`get_provider()` in one statement. The `channel` input parameter is +optional. If multiple accounts have been saved in one device and no +`channel` is provided, the default is `"ibm_cloud"`. + +``` python +# To access saved credentials for the IBM cloud channel +service = QiskitRuntimeService(channel="ibm_cloud") + +# To access saved credentials for the IBM quantum channel +service = QiskitRuntimeService(channel="ibm_quantum") +``` + + + +``` python +IBMQ.load_account() +``` + + + + +## Channel selection (get a provider) + +Use the updated code to select a channel. + + + +The new syntax combines the functionality from `load_account()` and +`get_provider()` in one statement. When using the `ibm_quantum` channel, +the `hub`, `group`, and `project` are specified through the new +`instance` keyword. + +``` python +# To access saved credentials for the IBM quantum channel and select an instance +service = QiskitRuntimeService(channel="ibm_quantum", instance="my_hub/my_group/my_project") +``` + + + +``` python +provider = IBMQ.get_provider(project="my_project", group="my_group", hub="my_hub") +``` + + + +## Get the system + +Use the updated code to view systems and simulators. + + + +``` python +# You can specify the instance in service.backend() instead of initializing a new service +backend = service.backend("ibm_backend", instance="h1/g1/p1") +``` +If you don't know what backend you want to use, you can instead use code such as the following: + +```python +from qiskit_ibm_runtime import QiskitRuntimeService + +service = QiskitRuntimeService() +backend = service.least_busy(operational=True, simulator=False, min_num_qubits=num_qubits) +``` + + + +``` python +provider = IBMQ.get_provider(hub="h1", group="g1", project="p1") +backend = provider.get_backend("ibm_backend") +``` + + + +## Upload, view, or delete custom prototype programs + +This function has been replaced with Quantum Serverless patterns. For instructions to migrate, see [Converting from Qiskit Runtime Programs.](https://qiskit-extensions.github.io/quantum-serverless/migration/migration_from_qiskit_runtime_programs.html) + + +# Parametrized circuits with primitives + +Parametrized circuits are a commonly used tool for quantum algorithm +design. Because `backend.run()` did not accept parametrized +circuits, the parameter binding step had to be integrated in the +algorithm workflow. The primitives can perform the parameter binding +step internally, which results in a simplification of the algorithm-side +logic. + +The following example summarizes the new workflow for managing +parametrized circuits. + +## Example + +Define a parametrized circuit: + +``` python +from qiskit.circuit import QuantumCircuit, ParameterVector + +n = 3 +thetas = ParameterVector('θ',n) + +qc = QuantumCircuit(n, 1) +qc.h(0) + +for i in range(n-1): + qc.cx(i, i+1) + +for i,t in enumerate(thetas): + qc.rz(t, i) + +for i in reversed(range(n-1)): + qc.cx(i, i+1) + +qc.h(0) +qc.measure(0, 0) + +qc.draw() +``` + +V2 primitives support only circuits that adhere to the Instruction Set Architecture (ISA) of a particular backend, so we must transform our circuits. + +```python +from qiskit_ibm_runtime import QiskitRuntimeService +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager + +service = QiskitRuntimeService() +backend = service.least_busy(operational=True, simulator=False) + +pm = generate_preset_pass_manager(backend=backend, optimization_level=1) +isa_circuit = pm.run(qc) +``` + +We want to assign the following parameter values to the circuit: + +``` python +import numpy as np +theta_values = [np.pi/2, np.pi/2, np.pi/2] +``` + + + +The primitives take in parametrized circuits directly, together +with the parameter values, and the parameter assignment operation can be +performed more efficiently on the server side of the primitive. The input is in the form of primitive unified blocs (PUBs). Each PUB is a tuple that contains a circuit and the data broadcasted to it. For further details, see [Introduction to primitives.](../../run/primitives#interface-changes) + +This feature is particularly interesting when working with iterative +algorithms because the parametrized circuit remains unchanged between +calls while the parameter values change. The primitives can transpile +once and then cache the unbound circuit, using classical resources more +efficiently. Moreover, only the updated parameters are transferred to +the cloud, saving additional bandwidth. + + +As shown in the previous image, the classical register name is `c`. Alternatively, you can find the classical register name by running `.cregs`. For example: `qc.cregs`. + + +``` python +from qiskit_ibm_runtime import SamplerV2 as Sampler + +sampler = Sampler(backend) +job = sampler.run([(isa_circuit, theta_values)]) +result = job.result() +# Get results for the first (and only) PUB +pub_result = result[0] +# Get counts from the classical register "c". +print(f" >> Counts for the c output register: {pub_result.data.c.get_counts()}") +``` + + + +The parameter values had to be bound to their respective +circuit parameters prior to calling `backend.run()`. + +``` python +from qiskit import Aer + +bound_circuit = qc.bind_parameters(theta_values) +bound_circuit.draw() + +backend = Aer.get_backend('aer_simulator') +job = backend.run(bound_circuit) +counts = job.result().get_counts() +print(counts) +``` + + + +# Algorithm tuning + +One of the advantages of the primitives is that they abstract away the +circuit execution setup so that algorithm developers can focus on the +pure algorithmic components. However, sometimes, to get the most out of +an algorithm, you might want to tune certain primitive options. For details, see [Advanced runtime options](../../run/advanced-runtime-options). diff --git a/docs/api/migration-guides/qiskit-runtime.mdx b/docs/api/migration-guides/qiskit-runtime.mdx index 6e8b49274d4..6e074905d80 100644 --- a/docs/api/migration-guides/qiskit-runtime.mdx +++ b/docs/api/migration-guides/qiskit-runtime.mdx @@ -10,31 +10,20 @@ in_page_toc_max_heading_level: 2 # Migrate to using Qiskit Runtime primitives This guide describes key patterns of behavior and use cases with code -examples to help you migrate code from the legacy `qiskit-ibmq-provider` -package to use the Qiskit Runtime primitives. +examples to help you migrate code from the legacy `backend.run()` interface (`qiskit-ibmq-provider` package) to use the Qiskit Runtime primitives interface (`qiskit-ibm-runtime` package). -## Overview - -There are two methods for accessing IBM Quantum™ systems. First, the `qiskit-ibm-provider` package provides the `backend.run()` interface, allowing direct access to IBM Quantum systems with no pre- or post-processing involved. This level of access is suitable for those users who want **precise control** over circuit execution and result processing. This level of access is needed for those at the level of kernel developer who are looking to develop, for example, circuit optimization routines or error mitigation techniques, or who want to characterize quantum systems. + +Because both `backend.run()` and the "version 1" primitives are being deprecated, this guide uses only the V2 primitives. + -In contrast, Qiskit Runtime is designed to **streamline algorithm and application construction** by removing the need for users to understand technical hardware and low-level software details. Advanced processing techniques for error suppression and mitigation are automatically applied, giving users high-fidelity results without the burden of having to code these routines themselves. Sessions within Qiskit Runtime allow users to run iterative algorithm circuits back to back, or batch collections of circuits without having to re-queue each job. This results in more efficient quantum processor use and reduces the time users spend running complex computations. +## Overview -backend.run is required for running dynamic circuits. +The `qiskit-ibm-runtime` package provides cloud access to the IBM Quantum™ systems through the primitives interface, which supersedes (and fully replaces) the former hardware interface, `backend.run()`. The `backend.run()` interface coexisted with the original (V1) primitives model as the dedicated “direct hardware access” entry point. With the introduction of the V2 primitives interface, the new `SamplerV2` class now fulfills that role. Consequentially, `qiskit-ibmq-provider`, the package that exposed the `backend.run()` interface, has been deprecated. -Primitives are the recommended tool to write quantum algorithms, as they -encapsulate common device queries seen in application packages and allow -for managed performance through the Qiskit Runtime service. However, if -your algorithm requires more granular information, such as pre-shot -measurements, the primitives might not provide the desired abstraction -level. +The Qiskit Runtime primitives implement the reference Sampler V2 and Estimator V2 interfaces found in `qiskit.primitives`, and enable capabilities not available with the legacy `backend.run()` interface. These capabilities include application of advanced processing techniques for error suppression and mitigation in Estimator, the ability to efficiently sweep between arrays of parameter value sets or observables in both Sampler and Estimator, and access to the new local testing mode. Additionally, Qiskit Runtime lets users run iterative algorithm circuits back to back (session mode) or in collections of circuits without having to re-queue each job (batch mode). This results in more efficient quantum processor use and reduces the time spent running complex computations. -The Qiskit Runtime primitives implement the reference `Sampler` and -`Estimator` interfaces found in -[qiskit.primitives](../qiskit/primitives). -These interfaces let you switch between primitive implementations with -minimal code changes. Different primitive implementations can be found -in the `qiskit`, `qiskit_aer`, and `qiskit_ibm_runtime` libraries. Each -implementation serves a specific purpose: + +Different packages expose different "flavors" of the primitive interfaces, for example: - The primitives in `qiskit` can perform local state vector simulations - useful for quickly prototyping algorithms. @@ -44,9 +33,8 @@ implementation serves a specific purpose: simulators and real hardware through the Qiskit Runtime service. They include exclusive features such as built-in circuit optimization and error mitigation support. - - - The **only primitives that provide access to the Qiskit Runtime service** are those imported from `qiskit_ibm_runtime` (Qiskit Runtime Primitives). + +The **only primitives that provide access to the Qiskit Runtime service** are those imported from `qiskit_ibm_runtime` (Qiskit Runtime Primitives). When migrating, the key to writing an equivalent algorithm using @@ -79,9 +67,7 @@ code to Qiskit Runtime:
How do the Qiskit Runtime primitives differ from backend.run? -There are two methods for accessing IBM Quantum systems. First, the qiskit-ibm-provider package provides the backend.run() interface, allowing direct access to IBM Quantum systems with no pre- or post-processing involved. This level of access is suitable for those users who want precise control over circuit execution and result processing. This level of access is needed for those looking to work at the level Kernel developer developing, for example, circuit optimization routines, error mitigation techniques, or characterizing quantum systems. - -In contrast, Qiskit Runtime is designed to streamline algorithm and application construction by removing the need for users to understand technical hardware and low-level software details. Advanced processing techniques for error suppression and mitigation are automatically applied, giving users high-fidelity results without the burden of having to code these routines themselves. The inclusion of sessions within Qiskit Runtime allows users to run iterative algorithm circuits back to back, or batch collections of circuits without having to re-queue each job. This results in more efficient quantum processor utilization and reduces the total amount of time users spend running complex computations. +Qiskit Runtime is designed to streamline algorithm and application construction by removing the need for users to understand technical hardware and low-level software details. Advanced processing techniques for error suppression and mitigation are automatically applied, giving users high-fidelity results without the burden of having to code these routines themselves. The inclusion of different execution modes within Qiskit Runtime allows users to run iterative algorithm circuits back to back (sessions), or batch collections of circuits without having to re-queue each job (batch mode). This results in more efficient quantum processor utilization and reduces the total amount of time users spend running complex computations.
@@ -95,9 +81,6 @@ Platform. Some information that might help you decide includes: - The available plans: - Qiskit Runtime is available in both the Open (free access) or Premium (contract-based paid access) plan on IBM Quantum Platform. See [IBM Quantum access plans](https://www.ibm.com/quantum/access-plans) for details. - Qiskit Runtime is accessible through the Lite (free access) or Standard (pay-as-you-go access) plan in IBM Cloud. See [Qiskit Runtime plans](https://cloud.ibm.com/docs/quantum-computing?topic=quantum-computing-plans) on IBM Cloud for details. -- The use case requirements: - - IBM Quantum Platform offers a visual circuit composer (Quantum Composer) and a Jupyter Notebook environment (Quantum Lab). - - IBM Cloud offers a cloud native service that is ideal if users need to integrate quantum capabilities with other cloud services.
@@ -109,14 +92,6 @@ can get set up on either platform by following the steps in [Install and set up. -
-Should I modify the Qiskit Terra algorithms? - -As of v0.22, [Qiskit Terra algorithms](https://github.com/Qiskit/qiskit/tree/stable/0.46/qiskit/algorithms) use Qiskit Runtime primitives. Thus, there is no need for users to -modify amplitude estimators or any other Qiskit Terra algorithms. - -
-
Which primitive should I use? @@ -139,265 +114,11 @@ when trying to discover the extremal energy of a system.
-## Migrate setup from qiskit-ibmq-provider - -This guide describes how to migrate code from the legacy IBMQ provider -`qiskit-ibmq-provider` package to use Qiskit Runtime -`qiskit-ibm-runtime`. This guide includes instructions to -migrate legacy runtime programs to the new syntax. However, the ability -to use custom uploaded programs has been deprecated and has been replaced with Quantum Serverless patterns. For instructions to migrate, see [Converting from Qiskit Runtime Programs.](https://qiskit-extensions.github.io/quantum-serverless/migration/migration_from_qiskit_runtime_programs.html) - -### Changes in Class name and location - -The classes related to Qiskit Runtime that used to be included in -`qiskit-ibmq-provider` are now part of `qiskit-ibm-runtime`. Before, the -provider used to populate the `qiskit.providers.ibmq.runtime` namespace -with objects for Qiskit Runtime. These now live in the -`qiskit_ibm_runtime` module. - -The module from which the classes are imported has changed. The -following table contains example access patterns in -`qiskit.providers.ibmq.runtime` and their new form in -`qiskit_ibm_runtime`: - -| class in qiskit-ibmq-provider | class in qiskit-ibm-runtime | Notes | -|--------------------------------------------------|-------------------------------------------|----------------------------------------------------------------------------------------------------------------------| -| qiskit.providers.ibmq.runtime.IBMRuntimeService | qiskit_ibm_runtime.QiskitRuntimeService | IBMRuntimeService class was removed from qiskit-ibm-runtime 0.6 and replaced by the new class in qiskit-ibm-runtime. | -| qiskit.providers.ibmq.runtime.RuntimeJob | qiskit_ibm_runtime.RuntimeJob | -| qiskit.providers.ibmq.runtime.RuntimeProgram | qiskit_ibm_runtime.RuntimeProgram | -| qiskit.providers.ibmq.runtime.UserMessenger | qiskit_ibm_runtime.program.UserMessenger | New location: qiskit_ibm_runtime.program | -| qiskit.providers.ibmq.runtime.ProgramBackend | qiskit_ibm_runtime.program.ProgramBackend | New location: qiskit_ibm_runtime.program | -| qiskit.providers.ibmq.runtime.ResultDecoder | qiskit_ibm_runtime.program.ResultDecoder | New location: qiskit_ibm_runtime.program | -| qiskit.providers.ibmq.runtime.RuntimeEncoder | qiskit_ibm_runtime.RuntimeEncoder | -| qiskit.providers.ibmq.runtime.RuntimeDecoder | qiskit_ibm_runtime.RuntimeDecoder | -| qiskit.providers.ibmq.runtime.ParameterNamespace | qiskit_ibm_runtime.ParameterNamespace | -| qiskit.providers.ibmq.runtime.RuntimeOptions | qiskit_ibm_runtime.RuntimeOptions | - - -### Import path - -The import path has changed as follows: - -**Legacy** - -``` python -from qiskit import IBMQ -``` - -**Updated** - -``` python -from qiskit_ibm_runtime import QiskitRuntimeService -``` - -### Save accounts - -Use the updated code to work save accounts. - -**Legacy** - -``` python -IBMQ.save_account("", overwrite=True) -``` - -**Updated** - -The new syntax accepts credentials for -Qiskit Runtime on IBM Cloud or IBM Quantum Platform. For more -information on retrieving account credentials, see [Install and set up](../../start/install). - -``` python -# IBM Cloud channel - -QiskitRuntimeService.save_account(channel="ibm_cloud", token="", instance="", overwrite=True) - -# IBM Quantum channel; set to default - -QiskitRuntimeService.save_account(channel="ibm_quantum", token="", overwrite=True, default=true) -``` - -Additionally, you can now name your saved credentials and load the credentials by name. - - -``` python -# Save different accounts for open and premium access - -QiskitRuntimeService.save_account(channel="ibm_quantum", token="", instance="h1/g1/p1", name="premium") -QiskitRuntimeService.save_account(channel="ibm_quantum", token="", instance="h2/g2/p2", name="open") - -# Load the "open" credentials - -service = QiskitRuntimeService(name="open") -``` - -### Load accounts - -Use the updated code to load accounts. - -**Legacy** - -``` python -IBMQ.load_account() -``` - -**Updated** - -The new syntax combines the functionality from `load_account()` and -`get_provider()` in one statement. The `channel` input parameter is -optional. If multiple accounts have been saved in one device and no -`channel` is provided, the default is `"ibm_cloud"`. - -``` python -# To access saved credentials for the IBM cloud channel -service = QiskitRuntimeService(channel="ibm_cloud") - -# To access saved credentials for the IBM quantum channel -service = QiskitRuntimeService(channel="ibm_quantum") -``` - - -### Channel selection (get a provider) - -Use the updated code to select a channel. - -**Legacy** - -``` python -provider = IBMQ.get_provider(project="my_project", group="my_group", hub="my_hub") -``` - -**Updated** - -The new syntax combines the functionality from `load_account()` and -`get_provider()` in one statement. When using the `ibm_quantum` channel, -the `hub`, `group`, and `project` are specified through the new -`instance` keyword. - -``` python -# To access saved credentials for the IBM quantum channel and select an instance -service = QiskitRuntimeService(channel="ibm_quantum", instance="my_hub/my_group/my_project") -``` - -### Get the system or simulator - -Use the updated code to view systems and simulators. - -**Legacy** - -``` python -provider = IBMQ.get_provider(hub="h1", group="g1", project="p1") -backend = provider.get_backend("ibm_backend") -``` - -**Updated** - -``` python -# You can specify the instance in service.backend() instead of initializing a new service -backend = service.backend("ibm_backend", instance="h1/g1/p1") -``` - -### Upload, view, or delete custom prototype programs - -This function has been replaced with Quantum Serverless patterns. For instructions to migrate, see [Converting from Qiskit Runtime Programs.](https://qiskit-extensions.github.io/quantum-serverless/migration/migration_from_qiskit_runtime_programs.html) - - -## Parametrized circuits with primitives - -Parametrized circuits are a commonly used tool for quantum algorithm -design. Because `backend.run()` did not accept parametrized -circuits, the parameter binding step had to be integrated in the -algorithm workflow. The primitives can perform the parameter binding -step internally, which results in a simplification of the algorithm-side -logic. - -The following example summarizes the new workflow for managing -parametrized circuits. - -### Example - -Let's define a parametrized circuit: - -``` python -from qiskit.circuit import QuantumCircuit, ParameterVector - -n = 3 -thetas = ParameterVector('θ',n) - -qc = QuantumCircuit(n, 1) -qc.h(0) - -for i in range(n-1): - qc.cx(i, i+1) - -for i,t in enumerate(thetas): - qc.rz(t, i) - -for i in reversed(range(n-1)): - qc.cx(i, i+1) - -qc.h(0) -qc.measure(0, 0) - -qc.draw() -``` - -We want to assign the following parameter values to the circuit: - -``` python -import numpy as np -theta_values = [np.pi/2, np.pi/2, np.pi/2] -``` - -### Legacy - -Previously, the parameter values had to be bound to their respective -circuit parameters prior to calling `backend.run()`. - -``` python -from qiskit import Aer - -bound_circuit = qc.bind_parameters(theta_values) -bound_circuit.draw() - -backend = Aer.get_backend('aer_simulator') -job = backend.run(bound_circuit) -counts = job.result().get_counts() -print(counts) -``` - -### Primitives - -Now, the primitives take in parametrized circuits directly, together -with the parameter values, and the parameter assignment operation can be -performed more efficiently on the server side of the primitive. - -This feature is particularly interesting when working with iterative -algorithms because the parametrized circuit remains unchanged between -calls while the parameter values change. The primitives can transpile -once and then cache the unbound circuit, using classical resources more -efficiently. Moreover, only the updated parameters are transferred to -the cloud, saving additional bandwidth. - -``` python -from qiskit.primitives import Sampler - -sampler = Sampler() -job = sampler.run(qc, theta_values) -result = job.result().quasi_dists -print(result) -``` - -## Algorithm tuning - -One of the advantages of the primitives is that they abstract away the -circuit execution setup so that algorithm developers can focus on the -pure algorithmic components. However, sometimes, to get the most out of -an algorithm, you might want to tune certain primitive options. For details, see [Advanced runtime options](../../run/advanced-runtime-options). - ## Next steps - - Review some [migration examples](qiskit-runtime-examples). + - Start by [migrating your setup.](qiskit-runtime-setup) + - Review some [migration examples.](qiskit-runtime-examples) - [Get started with Estimator.](../../run/primitives-get-started#start-estimator) - [Get started with Sampler.](../../run/primitives-get-started#start-sampler) - Explore [sessions.](../../run/sessions) diff --git a/docs/api/migration-guides/v2-primitives.mdx b/docs/api/migration-guides/v2-primitives.mdx index b9dd9198522..ea66d7d52ed 100644 --- a/docs/api/migration-guides/v2-primitives.mdx +++ b/docs/api/migration-guides/v2-primitives.mdx @@ -424,7 +424,7 @@ options.resilience_level = 2 ### Transpilation -V2 primitives support only ISA circuits. Because the primitives do not perform layout, routing, and translation operations, the corresponding transpilation options from V1 are not supported. For Estimator, you can still use `optimization_level` to indicate how much optimization the primitives should apply to the ISA circuits. The valid values are 0 and 1. +V2 primitives support only circuits that adhere to the Instruction Set Architecture (ISA) of a particular backend. Because the primitives do not perform layout, routing, and translation operations, the corresponding transpilation options from V1 are not supported. For Estimator, you can still use `optimization_level` to indicate how much optimization the primitives should apply to the ISA circuits. The valid values are 0 and 1. Dynamical decoupling is no longer automatically added for `optimization_level=1`. You can, however, enable it by using the `dynamical_decoupling` option. From 3b730938d90e6f13230b25062a031f23ee582834 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Tue, 26 Mar 2024 15:53:25 -0500 Subject: [PATCH 05/65] fix link --- docs/api/migration-guides/qiskit-runtime.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/migration-guides/qiskit-runtime.mdx b/docs/api/migration-guides/qiskit-runtime.mdx index 6e074905d80..f5f02f42b66 100644 --- a/docs/api/migration-guides/qiskit-runtime.mdx +++ b/docs/api/migration-guides/qiskit-runtime.mdx @@ -56,7 +56,7 @@ This guide is for algorithm developers who need to refactor algorithms to use pr The following topics are use cases with code migration examples: -- [Update parameter values while running](#parm-circ) +- [Update parameter values while running](qiskit-runtime-setup#parm-circ) - [Algorithm tuning options (shots, transpilation, error mitigation)](../../run/advanced-runtime-options) ## FAQs From a81964e1ca989b4cd3175c4480b5c328da305fcc Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Tue, 26 Mar 2024 15:57:56 -0500 Subject: [PATCH 06/65] add note type --- docs/api/migration-guides/qiskit-runtime.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/migration-guides/qiskit-runtime.mdx b/docs/api/migration-guides/qiskit-runtime.mdx index f5f02f42b66..65b702a5eb0 100644 --- a/docs/api/migration-guides/qiskit-runtime.mdx +++ b/docs/api/migration-guides/qiskit-runtime.mdx @@ -12,7 +12,7 @@ in_page_toc_max_heading_level: 2 This guide describes key patterns of behavior and use cases with code examples to help you migrate code from the legacy `backend.run()` interface (`qiskit-ibmq-provider` package) to use the Qiskit Runtime primitives interface (`qiskit-ibm-runtime` package). - + Because both `backend.run()` and the "version 1" primitives are being deprecated, this guide uses only the V2 primitives. From fe250eb3f1e0fe6cd18ae24497ba7cc9fb7c1746 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Tue, 26 Mar 2024 16:03:12 -0500 Subject: [PATCH 07/65] add some tabs --- .../qiskit-runtime-from-provider.mdx | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-from-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-provider.mdx index 149c8856a4d..428aab59c28 100644 --- a/docs/api/migration-guides/qiskit-runtime-from-provider.mdx +++ b/docs/api/migration-guides/qiskit-runtime-from-provider.mdx @@ -30,29 +30,32 @@ circuit.cx(0, 1) circuit.measure_all() ``` -In Provider, the code is: - + + ```python -from qiskit_ibm_provider import IBMProvider +from qiskit_ibm_runtime import QiskitRuntimeService -provider = IBMProvider() -backend = provider.get_backend("ibmq_qasm_simulator") +service = QiskitRuntimeService(channel="ibm_quantum") +backend = service.backend("ibmq_qasm_simulator") transpiled_circuit = transpile(circuit, backend=backend) job = backend.run(transpiled_circuit) print(job.result()) ``` + -In Runtime, the code is: - + ```python -from qiskit_ibm_runtime import QiskitRuntimeService +from qiskit_ibm_provider import IBMProvider -service = QiskitRuntimeService(channel="ibm_quantum") -backend = service.backend("ibmq_qasm_simulator") +provider = IBMProvider() +backend = provider.get_backend("ibmq_qasm_simulator") transpiled_circuit = transpile(circuit, backend=backend) job = backend.run(transpiled_circuit) print(job.result()) ``` + + + **Example 2: Execution of backend.run() within a session:** From 9078d7dd8f396a0d3c3127aea5241d4bad9574b6 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Wed, 27 Mar 2024 14:43:14 -0500 Subject: [PATCH 08/65] reformat --- docs/api/migration-guides/_toc.json | 18 +- .../qiskit-runtime-examples.mdx | 212 ++++++------- ...x => qiskit-runtime-from-ibm-provider.mdx} | 52 ++-- .../qiskit-runtime-from-ibmq-provider.mdx | 292 ++++++++++++++++++ .../qiskit-runtime-options.mdx | 46 +++ .../migration-guides/qiskit-runtime-setup.mdx | 6 +- .../qiskit-runtime-use-case.mdx | 120 +++++++ 7 files changed, 605 insertions(+), 141 deletions(-) rename docs/api/migration-guides/{qiskit-runtime-from-provider.mdx => qiskit-runtime-from-ibm-provider.mdx} (65%) create mode 100644 docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx create mode 100644 docs/api/migration-guides/qiskit-runtime-options.mdx create mode 100644 docs/api/migration-guides/qiskit-runtime-use-case.mdx diff --git a/docs/api/migration-guides/_toc.json b/docs/api/migration-guides/_toc.json index 9ce6eadf512..4697332aa2d 100644 --- a/docs/api/migration-guides/_toc.json +++ b/docs/api/migration-guides/_toc.json @@ -39,11 +39,23 @@ "url": "/api/migration-guides/qiskit-runtime" }, { - "title": "Migrate setup", - "url": "/api/migration-guides/qiskit-runtime-setup" + "title": "Migrate from qiskit-ibmq-provider", + "url": "/api/migration-guides/qiskit-from-ibmq-provider" }, { - "title": "Examples", + "title": "Migrate from qiskit-ibm-provider", + "url": "/api/migration-guides/qiskit-runtime-from-ibm-provider" + }, + { + "title": "Migrate backend.run options to primitive options", + "url": "/api/migration-guides/qiskit-runtime-options" + }, + { + "title": "Common use cases", + "url": "/api/migration-guides/qiskit-runtime-use-case" + }, + { + "title": "End-to-end examples", "url": "/api/migration-guides/qiskit-runtime-examples" } ] diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 4293dd67329..d2dc58fee67 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -1,10 +1,10 @@ --- -title: Qiskit Runtime migration examples +title: End-to-end examples description: Examples of migrating from using backend.run to using Qiskit Runtime primitives --- -# Migration examples +# End-to-end examples Follow these examples to design a Qiskit Runtime algorithm. @@ -23,80 +23,71 @@ you don't have to manually construct the final expectation circuit. This results in a considerable reduction of the code complexity and a more compact algorithm design. - - **Backend.run() model:** In this model, you accessed real systems and remote simulators using the `qiskit-ibmq-provider` module (now migrated to `qiskit-ibm-provider`). To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface. - -
- Code example for `qiskit-ibmq-provider` & `backend.run()` - - ``` python - from qiskit import IBMQ - - # Select provider - provider = IBMQ.get_provider(hub="ibm-q", group="open", project="main") - - # Get backend - backend = provider.get_backend("ibmq_qasm_simulator") # cloud simulator - - # Run - result = backend.run(expectation_circuits) - ``` -
- -
- Code example for `qiskit-aer` & `backend.run()` +**Backend.run() model:** In this model, you accessed real systems and remote simulators using the `qiskit-ibmq-provider` module (now migrated to `qiskit-ibm-provider`). To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface. - ``` python - from qiskit_aer import AerSimulator # former import: from qiskit import Aer - - # Get local simulator backend - backend = AerSimulator() + + +``` python +from qiskit import IBMQ - # Run - result = backend.run(expectation_circuits) - ``` -
+# Select provider +provider = IBMQ.get_provider(hub="ibm-q", group="open", project="main") - **Primitives model:** Access real systems and remote simulators through the `qiskit-ibm-runtime` **primitives** (`Sampler` and `Estimator`). To run **local** simulations, you can import specific local primitives from `qiskit_aer.primitives` and `qiskit.primitives`. All of them follow the `BaseSampler` and `BaseEstimator` interfaces, but **only the Runtime primitives offer access to the Runtime service, sessions, and built-in error mitigation**. +# Get backend +backend = provider.get_backend("ibmq_qasm_simulator") # cloud simulator -
- Code example for Runtime Estimator +# Run +result = backend.run(expectation_circuits) +``` + - ``` python - from qiskit_ibm_runtime import QiskitRuntimeService, Estimator + +``` python +from qiskit_aer import AerSimulator # former import: from qiskit import Aer - # Define service - service = QiskitRuntimeService() +# Get local simulator backend +backend = AerSimulator() - # Get backend - backend = service.backend("ibmq_qasm_simulator") # cloud simulator +# Run +result = backend.run(expectation_circuits) +``` + + - # Define Estimator - # (see tutorials for more information about sessions) - estimator = Estimator(session=backend) +**Primitives model:** Access real systems and remote simulators through the `qiskit-ibm-runtime` **primitives** (`Sampler` and `Estimator`). To run **local** simulations, you can import specific local primitives from `qiskit_aer.primitives` and `qiskit.primitives`. All of them follow the `BaseSampler` and `BaseEstimator` interfaces, but **only the Runtime primitives offer access to the Runtime service, sessions, and built-in error mitigation**. - # Run Expectation value calculation - result = estimator.run(circuits, observables).result() - ``` -
+ + +``` python +from qiskit_ibm_runtime import QiskitRuntimeService, Estimator -
- Code example for Aer Estimator +# Define service +service = QiskitRuntimeService() - ``` python - from qiskit_aer import Estimator +# Get backend +backend = service.backend("ibmq_qasm_simulator") # cloud simulator - # Get local simulator Estimator - estimator = Estimator() +# Define Estimator +# (see tutorials for more information about sessions) +estimator = Estimator(session=backend) - # Run expectation value calculation - result = estimator.run(circuits, observables).result() - ``` +# Run Expectation value calculation +result = estimator.run(circuits, observables).result() +``` + -
+ +``` python +from qiskit_aer import Estimator -
+# Get local simulator Estimator +estimator = Estimator() +# Run expectation value calculation +result = estimator.run(circuits, observables).result() +``` + + If your code previously calculated expectation values using `backend.run()`, you most likely used the `qiskit.opflow` module to @@ -153,43 +144,9 @@ This step is no longer necessary when using the primitives. #### 2. Calculate expectation values on real device or cloud simulator -##### 2.a. Legacy: Use opflow & backend.run() - -The legacy workflow required many steps to compute an expectation value: - - - Replace `ibmq_qasm_simulator` with your device name to see the complete workflow for a real device. - - -``` python -from qiskit.opflow import StateFn, PauliExpectation, CircuitSampler -from qiskit import IBMQ - -# Define the state to sample -measurable_expression = StateFn(opflow_op, is_measurement=True).compose(opflow_state) - -# Convert to expectation value calculation object -expectation = PauliExpectation().convert(measurable_expression) - -# Define provider and backend -provider = IBMQ.get_provider(hub="ibm-q", group="open", project="main") -backend = provider.get_backend("ibmq_qasm_simulator") - -# Inject backend into circuit sampler -sampler = CircuitSampler(backend).convert(expectation) - -# Evaluate -expectation_value = sampler.eval().real -``` - -``` python ->>> print("expectation: ", expectation_value) -expectation: -1.065734058826613 -``` - -##### 2.b. Updated: Use the Estimator Runtime primitive - -The `Estimator` simplifies the user-side syntax, making it a more + + +Estimator simplifies the user-side syntax, making it a more convenient tool for algorithm design. @@ -226,15 +183,57 @@ to the following: - [How to run a session topic](../../run/run-jobs-in-session) -#### 3. Other execution alternatives (non-Runtime) + -This section describes how to use non-Runtime primitives to test an -algorithm using local simulation. Let's assume that we want to solve + +The legacy workflow required many steps to compute an expectation value: + + + Replace `ibmq_qasm_simulator` with your device name to see the complete workflow for a real device. + + +``` python +from qiskit.opflow import StateFn, PauliExpectation, CircuitSampler +from qiskit import IBMQ + +# Define the state to sample +measurable_expression = StateFn(opflow_op, is_measurement=True).compose(opflow_state) + +# Convert to expectation value calculation object +expectation = PauliExpectation().convert(measurable_expression) + +# Define provider and backend +provider = IBMQ.get_provider(hub="ibm-q", group="open", project="main") +backend = provider.get_backend("ibmq_qasm_simulator") + +# Inject backend into circuit sampler +sampler = CircuitSampler(backend).convert(expectation) + +# Evaluate +expectation_value = sampler.eval().real +``` + +``` python +>>> print("expectation: ", expectation_value) +expectation: -1.065734058826613 +``` + + + + +#### 3. Local execution + +This section describes how to use Qiskit Runtime to test an +algorithm locally. Let's assume that we want to solve the problem defined above with a local state vector simulation. - -##### 3.a. Legacy: Using the Qiskit Aer simulator + + +Qiskit Runtime has a local testing mode that gives you access to + + + ``` python from qiskit.opflow import StateFn, PauliExpectation, CircuitSampler from qiskit_aer import AerSimulator @@ -258,10 +257,10 @@ expectation_value = circuit_sampler.eval().real ``` python >>> print("expectation: ", expectation_value) expectation: -1.0636533500290943 -``` - -##### 3.b. Updated: Use the Reference Estimator or Aer Estimator primitive +``` + + The reference `Estimator` lets you perform either an exact or a shot-based noisy simulation based on the `Statevector` class in the `qiskit.quantum_info` module. @@ -299,8 +298,9 @@ expectation_value = estimator.run(state, op, shots=100).result().values >>> print("expectation: ", expectation_value) expectation: [-1.06365335] ``` + + -For more information on using the Aer primitives, see the [VQE tutorial](https://github.com/Qiskit/qiskit-tutorials/blob/master/tutorials/algorithms/03_vqe_simulation_with_noise.ipynb). For more information about running noisy simulations with the **Runtime primitives**, see the [Noisy simulators in Qiskit Runtime](../../verify/using-ibm-quantum-simulators) topic. diff --git a/docs/api/migration-guides/qiskit-runtime-from-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx similarity index 65% rename from docs/api/migration-guides/qiskit-runtime-from-provider.mdx rename to docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx index 428aab59c28..628ded06851 100644 --- a/docs/api/migration-guides/qiskit-runtime-from-provider.mdx +++ b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx @@ -1,34 +1,15 @@ --- -title: Migrate from qiskit_ibm_provider to qiskit_ibm_runtime -description: How to migrate `backend.run()` from Qiskit IBM Provider to Qiskit IBM Runtime ---- - -# Migrate `backend.run()` from `qiskit_ibm_provider` to `qiskit_ibm_runtime` +title: Migrate from qiskit-ibm-provider +description: Migrate from backend.run in qiskit-ibm-provider to using Qiskit Runtime primitives -The Qiskit Runtime interface includes two packages: -Qiskit IBM Provider (the [`qiskit_ibm_provider`](../qiskit-ibm-provider) package) and -Qiskit IBM Runtime (the [`qiskit_ibm_runtime`](../qiskit-ibm-runtime) package). Until now, -primitives (`Sampler` and `Estimator`) -were run in Runtime. Custom circuits that were manually transpiled and used `IBMBackend.run()` -were run in Provider. - -In the `qiskit-ibm-runtime` 0.15 release, we added support for running custom circuits using `IBMBackend.run()` in Runtime, -so users can run all programs through Runtime. +--- -This guide describes how to migrate code that implemented `IBMBackend.run()` -using qiskit_ibm_provider to use qiskit_ibm_runtime instead. +# Migrate from `qiskit_ibm_provider` to `qiskit_ibm_runtime` -**Example 1: Straightforward execution of IBMBackend.run()** +The [`qiskit_ibm_provider`](../qiskit-ibm-provider) package from Qiskit Runtime is being deprecated. This guide describes how to migrate code that implemented `IBMBackend.run()` +using `qiskit_ibm_provider` to use `qiskit_ibm_runtime` instead. -```python -from qiskit import * -from qiskit.compiler import transpile, assemble - -circuit = QuantumCircuit(2, 2) -circuit.h(0) -circuit.cx(0, 1) -circuit.measure_all() -``` +## Example: Straightforward execution of IBMBackend.run() @@ -54,10 +35,23 @@ job = backend.run(transpiled_circuit) print(job.result()) ``` + + +```python +from qiskit import * +from qiskit.compiler import transpile, assemble + +circuit = QuantumCircuit(2, 2) +circuit.h(0) +circuit.cx(0, 1) +circuit.measure_all() +``` + + -**Example 2: Execution of backend.run() within a session:** +## Example: Execution of backend.run() within a session This section of code is identical in Provider and in Runtime. @@ -73,7 +67,7 @@ backend.cancel_session() Sessions are implemented differently in `IBMBackend` than when using primitives. Therefore, we cannot run a primitive and use backend.run() within a single session. If you specify both, one will be run outside of the session. -**Example 3: Primitive session containing backend.run:** +## Example: Primitive session containing backend.run In this example, `sampler` is run within session, but `backend` is run independently of the session. @@ -89,7 +83,7 @@ with Session(backend=backend) as session: print(job2.session_id) # is None ``` -**Example 4: `Backend` session containing Sampler:** +## Example 4: `Backend` session containing Sampler In this example, `backend` is run within a session, but `sampler` is run independently of the session. diff --git a/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx new file mode 100644 index 00000000000..86fec2ab67c --- /dev/null +++ b/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx @@ -0,0 +1,292 @@ +--- +title: Migrate from qiskit_ibm_provider to qiskit_ibm_runtime +description: How to migrate `backend.run()` from Qiskit IBM Provider to Qiskit IBM Runtime +--- + +# Migrate from `qiskit_ibmq_provider` to `qiskit_ibm_runtime` + +This guide describes how to migrate code from the legacy IBMQ provider +`qiskit-ibmq-provider` package to use Qiskit Runtime +`qiskit-ibm-runtime`. + +## Changes in Class name and location + +The classes related to Qiskit Runtime that used to be included in +`qiskit-ibmq-provider` are now part of `qiskit-ibm-runtime`. Before, the +provider used to populate the `qiskit.providers.ibmq.runtime` namespace +with objects for Qiskit Runtime. These now live in the +`qiskit_ibm_runtime` module. + +The module from which the classes are imported has changed. The +following table contains example access patterns in +`qiskit.providers.ibmq.runtime` and their new form in +`qiskit_ibm_runtime`: + +| class in qiskit-ibmq-provider | class in qiskit-ibm-runtime | Notes | +|--------------------------------------------------|-------------------------------------------|----------------------------------------------------------------------------------------------------------------------| +| qiskit.providers.ibmq.runtime.IBMRuntimeService | qiskit_ibm_runtime.QiskitRuntimeService | IBMRuntimeService class was removed from qiskit-ibm-runtime 0.6 and replaced by the new class in qiskit-ibm-runtime. | +| qiskit.providers.ibmq.runtime.RuntimeJob | qiskit_ibm_runtime.RuntimeJob | +| qiskit.providers.ibmq.runtime.RuntimeProgram | | This class was used for custom programs, which are no longer supported. +| qiskit.providers.ibmq.runtime.UserMessenger | | This class was used for custom programs, which are no longer supported. | +| qiskit.providers.ibmq.runtime.ProgramBackend | | This class was used for custom programs, which are no longer supported. | +| qiskit.providers.ibmq.runtime.ResultDecoder | | This class was used for custom programs, which are no longer supported. | +| qiskit.providers.ibmq.runtime.RuntimeEncoder | qiskit_ibm_runtime.RuntimeEncoder | +| qiskit.providers.ibmq.runtime.RuntimeDecoder | qiskit_ibm_runtime.RuntimeDecoder | +| qiskit.providers.ibmq.runtime.ParameterNamespace | | This class was used for custom programs, which are no longer supported. +| qiskit.providers.ibmq.runtime.RuntimeOptions | qiskit_ibm_runtime.RuntimeOptions | + + +## Import path + +The import path has changed as follows: + + + +``` python +from qiskit_ibm_runtime import QiskitRuntimeService +``` + + + +``` python +from qiskit import IBMQ +``` + + + +## Save accounts + +Use the updated code to work save accounts. + + + +The new syntax accepts credentials for +Qiskit Runtime on IBM Cloud or IBM Quantum Platform. For more +information on retrieving account credentials, see [Install and set up](../../start/install). + +``` python +# IBM Cloud channel + +QiskitRuntimeService.save_account(channel="ibm_cloud", token="", instance="", overwrite=True) + +# IBM Quantum channel; set to default + +QiskitRuntimeService.save_account(channel="ibm_quantum", token="", overwrite=True, default=true) +``` + +Additionally, you can now name your saved credentials and load the credentials by name. + + +``` python +# Save different accounts for open and premium access + +QiskitRuntimeService.save_account(channel="ibm_quantum", token="", instance="h1/g1/p1", name="premium") +QiskitRuntimeService.save_account(channel="ibm_quantum", token="", instance="h2/g2/p2", name="open") + +# Load the "open" credentials + +service = QiskitRuntimeService(name="open") +``` + + + +``` python +IBMQ.save_account("", overwrite=True) +``` + + + + +## Load accounts + +Use the updated code to load accounts. + + + +The new syntax combines the functionality from `load_account()` and +`get_provider()` in one statement. The `channel` input parameter is +optional. If multiple accounts have been saved in one device and no +`channel` is provided, the default is `"ibm_cloud"`. + +``` python +# To access saved credentials for the IBM cloud channel +service = QiskitRuntimeService(channel="ibm_cloud") + +# To access saved credentials for the IBM quantum channel +service = QiskitRuntimeService(channel="ibm_quantum") +``` + + + +``` python +IBMQ.load_account() +``` + + + + +## Channel selection (get a provider) + +Use the updated code to select a channel. + + + +The new syntax combines the functionality from `load_account()` and +`get_provider()` in one statement. When using the `ibm_quantum` channel, +the `hub`, `group`, and `project` are specified through the new +`instance` keyword. + +``` python +# To access saved credentials for the IBM quantum channel and select an instance +service = QiskitRuntimeService(channel="ibm_quantum", instance="my_hub/my_group/my_project") +``` + + + +``` python +provider = IBMQ.get_provider(project="my_project", group="my_group", hub="my_hub") +``` + + + +## Get the system + +Use the updated code to view systems and simulators. + + + +``` python +# You can specify the instance in service.backend() instead of initializing a new service +backend = service.backend("ibm_backend", instance="h1/g1/p1") +``` +If you don't know what backend you want to use, you can instead use code such as the following: + +```python +from qiskit_ibm_runtime import QiskitRuntimeService + +service = QiskitRuntimeService() +backend = service.least_busy(operational=True, simulator=False, min_num_qubits=num_qubits) +``` + + + +``` python +provider = IBMQ.get_provider(hub="h1", group="g1", project="p1") +backend = provider.get_backend("ibm_backend") +``` + + + +## Upload, view, or delete custom prototype programs + +This function has been replaced with Quantum Serverless patterns. For instructions to migrate, see [Converting from Qiskit Runtime Programs.](https://qiskit-extensions.github.io/quantum-serverless/migration/migration_from_qiskit_runtime_programs.html) + + +## Parameterized circuits with primitives + +Parametrized circuits are a commonly used tool for quantum algorithm +design. Because `backend.run()` did not accept parametrized +circuits, the parameter binding step had to be integrated in the +algorithm workflow. The primitives can perform the parameter binding +step internally, which results in a simplification of the algorithm-side +logic. + +The following example summarizes the new workflow for managing +parametrized circuits. + +### Example + +Define a parametrized circuit: + +``` python +from qiskit.circuit import QuantumCircuit, ParameterVector + +n = 3 +thetas = ParameterVector('θ',n) + +qc = QuantumCircuit(n, 1) +qc.h(0) + +for i in range(n-1): + qc.cx(i, i+1) + +for i,t in enumerate(thetas): + qc.rz(t, i) + +for i in reversed(range(n-1)): + qc.cx(i, i+1) + +qc.h(0) +qc.measure(0, 0) + +qc.draw() +``` + +V2 primitives support only circuits that adhere to the Instruction Set Architecture (ISA) of a particular backend, so we must transform our circuits. + +```python +from qiskit_ibm_runtime import QiskitRuntimeService +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager + +service = QiskitRuntimeService() +backend = service.least_busy(operational=True, simulator=False) + +pm = generate_preset_pass_manager(backend=backend, optimization_level=1) +isa_circuit = pm.run(qc) +``` + +We want to assign the following parameter values to the circuit: + +``` python +import numpy as np +theta_values = [np.pi/2, np.pi/2, np.pi/2] +``` + + + +The primitives take in parametrized circuits directly, together +with the parameter values, and the parameter assignment operation can be +performed more efficiently on the server side of the primitive. The input is in the form of primitive unified blocs (PUBs). Each PUB is a tuple that contains a circuit and the data broadcasted to it. For further details, see [Introduction to primitives.](../../run/primitives#interface-changes) + +This feature is particularly interesting when working with iterative +algorithms because the parametrized circuit remains unchanged between +calls while the parameter values change. The primitives can transpile +once and then cache the unbound circuit, using classical resources more +efficiently. Moreover, only the updated parameters are transferred to +the cloud, saving additional bandwidth. + + +As shown in the previous image, the classical register name is `c`. Alternatively, you can find the classical register name by running `.cregs`. For example: `qc.cregs`. + + +``` python +from qiskit_ibm_runtime import SamplerV2 as Sampler + +sampler = Sampler(backend) +job = sampler.run([(isa_circuit, theta_values)]) +result = job.result() +# Get results for the first (and only) PUB +pub_result = result[0] +# Get counts from the classical register "c". +print(f" >> Counts for the c output register: {pub_result.data.c.get_counts()}") +``` + + + +The parameter values had to be bound to their respective +circuit parameters prior to calling `backend.run()`. + +``` python +from qiskit import Aer + +bound_circuit = qc.bind_parameters(theta_values) +bound_circuit.draw() + +backend = Aer.get_backend('aer_simulator') +job = backend.run(bound_circuit) +counts = job.result().get_counts() +print(counts) +``` + + + diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx new file mode 100644 index 00000000000..93049d6831f --- /dev/null +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -0,0 +1,46 @@ +--- +title: Migrate backend.run options to primitive options +description: Migrate backend.run options to Qiskit Runtime primitive options + + +in_page_toc_max_heading_level: 2 +--- + +# Migrate backend.run options to primitive options + +All `backend.run` options are now available through the Qiskit Runtime primitives. + +| backend.run options | SamplerV2 options | notes | +|---------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------| +| job_name | n/a, use job_tags instead | ibmq-provider only | +| job_share_level | n/a, this was deprecated long ago | ibmq-provider only | +| job_tags | options.environment.job_tags | | +| experiment_id | n/a, use job_tags instead | ibmq-provider only | +| header | You can attach metadata to circuits. The same metadata is returned in the result metadata, under “circuit_metadata”. | | +| shots | run([(…, shots)]) or run(…, shots=) or options.default_shots | | +| memory | Use result.data.meas.get_counts() to get counts and result.data.meas.get_bitstrings() to get per-shot measurements | SamplerV2 is essentially always memory=True | +| qubit_lo_freq | n/a, this option only applies to `Schedule` inputs, which was deprecated in 2022 | | +| meas_lo_freq | n/a, this option only applies to `Schedule` inputs, which was deprecated in 2022 | | +| schedule_los | n/a, this option only applies to `Schedule` inputs, which was deprecated in 2022 | | +| meas_level | options.execution.meas_type | (meas_level, meas_return) → meas_type 0, * → not implemented 1, “avg” → “avg_kerneled” 1, “single” → “kerneled” 2, * → “classified” | +| meas_return | options.execution.meas_type | | +| memory_slots | n/a, this is automatically determined by the system | ibmq-provider only | +| memory_slot_size | n/a, this is automatically determined by the system | ibmq-provider only | +| rep_time | n/a, use rep_delay instead | | +| rep_delay | options.execution.rep_delay | | +| init_qubits | options.execution.init_qubits | | +| parameter_binds | specify parameters in PUBs | ibmq-provider only | +| use_measure_esp | n/a, this is no longer supported by IBM backends | | +| live_data_enabled | n/a, this feature was removed in 2022 | ibmq-provider only | +| dynamic | n/a, no longer needed. SamplerV2 knows if it’s dynamic | ibm-provider only | +| init_circuit | n/a, use init_qubits instead | | +| init_num_resets | n/a, use init_qubits instead | | +| noise_model | options.simulator.noise_model | | +| seed_simulator | options.simulator.seed_simulator | | + +## Algorithm tuning + +One of the advantages of the primitives is that they abstract away the +circuit execution setup so that algorithm developers can focus on the +pure algorithmic components. However, sometimes, to get the most out of +an algorithm, you might want to tune certain primitive options. For details, see [Advanced runtime options](../../run/advanced-runtime-options). diff --git a/docs/api/migration-guides/qiskit-runtime-setup.mdx b/docs/api/migration-guides/qiskit-runtime-setup.mdx index f717f67fdda..68dee80769b 100644 --- a/docs/api/migration-guides/qiskit-runtime-setup.mdx +++ b/docs/api/migration-guides/qiskit-runtime-setup.mdx @@ -185,7 +185,7 @@ backend = provider.get_backend("ibm_backend") This function has been replaced with Quantum Serverless patterns. For instructions to migrate, see [Converting from Qiskit Runtime Programs.](https://qiskit-extensions.github.io/quantum-serverless/migration/migration_from_qiskit_runtime_programs.html) -# Parametrized circuits with primitives +## Parameterized circuits with primitives Parametrized circuits are a commonly used tool for quantum algorithm design. Because `backend.run()` did not accept parametrized @@ -197,7 +197,7 @@ logic. The following example summarizes the new workflow for managing parametrized circuits. -## Example +### Example Define a parametrized circuit: @@ -293,7 +293,7 @@ print(counts) -# Algorithm tuning +## Algorithm tuning One of the advantages of the primitives is that they abstract away the circuit execution setup so that algorithm developers can focus on the diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx new file mode 100644 index 00000000000..a3086a3910a --- /dev/null +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -0,0 +1,120 @@ +--- +title: Common use cases +description: Common use cases when migrating from backend.run to Qiskit Runtime primitives +--- + +# Common use cases + + +## Basic circuits + +## Dynamic circuits + + +## Parameterized circuits with primitives + +Parametrized circuits are a commonly used tool for quantum algorithm +design. Because `backend.run()` did not accept parametrized +circuits, the parameter binding step had to be integrated in the +algorithm workflow. The primitives can perform the parameter binding +step internally, which results in a simplification of the algorithm-side +logic. + +The following example summarizes the new workflow for managing +parametrized circuits. + +### Example + +Define a parametrized circuit: + +``` python +from qiskit.circuit import QuantumCircuit, ParameterVector + +n = 3 +thetas = ParameterVector('θ',n) + +qc = QuantumCircuit(n, 1) +qc.h(0) + +for i in range(n-1): + qc.cx(i, i+1) + +for i,t in enumerate(thetas): + qc.rz(t, i) + +for i in reversed(range(n-1)): + qc.cx(i, i+1) + +qc.h(0) +qc.measure(0, 0) + +qc.draw() +``` + +V2 primitives support only circuits that adhere to the Instruction Set Architecture (ISA) of a particular backend, so we must transform our circuits. + +```python +from qiskit_ibm_runtime import QiskitRuntimeService +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager + +service = QiskitRuntimeService() +backend = service.least_busy(operational=True, simulator=False) + +pm = generate_preset_pass_manager(backend=backend, optimization_level=1) +isa_circuit = pm.run(qc) +``` + +We want to assign the following parameter values to the circuit: + +``` python +import numpy as np +theta_values = [np.pi/2, np.pi/2, np.pi/2] +``` + + + +The primitives take in parametrized circuits directly, together +with the parameter values, and the parameter assignment operation can be +performed more efficiently on the server side of the primitive. The input is in the form of primitive unified blocs (PUBs). Each PUB is a tuple that contains a circuit and the data broadcasted to it. For further details, see [Introduction to primitives.](../../run/primitives#interface-changes) + +This feature is particularly interesting when working with iterative +algorithms because the parametrized circuit remains unchanged between +calls while the parameter values change. The primitives can transpile +once and then cache the unbound circuit, using classical resources more +efficiently. Moreover, only the updated parameters are transferred to +the cloud, saving additional bandwidth. + + +As shown in the previous image, the classical register name is `c`. Alternatively, you can find the classical register name by running `.cregs`. For example: `qc.cregs`. + + +``` python +from qiskit_ibm_runtime import SamplerV2 as Sampler + +sampler = Sampler(backend) +job = sampler.run([(isa_circuit, theta_values)]) +result = job.result() +# Get results for the first (and only) PUB +pub_result = result[0] +# Get counts from the classical register "c". +print(f" >> Counts for the c output register: {pub_result.data.c.get_counts()}") +``` + + + +The parameter values had to be bound to their respective +circuit parameters prior to calling `backend.run()`. + +``` python +from qiskit import Aer + +bound_circuit = qc.bind_parameters(theta_values) +bound_circuit.draw() + +backend = Aer.get_backend('aer_simulator') +job = backend.run(bound_circuit) +counts = job.result().get_counts() +print(counts) +``` + + From da637594eb4a824e4787ea8a5ba8bccfe1752c35 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Wed, 27 Mar 2024 14:51:45 -0500 Subject: [PATCH 09/65] fix links --- docs/api/migration-guides/index.mdx | 5 ++++- docs/api/migration-guides/qiskit-runtime-examples.mdx | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/api/migration-guides/index.mdx b/docs/api/migration-guides/index.mdx index d62c1a20548..479bb862855 100644 --- a/docs/api/migration-guides/index.mdx +++ b/docs/api/migration-guides/index.mdx @@ -14,8 +14,11 @@ These migration guides help you more effectively use Qiskit and Qiskit Runtime: * [Migrate to the Qiskit Runtime V2 primitives](/api/migration-guides/v2-primitives) * Migrate to Qiskit Runtime * [How to migrate](./qiskit-runtime) + * [Migrate from `qiskit-ibmq-provider`](./qiskit-runtime-from-ibmq-provider) + * [Migrate from `qiskit_ibm_provider`](./qiskit-runtime-from-ibm-provider) + * [Migrate `backend.run` options to primitives](./qiskit-runtime-options) + * [Common use cases](./qiskit-runtime-use-case) * [Examples](./qiskit-runtime-examples) - * [Migrate `backend.run()` from `qiskit_ibm_provider` to `qiskit_ibm_runtime`](./qiskit-runtime-from-provider) * [Migrate from cloud simulators to local simulators](/api/migration-guides/local-simulators) * Qiskit 0.44 changes * [`qiskit.algorithms` new interface](./qiskit-algorithms-module) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index d2dc58fee67..d1c95809693 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -284,7 +284,7 @@ expectation: [-1.03134297] You can still access the Aer Simulator through its dedicated `Estimator`. This can be handy for performing simulations with noise models. In this example, the simulation method has been updated to match -the result from [3.a](#3a). +the Qiskit Aer simulator example result. ``` python from qiskit_aer.primitives import Estimator # import change From 763741aa272250ba35ab4ab93a1ead0ae57442c9 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Wed, 27 Mar 2024 14:56:35 -0500 Subject: [PATCH 10/65] update link --- docs/api/migration-guides/_toc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/migration-guides/_toc.json b/docs/api/migration-guides/_toc.json index 4697332aa2d..68aac283b7e 100644 --- a/docs/api/migration-guides/_toc.json +++ b/docs/api/migration-guides/_toc.json @@ -40,7 +40,7 @@ }, { "title": "Migrate from qiskit-ibmq-provider", - "url": "/api/migration-guides/qiskit-from-ibmq-provider" + "url": "/api/migration-guides/qiskit-runtime-from-ibmq-provider" }, { "title": "Migrate from qiskit-ibm-provider", From 4574dbb39454a90d6c37d9ae33da316647aadbc0 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Thu, 28 Mar 2024 15:15:30 -0500 Subject: [PATCH 11/65] more edits --- .../qiskit-runtime-examples.mdx | 210 ++++++++++++++---- .../qiskit-runtime-options.mdx | 2 +- .../qiskit-runtime-use-case.mdx | 4 +- docs/api/migration-guides/qiskit-runtime.mdx | 83 ++----- 4 files changed, 188 insertions(+), 111 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index d1c95809693..471fa474671 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -54,37 +54,45 @@ result = backend.run(expectation_circuits) -**Primitives model:** Access real systems and remote simulators through the `qiskit-ibm-runtime` **primitives** (`Sampler` and `Estimator`). To run **local** simulations, you can import specific local primitives from `qiskit_aer.primitives` and `qiskit.primitives`. All of them follow the `BaseSampler` and `BaseEstimator` interfaces, but **only the Runtime primitives offer access to the Runtime service, sessions, and built-in error mitigation**. +**Primitives model:** Access real systems and remote simulators through the `qiskit-ibm-runtime` **primitives** (`Sampler` and `Estimator`). Use **Local testing mode** to run local simulations on Qiskit Runtime fake backends or Aer simulators. The following examples assume you have defined circuits `isa_circuits` and observables `isa_observables`. - + ``` python -from qiskit_ibm_runtime import QiskitRuntimeService, Estimator +from qiskit_ibm_runtime import EstimatorV2 as Estimator, QiskitRuntimeService -# Define service +# Define the service. This allows you to access IBM Quantum systems. service = QiskitRuntimeService() -# Get backend -backend = service.backend("ibmq_qasm_simulator") # cloud simulator +# Get a backend +backend = service.least_busy(operational=True, simulator=False) # Define Estimator -# (see tutorials for more information about sessions) -estimator = Estimator(session=backend) +estimator = Estimator(backend) -# Run Expectation value calculation -result = estimator.run(circuits, observables).result() +# Run an expectation value calculation +job = estimator.run([(isa_circuits, isa_observables)]) +result = job.result() ``` - + ``` python -from qiskit_aer import Estimator +from qiskit_ibm_runtime import EstimatorV2 as Estimator +from qiskit_ibm_runtime.fake_provider import FakeManilaV2 -# Get local simulator Estimator -estimator = Estimator() +# Run the sampler job locally using FakeManilaV2 +fake_manila = FakeManilaV2() + +# You can use a fixed seed to get fixed results. +options = {"simulator": {"seed_simulator": 42}} -# Run expectation value calculation -result = estimator.run(circuits, observables).result() +# Define Estimator +estimator = Estimator(backend=fake_manila, options=options) + +# Run an expectation value calculation +job = estimator.run([(isa_circuits, isa_observables)]) +result = job.result() ``` @@ -102,6 +110,46 @@ We want to compute the expectation value of a quantum state (circuit) with respect to a certain operator. In this example, we are using the H2 molecule and an arbitrary circuit as the quantum state: + + +For Qiskit Runtime, circuits and parameters must obey the Instruction Set Architecture (ISA) of a particular backend. + +``` python +from qiskit import QuantumCircuit +from qiskit.quantum_info import SparsePauliOp + +# Step 1: Define operator +op = SparsePauliOp.from_list( + [ + ("II", -1.052373245772859), + ("IZ", 0.39793742484318045), + ("ZI", -0.39793742484318045), + ("ZZ", -0.01128010425623538), + ("XX", 0.18093119978423156), + ] +) + +# Step 2: Define quantum state +state = QuantumCircuit(2) +state.x(0) +state.x(1) + +# Define the backend +from qiskit_ibm_runtime import QiskitRuntimeService +service = QiskitRuntimeService() +backend = service.least_busy(operational=True, simulator=False) + +# Convert inputs to ISA +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager + +pm = generate_preset_pass_manager(backend=backend, optimization_level=1) +isa_state = pm.run(state) +isa_observables = [operator.apply_layout(isa_state.layout) for operator in op] + +``` + + + ``` python from qiskit import QuantumCircuit from qiskit.quantum_info import SparsePauliOp @@ -122,9 +170,12 @@ state = QuantumCircuit(2) state.x(0) state.x(1) ``` + + + -##### 1.a. Legacy: Convert problem to opflow +##### 1.a. Legacy only: Convert problem to opflow `qiskit.opflow` provided its own classes to represent both operators and quantum states, so the problem defined above would be wrapped as: @@ -136,56 +187,38 @@ opflow_op = PauliSumOp(op) opflow_state = CircuitStateFn(state) ``` -This step is no longer necessary when using the primitives. +This step is not necessary when using the primitives. For instructions to migrate from `qiskit.opflow`, see the [Opflow migration guide](./qiskit-opflow-module). -#### 2. Calculate expectation values on real device or cloud simulator +#### 2. Calculate expectation values Estimator simplifies the user-side syntax, making it a more convenient tool for algorithm design. - - Replace `ibmq_qasm_simulator` with your device name to see the complete workflow for a real device. - - ``` python -from qiskit_ibm_runtime import QiskitRuntimeService, Estimator - -service = QiskitRuntimeService() -backend = service.backend("ibmq_qasm_simulator") +from qiskit_ibm_runtime import EstimatorV2 as Estimator -estimator = Estimator(session=backend) +estimator = Estimator(backend, options={"default_shots": int(1e4)}) +job = estimator.run([(isa_state, isa_observables)]) -expectation_value = estimator.run(state, op).result().values +# Get results for the first (and only) PUB +pub_result = job.result()[0] ``` Note that the Estimator returns a list of values, as it can perform batched evaluations. ``` python ->>> print("expectation: ", expectation_value) -expectation: [-1.06329149] +>>> print(f">>> Expectation values: {pub_result.data.evs}") +>>> Expectation values: [-1.05237325 -0.20984981 0.37345495 -0.00564005 -0.00141352] ``` - -The `Estimator` Runtime primitive offers a series of features and tuning -options that do not have a legacy alternative to migrate from, but can -help improve your performance and results. For more information, refer -to the following: - -- [Setting execution options - topic](../../run/advanced-runtime-options) -- [Primitive execution options API - reference](../qiskit-ibm-runtime/qiskit_ibm_runtime.options.Options) -- [How to run a session - topic](../../run/run-jobs-in-session) - - + The legacy workflow required many steps to compute an expectation value: @@ -228,10 +261,77 @@ algorithm locally. Let's assume that we want to solve the problem defined above with a local state vector simulation. - -Qiskit Runtime has a local testing mode that gives you access to + +To use local testing mode, specify one of the fake backends from ``qiskit_ibm_runtime.fake_provider`` or specify a Qiskit Aer backend when instantiating a primitive or a session. + +- **Fake backends**: The [fake backends](../qiskit-ibm-runtime/fake_provider) in ``qiskit_ibm_runtime.fake_provider`` mimic the behaviors of IBM Quantum™ systems by using system snapshots. The system snapshots contain important information about the quantum system, such as the coupling map, basis gates, and qubit properties, which are useful for testing the transpiler and performing noisy simulations of the system. The noise model from the snapshot is automatically applied during simulation. +- **Aer simulator**: Simulators from [Qiskit Aer](../../verify/simulate-with-qiskit-aer) provide higher-performance simulation that can handle larger circuits and [custom noise models](../../verify/building_noise_models). It also supports Clifford simulation mode, which can efficiently simulate Clifford circuits with a large number of qubits. +The only part of the previous example that we need to change is the backend definition. The rest of the code is identical. However, some options and execution modes are ignored when using local testing mode and will generate warnings if included. +``` python +from qiskit import QuantumCircuit +from qiskit.quantum_info import SparsePauliOp + +# Step 1: Define operator +op = SparsePauliOp.from_list( + [ + ("II", -1.052373245772859), + ("IZ", 0.39793742484318045), + ("ZI", -0.39793742484318045), + ("ZZ", -0.01128010425623538), + ("XX", 0.18093119978423156), + ] +) + +# Step 2: Define quantum state +state = QuantumCircuit(2) +state.x(0) +state.x(1) + +# Define a local backend +from qiskit_ibm_runtime.fake_provider import FakeManilaV2 +backend = FakeManilaV2() + +# You could use an Aer simulator instead by using the following code: +# from qiskit_aer import AerSimulator +# backend = AerSimulator() + +# We don't need these lines when running in local testing mode: +# from qiskit_ibm_runtime import QiskitRuntimeService +# service = QiskitRuntimeService() + + +# Convert inputs to ISA +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager + +pm = generate_preset_pass_manager(backend=backend, optimization_level=1) +isa_state = pm.run(state) +isa_observables = [operator.apply_layout(isa_state.layout) for operator in op] +``` + + + +``` python +from qiskit import QuantumCircuit +from qiskit.quantum_info import SparsePauliOp + +# Step 1: Define operator +op = SparsePauliOp.from_list( + [ + ("II", -1.052373245772859), + ("IZ", 0.39793742484318045), + ("ZI", -0.39793742484318045), + ("ZZ", -0.01128010425623538), + ("XX", 0.18093119978423156), + ] +) + +# Step 2: Define quantum state +state = QuantumCircuit(2) +state.x(0) +state.x(1) +``` ``` python @@ -673,3 +773,19 @@ binary_quasi_dist: {'0001': 0.2802734375, '0010': 0.2412109375, '0000': 0.23925 ``` For more information, see [Noisy simulators in Qiskit Runtime](../../verify/using-ibm-quantum-simulators). + +## Next steps +The Runtime primitives offer a series of features and tuning +options, some of which do not have a legacy alternative to migrate from, but can +help improve your performance and results. For more information, refer +to the following: + + +- [Common use cases](qiskit-runtime-use-case) +- [Migrate `backend.run` options to primitive options](qiskit-runtime-options) +- [Setting execution options topic](../../run/advanced-runtime-options) +- [Primitive execution options API reference](../qiskit-ibm-runtime/qiskit_ibm_runtime.options.Options) +- [How to run a session topic](../../run/run-jobs-in-session) +- [Qiskit Runtime local testing mode topic](../../verify/local-testing-mode) + + diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index 93049d6831f..dd43f7118e9 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -6,7 +6,7 @@ description: Migrate backend.run options to Qiskit Runtime primitive options in_page_toc_max_heading_level: 2 --- -# Migrate backend.run options to primitive options +# Migrate `backend.run` options to primitive options All `backend.run` options are now available through the Qiskit Runtime primitives. diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index a3086a3910a..bf015151d75 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -72,7 +72,7 @@ theta_values = [np.pi/2, np.pi/2, np.pi/2] ``` - + The primitives take in parametrized circuits directly, together with the parameter values, and the parameter assignment operation can be performed more efficiently on the server side of the primitive. The input is in the form of primitive unified blocs (PUBs). Each PUB is a tuple that contains a circuit and the data broadcasted to it. For further details, see [Introduction to primitives.](../../run/primitives#interface-changes) @@ -101,7 +101,7 @@ print(f" >> Counts for the c output register: {pub_result.data.c.get_counts()}") ``` - + The parameter values had to be bound to their respective circuit parameters prior to calling `backend.run()`. diff --git a/docs/api/migration-guides/qiskit-runtime.mdx b/docs/api/migration-guides/qiskit-runtime.mdx index 65b702a5eb0..d5abc43ddce 100644 --- a/docs/api/migration-guides/qiskit-runtime.mdx +++ b/docs/api/migration-guides/qiskit-runtime.mdx @@ -37,88 +37,49 @@ Different packages expose different "flavors" of the primitive interfaces, for e The **only primitives that provide access to the Qiskit Runtime service** are those imported from `qiskit_ibm_runtime` (Qiskit Runtime Primitives). +## Basic steps to migrate to primitives + +### Step 1 - Determine which primitive to use + When migrating, the key to writing an equivalent algorithm using primitives is to first identify what is the minimal unit of information your algorithm is based on: -- If it uses an **expectation value**, you will need an `Estimator`. -- If it uses a **probability distribution** (from sampling the device), you will need a `Sampler`. - -After determining which primitive to use, identify where the algorithm -accesses the system. Look for the call to `backend.run()`. Next, you -will replace this call with the respective primitive call, as shown in -the following examples. - -This guide is for algorithm developers who need to refactor algorithms to use primitives instead of `backend.run()`. See examples here: - - - [Update code that performs circuit sampling](qiskit-runtime-examples#sampler-algorithm) - - [Update code that calculates expectation values](qiskit-runtime-examples#estimator-algorithm) - -The following topics are use cases with code migration examples: - -- [Update parameter values while running](qiskit-runtime-setup#parm-circ) -- [Algorithm tuning options (shots, transpilation, error mitigation)](../../run/advanced-runtime-options) - -## FAQs - -Users might have the following questions when planning to migrate their -code to Qiskit Runtime: - -
-How do the Qiskit Runtime primitives differ from backend.run? - -Qiskit Runtime is designed to streamline algorithm and application construction by removing the need for users to understand technical hardware and low-level software details. Advanced processing techniques for error suppression and mitigation are automatically applied, giving users high-fidelity results without the burden of having to code these routines themselves. The inclusion of different execution modes within Qiskit Runtime allows users to run iterative algorithm circuits back to back (sessions), or batch collections of circuits without having to re-queue each job (batch mode). This results in more efficient quantum processor utilization and reduces the total amount of time users spend running complex computations. +- If it uses an **expectation value** of a certain observable with respect to a +quantum state (a real number), you will need an `Estimator`. -
+ An expectation value of an observable could be the target quantity in scenarios where knowing a quantum state is not relevant. This often occurs in optimization problems or chemistry applications. For example, when trying to discover the extremal energy of a system. +- If it uses a **probability distribution** from sampling the device (a list of quasi-probabilities), you will need a `Sampler`. -
-Which channel should I use? + A probability distribution is often of interest in optimization problems that return a classical bit string, encoding a certain solution to a problem at hand. In these cases, you might be interested in finding a bit string that corresponds to a ket value with the largest probability of being measured from a quantum state, for example. -After deciding to use Qiskit Runtime primitives, the user must determine -whether to access Qiskit Runtime through IBM Cloud or IBM Quantum -Platform. Some information that might help you decide includes: +### Step 2 - Change imports as necessary -- The available plans: - - Qiskit Runtime is available in both the Open (free access) or Premium (contract-based paid access) plan on IBM Quantum Platform. See [IBM Quantum access plans](https://www.ibm.com/quantum/access-plans) for details. - - Qiskit Runtime is accessible through the Lite (free access) or Standard (pay-as-you-go access) plan in IBM Cloud. See [Qiskit Runtime plans](https://cloud.ibm.com/docs/quantum-computing?topic=quantum-computing-plans) on IBM Cloud for details. +Follow the steps in the appropriate topic to change your import options and other setup information: -
+- [Migrate from `qiskit-ibm-provider`.](qiskit-runtime-from-ibm-provider) +- [Migrate from `qiskit-ibmq-provider`.](qiskit-runtime-from-ibmq-provider) -
-How do I set up my channel? +### Step 3 - Replace the call to `backend.run` with a call to `qiskit_ibm_runtime`. -After deciding which channel to use to interact with Qiskit Runtime, you -can get set up on either platform by following the steps in [Install and set up.](../../start/install) +See these topics: -
+- [Update code that performs circuit sampling](qiskit-runtime-examples#sampler-algorithm) +- [Update code that calculates expectation values](qiskit-runtime-examples#estimator-algorithm) +- [Common use cases (basic, parameterized, and dynamic circuits)](qiskit-runtime-use-case) -
-Which primitive should I use? -When choosing which primitive to use, you first need to understand -whether the algorithm uses a **quasi-probability distribution** sampled -from a quantum state (a list of quasi-probabilities), or an -**expectation value** of a certain observable with respect to a -quantum state (a real number). +### Step 3a - replace any `backend.run` options with `qiskit_ibm_runtime`. -A probability distribution is often of interest in optimization problems -that return a classical bit string, encoding a certain solution to a -problem at hand. In these cases, you might be interested in finding a -bit string that corresponds to a ket value with the largest probability -of being measured from a quantum state, for example. +See the following topics: -An expectation value of an observable could be the target quantity in -scenarios where knowing a quantum state is not relevant. This often -occurs in optimization problems or chemistry applications. For example, -when trying to discover the extremal energy of a system. +- [Migrate `backend.run` options to primitive options.](qiskit-runtime-options) +- [Algorithm tuning options (shots, transpilation, and error mitigation)](../../run/advanced-runtime-options) -
## Next steps - - Start by [migrating your setup.](qiskit-runtime-setup) - - Review some [migration examples.](qiskit-runtime-examples) - [Get started with Estimator.](../../run/primitives-get-started#start-estimator) - [Get started with Sampler.](../../run/primitives-get-started#start-sampler) - Explore [sessions.](../../run/sessions) From cbd06b64468e1748d3bef5051e1a311bf26dcb20 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Thu, 28 Mar 2024 17:23:54 -0500 Subject: [PATCH 12/65] edits --- .../qiskit-runtime-examples.mdx | 171 ++++++++---------- docs/api/migration-guides/v2-primitives.mdx | 1 + 2 files changed, 79 insertions(+), 93 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 471fa474671..24cd61c801e 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -57,7 +57,7 @@ result = backend.run(expectation_circuits) **Primitives model:** Access real systems and remote simulators through the `qiskit-ibm-runtime` **primitives** (`Sampler` and `Estimator`). Use **Local testing mode** to run local simulations on Qiskit Runtime fake backends or Aer simulators. The following examples assume you have defined circuits `isa_circuits` and observables `isa_observables`. - + ``` python from qiskit_ibm_runtime import EstimatorV2 as Estimator, QiskitRuntimeService @@ -76,7 +76,7 @@ result = job.result() ``` - + ``` python from qiskit_ibm_runtime import EstimatorV2 as Estimator from qiskit_ibm_runtime.fake_provider import FakeManilaV2 @@ -97,13 +97,14 @@ result = job.result() + +### End-to-end example + If your code previously calculated expectation values using `backend.run()`, you most likely used the `qiskit.opflow` module to handle operators and state functions. To support this scenario, the following migration example shows how to replace the (`qiskit.opflow` & `backend.run()`) workflow with an Estimator-based workflow. -### End-to-end example - #### 1. Problem definition We want to compute the expectation value of a quantum state (circuit) @@ -111,7 +112,7 @@ with respect to a certain operator. In this example, we are using the H2 molecule and an arbitrary circuit as the quantum state: - + For Qiskit Runtime, circuits and parameters must obey the Instruction Set Architecture (ISA) of a particular backend. ``` python @@ -187,11 +188,7 @@ opflow_op = PauliSumOp(op) opflow_state = CircuitStateFn(state) ``` -This step is not necessary when using the primitives. - - - For instructions to migrate from `qiskit.opflow`, see the [Opflow migration guide](./qiskit-opflow-module). - +This step is not necessary when using the primitives. For instructions to migrate from `qiskit.opflow`, see the [Opflow migration guide](./qiskit-opflow-module). #### 2. Calculate expectation values @@ -257,8 +254,7 @@ expectation: -1.065734058826613 #### 3. Local execution This section describes how to use Qiskit Runtime to test an -algorithm locally. Let's assume that we want to solve -the problem defined above with a local state vector simulation. +algorithm locally. These examples solve the problem defined above with a local simulation. @@ -332,6 +328,9 @@ state = QuantumCircuit(2) state.x(0) state.x(1) ``` + +For information about running noisy simulations with the Runtime primitives, see [Noisy simulators in Qiskit Runtime](../../verify/using-ibm-quantum-simulators) and [Local testing mode](../../verify/local-testing-mode). + ``` python @@ -402,7 +401,6 @@ expectation: [-1.06365335] -For more information about running noisy simulations with the **Runtime primitives**, see the [Noisy simulators in Qiskit Runtime](../../verify/using-ibm-quantum-simulators) topic. ## Use Sampler to design an algorithm @@ -419,11 +417,9 @@ probability distributions from measurement counts. Both `Sampler` and `backend.run()` take in circuits as inputs. The main difference is the format of the output: `backend.run()` outputs -**counts**, while `Sampler` processes those counts and outputs the -**quasi-probability distribution** associated with them. +**counts**, while `Sampler` processes those counts and outputs the **per-shot measurements** (in the form of bitstrings) associated with them. - - **Backend.run() model:** In this model, you used the `qiskit-ibmq-provider` (now migrated to `qiskit-ibm-provider`) module to access real systems and remote simulators. To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface. +**Backend.run() model:** In this model, you used the `qiskit-ibmq-provider` (now migrated to `qiskit-ibm-provider`) module to access real systems and remote simulators. To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface.
Code example with `qiskit-ibmq-provider` and `backend.run()` @@ -456,60 +452,69 @@ difference is the format of the output: `backend.run()` outputs ```
- **Primitives model:** Access real systems and remote simulators through the `qiskit-ibm-runtime` Sampler and Estimator *primitives*. To run **local** simulations, import specific local primitives from `qiskit_aer.primitives` and `qiskit.primitives`. All of them follow the `BaseSampler` and `BaseEstimator` interfaces, but **only the Runtime primitives offer access to the Runtime service, sessions, and built-in error mitigation**. + **Primitives model:** Access real systems and remote simulators through the `qiskit-ibm-runtime` Sampler and Estimator *primitives*. Use **local testing mode** to run local simulations by using Qiskit Runtime fake backends or Aer simulators.
Code example for Runtime Sampler ``` python - from qiskit_ibm_runtime import QiskitRuntimeService, Sampler + from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler # Define service service = QiskitRuntimeService() # Get backend - backend = service.backend("ibmq_qasm_simulator") # Use a cloud simulator + backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127) # Define Sampler - # (see tutorials more more info on sessions) - sampler = Sampler(session=backend) + sampler = Sampler(backend=backend) - # Run Quasi-Probability calculation - result = sampler.run(circuits).result() + # Run calculation + job = sampler.run([(isa_circuit,)]) + result = job.result() ```
-
- Code example for Aer Sampler - ``` python - from qiskit_aer import Sampler +## End-to-end example - # Get local simulator Sampler - sampler = Sampler() +The following example shows an end-to-end example of sampling a circuit by using `backend.run()` and `Sampler`. - # Run Quasi-Probability calculation - result = sampler.run(circuits).result() - ``` -
+### 1. Problem definition +We want to find the probability distribution +associated with a quantum state: + + + Important: When using the `Sampler` primitive, the circuit **must contain measurements**. + + + For Qiskit Runtime, circuits must obey the ISA of a particular backend. +``` python +from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler + +service = QiskitRuntimeService() +backend = service.least_busy(operational=True, simulator=False) -Next, we will show an end-to-end example of sampling a circuit: first, -with `backend.run()`, then by using the `Sampler`. +from qiskit import QuantumCircuit -## End-to-end example +circuit = QuantumCircuit(4) +circuit.h(range(2)) +circuit.cx(0,1) +circuit.measure_all() # measurement! -### 1. Problem definition +# Convert to ISA circuits +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager -We want to find the probability (or quasi-probability) distribution -associated with a quantum state: +pm = generate_preset_pass_manager(backend=backend, optimization_level=1) +isa_circuit = pm.run(circuit) - - Important: If you want to use the `Sampler` primitive, the circuit **must contain measurements**. - +``` + + ``` python from qiskit import QuantumCircuit @@ -518,11 +523,37 @@ circuit.h(range(2)) circuit.cx(0,1) circuit.measure_all() # measurement! ``` + + -### 2. Calculate probability distribution on a real device or cloud simulator +### 2. Calculate counts probability distribution on a real device or local simulator -#### 2.a. Legacy: Use backend.run() + + +While the user-side syntax of the `Sampler` is very similar to +`backend.run()`, notice that the workflow is now simplified, as the +quasi-probability distribution is returned **directly** (no need to +perform post-processing), together with some key metadata. +``` python +from qiskit_ibm_runtime import SamplerV2 as Sampler + +sampler = Sampler(backend=backend) + +job = sampler.run([(isa_circuit,)]) +result = job.result() +# Get results for the first (and only) PUB +pub_result = result[0] + +# Get counts from the classical register "meas". +print(f" >> Counts for the meas output register: {pub_result.data.meas.get_counts()}") +``` + + >> Counts for the meas output register: {'0001': 210, '0010': 305, '0000': 282, '0011': 201, '0101': 2, '1010': 6, '0110': 5, '0100': 6, '1000': 3, '0111': 1, '1001': 2, '1011': 1} + + + + The required steps to reach our goal with `backend.run()` are: 1. Run circuits @@ -585,58 +616,12 @@ counts: {'0000': 255, '0001': 258, '0010': 243, '0011': 268} quasi_dists: {'0000': 0.2490234375, '0001': 0.251953125, '0010': 0.2373046875, '0011': 0.26171875} ``` -#### 2.b. Updated: Use the Sampler runtime primitive - -While the user-side syntax of the `Sampler` is very similar to -`backend.run()`, notice that the workflow is now simplified, as the -quasi-probability distribution is returned **directly** (no need to -perform post-processing), together with some key metadata. - - - Replace `ibmq_qasm_simulator` with your device name to see the complete workflow for a real device. - - -``` python -from qiskit_ibm_runtime import QiskitRuntimeService, Sampler - -service = QiskitRuntimeService(channel="ibm_quantum") -backend = service.backend("ibmq_qasm_simulator") - -sampler = Sampler(session=backend) - -result = sampler.run(circuit, shots=1024).result() -quasi_dists = result.quasi_dists -``` - -``` python ->>> print("result: ", result) ->>> print("quasi_dists: ", quasi_dists) -result: SamplerResult(quasi_dists=[{0: 0.2802734375, 1: 0.2509765625, 2: 0.232421875, 3: 0.236328125}], -metadata=[{'header_metadata': {}, 'shots': 1024, 'readout_mitigation_overhead': 1.0, -'readout_mitigation_time': 0.03801989182829857}]) -quasi_dists: [{0: 0.2802734375, 1: 0.2509765625, 2: 0.232421875, 3: 0.236328125}] -``` + + - - Be careful with the output format. With `Sampler`, the states are no longer represented by bit strings, for example, `"11"`, but by integers, for example, `3`. To convert the `Sampler` output to bit strings, you can use the `QuasiDistribution.binary_probabilities()` method, as shown below. - -``` python ->>> # convert the output to bit strings ->>> binary_quasi_dist = quasi_dists[0].binary_probabilities() ->>> print("binary_quasi_dist: ", binary_quasi_dist) -binary_quasi_dist: {'0000': 0.2802734375, '0001': 0.2509765625, '0010': 0.232421875, '0011': 0.236328125} -``` - -The `Sampler` Runtime primitive offers several features and tuning -options that do not have a legacy alternative to migrate from, but can -help improve your performance and results. For more information, refer -to the following: -- [Error mitigation tutorial](https://learning.quantum.ibm.com/tutorial/error-suppression-and-error-mitigation-with-qiskit-runtime) -- [Setting execution options topic](../../run/advanced-runtime-options) -- [How to run a session topic](../../run/run-jobs-in-session) ### 3. Other execution alternatives (non-Runtime) diff --git a/docs/api/migration-guides/v2-primitives.mdx b/docs/api/migration-guides/v2-primitives.mdx index ea66d7d52ed..f97b9855be3 100644 --- a/docs/api/migration-guides/v2-primitives.mdx +++ b/docs/api/migration-guides/v2-primitives.mdx @@ -874,6 +874,7 @@ import numpy as np from qiskit.circuit.library import IQP from qiskit.quantum_info import random_hermitian from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager service = QiskitRuntimeService() From ec906165e21579db4a57811773ba35961a02cab4 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Thu, 28 Mar 2024 17:24:54 -0500 Subject: [PATCH 13/65] commit --- docs/api/migration-guides/qiskit-runtime-examples.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 24cd61c801e..e23fa9187aa 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -526,11 +526,11 @@ circuit.measure_all() # measurement!
-### 2. Calculate counts probability distribution on a real device or local simulator +### 2. Calculate counts on a real device or local simulator -While the user-side syntax of the `Sampler` is very similar to + While the user-side syntax of the `Sampler` is very similar to `backend.run()`, notice that the workflow is now simplified, as the quasi-probability distribution is returned **directly** (no need to perform post-processing), together with some key metadata. From ada2001819a70484c10dc293dfbf1834776ac700 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Thu, 28 Mar 2024 20:43:38 -0500 Subject: [PATCH 14/65] update code --- .../migration-guides/qiskit-runtime-examples.mdx | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index e23fa9187aa..e5d30411091 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -526,7 +526,7 @@ circuit.measure_all() # measurement! -### 2. Calculate counts on a real device or local simulator +### 2. Get counts from the result @@ -547,10 +547,8 @@ pub_result = result[0] # Get counts from the classical register "meas". print(f" >> Counts for the meas output register: {pub_result.data.meas.get_counts()}") -``` - >> Counts for the meas output register: {'0001': 210, '0010': 305, '0000': 282, '0011': 201, '0101': 2, '1010': 6, '0110': 5, '0100': 6, '1000': 3, '0111': 1, '1001': 2, '1011': 1} - +``` @@ -558,7 +556,6 @@ The required steps to reach our goal with `backend.run()` are: 1. Run circuits 2. Get counts from the result object -3. Use the counts and shots to calculate the probability distribution First, we run the circuit in a cloud simulator and output the result object: @@ -604,16 +601,9 @@ Now we get the probability distribution from the output: ``` python counts = result.get_counts(circuit) -quasi_dists = {} -for key,count in counts.items(): - quasi_dists[key] = count/1024 -``` -``` python >>> print("counts: ", counts) ->>> print("quasi_dists: ", quasi_dists) counts: {'0000': 255, '0001': 258, '0010': 243, '0011': 268} -quasi_dists: {'0000': 0.2490234375, '0001': 0.251953125, '0010': 0.2373046875, '0011': 0.26171875} ``` From 94be339fa5da6703a9b59b4d9219600cc1f7fbc9 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Thu, 28 Mar 2024 22:40:25 -0500 Subject: [PATCH 15/65] dynamic circuits --- .../qiskit-runtime-examples.mdx | 148 +----------------- .../qiskit-runtime-use-case.mdx | 23 +++ 2 files changed, 31 insertions(+), 140 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index e5d30411091..1f7d543bf0a 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -498,6 +498,11 @@ from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler service = QiskitRuntimeService() backend = service.least_busy(operational=True, simulator=False) +# To use Fake backends with local testing mode, import it and use it as the backend instead + +# from qiskit_ibm_runtime.fake_provider import FakeManilaV2 +# backend = FakeManilaV2() + from qiskit import QuantumCircuit circuit = QuantumCircuit(4) @@ -547,8 +552,10 @@ pub_result = result[0] # Get counts from the classical register "meas". print(f" >> Counts for the meas output register: {pub_result.data.meas.get_counts()}") - >> Counts for the meas output register: {'0001': 210, '0010': 305, '0000': 282, '0011': 201, '0101': 2, '1010': 6, '0110': 5, '0100': 6, '1000': 3, '0111': 1, '1001': 2, '1011': 1} + ``` +>> Counts for the meas output register: {'0001': 210, '0010': 305, '0000': 282, '0011': 201, '0101': 2, '1010': 6, '0110': 5, '0100': 6, '1000': 3, '0111': 1, '1001': 2, '1011': 1} +
@@ -610,145 +617,6 @@ counts: {'0000': 255, '0001': 258, '0010': 243, '0011': 268}
- - - -### 3. Other execution alternatives (non-Runtime) - -The following migration paths use non-Runtime primitives to use local -simulation to test an algorithm. Let's assume that we want to use a -local state vector simulation to solve the problem defined above. - -#### 3.a. Legacy: Use the Qiskit Aer simulator - -``` python -from qiskit_aer import AerSimulator - -# Define the statevector simulator -simulator = AerSimulator(method="statevector") - -# Run and get counts -result = simulator.run(circuit, shots=1024).result() -``` - -``` python ->>> print("result: ", result) -result: Result(backend_name='aer_simulator_statevector', backend_version='0.11.2', -qobj_id='e51e51bc-96d8-4e10-aa4e-15ee6264f4a0', job_id='c603daa7-2c03-488c-8c75-8c6ea0381bbc', -success=True, results=[ExperimentResult(shots=1024, success=True, meas_level=2, -data=ExperimentResultData(counts={'0x2': 236, '0x0': 276, '0x3': 262, '0x1': 250}), -header=QobjExperimentHeader(clbit_labels=[['meas', 0], ['meas', 1], ['meas', 2], ['meas', 3]], -creg_sizes=[['meas', 4]], global_phase=0.0, memory_slots=4, metadata={}, n_qubits=4, name='circuit-930', -qreg_sizes=[['q', 4]], qubit_labels=[['q', 0], ['q', 1], ['q', 2], ['q', 3]]), status=DONE, -seed_simulator=3531074553, metadata={'parallel_state_update': 16, 'parallel_shots': 1, -'sample_measure_time': 0.000405246, 'noise': 'ideal', 'batched_shots_optimization': False, -'remapped_qubits': False, 'device': 'CPU', 'active_input_qubits': [0, 1, 2, 3], 'measure_sampling': True, -'num_clbits': 4, 'input_qubit_map': [[3, 3], [2, 2], [1, 1], [0, 0]], 'num_qubits': 4, 'method': 'statevector', -'fusion': {'applied': False, 'max_fused_qubits': 5, 'threshold': 14, 'enabled': True}}, time_taken=0.001981756)], -date=2023-02-27T12:38:18.580995, status=COMPLETED, header=QobjHeader(backend_name='aer_simulator_statevector', -backend_version='0.11.2'), metadata={'mpi_rank': 0, 'num_mpi_processes': 1, 'num_processes_per_experiments': 1, -'time_taken': 0.002216379, 'max_gpu_memory_mb': 0, 'time_taken_execute': 0.002005713, 'max_memory_mb': 65536, -'time_taken_load_qobj': 0.000200642, 'parallel_experiments': 1, 'omp_enabled': True}, -time_taken=0.0025920867919921875) -``` - -Now let's get the probability distribution from the output: - -``` python -counts = result.get_counts(circuit) -quasi_dists = {} -for key,count in counts.items(): - quasi_dists[key] = count/1024 -``` - -``` python ->>> print("counts: ", counts) ->>> print("quasi_dists: ", quasi_dists) -counts: {'0010': 236, '0000': 276, '0011': 262, '0001': 250} -quasi_dists: {'0010': 0.23046875, '0000': 0.26953125, '0011': 0.255859375, '0001': 0.244140625} -``` - -#### 3.b. Updated: Use the Reference Sampler or Aer Sampler primitive - -The reference `Sampler` lets you perform an exact or a shot-based noisy -simulation based on the `Statevector` class in the `qiskit.quantum_info` -module. - -``` python -from qiskit.primitives import Sampler - -sampler = Sampler() - -result = sampler.run(circuit).result() -quasi_dists = result.quasi_dists -``` - -``` python ->>> print("result: ", result) ->>> print("quasi_dists: ", quasi_dists) -result: SamplerResult(quasi_dists=[{0: 0.249999999999, 1: 0.249999999999, -2: 0.249999999999, 3: 0.249999999999}], metadata=[{}]) -quasi_dists: [{0: 0.249999999999, 1: 0.249999999999, 2: 0.249999999999, -3: 0.249999999999}] -``` - -If shots are specified, this primitive outputs a shot-based simulation -(no longer exact): - -``` python -from qiskit.primitives import Sampler - -sampler = Sampler() - -result = sampler.run(circuit, shots=1024).result() -quasi_dists = result.quasi_dists -``` - -``` python ->>> print("result: ", result) ->>> print("quasi_dists: ", quasi_dists) -result: SamplerResult(quasi_dists=[{0: 0.2490234375, 1: 0.2578125, -2: 0.2431640625, 3: 0.25}], metadata=[{'shots': 1024}]) -quasi_dists: [{0: 0.2490234375, 1: 0.2578125, 2: 0.2431640625, 3: 0.25}] -``` - -You can still access the Aer simulator through its dedicated `Sampler`. -This can be handy for performing simulations with noise models. In this -example, the simulation method has been updated to match the result from -3.a. - -``` python -from qiskit_aer.primitives import Sampler as AerSampler # import change! - -sampler = AerSampler(run_options= {"method": "statevector"}) - -result = sampler.run(circuit, shots=1024).result() -quasi_dists = result.quasi_dists -``` - -``` python ->>> print("result: ", result) ->>> print("quasi_dists: ", quasi_dists) -result: SamplerResult(quasi_dists=[{1: 0.2802734375, 2: 0.2412109375, 0: 0.2392578125, -3: 0.2392578125}], metadata=[{'shots': 1024, 'simulator_metadata': -{'parallel_state_update': 16, 'parallel_shots': 1, 'sample_measure_time': 0.000409608, -'noise': 'ideal', 'batched_shots_optimization': False, 'remapped_qubits': False, -'device': 'CPU', 'active_input_qubits': [0, 1, 2, 3], 'measure_sampling': True, -'num_clbits': 4, 'input_qubit_map': [[3, 3], [2, 2], [1, 1], [0, 0]], 'num_qubits': 4, -'method': 'statevector', 'fusion': {'applied': False, 'max_fused_qubits': 5, -'threshold': 14, 'enabled': True}}}]) -quasi_dists: [{1: 0.2802734375, 2: 0.2412109375, 0: 0.2392578125, 3: 0.2392578125}] -``` - -``` python ->>> # Convert the output to bit strings ->>> binary_quasi_dist = quasi_dists[0].binary_probabilities() ->>> print("binary_quasi_dist: ", binary_quasi_dist) -binary_quasi_dist: {'0001': 0.2802734375, '0010': 0.2412109375, '0000': 0.2392578125, '0011': 0.2392578125} -``` - -For more information, see [Noisy simulators in Qiskit Runtime](../../verify/using-ibm-quantum-simulators). - ## Next steps The Runtime primitives offer a series of features and tuning options, some of which do not have a legacy alternative to migrate from, but can diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index bf015151d75..a1dc402fe93 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -10,6 +10,29 @@ description: Common use cases when migrating from backend.run to Qiskit Runtime ## Dynamic circuits +To migrate programs that run dynamic circuits, change the `backend.run(dynamic_circ)` to `sampler.run([dynamic_circ])`. + + + +```python +job = sampler.run([dynamic_circ]) + +pub_result = job.result()[0] +print(f">>> Hardware counts: {pub_result.data.meas.get_counts()}") +``` + + + +```python +job = backend.run(dynamic_circ, dynamic=True) +job.job_id() + +hardware_counts = job.result().get_counts() +hardware_counts +``` + + + ## Parameterized circuits with primitives From d7d7a7d39281358132c400777b5fcdccef487510 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Thu, 28 Mar 2024 22:41:00 -0500 Subject: [PATCH 16/65] commit --- docs/api/migration-guides/qiskit-runtime-use-case.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index a1dc402fe93..36c5feedaa9 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -14,7 +14,7 @@ To migrate programs that run dynamic circuits, change the `backend.run(dynamic_c -```python + ```python job = sampler.run([dynamic_circ]) pub_result = job.result()[0] @@ -23,7 +23,7 @@ print(f">>> Hardware counts: {pub_result.data.meas.get_counts()}") -```python + ```python job = backend.run(dynamic_circ, dynamic=True) job.job_id() From 883aea1d516c368f6a81944fd50b77776e18c6de Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 29 Mar 2024 12:57:54 -0500 Subject: [PATCH 17/65] update examples --- .../qiskit-runtime-examples.mdx | 2 - .../qiskit-runtime-options.mdx | 36 ++++----- .../qiskit-runtime-use-case.mdx | 81 ++++++++++++++++--- docs/api/migration-guides/qiskit-runtime.mdx | 7 +- docs/api/migration-guides/v2-primitives.mdx | 1 + 5 files changed, 91 insertions(+), 36 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 1f7d543bf0a..fa76b58b529 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -541,8 +541,6 @@ quasi-probability distribution is returned **directly** (no need to perform post-processing), together with some key metadata. ``` python -from qiskit_ibm_runtime import SamplerV2 as Sampler - sampler = Sampler(backend=backend) job = sampler.run([(isa_circuit,)]) diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index dd43f7118e9..0464acd0a5b 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -8,33 +8,33 @@ in_page_toc_max_heading_level: 2 # Migrate `backend.run` options to primitive options -All `backend.run` options are now available through the Qiskit Runtime primitives. +All `backend.run` options are now available through the Qiskit Runtime primitives. There are additional options available with the V2 primitives. See the [API reference](/api/qiskit-ibm-runtime/options) for the list of available options. See [Advanced Qiskit Runtime options](../._createMdxContent./run/advanced-runtime-options) for details about specifying V2 primitives options. -| backend.run options | SamplerV2 options | notes | +| backend.run options | V2 Primitive options | Notes | |---------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------| -| job_name | n/a, use job_tags instead | ibmq-provider only | -| job_share_level | n/a, this was deprecated long ago | ibmq-provider only | +| job_name | N/A: Use job_tags instead. | ibmq-provider only | +| job_share_level | N/A: This was deprecated long ago. | ibmq-provider only | | job_tags | options.environment.job_tags | | -| experiment_id | n/a, use job_tags instead | ibmq-provider only | +| experiment_id | N/A: Use job_tags instead. | ibmq-provider only | | header | You can attach metadata to circuits. The same metadata is returned in the result metadata, under “circuit_metadata”. | | -| shots | run([(…, shots)]) or run(…, shots=) or options.default_shots | | +| shots | run([(…, shots)]) or run(…, shots=) or options.default_shots | default_shots is availble only with SamplerV2 | | memory | Use result.data.meas.get_counts() to get counts and result.data.meas.get_bitstrings() to get per-shot measurements | SamplerV2 is essentially always memory=True | -| qubit_lo_freq | n/a, this option only applies to `Schedule` inputs, which was deprecated in 2022 | | -| meas_lo_freq | n/a, this option only applies to `Schedule` inputs, which was deprecated in 2022 | | -| schedule_los | n/a, this option only applies to `Schedule` inputs, which was deprecated in 2022 | | +| qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | +| meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | +| schedule_los | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | | meas_level | options.execution.meas_type | (meas_level, meas_return) → meas_type 0, * → not implemented 1, “avg” → “avg_kerneled” 1, “single” → “kerneled” 2, * → “classified” | | meas_return | options.execution.meas_type | | -| memory_slots | n/a, this is automatically determined by the system | ibmq-provider only | -| memory_slot_size | n/a, this is automatically determined by the system | ibmq-provider only | -| rep_time | n/a, use rep_delay instead | | +| memory_slots | N/A: This is automatically determined by the system. | ibmq-provider only | +| memory_slot_size | N/A: This is automatically determined by the system. | ibmq-provider only | +| rep_time | N/A: Use rep_delay instead. | | | rep_delay | options.execution.rep_delay | | | init_qubits | options.execution.init_qubits | | -| parameter_binds | specify parameters in PUBs | ibmq-provider only | -| use_measure_esp | n/a, this is no longer supported by IBM backends | | -| live_data_enabled | n/a, this feature was removed in 2022 | ibmq-provider only | -| dynamic | n/a, no longer needed. SamplerV2 knows if it’s dynamic | ibm-provider only | -| init_circuit | n/a, use init_qubits instead | | -| init_num_resets | n/a, use init_qubits instead | | +| parameter_binds | Specify parameters in PUBs. | ibmq-provider only | +| use_measure_esp | N/A: This is no longer supported by IBM backends. | | +| live_data_enabled | N/A: This feature was removed in 2022. | ibmq-provider only | +| dynamic | N/A: No longer needed. SamplerV2 knows if it’s dynamic. | ibm-provider only | +| init_circuit | N/A: Use init_qubits instead. | | +| init_num_resets | N/A: Use init_qubits instead. | | | noise_model | options.simulator.noise_model | | | seed_simulator | options.simulator.seed_simulator | | diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index 36c5feedaa9..a24d6cd08c6 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -4,13 +4,65 @@ description: Common use cases when migrating from backend.run to Qiskit Runtime --- # Common use cases - +This topic describes how to migrate programs with the most commonly used types of circuits. For a full example, see [End-to-end examples.](qiskit-runtime-examples) ## Basic circuits +The only changes when running basic circuits are how you run the job and retrieve results. + + + +```python +from qiskit_ibm_runtime import SamplerV2 as Sampler + +job = sampler.run([(isa_circuit,)]) +result = job.result() +# Get results for the first (and only) PUB +pub_result = result[0] + +``` + + + +``` python +from qiskit import IBMQ + +# Define provider and backend +provider = IBMQ.load_account() + +job = backend.run(circuit) +result = job.result() +``` + + + +## Circuits with options + +All options that were available with `backend.run` are available in the Qiskit Runtime primitives, but they are specified differently. For more information, see [Migrate `backend.run` options to primitive options](qiskit-runtime-options) and [Advanced Qiskit Runtime options.](../._createMdxContent./run/advanced-runtime-options) + + + + +```python +from qiskit_ibm_runtime import SamplerV2 as Sampler + +sampler.options.default_shots = 1024 +``` + + + + +```python +from qiskit import IBMQ + +backend.run(circuit, shots=1024) +``` + + + ## Dynamic circuits -To migrate programs that run dynamic circuits, change the `backend.run(dynamic_circ)` to `sampler.run([dynamic_circ])`. +To migrate programs that run dynamic circuits, change the run call. @@ -33,8 +85,10 @@ hardware_counts +For more information about dynamic circuits, see the [Classical feedforward and control flow](../../build/classical-feedforward-and-control-flow) topic, or try the [Repeat until success](https://learning.quantum.ibm.com/tutorial/repeat-until-success) tutorial. + -## Parameterized circuits with primitives +## Parameterized circuits Parametrized circuits are a commonly used tool for quantum algorithm design. Because `backend.run()` did not accept parametrized @@ -74,7 +128,17 @@ qc.measure(0, 0) qc.draw() ``` -V2 primitives support only circuits that adhere to the Instruction Set Architecture (ISA) of a particular backend, so we must transform our circuits. + +Assign the following parameter values to the circuit: + +``` python +import numpy as np +theta_values = [np.pi/2, np.pi/2, np.pi/2] +``` + + + +Qiskit Runtime V2 primitives support only circuits that adhere to the Instruction Set Architecture (ISA) of a particular backend, so we must transform our circuits. ```python from qiskit_ibm_runtime import QiskitRuntimeService @@ -87,15 +151,6 @@ pm = generate_preset_pass_manager(backend=backend, optimization_level=1) isa_circuit = pm.run(qc) ``` -We want to assign the following parameter values to the circuit: - -``` python -import numpy as np -theta_values = [np.pi/2, np.pi/2, np.pi/2] -``` - - - The primitives take in parametrized circuits directly, together with the parameter values, and the parameter assignment operation can be performed more efficiently on the server side of the primitive. The input is in the form of primitive unified blocs (PUBs). Each PUB is a tuple that contains a circuit and the data broadcasted to it. For further details, see [Introduction to primitives.](../../run/primitives#interface-changes) diff --git a/docs/api/migration-guides/qiskit-runtime.mdx b/docs/api/migration-guides/qiskit-runtime.mdx index d5abc43ddce..bbca49f856e 100644 --- a/docs/api/migration-guides/qiskit-runtime.mdx +++ b/docs/api/migration-guides/qiskit-runtime.mdx @@ -10,10 +10,11 @@ in_page_toc_max_heading_level: 2 # Migrate to using Qiskit Runtime primitives This guide describes key patterns of behavior and use cases with code -examples to help you migrate code from the legacy `backend.run()` interface (`qiskit-ibmq-provider` package) to use the Qiskit Runtime primitives interface (`qiskit-ibm-runtime` package). +examples to help you migrate code from the legacy `backend.run()` interface (`qiskit-ibmq-provider` package) to use the Qiskit Runtime primitives interface (`qiskit-ibm-runtime` package). - -Because both `backend.run()` and the "version 1" primitives are being deprecated, this guide uses only the V2 primitives. + +- Because `backend.run()` only returned counts, the direct replacement is Qiskit Runtime `SamplerV2`. However, if you used manual processing with `backend.run()` to return an expectation value, you can now use Qiskit Runtime `EstimatorV2` instead. +- Because both `backend.run()` and the "version 1" primitives are being deprecated, this guide uses only the V2 primitives. ## Overview diff --git a/docs/api/migration-guides/v2-primitives.mdx b/docs/api/migration-guides/v2-primitives.mdx index f97b9855be3..ba6030ded34 100644 --- a/docs/api/migration-guides/v2-primitives.mdx +++ b/docs/api/migration-guides/v2-primitives.mdx @@ -234,6 +234,7 @@ print(f" >> Counts for the alpha output register: {pub_result.data.alpha.get_cou print(f" >> Counts for the beta output register: {pub_result.data.beta.get_counts()}") ``` + ### Options Options are specified differently in the V2 primitives in these ways: From 90fd63d11122e8e97a7b1978b89a1c116ccd5de7 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 29 Mar 2024 13:00:41 -0500 Subject: [PATCH 18/65] spelling --- docs/api/migration-guides/qiskit-runtime-options.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index 0464acd0a5b..698757b09e4 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -17,7 +17,7 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | job_tags | options.environment.job_tags | | | experiment_id | N/A: Use job_tags instead. | ibmq-provider only | | header | You can attach metadata to circuits. The same metadata is returned in the result metadata, under “circuit_metadata”. | | -| shots | run([(…, shots)]) or run(…, shots=) or options.default_shots | default_shots is availble only with SamplerV2 | +| shots | run([(…, shots)]) or run(…, shots=) or options.default_shots | default_shots is available only with SamplerV2 | | memory | Use result.data.meas.get_counts() to get counts and result.data.meas.get_bitstrings() to get per-shot measurements | SamplerV2 is essentially always memory=True | | qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | | meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | From 3acf8c8c53ee3b313b5dac1ff83b204f4dab19dd Mon Sep 17 00:00:00 2001 From: Rebecca Dimock <66339736+beckykd@users.noreply.github.com> Date: Fri, 29 Mar 2024 13:02:14 -0500 Subject: [PATCH 19/65] Update docs/api/migration-guides/qiskit-runtime-setup.mdx Co-authored-by: Jessie Yu --- docs/api/migration-guides/qiskit-runtime-setup.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-setup.mdx b/docs/api/migration-guides/qiskit-runtime-setup.mdx index 68dee80769b..3f1a10f614d 100644 --- a/docs/api/migration-guides/qiskit-runtime-setup.mdx +++ b/docs/api/migration-guides/qiskit-runtime-setup.mdx @@ -128,9 +128,9 @@ IBMQ.load_account() -## Channel selection (get a provider) +## Instance selection (get a provider) -Use the updated code to select a channel. +Use the updated code to select an instance. From a919109921637eb659e425009fe9c031da092b50 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 29 Mar 2024 13:04:33 -0500 Subject: [PATCH 20/65] edits --- docs/api/migration-guides/qiskit-runtime-options.mdx | 2 +- docs/api/migration-guides/qiskit-runtime-use-case.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index 698757b09e4..f1df3d05f90 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -8,7 +8,7 @@ in_page_toc_max_heading_level: 2 # Migrate `backend.run` options to primitive options -All `backend.run` options are now available through the Qiskit Runtime primitives. There are additional options available with the V2 primitives. See the [API reference](/api/qiskit-ibm-runtime/options) for the list of available options. See [Advanced Qiskit Runtime options](../._createMdxContent./run/advanced-runtime-options) for details about specifying V2 primitives options. +All `backend.run` options are now available through the Qiskit Runtime primitives. There are additional options available with the V2 primitives. See the [API reference](/api/qiskit-ibm-runtime/options) for the list of available options. See [Advanced Qiskit Runtime options](../../run/advanced-runtime-options) for details about specifying V2 primitives options. | backend.run options | V2 Primitive options | Notes | |---------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------| diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index a24d6cd08c6..c407aae6863 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -37,7 +37,7 @@ result = job.result() ## Circuits with options -All options that were available with `backend.run` are available in the Qiskit Runtime primitives, but they are specified differently. For more information, see [Migrate `backend.run` options to primitive options](qiskit-runtime-options) and [Advanced Qiskit Runtime options.](../._createMdxContent./run/advanced-runtime-options) +All options that were available with `backend.run` are available in the Qiskit Runtime primitives, but they are specified differently. For more information, see [Migrate `backend.run` options to primitive options](qiskit-runtime-options) and [Advanced Qiskit Runtime options.](../../run/advanced-runtime-options) From 4455b498b1d5c6a9f804a7a2fdb2880189446645 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 29 Mar 2024 14:04:19 -0500 Subject: [PATCH 21/65] rendering issue --- docs/api/migration-guides/qiskit-runtime-examples.mdx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index fa76b58b529..369f1a0f86e 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -549,11 +549,10 @@ result = job.result() pub_result = result[0] # Get counts from the classical register "meas". -print(f" >> Counts for the meas output register: {pub_result.data.meas.get_counts()}") +print(f" >> Meas output register counts: {pub_result.data.meas.get_counts()}") -``` ->> Counts for the meas output register: {'0001': 210, '0010': 305, '0000': 282, '0011': 201, '0101': 2, '1010': 6, '0110': 5, '0100': 6, '1000': 3, '0111': 1, '1001': 2, '1011': 1} - +>> Meas output register counts: {'0001': 210, '0010': 305, '0000': 282, '0011': 201, '0101': 2, '1010': 6, '0110': 5, '0100': 6, '1000': 3, '0111': 1, '1001': 2, '1011': 1} +``` From ba8cebe229ab55a6925efbe9508dc3b941720b08 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 29 Mar 2024 14:14:08 -0500 Subject: [PATCH 22/65] edits --- docs/api/migration-guides/_toc.json | 2 +- docs/api/migration-guides/index.mdx | 2 +- docs/api/migration-guides/qiskit-runtime.mdx | 8 +++----- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/api/migration-guides/_toc.json b/docs/api/migration-guides/_toc.json index 68aac283b7e..b59488db480 100644 --- a/docs/api/migration-guides/_toc.json +++ b/docs/api/migration-guides/_toc.json @@ -35,7 +35,7 @@ "title": "Migrate to Qiskit Runtime", "children": [ { - "title": "Migrate from backend.run to primitives", + "title": "Overview", "url": "/api/migration-guides/qiskit-runtime" }, { diff --git a/docs/api/migration-guides/index.mdx b/docs/api/migration-guides/index.mdx index 479bb862855..13803f764b0 100644 --- a/docs/api/migration-guides/index.mdx +++ b/docs/api/migration-guides/index.mdx @@ -13,7 +13,7 @@ These migration guides help you more effectively use Qiskit and Qiskit Runtime: * [Qiskit 1.0 feature changes](/api/migration-guides/qiskit-1.0-features) * [Migrate to the Qiskit Runtime V2 primitives](/api/migration-guides/v2-primitives) * Migrate to Qiskit Runtime - * [How to migrate](./qiskit-runtime) + * [Overview](./qiskit-runtime) * [Migrate from `qiskit-ibmq-provider`](./qiskit-runtime-from-ibmq-provider) * [Migrate from `qiskit_ibm_provider`](./qiskit-runtime-from-ibm-provider) * [Migrate `backend.run` options to primitives](./qiskit-runtime-options) diff --git a/docs/api/migration-guides/qiskit-runtime.mdx b/docs/api/migration-guides/qiskit-runtime.mdx index bbca49f856e..b8c3cf30ae6 100644 --- a/docs/api/migration-guides/qiskit-runtime.mdx +++ b/docs/api/migration-guides/qiskit-runtime.mdx @@ -7,19 +7,17 @@ in_page_toc_max_heading_level: 2 --- -# Migrate to using Qiskit Runtime primitives +# Overview This guide describes key patterns of behavior and use cases with code -examples to help you migrate code from the legacy `backend.run()` interface (`qiskit-ibmq-provider` package) to use the Qiskit Runtime primitives interface (`qiskit-ibm-runtime` package). +examples to help you migrate code from the legacy `backend.run()` interface to use the Qiskit Runtime primitives interface (`qiskit-ibm-runtime` package). - Because `backend.run()` only returned counts, the direct replacement is Qiskit Runtime `SamplerV2`. However, if you used manual processing with `backend.run()` to return an expectation value, you can now use Qiskit Runtime `EstimatorV2` instead. - Because both `backend.run()` and the "version 1" primitives are being deprecated, this guide uses only the V2 primitives. -## Overview - -The `qiskit-ibm-runtime` package provides cloud access to the IBM Quantum™ systems through the primitives interface, which supersedes (and fully replaces) the former hardware interface, `backend.run()`. The `backend.run()` interface coexisted with the original (V1) primitives model as the dedicated “direct hardware access” entry point. With the introduction of the V2 primitives interface, the new `SamplerV2` class now fulfills that role. Consequentially, `qiskit-ibmq-provider`, the package that exposed the `backend.run()` interface, has been deprecated. +The `qiskit-ibm-runtime` package provides cloud access to the IBM Quantum™ systems through the primitives interface, which supersedes (and fully replaces) the former hardware interface, `backend.run()`. The `backend.run()` interface coexisted with the original (V1) primitives model as the dedicated “direct hardware access” entry point. With the introduction of the V2 primitives interface, the new `SamplerV2` class now fulfills that role. Consequentially, `backend.run()` is being deprecated, along with `qiskit-ibm-provider`, which only exposed the `backend.run()` interface. The Qiskit Runtime primitives implement the reference Sampler V2 and Estimator V2 interfaces found in `qiskit.primitives`, and enable capabilities not available with the legacy `backend.run()` interface. These capabilities include application of advanced processing techniques for error suppression and mitigation in Estimator, the ability to efficiently sweep between arrays of parameter value sets or observables in both Sampler and Estimator, and access to the new local testing mode. Additionally, Qiskit Runtime lets users run iterative algorithm circuits back to back (session mode) or in collections of circuits without having to re-queue each job (batch mode). This results in more efficient quantum processor use and reduces the time spent running complex computations. From 2255b0b0876df1db7784748082de89c5e7c9dfa4 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 29 Mar 2024 15:45:35 -0500 Subject: [PATCH 23/65] delete unneeded examples --- .../qiskit-runtime-examples.mdx | 4 +- .../qiskit-runtime-from-ibm-provider.mdx | 102 ++++++------- .../qiskit-runtime-from-ibmq-provider.mdx | 143 ++---------------- .../qiskit-runtime-use-case.mdx | 1 + docs/api/migration-guides/qiskit-runtime.mdx | 18 +-- 5 files changed, 66 insertions(+), 202 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 369f1a0f86e..578567e2752 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -97,7 +97,7 @@ result = job.result() - + ### End-to-end example If your code previously calculated expectation values using @@ -475,7 +475,7 @@ difference is the format of the output: `backend.run()` outputs ``` - + ## End-to-end example The following example shows an end-to-end example of sampling a circuit by using `backend.run()` and `Sampler`. diff --git a/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx index 628ded06851..82183ee02f7 100644 --- a/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx +++ b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx @@ -6,38 +6,41 @@ description: Migrate from backend.run in qiskit-ibm-provider to using Qiskit Run # Migrate from `qiskit_ibm_provider` to `qiskit_ibm_runtime` -The [`qiskit_ibm_provider`](../qiskit-ibm-provider) package from Qiskit Runtime is being deprecated. This guide describes how to migrate code that implemented `IBMBackend.run()` +This topic describes how to migrate code that implemented `IBMBackend.run()` using `qiskit_ibm_provider` to use `qiskit_ibm_runtime` instead. -## Example: Straightforward execution of IBMBackend.run() +## Example: Basic execution ```python -from qiskit_ibm_runtime import QiskitRuntimeService - -service = QiskitRuntimeService(channel="ibm_quantum") -backend = service.backend("ibmq_qasm_simulator") -transpiled_circuit = transpile(circuit, backend=backend) -job = backend.run(transpiled_circuit) -print(job.result()) +import numpy as np +from qiskit.circuit.library import IQP +from qiskit.quantum_info import random_hermitian +from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler + +service = QiskitRuntimeService() + +backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127) + +circuit = QuantumCircuit(2, 2) +circuit.h(0) +circuit.cx(0, 1) +circuit.measure_all() + +pm = generate_preset_pass_manager(backend=backend, optimization_level=1) +isa_circuit = pm.run(circuit) + +sampler = Sampler(backend) +job = sampler.run([(isa_circuit,)]) +result = job.result() +print(f" > Counts: {result[0].data.meas.get_counts()}") ``` - + ```python from qiskit_ibm_provider import IBMProvider - -provider = IBMProvider() -backend = provider.get_backend("ibmq_qasm_simulator") -transpiled_circuit = transpile(circuit, backend=backend) -job = backend.run(transpiled_circuit) -print(job.result()) -``` - - - -```python from qiskit import * from qiskit.compiler import transpile, assemble @@ -45,16 +48,33 @@ circuit = QuantumCircuit(2, 2) circuit.h(0) circuit.cx(0, 1) circuit.measure_all() + +provider = IBMProvider() +backend = provider.get_backend("ibmq_qasm_simulator") +transpiled_circuit = transpile(circuit, backend=backend) +job = backend.run(transpiled_circuit) +print(job.result()) ``` -## Example: Execution of backend.run() within a session +## Example: Execute `backend.run()` within a session -This section of code is identical in Provider and in Runtime. + + +```python +with Session(service=service, backend=backend) as session: + sampler = Sampler(session=session) + job = sampler.run([(isa_circuit)]) + another_job = sampler.run([(another_isa_circuit)]) + result = job.result() + another_result = another_job.result() +``` + + ```python with backend.open_session() as session: job1 = backend.run(transpiled_circuit) @@ -63,37 +83,5 @@ with backend.open_session() as session: print(job2.session_id) backend.cancel_session() ``` - -Sessions are implemented differently in `IBMBackend` than when using primitives. -Therefore, we cannot run a primitive and use backend.run() within a single session. If you specify both, one will be run outside of the session. - -## Example: Primitive session containing backend.run - -In this example, `sampler` is run within session, but `backend` is run independently -of the session. - -```python -from qiskit_ibm_runtime import Session, Sampler - -with Session(backend=backend) as session: - sampler = Sampler(session=session) - job1 = sampler.run(transpiled_circuit) - job2 = backend.run(transpiled_circuit) # runs outside the session - print(job1.session_id) - print(job2.session_id) # is None -``` - -## Example 4: `Backend` session containing Sampler - -In this example, `backend` is run within a session, but `sampler` is run independently -of the session. - -```python -with backend.open_session() as session: - sampler = Sampler(backend=backend) - job1 = sampler.run(transpiled_circuit) # runs outside the session - job2 = backend.run(transpiled_circuit) - session_id = session.session_id - print(job1.session_id) # is None - print(job2.session_id) -``` + + \ No newline at end of file diff --git a/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx index 86fec2ab67c..e65c97b8446 100644 --- a/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx +++ b/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx @@ -5,14 +5,14 @@ description: How to migrate `backend.run()` from Qiskit IBM Provider to Qiskit I # Migrate from `qiskit_ibmq_provider` to `qiskit_ibm_runtime` -This guide describes how to migrate code from the legacy IBMQ provider +This topic describes how to migrate code from the legacy IBMQ provider `qiskit-ibmq-provider` package to use Qiskit Runtime `qiskit-ibm-runtime`. ## Changes in Class name and location -The classes related to Qiskit Runtime that used to be included in -`qiskit-ibmq-provider` are now part of `qiskit-ibm-runtime`. Before, the +The classes related to Qiskit Runtime that were included in +`qiskit-ibmq-provider` are now part of `qiskit-ibm-runtime`. Previously, the provider used to populate the `qiskit.providers.ibmq.runtime` namespace with objects for Qiskit Runtime. These now live in the `qiskit_ibm_runtime` module. @@ -41,13 +41,13 @@ following table contains example access patterns in The import path has changed as follows: - + ``` python from qiskit_ibm_runtime import QiskitRuntimeService ``` - + ``` python from qiskit import IBMQ ``` @@ -59,16 +59,12 @@ from qiskit import IBMQ Use the updated code to work save accounts. - + The new syntax accepts credentials for Qiskit Runtime on IBM Cloud or IBM Quantum Platform. For more information on retrieving account credentials, see [Install and set up](../../start/install). ``` python -# IBM Cloud channel - -QiskitRuntimeService.save_account(channel="ibm_cloud", token="", instance="", overwrite=True) - # IBM Quantum channel; set to default QiskitRuntimeService.save_account(channel="ibm_quantum", token="", overwrite=True, default=true) @@ -89,7 +85,7 @@ service = QiskitRuntimeService(name="open") ``` - + ``` python IBMQ.save_account("", overwrite=True) ``` @@ -102,7 +98,7 @@ IBMQ.save_account("", overwrite=True) Use the updated code to load accounts. - + The new syntax combines the functionality from `load_account()` and `get_provider()` in one statement. The `channel` input parameter is optional. If multiple accounts have been saved in one device and no @@ -117,7 +113,7 @@ service = QiskitRuntimeService(channel="ibm_quantum") ``` - + ``` python IBMQ.load_account() ``` @@ -130,7 +126,7 @@ IBMQ.load_account() Use the updated code to select a channel. - + The new syntax combines the functionality from `load_account()` and `get_provider()` in one statement. When using the `ibm_quantum` channel, the `hub`, `group`, and `project` are specified through the new @@ -142,7 +138,7 @@ service = QiskitRuntimeService(channel="ibm_quantum", instance="my_hub/my_group/ ``` - + ``` python provider = IBMQ.get_provider(project="my_project", group="my_group", hub="my_hub") ``` @@ -151,10 +147,12 @@ provider = IBMQ.get_provider(project="my_project", group="my_group", hub="my_hub ## Get the system -Use the updated code to view systems and simulators. +Use the updated code to specify a backend. - + +With Qiskit Runtime, you can also run in local testing mode as illustrated in [End-to-end examples.](qiskit-runtime-examples) + ``` python # You can specify the instance in service.backend() instead of initializing a new service backend = service.backend("ibm_backend", instance="h1/g1/p1") @@ -169,7 +167,7 @@ backend = service.least_busy(operational=True, simulator=False, min_num_qubits=n ``` - + ``` python provider = IBMQ.get_provider(hub="h1", group="g1", project="p1") backend = provider.get_backend("ibm_backend") @@ -181,112 +179,3 @@ backend = provider.get_backend("ibm_backend") This function has been replaced with Quantum Serverless patterns. For instructions to migrate, see [Converting from Qiskit Runtime Programs.](https://qiskit-extensions.github.io/quantum-serverless/migration/migration_from_qiskit_runtime_programs.html) - -## Parameterized circuits with primitives - -Parametrized circuits are a commonly used tool for quantum algorithm -design. Because `backend.run()` did not accept parametrized -circuits, the parameter binding step had to be integrated in the -algorithm workflow. The primitives can perform the parameter binding -step internally, which results in a simplification of the algorithm-side -logic. - -The following example summarizes the new workflow for managing -parametrized circuits. - -### Example - -Define a parametrized circuit: - -``` python -from qiskit.circuit import QuantumCircuit, ParameterVector - -n = 3 -thetas = ParameterVector('θ',n) - -qc = QuantumCircuit(n, 1) -qc.h(0) - -for i in range(n-1): - qc.cx(i, i+1) - -for i,t in enumerate(thetas): - qc.rz(t, i) - -for i in reversed(range(n-1)): - qc.cx(i, i+1) - -qc.h(0) -qc.measure(0, 0) - -qc.draw() -``` - -V2 primitives support only circuits that adhere to the Instruction Set Architecture (ISA) of a particular backend, so we must transform our circuits. - -```python -from qiskit_ibm_runtime import QiskitRuntimeService -from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager - -service = QiskitRuntimeService() -backend = service.least_busy(operational=True, simulator=False) - -pm = generate_preset_pass_manager(backend=backend, optimization_level=1) -isa_circuit = pm.run(qc) -``` - -We want to assign the following parameter values to the circuit: - -``` python -import numpy as np -theta_values = [np.pi/2, np.pi/2, np.pi/2] -``` - - - -The primitives take in parametrized circuits directly, together -with the parameter values, and the parameter assignment operation can be -performed more efficiently on the server side of the primitive. The input is in the form of primitive unified blocs (PUBs). Each PUB is a tuple that contains a circuit and the data broadcasted to it. For further details, see [Introduction to primitives.](../../run/primitives#interface-changes) - -This feature is particularly interesting when working with iterative -algorithms because the parametrized circuit remains unchanged between -calls while the parameter values change. The primitives can transpile -once and then cache the unbound circuit, using classical resources more -efficiently. Moreover, only the updated parameters are transferred to -the cloud, saving additional bandwidth. - - -As shown in the previous image, the classical register name is `c`. Alternatively, you can find the classical register name by running `.cregs`. For example: `qc.cregs`. - - -``` python -from qiskit_ibm_runtime import SamplerV2 as Sampler - -sampler = Sampler(backend) -job = sampler.run([(isa_circuit, theta_values)]) -result = job.result() -# Get results for the first (and only) PUB -pub_result = result[0] -# Get counts from the classical register "c". -print(f" >> Counts for the c output register: {pub_result.data.c.get_counts()}") -``` - - - -The parameter values had to be bound to their respective -circuit parameters prior to calling `backend.run()`. - -``` python -from qiskit import Aer - -bound_circuit = qc.bind_parameters(theta_values) -bound_circuit.draw() - -backend = Aer.get_backend('aer_simulator') -job = backend.run(bound_circuit) -counts = job.result().get_counts() -print(counts) -``` - - - diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index c407aae6863..fd597d15276 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -35,6 +35,7 @@ result = job.result() + ## Circuits with options All options that were available with `backend.run` are available in the Qiskit Runtime primitives, but they are specified differently. For more information, see [Migrate `backend.run` options to primitive options](qiskit-runtime-options) and [Advanced Qiskit Runtime options.](../../run/advanced-runtime-options) diff --git a/docs/api/migration-guides/qiskit-runtime.mdx b/docs/api/migration-guides/qiskit-runtime.mdx index b8c3cf30ae6..87810d6d8e3 100644 --- a/docs/api/migration-guides/qiskit-runtime.mdx +++ b/docs/api/migration-guides/qiskit-runtime.mdx @@ -21,20 +21,6 @@ The `qiskit-ibm-runtime` package provides cloud access to the IBM Quantum™ The Qiskit Runtime primitives implement the reference Sampler V2 and Estimator V2 interfaces found in `qiskit.primitives`, and enable capabilities not available with the legacy `backend.run()` interface. These capabilities include application of advanced processing techniques for error suppression and mitigation in Estimator, the ability to efficiently sweep between arrays of parameter value sets or observables in both Sampler and Estimator, and access to the new local testing mode. Additionally, Qiskit Runtime lets users run iterative algorithm circuits back to back (session mode) or in collections of circuits without having to re-queue each job (batch mode). This results in more efficient quantum processor use and reduces the time spent running complex computations. - -Different packages expose different "flavors" of the primitive interfaces, for example: - -- The primitives in `qiskit` can perform local state vector - simulations - useful for quickly prototyping algorithms. -- The primitives in `qiskit_aer` give access to the local Aer - simulators for tasks such as noisy simulation. -- The primitives in `qiskit_ibm_runtime` provide access to cloud - simulators and real hardware through the Qiskit Runtime service. - They include exclusive features such as built-in circuit - optimization and error mitigation support. - -The **only primitives that provide access to the Qiskit Runtime service** are those imported from `qiskit_ibm_runtime` (Qiskit Runtime Primitives). - ## Basic steps to migrate to primitives @@ -72,8 +58,8 @@ See these topics: See the following topics: -- [Migrate `backend.run` options to primitive options.](qiskit-runtime-options) -- [Algorithm tuning options (shots, transpilation, and error mitigation)](../../run/advanced-runtime-options) +- [Migrate `backend.run` options to primitive options.](qiskit-runtime-options) +- [Common use cases - Options section](qiskit-runtime-options#migrate-options) ## Next steps From 915acd47aa8e3289549b5da08b9f1fe25814972c Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 29 Mar 2024 15:47:43 -0500 Subject: [PATCH 24/65] link --- docs/api/migration-guides/qiskit-runtime.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/migration-guides/qiskit-runtime.mdx b/docs/api/migration-guides/qiskit-runtime.mdx index 87810d6d8e3..b45ac1cb305 100644 --- a/docs/api/migration-guides/qiskit-runtime.mdx +++ b/docs/api/migration-guides/qiskit-runtime.mdx @@ -59,7 +59,7 @@ See these topics: See the following topics: - [Migrate `backend.run` options to primitive options.](qiskit-runtime-options) -- [Common use cases - Options section](qiskit-runtime-options#migrate-options) +- [Common use cases - Options section](qiskit-runtime-use-case#migrate-options) ## Next steps From 70ff73c0106fa57729d26210502bdbaeda5d6e16 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 29 Mar 2024 15:58:36 -0500 Subject: [PATCH 25/65] title --- docs/api/migration-guides/_toc.json | 2 +- docs/api/migration-guides/index.mdx | 2 +- docs/api/migration-guides/qiskit-runtime-options.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api/migration-guides/_toc.json b/docs/api/migration-guides/_toc.json index b59488db480..1ed9f031e89 100644 --- a/docs/api/migration-guides/_toc.json +++ b/docs/api/migration-guides/_toc.json @@ -47,7 +47,7 @@ "url": "/api/migration-guides/qiskit-runtime-from-ibm-provider" }, { - "title": "Migrate backend.run options to primitive options", + "title": "Migrate options", "url": "/api/migration-guides/qiskit-runtime-options" }, { diff --git a/docs/api/migration-guides/index.mdx b/docs/api/migration-guides/index.mdx index 13803f764b0..9d68404f4cd 100644 --- a/docs/api/migration-guides/index.mdx +++ b/docs/api/migration-guides/index.mdx @@ -16,7 +16,7 @@ These migration guides help you more effectively use Qiskit and Qiskit Runtime: * [Overview](./qiskit-runtime) * [Migrate from `qiskit-ibmq-provider`](./qiskit-runtime-from-ibmq-provider) * [Migrate from `qiskit_ibm_provider`](./qiskit-runtime-from-ibm-provider) - * [Migrate `backend.run` options to primitives](./qiskit-runtime-options) + * [Migrate options](./qiskit-runtime-options) * [Common use cases](./qiskit-runtime-use-case) * [Examples](./qiskit-runtime-examples) * [Migrate from cloud simulators to local simulators](/api/migration-guides/local-simulators) diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index f1df3d05f90..856a0bcbae7 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -6,7 +6,7 @@ description: Migrate backend.run options to Qiskit Runtime primitive options in_page_toc_max_heading_level: 2 --- -# Migrate `backend.run` options to primitive options +# Migrate options All `backend.run` options are now available through the Qiskit Runtime primitives. There are additional options available with the V2 primitives. See the [API reference](/api/qiskit-ibm-runtime/options) for the list of available options. See [Advanced Qiskit Runtime options](../../run/advanced-runtime-options) for details about specifying V2 primitives options. From 85fa8cbd8c46f40fea033702e86ae59b06ef8886 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 29 Mar 2024 16:02:51 -0500 Subject: [PATCH 26/65] missing tag --- docs/api/migration-guides/qiskit-runtime-examples.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 578567e2752..81ef0177a32 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -97,7 +97,7 @@ result = job.result() - + ### End-to-end example If your code previously calculated expectation values using From 3f7341bb69a740fdf3bb2017beb8ac4bc1824a07 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 29 Mar 2024 16:09:16 -0500 Subject: [PATCH 27/65] Jessie comments --- .../migration-guides/qiskit-runtime-from-ibmq-provider.mdx | 5 ----- docs/api/migration-guides/qiskit-runtime-use-case.mdx | 4 ++++ 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx index e65c97b8446..87984faa02b 100644 --- a/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx +++ b/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx @@ -174,8 +174,3 @@ backend = provider.get_backend("ibm_backend") ``` - -## Upload, view, or delete custom prototype programs - -This function has been replaced with Quantum Serverless patterns. For instructions to migrate, see [Converting from Qiskit Runtime Programs.](https://qiskit-extensions.github.io/quantum-serverless/migration/migration_from_qiskit_runtime_programs.html) - diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index fd597d15276..045ba7f0fe8 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -197,3 +197,7 @@ print(counts) ``` + +## Upload, view, or delete custom prototype programs + +This function has been replaced with Quantum Serverless patterns. For instructions to migrate, see [Converting from Qiskit Runtime Programs.](https://qiskit-extensions.github.io/quantum-serverless/migration/migration_from_qiskit_runtime_programs.html) From a40be7407b101a0c5b613a995888ff8745272da0 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 29 Mar 2024 16:11:43 -0500 Subject: [PATCH 28/65] remove unused file --- .../migration-guides/qiskit-runtime-setup.mdx | 301 ------------------ 1 file changed, 301 deletions(-) delete mode 100644 docs/api/migration-guides/qiskit-runtime-setup.mdx diff --git a/docs/api/migration-guides/qiskit-runtime-setup.mdx b/docs/api/migration-guides/qiskit-runtime-setup.mdx deleted file mode 100644 index 3f1a10f614d..00000000000 --- a/docs/api/migration-guides/qiskit-runtime-setup.mdx +++ /dev/null @@ -1,301 +0,0 @@ ---- -title: Migrate setup to qiskit-ibm-runtime -description: Migrate setup from using backend.run to using Qiskit Runtime primitives - - -in_page_toc_max_heading_level: 2 ---- - -# Migrate setup to qiskit-ibm-runtime - -This guide describes how to migrate code from the legacy IBMQ provider -`qiskit-ibmq-provider` package to use Qiskit Runtime -`qiskit-ibm-runtime`. - -## Changes in Class name and location - -The classes related to Qiskit Runtime that used to be included in -`qiskit-ibmq-provider` are now part of `qiskit-ibm-runtime`. Before, the -provider used to populate the `qiskit.providers.ibmq.runtime` namespace -with objects for Qiskit Runtime. These now live in the -`qiskit_ibm_runtime` module. - -The module from which the classes are imported has changed. The -following table contains example access patterns in -`qiskit.providers.ibmq.runtime` and their new form in -`qiskit_ibm_runtime`: - -| class in qiskit-ibmq-provider | class in qiskit-ibm-runtime | Notes | -|--------------------------------------------------|-------------------------------------------|----------------------------------------------------------------------------------------------------------------------| -| qiskit.providers.ibmq.runtime.IBMRuntimeService | qiskit_ibm_runtime.QiskitRuntimeService | IBMRuntimeService class was removed from qiskit-ibm-runtime 0.6 and replaced by the new class in qiskit-ibm-runtime. | -| qiskit.providers.ibmq.runtime.RuntimeJob | qiskit_ibm_runtime.RuntimeJob | -| qiskit.providers.ibmq.runtime.RuntimeProgram | | This class was used for custom programs, which are no longer supported. -| qiskit.providers.ibmq.runtime.UserMessenger | | This class was used for custom programs, which are no longer supported. | -| qiskit.providers.ibmq.runtime.ProgramBackend | | This class was used for custom programs, which are no longer supported. | -| qiskit.providers.ibmq.runtime.ResultDecoder | | This class was used for custom programs, which are no longer supported. | -| qiskit.providers.ibmq.runtime.RuntimeEncoder | qiskit_ibm_runtime.RuntimeEncoder | -| qiskit.providers.ibmq.runtime.RuntimeDecoder | qiskit_ibm_runtime.RuntimeDecoder | -| qiskit.providers.ibmq.runtime.ParameterNamespace | | This class was used for custom programs, which are no longer supported. -| qiskit.providers.ibmq.runtime.RuntimeOptions | qiskit_ibm_runtime.RuntimeOptions | - - -## Import path - -The import path has changed as follows: - - - -``` python -from qiskit_ibm_runtime import QiskitRuntimeService -``` - - - -``` python -from qiskit import IBMQ -``` - - - -## Save accounts - -Use the updated code to work save accounts. - - - -The new syntax accepts credentials for -Qiskit Runtime on IBM Cloud or IBM Quantum Platform. For more -information on retrieving account credentials, see [Install and set up](../../start/install). - -``` python -# IBM Cloud channel - -QiskitRuntimeService.save_account(channel="ibm_cloud", token="", instance="", overwrite=True) - -# IBM Quantum channel; set to default - -QiskitRuntimeService.save_account(channel="ibm_quantum", token="", overwrite=True, default=true) -``` - -Additionally, you can now name your saved credentials and load the credentials by name. - - -``` python -# Save different accounts for open and premium access - -QiskitRuntimeService.save_account(channel="ibm_quantum", token="", instance="h1/g1/p1", name="premium") -QiskitRuntimeService.save_account(channel="ibm_quantum", token="", instance="h2/g2/p2", name="open") - -# Load the "open" credentials - -service = QiskitRuntimeService(name="open") -``` - - - -``` python -IBMQ.save_account("", overwrite=True) -``` - - - - -## Load accounts - -Use the updated code to load accounts. - - - -The new syntax combines the functionality from `load_account()` and -`get_provider()` in one statement. The `channel` input parameter is -optional. If multiple accounts have been saved in one device and no -`channel` is provided, the default is `"ibm_cloud"`. - -``` python -# To access saved credentials for the IBM cloud channel -service = QiskitRuntimeService(channel="ibm_cloud") - -# To access saved credentials for the IBM quantum channel -service = QiskitRuntimeService(channel="ibm_quantum") -``` - - - -``` python -IBMQ.load_account() -``` - - - - -## Instance selection (get a provider) - -Use the updated code to select an instance. - - - -The new syntax combines the functionality from `load_account()` and -`get_provider()` in one statement. When using the `ibm_quantum` channel, -the `hub`, `group`, and `project` are specified through the new -`instance` keyword. - -``` python -# To access saved credentials for the IBM quantum channel and select an instance -service = QiskitRuntimeService(channel="ibm_quantum", instance="my_hub/my_group/my_project") -``` - - - -``` python -provider = IBMQ.get_provider(project="my_project", group="my_group", hub="my_hub") -``` - - - -## Get the system - -Use the updated code to view systems and simulators. - - - -``` python -# You can specify the instance in service.backend() instead of initializing a new service -backend = service.backend("ibm_backend", instance="h1/g1/p1") -``` -If you don't know what backend you want to use, you can instead use code such as the following: - -```python -from qiskit_ibm_runtime import QiskitRuntimeService - -service = QiskitRuntimeService() -backend = service.least_busy(operational=True, simulator=False, min_num_qubits=num_qubits) -``` - - - -``` python -provider = IBMQ.get_provider(hub="h1", group="g1", project="p1") -backend = provider.get_backend("ibm_backend") -``` - - - -## Upload, view, or delete custom prototype programs - -This function has been replaced with Quantum Serverless patterns. For instructions to migrate, see [Converting from Qiskit Runtime Programs.](https://qiskit-extensions.github.io/quantum-serverless/migration/migration_from_qiskit_runtime_programs.html) - - -## Parameterized circuits with primitives - -Parametrized circuits are a commonly used tool for quantum algorithm -design. Because `backend.run()` did not accept parametrized -circuits, the parameter binding step had to be integrated in the -algorithm workflow. The primitives can perform the parameter binding -step internally, which results in a simplification of the algorithm-side -logic. - -The following example summarizes the new workflow for managing -parametrized circuits. - -### Example - -Define a parametrized circuit: - -``` python -from qiskit.circuit import QuantumCircuit, ParameterVector - -n = 3 -thetas = ParameterVector('θ',n) - -qc = QuantumCircuit(n, 1) -qc.h(0) - -for i in range(n-1): - qc.cx(i, i+1) - -for i,t in enumerate(thetas): - qc.rz(t, i) - -for i in reversed(range(n-1)): - qc.cx(i, i+1) - -qc.h(0) -qc.measure(0, 0) - -qc.draw() -``` - -V2 primitives support only circuits that adhere to the Instruction Set Architecture (ISA) of a particular backend, so we must transform our circuits. - -```python -from qiskit_ibm_runtime import QiskitRuntimeService -from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager - -service = QiskitRuntimeService() -backend = service.least_busy(operational=True, simulator=False) - -pm = generate_preset_pass_manager(backend=backend, optimization_level=1) -isa_circuit = pm.run(qc) -``` - -We want to assign the following parameter values to the circuit: - -``` python -import numpy as np -theta_values = [np.pi/2, np.pi/2, np.pi/2] -``` - - - -The primitives take in parametrized circuits directly, together -with the parameter values, and the parameter assignment operation can be -performed more efficiently on the server side of the primitive. The input is in the form of primitive unified blocs (PUBs). Each PUB is a tuple that contains a circuit and the data broadcasted to it. For further details, see [Introduction to primitives.](../../run/primitives#interface-changes) - -This feature is particularly interesting when working with iterative -algorithms because the parametrized circuit remains unchanged between -calls while the parameter values change. The primitives can transpile -once and then cache the unbound circuit, using classical resources more -efficiently. Moreover, only the updated parameters are transferred to -the cloud, saving additional bandwidth. - - -As shown in the previous image, the classical register name is `c`. Alternatively, you can find the classical register name by running `.cregs`. For example: `qc.cregs`. - - -``` python -from qiskit_ibm_runtime import SamplerV2 as Sampler - -sampler = Sampler(backend) -job = sampler.run([(isa_circuit, theta_values)]) -result = job.result() -# Get results for the first (and only) PUB -pub_result = result[0] -# Get counts from the classical register "c". -print(f" >> Counts for the c output register: {pub_result.data.c.get_counts()}") -``` - - - -The parameter values had to be bound to their respective -circuit parameters prior to calling `backend.run()`. - -``` python -from qiskit import Aer - -bound_circuit = qc.bind_parameters(theta_values) -bound_circuit.draw() - -backend = Aer.get_backend('aer_simulator') -job = backend.run(bound_circuit) -counts = job.result().get_counts() -print(counts) -``` - - - -## Algorithm tuning - -One of the advantages of the primitives is that they abstract away the -circuit execution setup so that algorithm developers can focus on the -pure algorithmic components. However, sometimes, to get the most out of -an algorithm, you might want to tune certain primitive options. For details, see [Advanced runtime options](../../run/advanced-runtime-options). From f2b66c2e450ef9623a52dd04db0f625604cde9fb Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 29 Mar 2024 17:16:50 -0500 Subject: [PATCH 29/65] edits --- .../qiskit-runtime-from-ibm-provider.mdx | 10 +++++--- .../qiskit-runtime-from-ibmq-provider.mdx | 13 +++++----- .../qiskit-runtime-options.mdx | 8 +++--- docs/api/migration-guides/qiskit-runtime.mdx | 25 +++++++++---------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx index 82183ee02f7..4883240eadf 100644 --- a/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx +++ b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx @@ -4,13 +4,15 @@ description: Migrate from backend.run in qiskit-ibm-provider to using Qiskit Run --- -# Migrate from `qiskit_ibm_provider` to `qiskit_ibm_runtime` +# Migrate from `qiskit_ibm_provider` -This topic describes how to migrate code that implemented `IBMBackend.run()` -using `qiskit_ibm_provider` to use `qiskit_ibm_runtime` instead. +This topic shows how to migrate code that implemented `IBMBackend.run()` +by using `qiskit_ibm_provider` to use `qiskit_ibm_runtime`. ## Example: Basic execution +Change the import and run statements, instantiate the primitive, and make sure the input is modified to adhere to the backend's instruction set architecture (ISA). + ```python @@ -60,7 +62,7 @@ print(job.result()) -## Example: Execute `backend.run()` within a session +## Example: Use sessions diff --git a/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx index 87984faa02b..3a0016b1c9f 100644 --- a/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx +++ b/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx @@ -1,9 +1,9 @@ --- -title: Migrate from qiskit_ibm_provider to qiskit_ibm_runtime +title: Migrate from qiskit_ibm_provider description: How to migrate `backend.run()` from Qiskit IBM Provider to Qiskit IBM Runtime --- -# Migrate from `qiskit_ibmq_provider` to `qiskit_ibm_runtime` +# Migrate from `qiskit_ibmq_provider` This topic describes how to migrate code from the legacy IBMQ provider `qiskit-ibmq-provider` package to use Qiskit Runtime @@ -13,12 +13,11 @@ This topic describes how to migrate code from the legacy IBMQ provider The classes related to Qiskit Runtime that were included in `qiskit-ibmq-provider` are now part of `qiskit-ibm-runtime`. Previously, the -provider used to populate the `qiskit.providers.ibmq.runtime` namespace +provider populated the `qiskit.providers.ibmq.runtime` namespace with objects for Qiskit Runtime. These now live in the `qiskit_ibm_runtime` module. -The module from which the classes are imported has changed. The -following table contains example access patterns in +The following table contains example access patterns in `qiskit.providers.ibmq.runtime` and their new form in `qiskit_ibm_runtime`: @@ -145,7 +144,7 @@ provider = IBMQ.get_provider(project="my_project", group="my_group", hub="my_hub -## Get the system +## Get accepts system Use the updated code to specify a backend. @@ -163,7 +162,7 @@ If you don't know what backend you want to use, you can instead use code such as from qiskit_ibm_runtime import QiskitRuntimeService service = QiskitRuntimeService() -backend = service.least_busy(operational=True, simulator=False, min_num_qubits=num_qubits) +backend = service.least_busy(operational=True, simulator=False, min_num_qubits=) ``` diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index 856a0bcbae7..d89a6d4a68d 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -8,7 +8,7 @@ in_page_toc_max_heading_level: 2 # Migrate options -All `backend.run` options are now available through the Qiskit Runtime primitives. There are additional options available with the V2 primitives. See the [API reference](/api/qiskit-ibm-runtime/options) for the list of available options. See [Advanced Qiskit Runtime options](../../run/advanced-runtime-options) for details about specifying V2 primitives options. +All `backend.run` options are now available through the Qiskit Runtime primitives, but there are additional options available with the V2 primitives. See the [API reference](/api/qiskit-ibm-runtime/options) for the full list of available options. See [End-to-end examples](qiskit-runtime-examples) and [Advanced Qiskit Runtime options](../../run/advanced-runtime-options) for more information about specifying V2 primitives options. | backend.run options | V2 Primitive options | Notes | |---------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------| @@ -17,7 +17,7 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | job_tags | options.environment.job_tags | | | experiment_id | N/A: Use job_tags instead. | ibmq-provider only | | header | You can attach metadata to circuits. The same metadata is returned in the result metadata, under “circuit_metadata”. | | -| shots | run([(…, shots)]) or run(…, shots=) or options.default_shots | default_shots is available only with SamplerV2 | +| shots | run([(…, shots)]), run(…, shots=), or options.default_shots | default_shots is available with SamplerV2 only | | memory | Use result.data.meas.get_counts() to get counts and result.data.meas.get_bitstrings() to get per-shot measurements | SamplerV2 is essentially always memory=True | | qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | | meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | @@ -32,7 +32,7 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | parameter_binds | Specify parameters in PUBs. | ibmq-provider only | | use_measure_esp | N/A: This is no longer supported by IBM backends. | | | live_data_enabled | N/A: This feature was removed in 2022. | ibmq-provider only | -| dynamic | N/A: No longer needed. SamplerV2 knows if it’s dynamic. | ibm-provider only | +| dynamic | N/A: No longer needed. SamplerV2 automatically detects dynamic circuits. | ibm-provider only | | init_circuit | N/A: Use init_qubits instead. | | | init_num_resets | N/A: Use init_qubits instead. | | | noise_model | options.simulator.noise_model | | @@ -43,4 +43,4 @@ All `backend.run` options are now available through the Qiskit Runtime primitive One of the advantages of the primitives is that they abstract away the circuit execution setup so that algorithm developers can focus on the pure algorithmic components. However, sometimes, to get the most out of -an algorithm, you might want to tune certain primitive options. For details, see [Advanced runtime options](../../run/advanced-runtime-options). +an algorithm, you might want to tune certain primitive options. For details, see [Advanced runtime options.](../../run/advanced-runtime-options) diff --git a/docs/api/migration-guides/qiskit-runtime.mdx b/docs/api/migration-guides/qiskit-runtime.mdx index b45ac1cb305..12dd3752767 100644 --- a/docs/api/migration-guides/qiskit-runtime.mdx +++ b/docs/api/migration-guides/qiskit-runtime.mdx @@ -13,11 +13,11 @@ This guide describes key patterns of behavior and use cases with code examples to help you migrate code from the legacy `backend.run()` interface to use the Qiskit Runtime primitives interface (`qiskit-ibm-runtime` package). -- Because `backend.run()` only returned counts, the direct replacement is Qiskit Runtime `SamplerV2`. However, if you used manual processing with `backend.run()` to return an expectation value, you can now use Qiskit Runtime `EstimatorV2` instead. +- Because `backend.run()` only returned counts, the direct replacement is Qiskit Runtime `SamplerV2`. However, if you used manual processing with `backend.run()` to return expectation values, you can now use Qiskit Runtime `EstimatorV2` instead. - Because both `backend.run()` and the "version 1" primitives are being deprecated, this guide uses only the V2 primitives. -The `qiskit-ibm-runtime` package provides cloud access to the IBM Quantum™ systems through the primitives interface, which supersedes (and fully replaces) the former hardware interface, `backend.run()`. The `backend.run()` interface coexisted with the original (V1) primitives model as the dedicated “direct hardware access” entry point. With the introduction of the V2 primitives interface, the new `SamplerV2` class now fulfills that role. Consequentially, `backend.run()` is being deprecated, along with `qiskit-ibm-provider`, which only exposed the `backend.run()` interface. +The `qiskit-ibm-runtime` package provides cloud access to the IBM Quantum™ systems through the primitives interface. The `backend.run()` interface coexisted with the original (V1) primitives model as the dedicated “direct hardware access” entry point. With the introduction of the V2 primitives interface, the new `SamplerV2` class now fulfills that role. Consequentially, `backend.run()` is being deprecated, along with `qiskit-ibm-provider`, which only exposed the `backend.run()` interface. The Qiskit Runtime primitives implement the reference Sampler V2 and Estimator V2 interfaces found in `qiskit.primitives`, and enable capabilities not available with the legacy `backend.run()` interface. These capabilities include application of advanced processing techniques for error suppression and mitigation in Estimator, the ability to efficiently sweep between arrays of parameter value sets or observables in both Sampler and Estimator, and access to the new local testing mode. Additionally, Qiskit Runtime lets users run iterative algorithm circuits back to back (session mode) or in collections of circuits without having to re-queue each job (batch mode). This results in more efficient quantum processor use and reduces the time spent running complex computations. @@ -27,16 +27,15 @@ The Qiskit Runtime primitives implement the reference Sampler V2 and Estimator V ### Step 1 - Determine which primitive to use When migrating, the key to writing an equivalent algorithm using -primitives is to first identify what is the minimal unit of information +primitives is to first identify what minimal unit of information your algorithm is based on: -- If it uses an **expectation value** of a certain observable with respect to a -quantum state (a real number), you will need an `Estimator`. +- If it uses an **expectation value** of a certain observable with respect to a quantum state (a real number), you will now use Estimator. - An expectation value of an observable could be the target quantity in scenarios where knowing a quantum state is not relevant. This often occurs in optimization problems or chemistry applications. For example, when trying to discover the extremal energy of a system. -- If it uses a **probability distribution** from sampling the device (a list of quasi-probabilities), you will need a `Sampler`. + An expectation value of an observable could be the target quantity in scenarios where knowing a quantum state is not relevant. This often occurs in optimization problems or chemistry applications. For example, when trying to discover the extremal energy of a system. +- If it uses a **probability distribution** from sampling the device (a list of quasi-probabilities), you will now use Sampler. - A probability distribution is often of interest in optimization problems that return a classical bit string, encoding a certain solution to a problem at hand. In these cases, you might be interested in finding a bit string that corresponds to a ket value with the largest probability of being measured from a quantum state, for example. + A probability distribution is often of interest in optimization problems that return a classical bit string, encoding a certain solution to a problem at hand. In these cases, you might be interested in finding a bit string that corresponds to a ket value with the largest probability of being measured from a quantum state, for example. ### Step 2 - Change imports as necessary @@ -47,19 +46,19 @@ Follow the steps in the appropriate topic to change your import options and othe ### Step 3 - Replace the call to `backend.run` with a call to `qiskit_ibm_runtime`. -See these topics: +See these topics for instructions: - [Update code that performs circuit sampling](qiskit-runtime-examples#sampler-algorithm) - [Update code that calculates expectation values](qiskit-runtime-examples#estimator-algorithm) - [Common use cases (basic, parameterized, and dynamic circuits)](qiskit-runtime-use-case) -### Step 3a - replace any `backend.run` options with `qiskit_ibm_runtime`. +### Step 3a - replace any `backend.run` options with `qiskit_ibm_runtime` options. -See the following topics: +See the following topics for instructions: -- [Migrate `backend.run` options to primitive options.](qiskit-runtime-options) -- [Common use cases - Options section](qiskit-runtime-use-case#migrate-options) +- [Migrate options.](qiskit-runtime-options) +- Common use cases [Options section.](qiskit-runtime-use-case#migrate-options) ## Next steps From ed2867230cda2a101cb1d694b639071543fb83bd Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 29 Mar 2024 17:47:21 -0500 Subject: [PATCH 30/65] more edits --- .../qiskit-runtime-examples.mdx | 145 +++++++++--------- .../qiskit-runtime-use-case.mdx | 18 ++- 2 files changed, 83 insertions(+), 80 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 81ef0177a32..fc613a9741c 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -11,19 +11,9 @@ Follow these examples to design a Qiskit Runtime algorithm. ## Use Estimator to design an algorithm -The Estimator primitive is used to design an algorithm that calculates -expectation values. +Use the Estimator primitive to design an algorithm that calculates expectation values. -### Background - -The role of the `Estimator` primitive is two-fold: it acts as an **entry point** to quantum devices or simulators, replacing the `Backend` -interface (commonly referred to as `backend.run()`). Additionally, it is -an **algorithmic abstraction** for expectation value calculations, so -you don't have to manually construct the final expectation circuit. -This results in a considerable reduction of the code complexity and a -more compact algorithm design. - -**Backend.run() model:** In this model, you accessed real systems and remote simulators using the `qiskit-ibmq-provider` module (now migrated to `qiskit-ibm-provider`). To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface. +**Backend.run() model:** In this model, you accessed real systems and remote simulators by using the `qiskit-ibmq-provider` module (which was migrated to `qiskit-ibm-provider`). To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface. @@ -101,19 +91,18 @@ result = job.result() ### End-to-end example If your code previously calculated expectation values using -`backend.run()`, you most likely used the `qiskit.opflow` module to +`backend.run()`, you likely used the `qiskit.opflow` module to handle operators and state functions. To support this scenario, the -following migration example shows how to replace the (`qiskit.opflow` & `backend.run()`) workflow with an Estimator-based workflow. +following migration example shows how to replace the `backend.run()` plus `qiskit.opflow` workflow with an Estimator-based workflow. #### 1. Problem definition We want to compute the expectation value of a quantum state (circuit) -with respect to a certain operator. In this example, we are using the H2 +with respect to a certain operator. This example uses the H2 molecule and an arbitrary circuit as the quantum state: -For Qiskit Runtime, circuits and parameters must obey the Instruction Set Architecture (ISA) of a particular backend. ``` python from qiskit import QuantumCircuit @@ -140,7 +129,7 @@ from qiskit_ibm_runtime import QiskitRuntimeService service = QiskitRuntimeService() backend = service.least_busy(operational=True, simulator=False) -# Convert inputs to ISA +# For Qiskit Runtime, circuits and parameters must obey the Instruction Set Architecture (ISA) of a particular backend. from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager pm = generate_preset_pass_manager(backend=backend, optimization_level=1) @@ -178,7 +167,7 @@ state.x(1) ##### 1.a. Legacy only: Convert problem to opflow -`qiskit.opflow` provided its own classes to represent both operators +`qiskit.opflow` provided classes to represent operators and quantum states, so the problem defined above would be wrapped as: ``` python @@ -253,12 +242,11 @@ expectation: -1.065734058826613 #### 3. Local execution -This section describes how to use Qiskit Runtime to test an -algorithm locally. These examples solve the problem defined above with a local simulation. +These examples solve the problem defined above by using local simulation. -To use local testing mode, specify one of the fake backends from ``qiskit_ibm_runtime.fake_provider`` or specify a Qiskit Aer backend when instantiating a primitive or a session. +To use local testing mode, specify one of the fake backends from ``qiskit_ibm_runtime.fake_provider`` or specify a Qiskit Aer simulator when instantiating a primitive or a session. - **Fake backends**: The [fake backends](../qiskit-ibm-runtime/fake_provider) in ``qiskit_ibm_runtime.fake_provider`` mimic the behaviors of IBM Quantum™ systems by using system snapshots. The system snapshots contain important information about the quantum system, such as the coupling map, basis gates, and qubit properties, which are useful for testing the transpiler and performing noisy simulations of the system. The noise model from the snapshot is automatically applied during simulation. - **Aer simulator**: Simulators from [Qiskit Aer](../../verify/simulate-with-qiskit-aer) provide higher-performance simulation that can handle larger circuits and [custom noise models](../../verify/building_noise_models). It also supports Clifford simulation mode, which can efficiently simulate Clifford circuits with a large number of qubits. @@ -408,72 +396,84 @@ expectation: [-1.06365335] The Sampler primitive is used to design an algorithm that samples circuits and extracts probability distributions. -### Background - -The role of the `Sampler` primitive is two-fold: it acts as an **entry -point** to quantum devices or simulators, replacing `backend.run()`. -Additionally, it is an **algorithmic abstraction** to extract -probability distributions from measurement counts. - Both `Sampler` and `backend.run()` take in circuits as inputs. The main difference is the format of the output: `backend.run()` outputs **counts**, while `Sampler` processes those counts and outputs the **per-shot measurements** (in the form of bitstrings) associated with them. **Backend.run() model:** In this model, you used the `qiskit-ibmq-provider` (now migrated to `qiskit-ibm-provider`) module to access real systems and remote simulators. To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface. -
- Code example with `qiskit-ibmq-provider` and `backend.run()` + + +``` python +from qiskit import IBMQ - ``` python - from qiskit import IBMQ +# Select provider +provider = IBMQ.load_account() - # Select provider - provider = IBMQ.load_account() +# Get backend +backend = provider.get_backend("ibmq_qasm_simulator") # Use the cloud simulator - # Get backend - backend = provider.get_backend("ibmq_qasm_simulator") # Use the cloud simulator +# Run +result = backend.run(circuits) +``` - # Run - result = backend.run(circuits) - ``` -
+
-
- Code example for `qiskit-aer` & `backend.run()` + +``` python +from qiskit_aer import AerSimulator # former import: from qiskit import Aer - ``` python - from qiskit_aer import AerSimulator # former import: from qiskit import Aer +# Get local simulator backend +backend = AerSimulator() - # Get local simulator backend - backend = AerSimulator() +# Run +result = backend.run(circuits) +``` + + - # Run - result = backend.run(circuits) - ``` -
+**Primitives model:** Access real systems and remote simulators through the `qiskit-ibm-runtime` Sampler and Estimator *primitives*. Use **local testing mode** to run local simulations by using Qiskit Runtime fake backends or Aer simulators. - **Primitives model:** Access real systems and remote simulators through the `qiskit-ibm-runtime` Sampler and Estimator *primitives*. Use **local testing mode** to run local simulations by using Qiskit Runtime fake backends or Aer simulators. + + +``` python +from qiskit_ibm_runtime import SamplerV2 as Sampler, QiskitRuntimeService -
- Code example for Runtime Sampler +# Define the service. This allows you to access IBM Quantum systems. +service = QiskitRuntimeService() - ``` python - from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler +# Get a backend +backend = service.least_busy(operational=True, simulator=False) - # Define service - service = QiskitRuntimeService() +# Define Sampler +sampler = Sampler(backend=backend) - # Get backend - backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127) +# Run calculation +job = sampler.run([(isa_circuit,)]) +result = job.result() +``` + - # Define Sampler - sampler = Sampler(backend=backend) + +``` python +from qiskit_ibm_runtime import SamplerV2 as Sampler +from qiskit_ibm_runtime.fake_provider import FakeManilaV2 - # Run calculation - job = sampler.run([(isa_circuit,)]) - result = job.result() - ``` -
+# Run the sampler job locally using FakeManilaV2 +fake_manila = FakeManilaV2() + +# You can use a fixed seed to get fixed results. +options = {"simulator": {"seed_simulator": 42}} + +# Define Sampler +sampler = Sampler(backend=fake_manila, options=options) + +# Run calculation +job = sampler.run([(isa_circuit,)])) +result = job.result() +``` +
+
## End-to-end example @@ -485,13 +485,12 @@ The following example shows an end-to-end example of sampling a circuit by using We want to find the probability distribution associated with a quantum state: - - Important: When using the `Sampler` primitive, the circuit **must contain measurements**. + +When using the `Sampler` primitive, the circuit **must contain measurements**. - For Qiskit Runtime, circuits must obey the ISA of a particular backend. ``` python from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler @@ -510,6 +509,7 @@ circuit.h(range(2)) circuit.cx(0,1) circuit.measure_all() # measurement! +# For Qiskit Runtime, circuits must obey the ISA of a particular backend. # Convert to ISA circuits from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager @@ -535,11 +535,6 @@ circuit.measure_all() # measurement! - While the user-side syntax of the `Sampler` is very similar to -`backend.run()`, notice that the workflow is now simplified, as the -quasi-probability distribution is returned **directly** (no need to -perform post-processing), together with some key metadata. - ``` python sampler = Sampler(backend=backend) @@ -615,7 +610,7 @@ counts: {'0000': 255, '0001': 258, '0010': 243, '0011': 268} ## Next steps -The Runtime primitives offer a series of features and tuning +The Qiskit Runtime primitives offer a series of features and tuning options, some of which do not have a legacy alternative to migrate from, but can help improve your performance and results. For more information, refer to the following: diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index 045ba7f0fe8..cd0b61d0b94 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -38,7 +38,7 @@ result = job.result() ## Circuits with options -All options that were available with `backend.run` are available in the Qiskit Runtime primitives, but they are specified differently. For more information, see [Migrate `backend.run` options to primitive options](qiskit-runtime-options) and [Advanced Qiskit Runtime options.](../../run/advanced-runtime-options) +All options that were available with `backend.run` are available in the Qiskit Runtime primitives, but they are specified differently. For more information, see [Migrate options](qiskit-runtime-options) and [Advanced Qiskit Runtime options.](../../run/advanced-runtime-options) @@ -128,7 +128,15 @@ qc.measure(0, 0) qc.draw() ``` - + ┌───┐ ┌──────────┐ ┌───┐┌─┐ +q_0: ┤ H ├──■──┤ Rz(θ[0]) ├───────────────────■──┤ H ├┤M├ + └───┘┌─┴─┐└──────────┘┌──────────┐ ┌─┴─┐└───┘└╥┘ +q_1: ─────┤ X ├─────■──────┤ Rz(θ[1]) ├──■──┤ X ├──────╫─ + └───┘ ┌─┴─┐ ├──────────┤┌─┴─┐└───┘ ║ +q_2: ─────────────┤ X ├────┤ Rz(θ[2]) ├┤ X ├───────────╫─ + └───┘ └──────────┘└───┘ ║ +c: 1/══════════════════════════════════════════════════╩═ + 0 Assign the following parameter values to the circuit: @@ -139,7 +147,7 @@ theta_values = [np.pi/2, np.pi/2, np.pi/2] -Qiskit Runtime V2 primitives support only circuits that adhere to the Instruction Set Architecture (ISA) of a particular backend, so we must transform our circuits. +Qiskit Runtime V2 primitives support only circuits that adhere to the Instruction Set Architecture (ISA) of a particular backend, so we must transform the circuits. ```python from qiskit_ibm_runtime import QiskitRuntimeService @@ -154,7 +162,7 @@ isa_circuit = pm.run(qc) The primitives take in parametrized circuits directly, together with the parameter values, and the parameter assignment operation can be -performed more efficiently on the server side of the primitive. The input is in the form of primitive unified blocs (PUBs). Each PUB is a tuple that contains a circuit and the data broadcasted to it. For further details, see [Introduction to primitives.](../../run/primitives#interface-changes) +performed more efficiently on the server side. The input is in the form of primitive unified blocs (PUBs), where each PUB is a tuple that contains a circuit and the data broadcasted to it. For further details, see [Introduction to primitives.](../../run/primitives#interface-changes) This feature is particularly interesting when working with iterative algorithms because the parametrized circuit remains unchanged between @@ -164,7 +172,7 @@ efficiently. Moreover, only the updated parameters are transferred to the cloud, saving additional bandwidth. -As shown in the previous image, the classical register name is `c`. Alternatively, you can find the classical register name by running `.cregs`. For example: `qc.cregs`. +You need the classical register name to get the results. By default, it is named `meas`. However, as shown in the previous image, the classical register name for this example is `c`. You can also find the classical register name by running `.cregs`. For example, `qc.cregs`. ``` python From ff3293375d8991e263287329fe781e995042a463 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 29 Mar 2024 17:48:01 -0500 Subject: [PATCH 31/65] commit --- .../qiskit-runtime-examples.mdx | 81 ++++++++++--------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index fc613a9741c..29d0bf27521 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -404,55 +404,55 @@ difference is the format of the output: `backend.run()` outputs -``` python -from qiskit import IBMQ - -# Select provider -provider = IBMQ.load_account() + ``` python + from qiskit import IBMQ -# Get backend -backend = provider.get_backend("ibmq_qasm_simulator") # Use the cloud simulator + # Select provider + provider = IBMQ.load_account() -# Run -result = backend.run(circuits) -``` + # Get backend + backend = provider.get_backend("ibmq_qasm_simulator") # Use the cloud simulator - + # Run + result = backend.run(circuits) + ``` + + - -``` python -from qiskit_aer import AerSimulator # former import: from qiskit import Aer + + ``` python + from qiskit_aer import AerSimulator # former import: from qiskit import Aer -# Get local simulator backend -backend = AerSimulator() + # Get local simulator backend + backend = AerSimulator() -# Run -result = backend.run(circuits) -``` - + # Run + result = backend.run(circuits) + ``` + -**Primitives model:** Access real systems and remote simulators through the `qiskit-ibm-runtime` Sampler and Estimator *primitives*. Use **local testing mode** to run local simulations by using Qiskit Runtime fake backends or Aer simulators. + **Primitives model:** Access real systems and remote simulators through the `qiskit-ibm-runtime` Sampler and Estimator *primitives*. Use **local testing mode** to run local simulations by using Qiskit Runtime fake backends or Aer simulators. - - -``` python -from qiskit_ibm_runtime import SamplerV2 as Sampler, QiskitRuntimeService + + + ``` python + from qiskit_ibm_runtime import SamplerV2 as Sampler, QiskitRuntimeService -# Define the service. This allows you to access IBM Quantum systems. -service = QiskitRuntimeService() + # Define the service. This allows you to access IBM Quantum systems. + service = QiskitRuntimeService() -# Get a backend -backend = service.least_busy(operational=True, simulator=False) + # Get a backend + backend = service.least_busy(operational=True, simulator=False) -# Define Sampler -sampler = Sampler(backend=backend) + # Define Sampler + sampler = Sampler(backend=backend) -# Run calculation -job = sampler.run([(isa_circuit,)]) -result = job.result() -``` - + # Run calculation + job = sampler.run([(isa_circuit,)]) + result = job.result() + ``` + ``` python @@ -491,7 +491,7 @@ When using the `Sampler` primitive, the circuit **must contain measurements**. -``` python + ``` python from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler service = QiskitRuntimeService() @@ -535,6 +535,11 @@ circuit.measure_all() # measurement! + While the user-side syntax of the `Sampler` is very similar to +`backend.run()`, notice that the workflow is now simplified, as the +quasi-probability distribution is returned **directly** (no need to +perform post-processing), together with some key metadata. + ``` python sampler = Sampler(backend=backend) @@ -610,7 +615,7 @@ counts: {'0000': 255, '0001': 258, '0010': 243, '0011': 268} ## Next steps -The Qiskit Runtime primitives offer a series of features and tuning +The Runtime primitives offer a series of features and tuning options, some of which do not have a legacy alternative to migrate from, but can help improve your performance and results. For more information, refer to the following: From 3f65b28a90f6f35dad935ed34742bd308f7eae99 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock <66339736+beckykd@users.noreply.github.com> Date: Tue, 2 Apr 2024 12:58:38 -0500 Subject: [PATCH 32/65] Apply suggestions from code review Co-authored-by: Jessie Yu --- .../qiskit-runtime-from-ibm-provider.mdx | 21 +++++++++---------- .../qiskit-runtime-from-ibmq-provider.mdx | 6 +++--- .../qiskit-runtime-options.mdx | 2 +- .../qiskit-runtime-use-case.mdx | 12 +++++++---- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx index 4883240eadf..c15a2046b1e 100644 --- a/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx +++ b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx @@ -16,9 +16,7 @@ Change the import and run statements, instantiate the primitive, and make sure t ```python -import numpy as np -from qiskit.circuit.library import IQP -from qiskit.quantum_info import random_hermitian +from qiskit import QuantumCircuit from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler service = QiskitRuntimeService() @@ -55,7 +53,7 @@ provider = IBMProvider() backend = provider.get_backend("ibmq_qasm_simulator") transpiled_circuit = transpile(circuit, backend=backend) job = backend.run(transpiled_circuit) -print(job.result()) +print(f" > Counts: {job.result().get_counts()}") ``` @@ -67,10 +65,12 @@ print(job.result()) ```python +from qiskit_ibm_runtime import Session + with Session(service=service, backend=backend) as session: sampler = Sampler(session=session) - job = sampler.run([(isa_circuit)]) - another_job = sampler.run([(another_isa_circuit)]) + job = sampler.run([isa_circuit]) + another_job = sampler.run([another_isa_circuit]) result = job.result() another_result = another_job.result() ``` @@ -79,11 +79,10 @@ with Session(service=service, backend=backend) as session: ```python with backend.open_session() as session: - job1 = backend.run(transpiled_circuit) - job2 = backend.run(transpiled_circuit) - print(job1.session_id) - print(job2.session_id) -backend.cancel_session() + job = backend.run(transpiled_circuit) + another_job = backend.run(transpiled_circuit) + result = job.result() + another_result = another_job.result() ``` \ No newline at end of file diff --git a/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx index 3a0016b1c9f..24517c4fe18 100644 --- a/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx +++ b/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx @@ -120,9 +120,9 @@ IBMQ.load_account() -## Channel selection (get a provider) +## Instance selection (get a provider) -Use the updated code to select a channel. +Use the updated code to select a hub, group, and project. @@ -144,7 +144,7 @@ provider = IBMQ.get_provider(project="my_project", group="my_group", hub="my_hub -## Get accepts system +## Get a backend Use the updated code to specify a backend. diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index d89a6d4a68d..ab035d0189e 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -13,7 +13,7 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | backend.run options | V2 Primitive options | Notes | |---------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------| | job_name | N/A: Use job_tags instead. | ibmq-provider only | -| job_share_level | N/A: This was deprecated long ago. | ibmq-provider only | +| job_share_level | N/A: This was deprecated long ago and no longer supported. | ibmq-provider only | | job_tags | options.environment.job_tags | | | experiment_id | N/A: Use job_tags instead. | ibmq-provider only | | header | You can attach metadata to circuits. The same metadata is returned in the result metadata, under “circuit_metadata”. | | diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index cd0b61d0b94..8089b785d54 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -14,7 +14,7 @@ The only changes when running basic circuits are how you run the job and retriev ```python from qiskit_ibm_runtime import SamplerV2 as Sampler -job = sampler.run([(isa_circuit,)]) +job = sampler.run([isa_circuit]) result = job.result() # Get results for the first (and only) PUB pub_result = result[0] @@ -36,7 +36,7 @@ result = job.result() -## Circuits with options +## Specifying options All options that were available with `backend.run` are available in the Qiskit Runtime primitives, but they are specified differently. For more information, see [Migrate options](qiskit-runtime-options) and [Advanced Qiskit Runtime options.](../../run/advanced-runtime-options) @@ -46,6 +46,7 @@ All options that were available with `backend.run` are available in the Qiskit R ```python from qiskit_ibm_runtime import SamplerV2 as Sampler +# You can use auto-complete to see and complete the options. sampler.options.default_shots = 1024 ``` @@ -66,8 +67,11 @@ backend.run(circuit, shots=1024) To migrate programs that run dynamic circuits, change the run call. - + ```python +from qiskit_ibm_runtime import SamplerV2 as Sampler + +sampler = Sampler(backend) job = sampler.run([dynamic_circ]) pub_result = job.result()[0] @@ -172,7 +176,7 @@ efficiently. Moreover, only the updated parameters are transferred to the cloud, saving additional bandwidth. -You need the classical register name to get the results. By default, it is named `meas`. However, as shown in the previous image, the classical register name for this example is `c`. You can also find the classical register name by running `.cregs`. For example, `qc.cregs`. +You need the classical register name to get the results. By default, it is named `meas` when you use `measure_all()`. However, as shown in the previous image, the classical register name for this example is `c`. You can also find the classical register name by running `.cregs`. For example, `qc.cregs`. ``` python From 64053c0c65a6a05b163e416d6cb27e8e615ea9cd Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Tue, 2 Apr 2024 16:33:43 -0500 Subject: [PATCH 33/65] comments - check table --- .../qiskit-runtime-from-ibm-provider.mdx | 128 +++++++++++++++++- .../qiskit-runtime-from-ibmq-provider.mdx | 39 ++++-- .../qiskit-runtime-options.mdx | 4 +- 3 files changed, 152 insertions(+), 19 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx index c15a2046b1e..e4dda120952 100644 --- a/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx +++ b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx @@ -9,6 +9,129 @@ description: Migrate from backend.run in qiskit-ibm-provider to using Qiskit Run This topic shows how to migrate code that implemented `IBMBackend.run()` by using `qiskit_ibm_provider` to use `qiskit_ibm_runtime`. +## Save accounts + +Use the updated code to work save accounts. + + + +The new syntax accepts credentials for +Qiskit Runtime on IBM Cloud or IBM Quantum Platform. For more +information on retrieving account credentials, see [Install and set up](../../start/install). + +``` python +# IBM Quantum channel; set to default + +QiskitRuntimeService.save_account(channel="ibm_quantum", token="", overwrite=True, default=true) +``` + +Additionally, you can now name your saved credentials and load the credentials by name. + + +``` python +# Save different accounts for open and premium access + +QiskitRuntimeService.save_account(channel="ibm_quantum", token="", instance="h1/g1/p1", name="premium") +QiskitRuntimeService.save_account(channel="ibm_quantum", token="", instance="h2/g2/p2", name="open") + +# Load the "open" credentials + +service = QiskitRuntimeService(name="open") +``` + + + +``` python +IBMProvider.save_account(token='MY_API_TOKEN') +``` + + + + +## Load accounts + +Use the updated code to load accounts. + + + +The new syntax combines the functionality from `load_account()` and +`get_provider()` in one statement. The `channel` input parameter is +optional. If multiple accounts have been saved in one device and no +`channel` is provided, the default is `"ibm_cloud"`. + +``` python +# To access saved credentials for the IBM cloud channel +service = QiskitRuntimeService(channel="ibm_cloud") + +# To access saved credentials for the IBM quantum channel +service = QiskitRuntimeService(channel="ibm_quantum") +``` + + + +``` python +IBMProvider.load_account() +``` + + + + +## Instance selection (get a provider) + +Use the updated code to select a hub, group, and project. + + + +The new syntax combines the functionality from `load_account()` and +`get_provider()` in one statement. When using the `ibm_quantum` channel, +the `hub`, `group`, and `project` are specified through the new +`instance` keyword. + +``` python +# To access saved credentials for the IBM quantum channel and select an instance +service = QiskitRuntimeService(channel="ibm_quantum", instance="my_hub/my_group/my_project") +``` + + + +``` python +provider = IBMProvider(instance="my_hub/my_group/my_project") + +``` + + + +## Get a backend + +Use the updated code to specify a backend. + + + +With Qiskit Runtime, you can also run in local testing mode as illustrated in [End-to-end examples.](qiskit-runtime-examples) + +``` python +# You can specify the instance in service.backend() instead of initializing a new service +backend = service.backend("ibm_backend", instance="h1/g1/p1") +``` +If you don't know what backend you want to use, you can instead use code such as the following: + +```python +from qiskit_ibm_runtime import QiskitRuntimeService + +service = QiskitRuntimeService() +backend = service.least_busy(operational=True, simulator=False, min_num_qubits=) +``` + + + +``` python +provider = ibm.get_provider(hub="h1", group="g1", project="p1") +backend = provider.get_backend("ibm_backend") +``` + + + + ## Example: Basic execution Change the import and run statements, instantiate the primitive, and make sure the input is modified to adhere to the backend's instruction set architecture (ISA). @@ -41,7 +164,7 @@ print(f" > Counts: {result[0].data.meas.get_counts()}") ```python from qiskit_ibm_provider import IBMProvider -from qiskit import * +from qiskit import QuantumCircuit from qiskit.compiler import transpile, assemble circuit = QuantumCircuit(2, 2) @@ -50,7 +173,7 @@ circuit.cx(0, 1) circuit.measure_all() provider = IBMProvider() -backend = provider.get_backend("ibmq_qasm_simulator") +backend = provider.get_backend("ibm_qasm_simulator") transpiled_circuit = transpile(circuit, backend=backend) job = backend.run(transpiled_circuit) print(f" > Counts: {job.result().get_counts()}") @@ -66,6 +189,7 @@ print(f" > Counts: {job.result().get_counts()}") ```python from qiskit_ibm_runtime import Session +from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler with Session(service=service, backend=backend) as session: sampler = Sampler(session=session) diff --git a/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx index 24517c4fe18..191d345b0da 100644 --- a/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx +++ b/docs/api/migration-guides/qiskit-runtime-from-ibmq-provider.mdx @@ -21,19 +21,19 @@ The following table contains example access patterns in `qiskit.providers.ibmq.runtime` and their new form in `qiskit_ibm_runtime`: -| class in qiskit-ibmq-provider | class in qiskit-ibm-runtime | Notes | +| Class in qiskit-ibmq-provider | Class in qiskit-ibm-runtime | Notes | |--------------------------------------------------|-------------------------------------------|----------------------------------------------------------------------------------------------------------------------| | qiskit.providers.ibmq.runtime.IBMRuntimeService | qiskit_ibm_runtime.QiskitRuntimeService | IBMRuntimeService class was removed from qiskit-ibm-runtime 0.6 and replaced by the new class in qiskit-ibm-runtime. | -| qiskit.providers.ibmq.runtime.RuntimeJob | qiskit_ibm_runtime.RuntimeJob | -| qiskit.providers.ibmq.runtime.RuntimeProgram | | This class was used for custom programs, which are no longer supported. -| qiskit.providers.ibmq.runtime.UserMessenger | | This class was used for custom programs, which are no longer supported. | -| qiskit.providers.ibmq.runtime.ProgramBackend | | This class was used for custom programs, which are no longer supported. | -| qiskit.providers.ibmq.runtime.ResultDecoder | | This class was used for custom programs, which are no longer supported. | -| qiskit.providers.ibmq.runtime.RuntimeEncoder | qiskit_ibm_runtime.RuntimeEncoder | -| qiskit.providers.ibmq.runtime.RuntimeDecoder | qiskit_ibm_runtime.RuntimeDecoder | -| qiskit.providers.ibmq.runtime.ParameterNamespace | | This class was used for custom programs, which are no longer supported. -| qiskit.providers.ibmq.runtime.RuntimeOptions | qiskit_ibm_runtime.RuntimeOptions | +| qiskit.providers.ibmq.runtime.RuntimeEncoder | qiskit_ibm_runtime.RuntimeEncoder | | +| qiskit.providers.ibmq.runtime.RuntimeDecoder | qiskit_ibm_runtime.RuntimeDecoder | | +The following classes were used for custom programs, which are no longer supported. Therefore, the classes are no longer supported: + +* qiskit.providers.ibmq.runtime.RuntimeProgram +* qiskit.providers.ibmq.runtime.UserMessenger +* qiskit.providers.ibmq.runtime.ProgramBackend +* qiskit.providers.ibmq.runtime.ResultDecoder +* qiskit.providers.ibmq.runtime.ParameterNamespace ## Import path @@ -61,7 +61,7 @@ Use the updated code to work save accounts. The new syntax accepts credentials for Qiskit Runtime on IBM Cloud or IBM Quantum Platform. For more -information on retrieving account credentials, see [Install and set up](../../start/install). +information on retrieving account credentials, see [Select and set up an IBM Quantum channel](../../start/setup-channel). ``` python # IBM Quantum channel; set to default @@ -98,8 +98,7 @@ Use the updated code to load accounts. -The new syntax combines the functionality from `load_account()` and -`get_provider()` in one statement. The `channel` input parameter is +The `channel` input parameter is optional. If multiple accounts have been saved in one device and no `channel` is provided, the default is `"ibm_cloud"`. @@ -150,8 +149,6 @@ Use the updated code to specify a backend. -With Qiskit Runtime, you can also run in local testing mode as illustrated in [End-to-end examples.](qiskit-runtime-examples) - ``` python # You can specify the instance in service.backend() instead of initializing a new service backend = service.backend("ibm_backend", instance="h1/g1/p1") @@ -164,6 +161,18 @@ from qiskit_ibm_runtime import QiskitRuntimeService service = QiskitRuntimeService() backend = service.least_busy(operational=True, simulator=False, min_num_qubits=) ``` +With Qiskit Runtime, you can also run in local testing mode. + +```python +# Define a local backend +from qiskit_ibm_runtime.fake_provider import FakeManilaV2 +backend = FakeManilaV2() + +# You could use an Aer simulator instead by using the following code: +# from qiskit_aer import AerSimulator +# backend = AerSimulator() +``` + diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index ab035d0189e..be70ca2b7a5 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -13,11 +13,11 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | backend.run options | V2 Primitive options | Notes | |---------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------| | job_name | N/A: Use job_tags instead. | ibmq-provider only | -| job_share_level | N/A: This was deprecated long ago and no longer supported. | ibmq-provider only | +| job_share_level | N/A: This was deprecated long ago and no longer supported. | ibmq-provider only | | job_tags | options.environment.job_tags | | | experiment_id | N/A: Use job_tags instead. | ibmq-provider only | | header | You can attach metadata to circuits. The same metadata is returned in the result metadata, under “circuit_metadata”. | | -| shots | run([(…, shots)]), run(…, shots=), or options.default_shots | default_shots is available with SamplerV2 only | +| shots | run([(…, shots)]) or
run(…, shots=) or
options.default_shots | default_shots is available with SamplerV2 only | | memory | Use result.data.meas.get_counts() to get counts and result.data.meas.get_bitstrings() to get per-shot measurements | SamplerV2 is essentially always memory=True | | qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | | meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | From 6d59807f03dfe7326e60d86ab88dd740c160d4a3 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Tue, 2 Apr 2024 16:48:49 -0500 Subject: [PATCH 34/65] need to close br tags --- docs/api/migration-guides/qiskit-runtime-options.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index be70ca2b7a5..4a6ed791def 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -17,7 +17,7 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | job_tags | options.environment.job_tags | | | experiment_id | N/A: Use job_tags instead. | ibmq-provider only | | header | You can attach metadata to circuits. The same metadata is returned in the result metadata, under “circuit_metadata”. | | -| shots | run([(…, shots)]) or
run(…, shots=) or
options.default_shots | default_shots is available with SamplerV2 only | +| shots | run([(…, shots)]) or

run(…, shots=) or

options.default_shots | | | memory | Use result.data.meas.get_counts() to get counts and result.data.meas.get_bitstrings() to get per-shot measurements | SamplerV2 is essentially always memory=True | | qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | | meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | From 57fd9cbca9eae54a411d5dad0c81be1987bc0bcd Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Tue, 2 Apr 2024 16:57:57 -0500 Subject: [PATCH 35/65] fix table --- docs/api/migration-guides/qiskit-runtime-options.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index 4a6ed791def..10899f9efcb 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -17,12 +17,12 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | job_tags | options.environment.job_tags | | | experiment_id | N/A: Use job_tags instead. | ibmq-provider only | | header | You can attach metadata to circuits. The same metadata is returned in the result metadata, under “circuit_metadata”. | | -| shots | run([(…, shots)]) or

run(…, shots=) or

options.default_shots | | +| shots | Any of the following:

run([(…, shots)])

run(…, shots=)

options.default_shots | | | memory | Use result.data.meas.get_counts() to get counts and result.data.meas.get_bitstrings() to get per-shot measurements | SamplerV2 is essentially always memory=True | | qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | | meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | | schedule_los | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | -| meas_level | options.execution.meas_type | (meas_level, meas_return) → meas_type 0, * → not implemented 1, “avg” → “avg_kerneled” 1, “single” → “kerneled” 2, * → “classified” | +| meas_level | options.execution.meas_type | (meas_level, meas_return) → meas_type

0, * → not implemented

1, “avg” → “avg_kerneled” 1, “single” → “kerneled”

2, * → “classified” | | meas_return | options.execution.meas_type | | | memory_slots | N/A: This is automatically determined by the system. | ibmq-provider only | | memory_slot_size | N/A: This is automatically determined by the system. | ibmq-provider only | From ae070c70c0a9b38c4669d60147630b927682fe68 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Tue, 2 Apr 2024 17:07:30 -0500 Subject: [PATCH 36/65] fix table --- docs/api/migration-guides/qiskit-runtime-options.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index 10899f9efcb..a4387d7fd60 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -22,7 +22,7 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | | meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | | schedule_los | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | -| meas_level | options.execution.meas_type | (meas_level, meas_return) → meas_type

0, * → not implemented

1, “avg” → “avg_kerneled” 1, “single” → “kerneled”

2, * → “classified” | +| meas_level | options.execution.meas_type | (meas_level, meas_return) → meas_type

0, * → not implemented

1, “avg” → “avg_kerneled”

1, “single” → “kerneled”

2, * → “classified” | | meas_return | options.execution.meas_type | | | memory_slots | N/A: This is automatically determined by the system. | ibmq-provider only | | memory_slot_size | N/A: This is automatically determined by the system. | ibmq-provider only | From 8e687b0e61e6aa1b211bc472680f58c2ec922330 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Wed, 3 Apr 2024 08:38:20 -0500 Subject: [PATCH 37/65] Edits --- .../api/migration-guides/qiskit-runtime-options.mdx | 10 +++++----- .../migration-guides/qiskit-runtime-use-case.mdx | 13 ++----------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index a4387d7fd60..caeaca1e118 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -18,12 +18,12 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | experiment_id | N/A: Use job_tags instead. | ibmq-provider only | | header | You can attach metadata to circuits. The same metadata is returned in the result metadata, under “circuit_metadata”. | | | shots | Any of the following:

run([(…, shots)])

run(…, shots=)

options.default_shots | | -| memory | Use result.data.meas.get_counts() to get counts and result.data.meas.get_bitstrings() to get per-shot measurements | SamplerV2 is essentially always memory=True | -| qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | -| meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | -| schedule_los | N/A: This option only applies to `Schedule` inputs, which was deprecated in 2022. | | +| memory | Use result.data..get_counts() to get counts and result.data..get_bitstrings() to get per-shot measurements | | +| qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | +| meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | +| schedule_los | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | | meas_level | options.execution.meas_type | (meas_level, meas_return) → meas_type

0, * → not implemented

1, “avg” → “avg_kerneled”

1, “single” → “kerneled”

2, * → “classified” | -| meas_return | options.execution.meas_type | | +| meas_return | options.execution.meas_type | See above | | memory_slots | N/A: This is automatically determined by the system. | ibmq-provider only | | memory_slot_size | N/A: This is automatically determined by the system. | ibmq-provider only | | rep_time | N/A: Use rep_delay instead. | | diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index 8089b785d54..563d9487151 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -132,15 +132,6 @@ qc.measure(0, 0) qc.draw() ``` - ┌───┐ ┌──────────┐ ┌───┐┌─┐ -q_0: ┤ H ├──■──┤ Rz(θ[0]) ├───────────────────■──┤ H ├┤M├ - └───┘┌─┴─┐└──────────┘┌──────────┐ ┌─┴─┐└───┘└╥┘ -q_1: ─────┤ X ├─────■──────┤ Rz(θ[1]) ├──■──┤ X ├──────╫─ - └───┘ ┌─┴─┐ ├──────────┤┌─┴─┐└───┘ ║ -q_2: ─────────────┤ X ├────┤ Rz(θ[2]) ├┤ X ├───────────╫─ - └───┘ └──────────┘└───┘ ║ -c: 1/══════════════════════════════════════════════════╩═ - 0 Assign the following parameter values to the circuit: @@ -151,7 +142,7 @@ theta_values = [np.pi/2, np.pi/2, np.pi/2] -Qiskit Runtime V2 primitives support only circuits that adhere to the Instruction Set Architecture (ISA) of a particular backend, so we must transform the circuits. +Only circuits that adhere to the Instruction Set Architecture (ISA) of a specific backend are accepted, so we must transform the circuits. ```python from qiskit_ibm_runtime import QiskitRuntimeService @@ -176,7 +167,7 @@ efficiently. Moreover, only the updated parameters are transferred to the cloud, saving additional bandwidth. -You need the classical register name to get the results. By default, it is named `meas` when you use `measure_all()`. However, as shown in the previous image, the classical register name for this example is `c`. You can also find the classical register name by running `.cregs`. For example, `qc.cregs`. +You need the classical register name to get the results. By default, it is named `meas` when you use `measure_all()`. However, the classical register name for this example is `c`. You can find the classical register name by running `.cregs`. For example, `qc.cregs`. ``` python From 0055ffbbbd267c4b797ec1d79d61c586d2d320bc Mon Sep 17 00:00:00 2001 From: Rebecca Dimock <66339736+beckykd@users.noreply.github.com> Date: Wed, 3 Apr 2024 10:35:03 -0500 Subject: [PATCH 38/65] Apply suggestions from code review Co-authored-by: Jessie Yu --- .../qiskit-runtime-examples.mdx | 18 ++++++++++++------ docs/api/migration-guides/qiskit-runtime.mdx | 3 ++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 29d0bf27521..39d3409d90e 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -13,7 +13,8 @@ Follow these examples to design a Qiskit Runtime algorithm. Use the Estimator primitive to design an algorithm that calculates expectation values. -**Backend.run() model:** In this model, you accessed real systems and remote simulators by using the `qiskit-ibmq-provider` module (which was migrated to `qiskit-ibm-provider`). To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface. +**Backend.run() model:** In this model, you accessed real systems and remote simulators by using the `qiskit-ibmq-provider` or the `qiskit-ibm-provider` module. To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface. + @@ -398,9 +399,11 @@ circuits and extracts probability distributions. Both `Sampler` and `backend.run()` take in circuits as inputs. The main difference is the format of the output: `backend.run()` outputs -**counts**, while `Sampler` processes those counts and outputs the **per-shot measurements** (in the form of bitstrings) associated with them. +**counts**, while `Sampler` returns **per-shot measurements** (but has convenience methods to also return counts). + + +**Backend.run() model:** In this model, you used the `qiskit-ibmq-provider` or the `qiskit-ibm-provider` module to access real systems and remote simulators. To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface. -**Backend.run() model:** In this model, you used the `qiskit-ibmq-provider` (now migrated to `qiskit-ibm-provider`) module to access real systems and remote simulators. To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface. @@ -432,7 +435,8 @@ difference is the format of the output: `backend.run()` outputs - **Primitives model:** Access real systems and remote simulators through the `qiskit-ibm-runtime` Sampler and Estimator *primitives*. Use **local testing mode** to run local simulations by using Qiskit Runtime fake backends or Aer simulators. + **Primitives model:** Access real systems through the `qiskit-ibm-runtime` Sampler and Estimator *primitives*. Use **local testing mode** to run local simulations by using Qiskit Runtime fake backends or Aer simulators. + @@ -449,7 +453,8 @@ difference is the format of the output: `backend.run()` outputs sampler = Sampler(backend=backend) # Run calculation - job = sampler.run([(isa_circuit,)]) + job = sampler.run([isa_circuit]) + result = job.result() ``` @@ -469,7 +474,8 @@ options = {"simulator": {"seed_simulator": 42}} sampler = Sampler(backend=fake_manila, options=options) # Run calculation -job = sampler.run([(isa_circuit,)])) +job = sampler.run([isa_circuit]) + result = job.result() ``` diff --git a/docs/api/migration-guides/qiskit-runtime.mdx b/docs/api/migration-guides/qiskit-runtime.mdx index 12dd3752767..5b6d5df0fea 100644 --- a/docs/api/migration-guides/qiskit-runtime.mdx +++ b/docs/api/migration-guides/qiskit-runtime.mdx @@ -33,7 +33,8 @@ your algorithm is based on: - If it uses an **expectation value** of a certain observable with respect to a quantum state (a real number), you will now use Estimator. An expectation value of an observable could be the target quantity in scenarios where knowing a quantum state is not relevant. This often occurs in optimization problems or chemistry applications. For example, when trying to discover the extremal energy of a system. -- If it uses a **probability distribution** from sampling the device (a list of quasi-probabilities), you will now use Sampler. +- If it uses a **probability distribution** from sampling the device, you will now use Sampler. + A probability distribution is often of interest in optimization problems that return a classical bit string, encoding a certain solution to a problem at hand. In these cases, you might be interested in finding a bit string that corresponds to a ket value with the largest probability of being measured from a quantum state, for example. From 0b531d63966c22bf0a26906bae7b902b553cab7f Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Wed, 3 Apr 2024 11:22:28 -0500 Subject: [PATCH 39/65] Pull out the Local section --- .../qiskit-runtime-examples.mdx | 189 ++---------------- 1 file changed, 22 insertions(+), 167 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 39d3409d90e..9d128067ac3 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -125,12 +125,16 @@ state = QuantumCircuit(2) state.x(0) state.x(1) -# Define the backend -from qiskit_ibm_runtime import QiskitRuntimeService -service = QiskitRuntimeService() -backend = service.least_busy(operational=True, simulator=False) +# Define a local backend +from qiskit_ibm_runtime.fake_provider import FakeManilaV2 +backend = FakeManilaV2() -# For Qiskit Runtime, circuits and parameters must obey the Instruction Set Architecture (ISA) of a particular backend. +# Define a real backend +# from qiskit_ibm_runtime import QiskitRuntimeService +# service = QiskitRuntimeService() +# backend = service.least_busy(operational=True, simulator=False) + +# Circuits and parameters must obey the Instruction Set Architecture (ISA) of a particular backend. from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager pm = generate_preset_pass_manager(backend=backend, optimization_level=1) @@ -209,7 +213,7 @@ Note that the Estimator returns a list of values, as it can perform batched eval The legacy workflow required many steps to compute an expectation value: - Replace `ibmq_qasm_simulator` with your device name to see the complete workflow for a real device. + Replace `ibmq_qasm_simulator` with your device name to run the complete workflow on a real device. ``` python @@ -240,157 +244,6 @@ expectation: -1.065734058826613 - -#### 3. Local execution - -These examples solve the problem defined above by using local simulation. - - - -To use local testing mode, specify one of the fake backends from ``qiskit_ibm_runtime.fake_provider`` or specify a Qiskit Aer simulator when instantiating a primitive or a session. - -- **Fake backends**: The [fake backends](../qiskit-ibm-runtime/fake_provider) in ``qiskit_ibm_runtime.fake_provider`` mimic the behaviors of IBM Quantum™ systems by using system snapshots. The system snapshots contain important information about the quantum system, such as the coupling map, basis gates, and qubit properties, which are useful for testing the transpiler and performing noisy simulations of the system. The noise model from the snapshot is automatically applied during simulation. -- **Aer simulator**: Simulators from [Qiskit Aer](../../verify/simulate-with-qiskit-aer) provide higher-performance simulation that can handle larger circuits and [custom noise models](../../verify/building_noise_models). It also supports Clifford simulation mode, which can efficiently simulate Clifford circuits with a large number of qubits. - -The only part of the previous example that we need to change is the backend definition. The rest of the code is identical. However, some options and execution modes are ignored when using local testing mode and will generate warnings if included. - -``` python -from qiskit import QuantumCircuit -from qiskit.quantum_info import SparsePauliOp - -# Step 1: Define operator -op = SparsePauliOp.from_list( - [ - ("II", -1.052373245772859), - ("IZ", 0.39793742484318045), - ("ZI", -0.39793742484318045), - ("ZZ", -0.01128010425623538), - ("XX", 0.18093119978423156), - ] -) - -# Step 2: Define quantum state -state = QuantumCircuit(2) -state.x(0) -state.x(1) - -# Define a local backend -from qiskit_ibm_runtime.fake_provider import FakeManilaV2 -backend = FakeManilaV2() - -# You could use an Aer simulator instead by using the following code: -# from qiskit_aer import AerSimulator -# backend = AerSimulator() - -# We don't need these lines when running in local testing mode: -# from qiskit_ibm_runtime import QiskitRuntimeService -# service = QiskitRuntimeService() - - -# Convert inputs to ISA -from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager - -pm = generate_preset_pass_manager(backend=backend, optimization_level=1) -isa_state = pm.run(state) -isa_observables = [operator.apply_layout(isa_state.layout) for operator in op] -``` - - - -``` python -from qiskit import QuantumCircuit -from qiskit.quantum_info import SparsePauliOp - -# Step 1: Define operator -op = SparsePauliOp.from_list( - [ - ("II", -1.052373245772859), - ("IZ", 0.39793742484318045), - ("ZI", -0.39793742484318045), - ("ZZ", -0.01128010425623538), - ("XX", 0.18093119978423156), - ] -) - -# Step 2: Define quantum state -state = QuantumCircuit(2) -state.x(0) -state.x(1) -``` - -For information about running noisy simulations with the Runtime primitives, see [Noisy simulators in Qiskit Runtime](../../verify/using-ibm-quantum-simulators) and [Local testing mode](../../verify/local-testing-mode). - - - -``` python -from qiskit.opflow import StateFn, PauliExpectation, CircuitSampler -from qiskit_aer import AerSimulator - -# Define the state to sample -measurable_expression = StateFn(opflow_op, is_measurement=True).compose(opflow_state) - -# Convert to expectation value calculation object -expectation = PauliExpectation().convert(measurable_expression) - -# Define statevector simulator -simulator = AerSimulator(method="statevector", shots=100) - -# Inject backend into circuit sampler -circuit_sampler = CircuitSampler(simulator).convert(expectation) - -# Evaluate -expectation_value = circuit_sampler.eval().real -``` - -``` python ->>> print("expectation: ", expectation_value) -expectation: -1.0636533500290943 -``` - - - -The reference `Estimator` lets you perform either an exact or a -shot-based noisy simulation based on the `Statevector` class in the -`qiskit.quantum_info` module. - -``` python -from qiskit.primitives import Estimator - -estimator = Estimator() - -expectation_value = estimator.run(state, op).result().values - -# for shot-based simulation: -expectation_value = estimator.run(state, op, shots=100).result().values -``` - -``` python ->>> print("expectation: ", expectation_value) -expectation: [-1.03134297] -``` - -You can still access the Aer Simulator through its dedicated -`Estimator`. This can be handy for performing simulations with noise -models. In this example, the simulation method has been updated to match -the Qiskit Aer simulator example result. - -``` python -from qiskit_aer.primitives import Estimator # import change - -estimator = Estimator(run_options= {"method": "statevector"}) - -expectation_value = estimator.run(state, op, shots=100).result().values -``` - -``` python ->>> print("expectation: ", expectation_value) -expectation: [-1.06365335] -``` - - - - - ## Use Sampler to design an algorithm @@ -498,15 +351,16 @@ When using the `Sampler` primitive, the circuit **must contain measurements**. ``` python -from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler +from qiskit_ibm_runtime import SamplerV2 as Sampler -service = QiskitRuntimeService() -backend = service.least_busy(operational=True, simulator=False) - -# To use Fake backends with local testing mode, import it and use it as the backend instead +# Define a local backend +from qiskit_ibm_runtime.fake_provider import FakeManilaV2 +backend = FakeManilaV2() -# from qiskit_ibm_runtime.fake_provider import FakeManilaV2 -# backend = FakeManilaV2() +# Define a real backend +# from qiskit_ibm_runtime import QiskitRuntimeService +# service = QiskitRuntimeService() +# backend = service.least_busy(operational=True, simulator=False) from qiskit import QuantumCircuit @@ -629,9 +483,10 @@ to the following: - [Common use cases](qiskit-runtime-use-case) - [Migrate `backend.run` options to primitive options](qiskit-runtime-options) -- [Setting execution options topic](../../run/advanced-runtime-options) +- [Setting execution options](../../run/advanced-runtime-options) - [Primitive execution options API reference](../qiskit-ibm-runtime/qiskit_ibm_runtime.options.Options) -- [How to run a session topic](../../run/run-jobs-in-session) -- [Qiskit Runtime local testing mode topic](../../verify/local-testing-mode) +- [How to run a session](../../run/run-jobs-in-session) +- [Qiskit Runtime local testing mode](../../verify/local-testing-mode) +- [Noisy simulators in Qiskit Runtime](../../verify/using-ibm-quantum-simulators) From 4547ea84aaa08aba1116698eaa2c4f67b640ee62 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Wed, 3 Apr 2024 13:13:20 -0500 Subject: [PATCH 40/65] combine examples --- .../migration-guides/qiskit-runtime-examples.mdx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 9d128067ac3..3bed08963fa 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -212,10 +212,6 @@ Note that the Estimator returns a list of values, as it can perform batched eval The legacy workflow required many steps to compute an expectation value: - - Replace `ibmq_qasm_simulator` with your device name to run the complete workflow on a real device. - - ``` python from qiskit.opflow import StateFn, PauliExpectation, CircuitSampler from qiskit import IBMQ @@ -226,10 +222,17 @@ measurable_expression = StateFn(opflow_op, is_measurement=True).compose(opflow_s # Convert to expectation value calculation object expectation = PauliExpectation().convert(measurable_expression) -# Define provider and backend +# Define provider and simulator backend provider = IBMQ.get_provider(hub="ibm-q", group="open", project="main") backend = provider.get_backend("ibmq_qasm_simulator") +# Define a statevector simulator +# from qiskit_aer import AerSimulator +# backend = AerSimulator(method="statevector", shots=100) + +# Define a real backend +# backend = provider.get_backend("ibm_brisbane") + # Inject backend into circuit sampler sampler = CircuitSampler(backend).convert(expectation) From 859fd651554f51c273db62578101059183497dcc Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Wed, 3 Apr 2024 14:28:55 -0500 Subject: [PATCH 41/65] update examples --- .../qiskit-runtime-examples.mdx | 94 +++++++++++-------- 1 file changed, 53 insertions(+), 41 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 3bed08963fa..1ee43e54698 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -13,7 +13,7 @@ Follow these examples to design a Qiskit Runtime algorithm. Use the Estimator primitive to design an algorithm that calculates expectation values. -**Backend.run() model:** In this model, you accessed real systems and remote simulators by using the `qiskit-ibmq-provider` or the `qiskit-ibm-provider` module. To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface. +**Backend.run() model:** In this model, you accessed real systems and remote simulators by using the `qiskit-ibmq-provider` or the `qiskit-ibm-provider` module. To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface. The following examples assume you have defined circuits `isa_circuits`. @@ -28,7 +28,7 @@ provider = IBMQ.get_provider(hub="ibm-q", group="open", project="main") backend = provider.get_backend("ibmq_qasm_simulator") # cloud simulator # Run -result = backend.run(expectation_circuits) +result = backend.run(isa_circuits) ``` @@ -40,7 +40,7 @@ from qiskit_aer import AerSimulator # former import: from qiskit import Aer backend = AerSimulator() # Run -result = backend.run(expectation_circuits) +result = backend.run(isa_circuits) ``` @@ -164,6 +164,25 @@ op = SparsePauliOp.from_list( state = QuantumCircuit(2) state.x(0) state.x(1) + +# Define provider and simulator backend +from qiskit import IBMQ + +provider = IBMQ.get_provider(hub="ibm-q", group="open", project="main") +backend = provider.get_backend("ibmq_qasm_simulator") + +# Define a statevector simulator +# from qiskit_aer import AerSimulator +# backend = AerSimulator(method="statevector", shots=100) + +# Define a real backend +# backend = provider.get_backend("ibm_brisbane") + +# Circuits must obey the Instruction Set Architecture (ISA) of a particular backend. +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager + +pm = generate_preset_pass_manager(backend=backend, optimization_level=1) +isa_state = pm.run(state) ```
@@ -179,7 +198,7 @@ and quantum states, so the problem defined above would be wrapped as: from qiskit.opflow import CircuitStateFn, PauliSumOp opflow_op = PauliSumOp(op) -opflow_state = CircuitStateFn(state) +opflow_state = CircuitStateFn(isa_state) ``` This step is not necessary when using the primitives. For instructions to migrate from `qiskit.opflow`, see the [Opflow migration guide](./qiskit-opflow-module). @@ -222,17 +241,6 @@ measurable_expression = StateFn(opflow_op, is_measurement=True).compose(opflow_s # Convert to expectation value calculation object expectation = PauliExpectation().convert(measurable_expression) -# Define provider and simulator backend -provider = IBMQ.get_provider(hub="ibm-q", group="open", project="main") -backend = provider.get_backend("ibmq_qasm_simulator") - -# Define a statevector simulator -# from qiskit_aer import AerSimulator -# backend = AerSimulator(method="statevector", shots=100) - -# Define a real backend -# backend = provider.get_backend("ibm_brisbane") - # Inject backend into circuit sampler sampler = CircuitSampler(backend).convert(expectation) @@ -273,7 +281,7 @@ difference is the format of the output: `backend.run()` outputs backend = provider.get_backend("ibmq_qasm_simulator") # Use the cloud simulator # Run - result = backend.run(circuits) + result = backend.run(isa_circuits) ```
@@ -286,7 +294,7 @@ difference is the format of the output: `backend.run()` outputs backend = AerSimulator() # Run - result = backend.run(circuits) + result = backend.run(isa_circuits) ```
@@ -294,7 +302,7 @@ difference is the format of the output: `backend.run()` outputs **Primitives model:** Access real systems through the `qiskit-ibm-runtime` Sampler and Estimator *primitives*. Use **local testing mode** to run local simulations by using Qiskit Runtime fake backends or Aer simulators. - + ``` python from qiskit_ibm_runtime import SamplerV2 as Sampler, QiskitRuntimeService @@ -338,11 +346,11 @@ result = job.result() -## End-to-end example +### End-to-end example The following example shows an end-to-end example of sampling a circuit by using `backend.run()` and `Sampler`. -### 1. Problem definition +#### 1. Problem definition We want to find the probability distribution associated with a quantum state: @@ -372,7 +380,7 @@ circuit.h(range(2)) circuit.cx(0,1) circuit.measure_all() # measurement! -# For Qiskit Runtime, circuits must obey the ISA of a particular backend. +# Circuits must obey the ISA of the backend. # Convert to ISA circuits from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager @@ -390,19 +398,34 @@ circuit = QuantumCircuit(4) circuit.h(range(2)) circuit.cx(0,1) circuit.measure_all() # measurement! + +# Define provider and simulator backend +from qiskit import IBMQ + +provider = IBMQ.get_provider(hub="ibm-q", group="open", project="main") +backend = provider.get_backend("ibmq_qasm_simulator") + +# Define a statevector simulator +# from qiskit_aer import AerSimulator +# backend = AerSimulator(method="statevector", shots=100) + +# Define a real backend +# backend = provider.get_backend("ibm_brisbane") + +# Circuits must obey the ISA of a particular backend. +# Convert to ISA circuits +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager + +pm = generate_preset_pass_manager(backend=backend, optimization_level=1) +isa_circuit = pm.run(circuit) ```
-### 2. Get counts from the result +#### 2. Get counts from the result - While the user-side syntax of the `Sampler` is very similar to -`backend.run()`, notice that the workflow is now simplified, as the -quasi-probability distribution is returned **directly** (no need to -perform post-processing), together with some key metadata. - ``` python sampler = Sampler(backend=backend) @@ -424,23 +447,12 @@ The required steps to reach our goal with `backend.run()` are: 1. Run circuits 2. Get counts from the result object -First, we run the circuit in a cloud simulator and output the result +First, we run the circuit and output the result object: - - Replace `ibmq_qasm_simulator` with your device name to see the complete workflow for a real device. - - - ``` python -from qiskit import IBMQ - -# Define provider and backend -provider = IBMQ.load_account() -backend = provider.get_backend("ibmq_qasm_simulator") - # Run -result = backend.run(circuit, shots=1024).result() +result = backend.run(isa_circuit, shots=1024).result() ``` ``` python @@ -467,7 +479,7 @@ time_taken=0.003215252, client_version={'qiskit': '0.39.5'}) Now we get the probability distribution from the output: ``` python -counts = result.get_counts(circuit) +counts = result.get_counts(isa_circuit) >>> print("counts: ", counts) counts: {'0000': 255, '0001': 258, '0010': 243, '0011': 268} From 9414dd41be23c9f2e8e6cd6852674859bbd943c1 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Wed, 3 Apr 2024 14:30:28 -0500 Subject: [PATCH 42/65] edits --- docs/api/migration-guides/qiskit-runtime-examples.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 1ee43e54698..8273010cb22 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -302,7 +302,7 @@ difference is the format of the output: `backend.run()` outputs **Primitives model:** Access real systems through the `qiskit-ibm-runtime` Sampler and Estimator *primitives*. Use **local testing mode** to run local simulations by using Qiskit Runtime fake backends or Aer simulators. - + ``` python from qiskit_ibm_runtime import SamplerV2 as Sampler, QiskitRuntimeService @@ -426,7 +426,7 @@ isa_circuit = pm.run(circuit) -``` python + ``` python sampler = Sampler(backend=backend) job = sampler.run([(isa_circuit,)]) From ee68272455c2f4e2a287c20b4057522014ba0774 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Wed, 3 Apr 2024 14:37:00 -0500 Subject: [PATCH 43/65] Because tables are the worst and you can't put anything special in them. --- docs/api/migration-guides/qiskit-runtime-options.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index caeaca1e118..6ed67320f1b 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -18,7 +18,7 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | experiment_id | N/A: Use job_tags instead. | ibmq-provider only | | header | You can attach metadata to circuits. The same metadata is returned in the result metadata, under “circuit_metadata”. | | | shots | Any of the following:

run([(…, shots)])

run(…, shots=)

options.default_shots | | -| memory | Use result.data..get_counts() to get counts and result.data..get_bitstrings() to get per-shot measurements | | +| memory | Use result.data.classical_register_name.get_counts() to get counts and result.data.classical_register_name.get_bitstrings() to get per-shot measurements | | | qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | | meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | | schedule_los | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | From baf0ce47837c8f522eb752e41174f31838159867 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Wed, 3 Apr 2024 14:57:48 -0500 Subject: [PATCH 44/65] try the table this way --- .../migration-guides/qiskit-runtime-options.mdx | 4 ++-- .../migration-guides/qiskit-runtime-use-case.mdx | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index 6ed67320f1b..15d3a54dcc9 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -22,8 +22,8 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | | meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | | schedule_los | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | -| meas_level | options.execution.meas_type | (meas_level, meas_return) → meas_type

0, * → not implemented

1, “avg” → “avg_kerneled”

1, “single” → “kerneled”

2, * → “classified” | -| meas_return | options.execution.meas_type | See above | +| meas_level | options.execution.meas_type:

avg_kerneled replaces meas_level=1 and meas_return="avg"

kerneled replaces meas_level=1 and meas_return="single"

classified replaces meas_level=2

meas_level=0 is no longer supported by IBM backends. | | +| meas_return | options.execution.meas_type (See above) | | | memory_slots | N/A: This is automatically determined by the system. | ibmq-provider only | | memory_slot_size | N/A: This is automatically determined by the system. | ibmq-provider only | | rep_time | N/A: Use rep_delay instead. | | diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index 563d9487151..30fcdd88682 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -12,7 +12,13 @@ The only changes when running basic circuits are how you run the job and retriev ```python -from qiskit_ibm_runtime import SamplerV2 as Sampler +from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler + +# Define the service. This allows you to access IBM Quantum systems. +service = QiskitRuntimeService() + +# Get a backend +backend = service.least_busy(operational=True, simulator=False) job = sampler.run([isa_circuit]) result = job.result() @@ -159,12 +165,7 @@ The primitives take in parametrized circuits directly, together with the parameter values, and the parameter assignment operation can be performed more efficiently on the server side. The input is in the form of primitive unified blocs (PUBs), where each PUB is a tuple that contains a circuit and the data broadcasted to it. For further details, see [Introduction to primitives.](../../run/primitives#interface-changes) -This feature is particularly interesting when working with iterative -algorithms because the parametrized circuit remains unchanged between -calls while the parameter values change. The primitives can transpile -once and then cache the unbound circuit, using classical resources more -efficiently. Moreover, only the updated parameters are transferred to -the cloud, saving additional bandwidth. +If you have multiple sets of parameter values you want to bind to the same circuit, you can specify them in a single PUB, in the format of (circuit, [parameter_value_set1, parameter_value_set2]). You need the classical register name to get the results. By default, it is named `meas` when you use `measure_all()`. However, the classical register name for this example is `c`. You can find the classical register name by running `.cregs`. For example, `qc.cregs`. From 71d1a878e9cd5547574eaef0ce4c67382dc5b7ba Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Wed, 3 Apr 2024 15:23:43 -0500 Subject: [PATCH 45/65] bullets? --- docs/api/migration-guides/qiskit-runtime-options.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index 15d3a54dcc9..fe836873348 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -13,12 +13,12 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | backend.run options | V2 Primitive options | Notes | |---------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------| | job_name | N/A: Use job_tags instead. | ibmq-provider only | -| job_share_level | N/A: This was deprecated long ago and no longer supported. | ibmq-provider only | +| job_share_level | N/A: This is no longer supported. | ibmq-provider only | | job_tags | options.environment.job_tags | | | experiment_id | N/A: Use job_tags instead. | ibmq-provider only | | header | You can attach metadata to circuits. The same metadata is returned in the result metadata, under “circuit_metadata”. | | -| shots | Any of the following:

run([(…, shots)])

run(…, shots=)

options.default_shots | | -| memory | Use result.data.classical_register_name.get_counts() to get counts and result.data.classical_register_name.get_bitstrings() to get per-shot measurements | | +| shots | Any of the following:

* run([(…, shots)])

* run(…, shots=)

* options.default_shots | | +| memory | Use result.data.classical_register_name.get_counts() to get counts

Use result.data.classical_register_name.get_bitstrings() to get per-shot measurements | | | qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | | meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | | schedule_los | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | From 03f0b6ee14fe15880caed0e83ca21ddfceca78c6 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Wed, 3 Apr 2024 15:29:34 -0500 Subject: [PATCH 46/65] fancy bullets --- docs/api/migration-guides/qiskit-runtime-options.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index fe836873348..e54ecba467c 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -17,12 +17,12 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | job_tags | options.environment.job_tags | | | experiment_id | N/A: Use job_tags instead. | ibmq-provider only | | header | You can attach metadata to circuits. The same metadata is returned in the result metadata, under “circuit_metadata”. | | -| shots | Any of the following:

* run([(…, shots)])

* run(…, shots=)

* options.default_shots | | +| shots | Any of the following:

• run([(…, shots)])

• run(…, shots=)

• options.default_shots | | | memory | Use result.data.classical_register_name.get_counts() to get counts

Use result.data.classical_register_name.get_bitstrings() to get per-shot measurements | | | qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | | meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | | schedule_los | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | -| meas_level | options.execution.meas_type:

avg_kerneled replaces meas_level=1 and meas_return="avg"

kerneled replaces meas_level=1 and meas_return="single"

classified replaces meas_level=2

meas_level=0 is no longer supported by IBM backends. | | +| meas_level | options.execution.meas_type:

• avg_kerneled replaces meas_level=1 and meas_return="avg"

• kerneled replaces meas_level=1 and meas_return="single"

• classified replaces meas_level=2

• meas_level=0 is no longer supported by IBM backends. | | | meas_return | options.execution.meas_type (See above) | | | memory_slots | N/A: This is automatically determined by the system. | ibmq-provider only | | memory_slot_size | N/A: This is automatically determined by the system. | ibmq-provider only | From bbb886ed071bb6706b7355761d9d6b84b7dedbe0 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Wed, 3 Apr 2024 15:33:34 -0500 Subject: [PATCH 47/65] edits --- docs/api/migration-guides/qiskit-runtime-options.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index e54ecba467c..0ab89103d55 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -18,12 +18,12 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | experiment_id | N/A: Use job_tags instead. | ibmq-provider only | | header | You can attach metadata to circuits. The same metadata is returned in the result metadata, under “circuit_metadata”. | | | shots | Any of the following:

• run([(…, shots)])

• run(…, shots=)

• options.default_shots | | -| memory | Use result.data.classical_register_name.get_counts() to get counts

Use result.data.classical_register_name.get_bitstrings() to get per-shot measurements | | +| memory | Use result.data.classical_register_name.get_counts() to get counts.

Use result.data.classical_register_name.get_bitstrings() to get per-shot measurements. | | | qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | | meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | | schedule_los | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | -| meas_level | options.execution.meas_type:

• avg_kerneled replaces meas_level=1 and meas_return="avg"

• kerneled replaces meas_level=1 and meas_return="single"

• classified replaces meas_level=2

• meas_level=0 is no longer supported by IBM backends. | | -| meas_return | options.execution.meas_type (See above) | | +| meas_level | options.execution.meas_type:

• For meas_level=1 and meas_return="avg", use avg_kerneled

• For meas_level=1 and meas_return="single", use kerneled

• For meas_level=2, use classified

• meas_level=0 is no longer supported by IBM backends. | | +| meas_return | options.execution.meas_type (See above.) | | | memory_slots | N/A: This is automatically determined by the system. | ibmq-provider only | | memory_slot_size | N/A: This is automatically determined by the system. | ibmq-provider only | | rep_time | N/A: Use rep_delay instead. | | From b877b2c7508c891722385058065a72817f437571 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock <66339736+beckykd@users.noreply.github.com> Date: Thu, 4 Apr 2024 09:47:48 -0500 Subject: [PATCH 48/65] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> --- .../migration-guides/qiskit-runtime-examples.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 8273010cb22..cc930690171 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -13,16 +13,16 @@ Follow these examples to design a Qiskit Runtime algorithm. Use the Estimator primitive to design an algorithm that calculates expectation values. -**Backend.run() model:** In this model, you accessed real systems and remote simulators by using the `qiskit-ibmq-provider` or the `qiskit-ibm-provider` module. To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface. The following examples assume you have defined circuits `isa_circuits`. +**Backend.run() model:** In this model, you accessed real systems and remote simulators by using the `qiskit-ibmq-provider` or the `qiskit-ibm-provider` module. To run **local** simulations, you could import a specific simulator from `qiskit-aer`. All of them followed the `backend.run()` interface. The following examples assume you have defined `isa_circuits`, circuits that follow the instruction set architecture (ISA) of the backend after undergoing transpilation. ``` python -from qiskit import IBMQ +from qiskit_ibm_provider import IBMProvider # Select provider -provider = IBMQ.get_provider(hub="ibm-q", group="open", project="main") +provider = IBMProvider() # Get backend backend = provider.get_backend("ibmq_qasm_simulator") # cloud simulator @@ -121,15 +121,15 @@ op = SparsePauliOp.from_list( ) # Step 2: Define quantum state -state = QuantumCircuit(2) -state.x(0) -state.x(1) +circuit = QuantumCircuit(2) +circuit.x(0) +circuit.x(1) # Define a local backend from qiskit_ibm_runtime.fake_provider import FakeManilaV2 backend = FakeManilaV2() -# Define a real backend +# Or define a real backend # from qiskit_ibm_runtime import QiskitRuntimeService # service = QiskitRuntimeService() # backend = service.least_busy(operational=True, simulator=False) From 835210f41cc7349a66d8bae2385bbbcd55c01a61 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock <66339736+beckykd@users.noreply.github.com> Date: Thu, 4 Apr 2024 09:49:28 -0500 Subject: [PATCH 49/65] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> --- docs/api/migration-guides/qiskit-runtime-examples.mdx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index cc930690171..72653b7192c 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -138,13 +138,15 @@ backend = FakeManilaV2() from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager pm = generate_preset_pass_manager(backend=backend, optimization_level=1) -isa_state = pm.run(state) +isa_circuit = pm.run(circuit) + isa_observables = [operator.apply_layout(isa_state.layout) for operator in op] ``` - + + ``` python from qiskit import QuantumCircuit from qiskit.quantum_info import SparsePauliOp From 00b6fe19911be7c7ca3a6e3e6f4f6477e8eac62a Mon Sep 17 00:00:00 2001 From: Rebecca Dimock <66339736+beckykd@users.noreply.github.com> Date: Thu, 4 Apr 2024 09:51:05 -0500 Subject: [PATCH 50/65] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> --- .../qiskit-runtime-examples.mdx | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 72653b7192c..645abe5f466 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -140,7 +140,8 @@ from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager pm = generate_preset_pass_manager(backend=backend, optimization_level=1) isa_circuit = pm.run(circuit) -isa_observables = [operator.apply_layout(isa_state.layout) for operator in op] +isa_observable = op.apply_layout(isa_state.layout) + ``` @@ -170,7 +171,8 @@ state.x(1) # Define provider and simulator backend from qiskit import IBMQ -provider = IBMQ.get_provider(hub="ibm-q", group="open", project="main") +provider = IBMProvider() + backend = provider.get_backend("ibmq_qasm_simulator") # Define a statevector simulator @@ -184,7 +186,11 @@ backend = provider.get_backend("ibmq_qasm_simulator") from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager pm = generate_preset_pass_manager(backend=backend, optimization_level=1) -isa_state = pm.run(state) + +from qiskit.opflow import CircuitStateFn, PauliSumOp + +opflow_op = PauliSumOp(op) +opflow_state = CircuitStateFn(isa_state) ``` @@ -209,14 +215,16 @@ This step is not necessary when using the primitives. For instructions to migrat -Estimator simplifies the user-side syntax, making it a more +Estimator simplifies the user-side syntax compared to the legacy approaches, making it a more + convenient tool for algorithm design. ``` python from qiskit_ibm_runtime import EstimatorV2 as Estimator estimator = Estimator(backend, options={"default_shots": int(1e4)}) -job = estimator.run([(isa_state, isa_observables)]) +job = estimator.run([(isa_state, isa_observable)]) + # Get results for the first (and only) PUB pub_result = job.result()[0] @@ -225,17 +233,18 @@ pub_result = job.result()[0] Note that the Estimator returns a list of values, as it can perform batched evaluations. ``` python ->>> print(f">>> Expectation values: {pub_result.data.evs}") ->>> Expectation values: [-1.05237325 -0.20984981 0.37345495 -0.00564005 -0.00141352] +print(f">>> Expectation value: {pub_result.data.evs}") +>>> Expectation value: -0.8879899326312926 + ``` -The legacy workflow required many steps to compute an expectation value: +The legacy workflow required additional elements and steps to compute an expectation value. The `QuantumInstance` class stored a `PassManager` and a `Backend` instance, and wrapped the conversion step to ISA circuits and `backend.run` calls. The `CircuitSampler` class from `qiskit.opflow` wrapped the `QuantumInstance` `run` and `transpile` methods. This degree of nesting is no longer supported, the new workflow allows to access and directly manipulate all the key components of the computation (backend, pass manager, circuits and observables) at all stages of the algorithm. ``` python from qiskit.opflow import StateFn, PauliExpectation, CircuitSampler -from qiskit import IBMQ +from qiskit.utils import QuantumInstance # Define the state to sample measurable_expression = StateFn(opflow_op, is_measurement=True).compose(opflow_state) @@ -243,8 +252,12 @@ measurable_expression = StateFn(opflow_op, is_measurement=True).compose(opflow_s # Convert to expectation value calculation object expectation = PauliExpectation().convert(measurable_expression) -# Inject backend into circuit sampler -sampler = CircuitSampler(backend).convert(expectation) +# Define quantum instance with backend and pass manager +quantum_instance = QuantumInstance(backend, pass_manager = pm) + +# Inject quantum instance into circuit sampler and convert +sampler = CircuitSampler(quantum_instance).convert(expectation) + # Evaluate expectation_value = sampler.eval().real @@ -274,7 +287,8 @@ difference is the format of the output: `backend.run()` outputs ``` python - from qiskit import IBMQ + from qiskit_ibm_provider import IBMProvider + # Select provider provider = IBMQ.load_account() From 9104db6502cea6303727874dcb176eadfc476647 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock <66339736+beckykd@users.noreply.github.com> Date: Thu, 4 Apr 2024 09:53:00 -0500 Subject: [PATCH 51/65] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> --- docs/api/migration-guides/qiskit-runtime-examples.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 645abe5f466..a89446ba6aa 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -169,7 +169,8 @@ state.x(0) state.x(1) # Define provider and simulator backend -from qiskit import IBMQ +from qiskit_ibm_provider import IBMProvider + provider = IBMProvider() From 88780e1c29f011a89708d816dc1ce8615833da0e Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Thu, 4 Apr 2024 10:40:32 -0500 Subject: [PATCH 52/65] Comments from review --- .../qiskit-runtime-examples.mdx | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index a89446ba6aa..4d7a87d7c43 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -147,6 +147,7 @@ isa_observable = op.apply_layout(isa_state.layout) +This code block shows a legacy workflow that handles operators using `qiskit.opflow`. `qiskit.opflow` provided custom classes to represent operators and quantum states (`CircuitStateFn`, `PauliSumOp`), which were required to wrap the standard Qiskit objects. This extra step is not necessary in the updated workflow. Note that in this case we are not running the pass manager to transpile the circuit (and observable) to ISA. This operation had to be performed in the later step, also through custom wrappers that are no longer necessary. For more detailed instructions to migrate from `qiskit.opflow`, see the [Opflow migration guide](./qiskit-opflow-module). ``` python from qiskit import QuantumCircuit @@ -196,22 +197,6 @@ opflow_state = CircuitStateFn(isa_state) - - -##### 1.a. Legacy only: Convert problem to opflow - -`qiskit.opflow` provided classes to represent operators -and quantum states, so the problem defined above would be wrapped as: - -``` python -from qiskit.opflow import CircuitStateFn, PauliSumOp - -opflow_op = PauliSumOp(op) -opflow_state = CircuitStateFn(isa_state) -``` - -This step is not necessary when using the primitives. For instructions to migrate from `qiskit.opflow`, see the [Opflow migration guide](./qiskit-opflow-module). - #### 2. Calculate expectation values From f654cb5ff41bbaee8c561990327c81b08ec32080 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Thu, 4 Apr 2024 13:33:36 -0500 Subject: [PATCH 53/65] add isa-circuits --- .../qiskit-runtime-use-case.mdx | 8 ++++-- docs/api/migration-guides/qiskit-runtime.mdx | 26 +++++++++---------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index 30fcdd88682..4ac55e6fce8 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -35,7 +35,7 @@ from qiskit import IBMQ # Define provider and backend provider = IBMQ.load_account() -job = backend.run(circuit) +job = backend.run(isa_circuit) result = job.result() ``` @@ -194,8 +194,12 @@ from qiskit import Aer bound_circuit = qc.bind_parameters(theta_values) bound_circuit.draw() +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager +pm = generate_preset_pass_manager(backend=backend, optimization_level=1) +isa_circuit = pm.run(bound_circuit) + backend = Aer.get_backend('aer_simulator') -job = backend.run(bound_circuit) +job = backend.run(isa_circuit) counts = job.result().get_counts() print(counts) ``` diff --git a/docs/api/migration-guides/qiskit-runtime.mdx b/docs/api/migration-guides/qiskit-runtime.mdx index 5b6d5df0fea..dc8835bded4 100644 --- a/docs/api/migration-guides/qiskit-runtime.mdx +++ b/docs/api/migration-guides/qiskit-runtime.mdx @@ -24,7 +24,7 @@ The Qiskit Runtime primitives implement the reference Sampler V2 and Estimator V ## Basic steps to migrate to primitives -### Step 1 - Determine which primitive to use +### Step 1: Determine which primitive to use When migrating, the key to writing an equivalent algorithm using primitives is to first identify what minimal unit of information @@ -38,14 +38,14 @@ your algorithm is based on: A probability distribution is often of interest in optimization problems that return a classical bit string, encoding a certain solution to a problem at hand. In these cases, you might be interested in finding a bit string that corresponds to a ket value with the largest probability of being measured from a quantum state, for example. -### Step 2 - Change imports as necessary +### Step 2: Change imports as necessary Follow the steps in the appropriate topic to change your import options and other setup information: -- [Migrate from `qiskit-ibm-provider`.](qiskit-runtime-from-ibm-provider) -- [Migrate from `qiskit-ibmq-provider`.](qiskit-runtime-from-ibmq-provider) +- [Migrate from `qiskit-ibm-provider`](qiskit-runtime-from-ibm-provider) +- [Migrate from `qiskit-ibmq-provider`](qiskit-runtime-from-ibmq-provider) -### Step 3 - Replace the call to `backend.run` with a call to `qiskit_ibm_runtime`. +### Step 3: Replace the call to `backend.run` with a call to `qiskit_ibm_runtime`. See these topics for instructions: @@ -54,21 +54,21 @@ See these topics for instructions: - [Common use cases (basic, parameterized, and dynamic circuits)](qiskit-runtime-use-case) -### Step 3a - replace any `backend.run` options with `qiskit_ibm_runtime` options. +### Step 3a: replace any `backend.run` options with `qiskit_ibm_runtime` options. See the following topics for instructions: -- [Migrate options.](qiskit-runtime-options) -- Common use cases [Options section.](qiskit-runtime-use-case#migrate-options) +- [Migrate options](qiskit-runtime-options) +- Common use cases [Options section](qiskit-runtime-use-case#migrate-options) ## Next steps - - [Get started with Estimator.](../../run/primitives-get-started#start-estimator) - - [Get started with Sampler.](../../run/primitives-get-started#start-sampler) - - Explore [sessions.](../../run/sessions) - - [Run a primitive in a session.](../../run/run-jobs-in-session) - - Experiment with the [Submit pre-transpiled circuits tutorial.](https://learning.quantum.ibm.com/tutorial/submitting-user-transpiled-circuits-using-primitives) + - [Get started with Estimator](../../run/primitives-get-started#start-estimator) + - [Get started with Sampler](../../run/primitives-get-started#start-sampler) + - Explore [sessions](../../run/sessions) + - [Run a primitive in a session](../../run/run-jobs-in-session) + - Experiment with the [Submit pre-transpiled circuits tutorial](https://learning.quantum.ibm.com/tutorial/submitting-user-transpiled-circuits-using-primitives) \ No newline at end of file From 6a15cedc7e6b9574f4b4ad32284d33ba25cd3c45 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Thu, 4 Apr 2024 15:02:02 -0500 Subject: [PATCH 54/65] extra space --- docs/api/migration-guides/v2-primitives.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/migration-guides/v2-primitives.mdx b/docs/api/migration-guides/v2-primitives.mdx index ba6030ded34..e83b61e70f2 100644 --- a/docs/api/migration-guides/v2-primitives.mdx +++ b/docs/api/migration-guides/v2-primitives.mdx @@ -372,7 +372,7 @@ backend = service.least_busy(operational=True, simulator=False) estimator = Estimator(backend) # Set resilience_level to 0 -estimator.options. resilience_level = 0 +estimator.options.resilience_level = 0 # Turn on measurement error mitigation estimator.options.resilience.measure_mitigation = True From 04f0e507fe7e768075a4dec41218542463c90fec Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Thu, 4 Apr 2024 16:39:21 -0500 Subject: [PATCH 55/65] meas-level-1 --- .../qiskit-runtime-use-case.mdx | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index 4ac55e6fce8..1e3631ebd32 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -206,6 +206,62 @@ print(counts)
+## Get the averaged IQ data (meas_level=1) + + + +```python +from qiskit.circuit import QuantumCircuit +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager +from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler + +circuit = QuantumCircuit(2, 2) +circuit.h(0) +circuit.cx(0, 1) +circuit.measure_all() + +service = QiskitRuntimeService() +backend = service.least_busy(operational=True, simulator=False) +pm = generate_preset_pass_manager(backend=backend, optimization_level=1) +isa_circuit = pm.run(circuit) + +sampler = Sampler(backend) +# Get the averaged IQ data. +# This is equivalent to meas_level=1, meas_return="avg" in backend.run +sampler.options.execution.meas_type = "avg_kerneled" +job = sampler.run([isa_circuit], shots=10) +pub_result = job.result()[0] +print(f">>> Averaged IQ data: {pub_result.data.meas}") +``` + + + +```python +from qiskit import QuantumCircuit +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager + +circuit = QuantumCircuit(2, 2) +circuit.h(0) +circuit.cx(0, 1) +circuit.measure_all() + +# Define provider and simulator backend +from qiskit import IBMQ + +IBMQ.load_account() +provider = IBMQ.get_provider(hub="ibm-q", group="open", project="main") +backend = provider.get_backend("ibmq_qasm_simulator") + +pm = generate_preset_pass_manager(backend=backend, optimization_level=1) +isa_circuit = pm.run(circuit) + +result = backend.run(isa_circuit, shots=10, meas_level=1, meas_return="avg").result() + +>>> print("result: ", result) +``` + + + ## Upload, view, or delete custom prototype programs This function has been replaced with Quantum Serverless patterns. For instructions to migrate, see [Converting from Qiskit Runtime Programs.](https://qiskit-extensions.github.io/quantum-serverless/migration/migration_from_qiskit_runtime_programs.html) From 8761acd68e691067fe278ef6ac9547b2829d77ee Mon Sep 17 00:00:00 2001 From: Rebecca Dimock <66339736+beckykd@users.noreply.github.com> Date: Thu, 4 Apr 2024 16:51:56 -0500 Subject: [PATCH 56/65] Apply suggestions from code review Co-authored-by: Jessie Yu --- docs/api/migration-guides/qiskit-runtime-examples.mdx | 3 ++- .../api/migration-guides/qiskit-runtime-from-ibm-provider.mdx | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 4d7a87d7c43..da2ba264595 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -431,7 +431,8 @@ isa_circuit = pm.run(circuit) ``` python sampler = Sampler(backend=backend) -job = sampler.run([(isa_circuit,)]) +job = sampler.run([isa_circuit]) + result = job.result() # Get results for the first (and only) PUB pub_result = result[0] diff --git a/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx index e4dda120952..6c27893353b 100644 --- a/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx +++ b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx @@ -20,6 +20,8 @@ Qiskit Runtime on IBM Cloud or IBM Quantum Platform. For more information on retrieving account credentials, see [Install and set up](../../start/install). ``` python +from qiskit_ibm_runtime import QiskitRuntimeService + # IBM Quantum channel; set to default QiskitRuntimeService.save_account(channel="ibm_quantum", token="", overwrite=True, default=true) @@ -155,7 +157,7 @@ pm = generate_preset_pass_manager(backend=backend, optimization_level=1) isa_circuit = pm.run(circuit) sampler = Sampler(backend) -job = sampler.run([(isa_circuit,)]) +job = sampler.run([isa_circuit]) result = job.result() print(f" > Counts: {result[0].data.meas.get_counts()}") ``` From bbe49d967d40aa0cb8d619c86b26cffb0be96f13 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Thu, 4 Apr 2024 17:07:15 -0500 Subject: [PATCH 57/65] comments --- .../qiskit-runtime-from-ibm-provider.mdx | 15 +++++++++++++-- .../migration-guides/qiskit-runtime-options.mdx | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx index e4dda120952..72f2a50b861 100644 --- a/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx +++ b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx @@ -17,7 +17,7 @@ Use the updated code to work save accounts. The new syntax accepts credentials for Qiskit Runtime on IBM Cloud or IBM Quantum Platform. For more -information on retrieving account credentials, see [Install and set up](../../start/install). +information on retrieving account credentials, see [Install and set up](../../start/setup-channel). ``` python # IBM Quantum channel; set to default @@ -107,7 +107,6 @@ Use the updated code to specify a backend. -With Qiskit Runtime, you can also run in local testing mode as illustrated in [End-to-end examples.](qiskit-runtime-examples) ``` python # You can specify the instance in service.backend() instead of initializing a new service @@ -120,6 +119,18 @@ from qiskit_ibm_runtime import QiskitRuntimeService service = QiskitRuntimeService() backend = service.least_busy(operational=True, simulator=False, min_num_qubits=) +``` + +With Qiskit Runtime, you can also run in local testing mode. + +```python +# Define a local backend +from qiskit_ibm_runtime.fake_provider import FakeManilaV2 +backend = FakeManilaV2() + +# You could use an Aer simulator instead by using the following code: +# from qiskit_aer import AerSimulator +# backend = AerSimulator() ``` diff --git a/docs/api/migration-guides/qiskit-runtime-options.mdx b/docs/api/migration-guides/qiskit-runtime-options.mdx index 0ab89103d55..6d5f076c44c 100644 --- a/docs/api/migration-guides/qiskit-runtime-options.mdx +++ b/docs/api/migration-guides/qiskit-runtime-options.mdx @@ -18,7 +18,7 @@ All `backend.run` options are now available through the Qiskit Runtime primitive | experiment_id | N/A: Use job_tags instead. | ibmq-provider only | | header | You can attach metadata to circuits. The same metadata is returned in the result metadata, under “circuit_metadata”. | | | shots | Any of the following:

• run([(…, shots)])

• run(…, shots=)

• options.default_shots | | -| memory | Use result.data.classical_register_name.get_counts() to get counts.

Use result.data.classical_register_name.get_bitstrings() to get per-shot measurements. | | +| memory | Use result.data.\.get_counts() to get counts.

Use result.data.\.get_bitstrings() to get per-shot measurements. | | | qubit_lo_freq | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | | meas_lo_freq | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | | schedule_los | N/A: This option only applies to `Schedule` inputs, which was removed in 2022. | | From f56fc8881372c8863b64ed2ac642a62916494736 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock <66339736+beckykd@users.noreply.github.com> Date: Fri, 5 Apr 2024 11:11:19 -0500 Subject: [PATCH 58/65] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> --- .../migration-guides/qiskit-runtime-use-case.mdx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index 1e3631ebd32..f1c2ba4fcc4 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -52,6 +52,8 @@ All options that were available with `backend.run` are available in the Qiskit R ```python from qiskit_ibm_runtime import SamplerV2 as Sampler +sampler = Sampler(backend) + # You can use auto-complete to see and complete the options. sampler.options.default_shots = 1024 ``` @@ -60,9 +62,12 @@ sampler.options.default_shots = 1024 ```python -from qiskit import IBMQ +from qiskit_ibm_provider import IBMProvider -backend.run(circuit, shots=1024) +provider = IBMProvider() +backend = provider.get_backend("backend_name") + +backend.run(isa_circuit, shots=1024) ```
@@ -246,10 +251,9 @@ circuit.cx(0, 1) circuit.measure_all() # Define provider and simulator backend -from qiskit import IBMQ +from qiskit_ibm_provider import IBMProvider -IBMQ.load_account() -provider = IBMQ.get_provider(hub="ibm-q", group="open", project="main") +provider = IBMProvider() backend = provider.get_backend("ibmq_qasm_simulator") pm = generate_preset_pass_manager(backend=backend, optimization_level=1) From 2462aa0f0e7b53b321de8974a5b014d124fc1019 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 5 Apr 2024 14:20:13 -0500 Subject: [PATCH 59/65] Elena comments --- docs/api/migration-guides/qiskit-runtime-use-case.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index f1c2ba4fcc4..27f1c2068c4 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -30,10 +30,10 @@ pub_result = result[0] ``` python -from qiskit import IBMQ +from qiskit_ibm_provider import IBMProvider # Define provider and backend -provider = IBMQ.load_account() +provider = IBMProvider() job = backend.run(isa_circuit) result = job.result() From 7a747a0c2225fe95482a2f4d8d30cd068d318bc5 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 5 Apr 2024 14:29:38 -0500 Subject: [PATCH 60/65] Explain how to find the classical register name --- docs/api/migration-guides/v2-primitives.mdx | 2 +- docs/run/primitives.mdx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api/migration-guides/v2-primitives.mdx b/docs/api/migration-guides/v2-primitives.mdx index e83b61e70f2..3113d5223f1 100644 --- a/docs/api/migration-guides/v2-primitives.mdx +++ b/docs/api/migration-guides/v2-primitives.mdx @@ -110,7 +110,7 @@ The output is now in the [`PubResult`](/api/qiskit/qiskit.primitives.PubResult) order in which they were measured. * Sampler V2 has convenience methods like `get_counts()` to help with migration. * The Sampler V2 result objects organize data in terms of their **input circuits' classical register names**, for - compatibility with dynamic circuits. By default, the classical register name is `meas`, as shown in the following example. When defining your circuit, if you create one or more classical registers with a non-default name, you would use that name to get those results. + compatibility with dynamic circuits. By default, the classical register name is `meas`, as shown in the following example. When defining your circuit, if you create one or more classical registers with a non-default name, you would use that name to get those results. You can find the classical register name by running `.cregs`. For example, `qc.cregs`. ```python # Define a quantum circuit with 2 qubits diff --git a/docs/run/primitives.mdx b/docs/run/primitives.mdx index f7ddd45abf1..39c2084cc88 100644 --- a/docs/run/primitives.mdx +++ b/docs/run/primitives.mdx @@ -91,7 +91,7 @@ estimator.run([circuit1, circuit2, ...],[observable1, observable2, ...], * The `run()` method takes an array of PUBs. Each PUB is in the format (``, ``, ``, ``), where the optional `parameter values` can be a list or a single parameter. * Combines elements from observables and parameter values by following NumPy broadcasting rules as described below. -* Each input PUB has a corresponding PubResult that contains both data and metadata. +* Each input PUB has a corresponding PubResult that contains both data and metadata. You need the classical register name to get the results. By default, it is named `meas`. You can find the classical register name by running `.cregs`. For example, `qc.cregs`. Example: @@ -204,7 +204,7 @@ sampler.run([circuit1, circuit2, ...],[observable1, observable2, ...],[param_val * Elements from each are aggregated. For example, each array of parameter values in the PUB is applied to the PUB's circuit. * Obeys program outputs. Typically this is a bit array but can also be an array of complex numbers (measurement level 1). * Returns raw data type. Data from each shot is returned (analogous to `memory=True` in the `backend.run` interface), and post-processing is done by using convenience methods. -* Output data is grouped by output registers. +* Output data is grouped by output registers. You need the classical register name to get the results. By default, it is named `meas`. You can find the classical register name by running `.cregs`. For example, `qc.cregs`. Example: From 997d68e85061f33a4803b6b054e56d4a63547544 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Fri, 5 Apr 2024 14:46:32 -0500 Subject: [PATCH 61/65] not in estimator --- docs/run/primitives.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/run/primitives.mdx b/docs/run/primitives.mdx index 39c2084cc88..bffde28f35a 100644 --- a/docs/run/primitives.mdx +++ b/docs/run/primitives.mdx @@ -91,7 +91,7 @@ estimator.run([circuit1, circuit2, ...],[observable1, observable2, ...], * The `run()` method takes an array of PUBs. Each PUB is in the format (``, ``, ``, ``), where the optional `parameter values` can be a list or a single parameter. * Combines elements from observables and parameter values by following NumPy broadcasting rules as described below. -* Each input PUB has a corresponding PubResult that contains both data and metadata. You need the classical register name to get the results. By default, it is named `meas`. You can find the classical register name by running `.cregs`. For example, `qc.cregs`. +* Each input PUB has a corresponding PubResult that contains both data and metadata. Example: From 84e9e96a95eabd206ee44a97bccd3f89675ed6ad Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Mon, 8 Apr 2024 13:33:34 -0500 Subject: [PATCH 62/65] Jessie comment --- docs/run/primitives.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/run/primitives.mdx b/docs/run/primitives.mdx index bffde28f35a..99a8ec13e34 100644 --- a/docs/run/primitives.mdx +++ b/docs/run/primitives.mdx @@ -205,6 +205,7 @@ sampler.run([circuit1, circuit2, ...],[observable1, observable2, ...],[param_val * Obeys program outputs. Typically this is a bit array but can also be an array of complex numbers (measurement level 1). * Returns raw data type. Data from each shot is returned (analogous to `memory=True` in the `backend.run` interface), and post-processing is done by using convenience methods. * Output data is grouped by output registers. You need the classical register name to get the results. By default, it is named `meas`. You can find the classical register name by running `.cregs`. For example, `qc.cregs`. +* Supports circuits with classical feedforward and control flow. Example: From d2b205b66d3e6ebda0e416f772837f34dca4f1d0 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock <66339736+beckykd@users.noreply.github.com> Date: Mon, 8 Apr 2024 13:36:27 -0500 Subject: [PATCH 63/65] Apply suggestions from code review Co-authored-by: Jessie Yu --- .../qiskit-runtime-from-ibm-provider.mdx | 13 ++++++------- .../migration-guides/qiskit-runtime-use-case.mdx | 1 + docs/run/primitives.mdx | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx index 2346489fbe5..c591a1c7ba1 100644 --- a/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx +++ b/docs/api/migration-guides/qiskit-runtime-from-ibm-provider.mdx @@ -11,7 +11,7 @@ by using `qiskit_ibm_provider` to use `qiskit_ibm_runtime`. ## Save accounts -Use the updated code to work save accounts. +Use the updated code to save accounts. @@ -56,8 +56,7 @@ Use the updated code to load accounts. -The new syntax combines the functionality from `load_account()` and -`get_provider()` in one statement. The `channel` input parameter is +The `channel` input parameter is optional. If multiple accounts have been saved in one device and no `channel` is provided, the default is `"ibm_cloud"`. @@ -72,7 +71,7 @@ service = QiskitRuntimeService(channel="ibm_quantum") ``` python -IBMProvider.load_account() +provider = IBMProvider() ``` @@ -84,8 +83,7 @@ Use the updated code to select a hub, group, and project. -The new syntax combines the functionality from `load_account()` and -`get_provider()` in one statement. When using the `ibm_quantum` channel, +When using the `ibm_quantum` channel, the `hub`, `group`, and `project` are specified through the new `instance` keyword. @@ -153,6 +151,7 @@ Change the import and run statements, instantiate the primitive, and make sure t ```python from qiskit import QuantumCircuit +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler service = QiskitRuntimeService() @@ -178,7 +177,7 @@ print(f" > Counts: {result[0].data.meas.get_counts()}") ```python from qiskit_ibm_provider import IBMProvider from qiskit import QuantumCircuit -from qiskit.compiler import transpile, assemble +from qiskit.compiler import transpile circuit = QuantumCircuit(2, 2) circuit.h(0) diff --git a/docs/api/migration-guides/qiskit-runtime-use-case.mdx b/docs/api/migration-guides/qiskit-runtime-use-case.mdx index 27f1c2068c4..02582e671be 100644 --- a/docs/api/migration-guides/qiskit-runtime-use-case.mdx +++ b/docs/api/migration-guides/qiskit-runtime-use-case.mdx @@ -34,6 +34,7 @@ from qiskit_ibm_provider import IBMProvider # Define provider and backend provider = IBMProvider() +backend = provider.get_backend("ibmq_qasm_simulator") job = backend.run(isa_circuit) result = job.result() diff --git a/docs/run/primitives.mdx b/docs/run/primitives.mdx index 99a8ec13e34..fb4d199a7a5 100644 --- a/docs/run/primitives.mdx +++ b/docs/run/primitives.mdx @@ -204,7 +204,7 @@ sampler.run([circuit1, circuit2, ...],[observable1, observable2, ...],[param_val * Elements from each are aggregated. For example, each array of parameter values in the PUB is applied to the PUB's circuit. * Obeys program outputs. Typically this is a bit array but can also be an array of complex numbers (measurement level 1). * Returns raw data type. Data from each shot is returned (analogous to `memory=True` in the `backend.run` interface), and post-processing is done by using convenience methods. -* Output data is grouped by output registers. You need the classical register name to get the results. By default, it is named `meas`. You can find the classical register name by running `.cregs`. For example, `qc.cregs`. +* Output data is grouped by output registers. You need the classical register name to get the results. By default, it is named `meas` if you use `measure_all()`. You can find the classical register name by running `.cregs`. For example, `qc.cregs`. * Supports circuits with classical feedforward and control flow. Example: From 98860e91dcf52bea8ec509d002c4d78a85936f9b Mon Sep 17 00:00:00 2001 From: Rebecca Dimock <66339736+beckykd@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:16:50 -0500 Subject: [PATCH 64/65] Apply suggestions from code review Co-authored-by: Jessie Yu --- .../qiskit-runtime-examples.mdx | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index da2ba264595..8b366558313 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -17,7 +17,8 @@ Use the Estimator primitive to design an algorithm that calculates expectation v - + + ``` python from qiskit_ibm_provider import IBMProvider @@ -45,7 +46,8 @@ result = backend.run(isa_circuits) -**Primitives model:** Access real systems and remote simulators through the `qiskit-ibm-runtime` **primitives** (`Sampler` and `Estimator`). Use **Local testing mode** to run local simulations on Qiskit Runtime fake backends or Aer simulators. The following examples assume you have defined circuits `isa_circuits` and observables `isa_observables`. +**Primitives model:** Access real systems through the `qiskit-ibm-runtime` **primitives** (`Sampler` and `Estimator`). Use **Local testing mode** to run local simulations on Qiskit Runtime fake backends or Aer simulators. The following examples assume you have defined circuits `isa_circuits` and observables `isa_observables`. + @@ -140,7 +142,8 @@ from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager pm = generate_preset_pass_manager(backend=backend, optimization_level=1) isa_circuit = pm.run(circuit) -isa_observable = op.apply_layout(isa_state.layout) +isa_observable = op.apply_layout(isa_circuit.layout) + ``` @@ -209,7 +212,8 @@ convenient tool for algorithm design. from qiskit_ibm_runtime import EstimatorV2 as Estimator estimator = Estimator(backend, options={"default_shots": int(1e4)}) -job = estimator.run([(isa_state, isa_observable)]) +job = estimator.run([(isa_circuit, isa_observable)]) + # Get results for the first (and only) PUB @@ -271,13 +275,15 @@ difference is the format of the output: `backend.run()` outputs - + + ``` python from qiskit_ibm_provider import IBMProvider # Select provider - provider = IBMQ.load_account() + provider = IBMProvider() + # Get backend backend = provider.get_backend("ibmq_qasm_simulator") # Use the cloud simulator @@ -402,9 +408,9 @@ circuit.cx(0,1) circuit.measure_all() # measurement! # Define provider and simulator backend -from qiskit import IBMQ +from qiskit_ibm_provider import IBMProvider -provider = IBMQ.get_provider(hub="ibm-q", group="open", project="main") +provider = IBMProvider(instance="ibm-q/open/main") backend = provider.get_backend("ibmq_qasm_simulator") # Define a statevector simulator From fb24173490c830d580b0da7be53ef48983019512 Mon Sep 17 00:00:00 2001 From: Rebecca Dimock Date: Mon, 8 Apr 2024 15:02:38 -0500 Subject: [PATCH 65/65] add brackets --- docs/api/migration-guides/qiskit-runtime-examples.mdx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/api/migration-guides/qiskit-runtime-examples.mdx b/docs/api/migration-guides/qiskit-runtime-examples.mdx index 8b366558313..3036ee08001 100644 --- a/docs/api/migration-guides/qiskit-runtime-examples.mdx +++ b/docs/api/migration-guides/qiskit-runtime-examples.mdx @@ -143,9 +143,6 @@ pm = generate_preset_pass_manager(backend=backend, optimization_level=1) isa_circuit = pm.run(circuit) isa_observable = op.apply_layout(isa_circuit.layout) - - - ``` @@ -224,8 +221,10 @@ Note that the Estimator returns a list of values, as it can perform batched eval ``` python print(f">>> Expectation value: {pub_result.data.evs}") ->>> Expectation value: -0.8879899326312926 - +``` +Output +```text +>>> Expectation value: [-0.8879899326312926] ```