Skip to content

Commit

Permalink
Revamp options page (#1499)
Browse files Browse the repository at this point in the history
Closes #1416 
Closes #1453 
Closes #1247
Closes #1529 

Comment from Blake: the discoverability of the detailed Sampler and
Estimator options is very poor. i.e. a user can only find these by
navigating the Qiskit Runtime IBM Client API docs. Can we add links to
[SamplerOptions](https://docs.quantum.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.SamplerOptions)
and
[EstimatorOptions](https://docs.quantum.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.EstimatorOptions)
to the [Get started with
primitives](https://docs.quantum.ibm.com/guides/get-started-with-primitives)
page?

---------

Co-authored-by: Arnau Casau <[email protected]>
Co-authored-by: Ian Hincks <[email protected]>
Co-authored-by: Jessie Yu <[email protected]>
  • Loading branch information
4 people authored Jul 16, 2024
1 parent f3eeb24 commit e2f98a8
Show file tree
Hide file tree
Showing 12 changed files with 435 additions and 117 deletions.
4 changes: 2 additions & 2 deletions docs/api/migration-guides/qiskit-quantum-instance.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ yourself two questions:
This question is not new. In the legacy algorithm workflow, you would set up a
[`qiskit.utils.QuantumInstance`](../qiskit/0.46/qiskit.utils.QuantumInstance) with either a real system from a provider, or a simulator.
For this migration, this "system selection" process is translated to **where** do you import your primitives from:

* Using **local** statevector simulators for quick prototyping: **Reference primitives**
* Using **local** noisy simulations for finer algorithm tuning: **Aer primitives**
* Accessing **runtime-enabled systems** (or cloud simulators): **Qiskit Runtime primitives**
Expand All @@ -90,7 +90,7 @@ yourself two questions:
Arguably, the `Sampler` is the closest primitive to [`qiskit.utils.QuantumInstance`](../qiskit/0.46/qiskit.utils.QuantumInstance), as they
both execute circuits and provide a result. However, with the [`qiskit.utils.QuantumInstance`](../qiskit/0.46/qiskit.utils.QuantumInstance),
the result data was system-dependent (it could be a counts `dict`, a `numpy.array` for
statevector simulations, and so on), while `Sampler` normalizes its `SamplerResult` to
statevector simulations, and so on), while `Sampler` normalizes its `SamplerResult` to
return a [`qiskit.result.QuasiDistribution`](../qiskit/qiskit.result.QuasiDistribution) object with the resulting quasi-probability distribution.

The `Estimator` provides a specific abstraction for the expectation value calculation that can replace
Expand Down
2 changes: 1 addition & 1 deletion docs/api/migration-guides/qiskit-runtime-examples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,8 @@ Output
</TabItem>

<TabItem value="legacy" label="backend.run()">
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.

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
Expand Down
2 changes: 1 addition & 1 deletion docs/api/migration-guides/qiskit-runtime-options.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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, 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](/guides/runtime-options-overview) for more information 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](/guides/runtime-options-overview) for more information about specifying V2 primitives options.

| backend.run options | V2 Primitive options | Notes |
|---------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|
Expand Down
12 changes: 6 additions & 6 deletions docs/api/migration-guides/qiskit-runtime-use-case.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: Common use cases when migrating from backend.run to Qiskit Runtime
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.
The only changes when running basic circuits are how you run the job and retrieve results.

<Tabs>
<TabItem value="Updated" label="Runtime primitives">
Expand Down Expand Up @@ -80,7 +80,7 @@ To migrate programs that run dynamic circuits, change the run call.

<Tabs>
<TabItem value="primitives" label="Sampler">
```python
```python
from qiskit_ibm_runtime import SamplerV2 as Sampler

sampler = Sampler(backend)
Expand All @@ -92,7 +92,7 @@ print(f">>> Hardware counts: {pub_result.data.meas.get_counts()}")
</TabItem>

<TabItem value="backend" label="backend.run">
```python
```python
job = backend.run(dynamic_circ, dynamic=True)
job.job_id()

Expand Down Expand Up @@ -154,7 +154,7 @@ theta_values = [np.pi/2, np.pi/2, np.pi/2]

<Tabs>
<TabItem value="updated" label="Runtime primitives">
Only circuits that adhere to the Instruction Set Architecture (ISA) of a specific backend are accepted, 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
Expand Down Expand Up @@ -185,7 +185,7 @@ 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".
# Get counts from the classical register "c".
print(f" >> Counts for the c output register: {pub_result.data.c.get_counts()}")
```
</TabItem>
Expand Down Expand Up @@ -232,7 +232,7 @@ pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)

sampler = Sampler(backend)
# Get the averaged IQ data.
# 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)
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/_toc.json
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@
"title": "Configure runtime options",
"children": [
{
"title": "Configure runtime compilation",
"title": "Configure error suppression",
"url": "/guides/configure-error-suppression"
},
{
Expand Down
50 changes: 8 additions & 42 deletions docs/guides/configure-error-mitigation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,11 @@ which levels and corresponding methods are available for each of the
primitives.

<Admonition type="info" title="Attention">
Error mitigation is task specific so the techniques you are able to
Error mitigation is task specific, so the techniques you are able to
apply vary based whether you are sampling a distribution or generating
expectation values.
</Admonition>

<Admonition type="caution" title="Important">
To ensure faster and more efficient results, as of 1 March 2024, circuits and observables need to be transformed to only use instructions supported by the system (referred to as *instruction set architecture (ISA)* circuits and observables) before being submitted to the Qiskit Runtime primitives. See the [transpilation documentation](./transpile) for instructions to transform circuits. Due to this change, the primitives will no longer perform layout or routing operations. Consequently, transpilation options referring to those tasks will no longer have any effect. By default, all V1 primitives optimize the input circuits. To bypass all optimization when using a V1 primitive, set `optimization_level=0`.

*Exception*: When you initialize the Qiskit Runtime Service with the Q-CTRL channel strategy (example below), abstract circuits are still supported.

``` python
service = QiskitRuntimeService(channel="ibm_cloud", channel_strategy="q-ctrl")
```

</Admonition>

<span id="resilience-table"></span>

<Tabs>
Expand Down Expand Up @@ -100,7 +89,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-error) 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 (V2 primitives).](#advanced-error) You cannot specify resilience levels in Sampler V2. However, you can set custom techniques individually.

<details>
<summary>Resilience Level 0</summary>
Expand Down Expand Up @@ -139,7 +128,7 @@ stage). This approach tends to reduce errors in expectation values, but
is not guaranteed to produce an unbiased result.


![This image shows a graph. The x-axis is labeled Noise amplification factor. The y-axis is labeled Expectation value. An upward sloping line is labeled Mitigated value. Points near the line are noise-amplified values. There is a horizontal line just above the X-axis labeled Exact value. ](/images/optimize/resilience-2.png "Illustration of the ZNE method")
![This image shows a graph. The x-axis is labeled Noise amplification factor. The y-axis is labeled Expectation value. An upward sloping line is labeled Mitigated value. Points near the line are noise-amplified values. There is a horizontal line just above the X-axis labeled Exact value.](/images/optimize/resilience-2.svg "Illustration of the ZNE method")

The overhead of this method scales with the number of noise factors. The
default settings sample the expectation value at three noise factors,
Expand Down Expand Up @@ -172,7 +161,7 @@ estimator = Estimator(backend, options={"resilience_level": 2})

<Admonition type="info" title="Note">

As you increase the resilience level, you will be able to use additional methods to improve the accuracy of your result. However, because the methods become more advanced with each level, they require additional sampling overhead (time) to generate more accurate expectation values. Note that higher resilience levels do not guarantee better quality. Higher levels only mean greater overhead. Each method has its strengths and weaknesses. For example, TREX (Twirled Readout Error eXtinction) is good for shallow circuits because of its readout error mitigation, whereas ZNE (Zero Noise Extrapolation) is good for deeper circuits. PEC can mitigate arbitrary errors but may not work in practice because of its large overhead.
As you increase the resilience level, you can use additional methods to improve the accuracy of your result. However, because the methods become more advanced with each level, they require additional sampling overhead (time) to generate more accurate expectation values. Note that higher resilience levels do not guarantee better quality. Higher levels only mean greater overhead. Each method has its strengths and weaknesses. For example, TREX (Twirled Readout Error eXtinction) is good for shallow circuits because of its readout error mitigation, whereas ZNE (Zero Noise Extrapolation) is good for deeper circuits. PEC can mitigate arbitrary errors but might not work in practice because of its large overhead.
</Admonition>

## Configure Estimator (V1) with resilience levels
Expand Down Expand Up @@ -217,7 +206,7 @@ stage). This approach tends to reduce errors in expectation values, but
is not guaranteed to produce an unbiased result.


![This image shows a graph. The x-axis is labeled Noise amplification factor. The y-axis is labeled Expectation value. An upward sloping line is labeled Mitigated value. Points near the line are noise-amplified values. There is a horizontal line just above the X-axis labeled Exact value. ](/images/optimize/resilience-2.png "Illustration of the ZNE method")
![This image shows a graph. The x-axis is labeled Noise amplification factor. The y-axis is labeled Expectation value. An upward sloping line is labeled Mitigated value. Points near the line are noise-amplified values. There is a horizontal line just above the X-axis labeled Exact value.](/images/optimize/resilience-2.svg "Illustration of the ZNE method")

The overhead of this method scales with the number of noise factors. The
default settings sample the expectation value at three noise factors,
Expand Down Expand Up @@ -320,7 +309,7 @@ problems.

### Example

The Estimator interface lets users seamlessly work with the variety of
The Estimator interface lets you seamlessly work with the variety of
error mitigation methods to reduce error in expectation values of
observables. The following code uses Zero Noise Extrapolation by simply
setting `resilience_level=2`.
Expand Down Expand Up @@ -471,32 +460,9 @@ job = estimator.run(circuits=[psi1], observables=[H1], parameter_values=[theta1]
psi1_H1 = job.result()
```

<span id="no-error-mitigation"></span>
## Turn off all error mitigation and error suppression

You can turn off all error mitigation and suppression if you are, for example, doing research on your own mitigation techniques. To accomplish this, for EstimatorV2, set `resilience_level = 0`. For SamplerV2, no changes are necessary because no error mitigation or suppression options are enabled by default.

Example:
## Turn off all error mitigation

Turn off all error mitigation and suppression in EstimatorV2.

```python
from qiskit_ibm_runtime import EstimatorV2 as Estimator, Options, 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)

# Define Estimator
estimator = Estimator(backend)

options = estimator.options

# Turn off all error mitigation and suppression
options.resilience_level = 0
```
For instructions to turn off all error mitigation, see the [Turn off all error suppression and mitigation](runtime-options-overview#no-error-mitigation) section.

## Next steps

Expand Down
19 changes: 12 additions & 7 deletions docs/guides/configure-error-suppression.mdx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
---
title: Configure runtime compilation
description: How to configure runtime compilation in Qiskit Runtime.
title: Configure error suppression
description: How to configure error suppression in Qiskit Runtime. (Previous topic - runtime compilation)

---

# Configure runtime compilation for Qiskit Runtime
# Configure error suppression for Qiskit Runtime

Runtime compilation techniques transform your circuit to minimize errors. Runtime compilation adds some classical pre-processing overhead to your overall runtime. Therefore, it is important to achieve a balance between perfecting your results and ensuring that your job completes in a reasonable amount of time.

Primitives let you employ runtime compilation by choosing advanced runtime compilation options. If you don't want any processing done to minimize errors, follow the instructions in the [Turn off all error mitigation and error suppression](runtime-options-overview#no-error-mitigation) section.

<Admonition type="caution" title="Important">
To ensure faster and more efficient results, as of 1 March 2024, circuits and observables need to be transformed to only use instructions supported by the system (referred to as *instruction set architecture (ISA)* circuits and observables) before being submitted to the Qiskit Runtime primitives. See the [transpilation documentation](./transpile) for instructions to transform circuits. Due to this change, the primitives will no longer perform layout or routing operations. Consequently, transpilation options referring to those tasks will no longer have any effect. By default, all V1 primitives optimize the input circuits. To bypass all optimization when using a V1 primitive, set `optimization_level=0`.

Expand Down Expand Up @@ -126,11 +128,11 @@ psi1_H1 = job.result()


<span id="transpilation-table"></span>
## Advanced runtime compilation options
## Advanced error suppression options

<Tabs>
<TabItem value="PrimV2" label="V2 primitives">
In the V2 primitives, you can explicitly enable and disable individual error mitigation/suppression methods, such as dynamical decoupling.
In the V2 primitives, you can explicitly enable and disable individual error mitigation and suppression methods, such as dynamical decoupling.

<Admonition type = "note">
Dynamical decoupling is not supported when the input circuits are dynamic.
Expand All @@ -154,15 +156,18 @@ print(f">>> dynamical decoupling sequence to use: {sampler.options.dynamical_dec
</TabItem>

<TabItem value="PrimV1" label="V1 primitives">
Because all input must be ISA, options.transpilation.xxx will be ignored.
Because all input must be ISA, `options.transpilation.xxx` is ignored. See [Advanced runtime options](runtime-options-overview) for information.
</TabItem>
</Tabs>

## Turn off all error suppression

For instructions to turn off all error suppression, see the [Turn off all error suppression and mitigation](runtime-options-overview#no-error-mitigation) section.

## Next steps

<Admonition type="tip" title="Recommendations">
- Try a tutorial that uses optimization levels, such as the [Variational quantum eigensolver](https://learning.quantum.ibm.com/tutorial/variational-quantum-eigensolver) tutorial.
- Learn how to transpile locally in the [Transpile](./transpile) section.
- Learn how to transpile locally in the [Transpile](./transpile/) section.
- Try the [Submit pre-transpiled circuits](https://learning.quantum.ibm.com/tutorial/submitting-user-transpiled-circuits-using-primitives) tutorial.
</Admonition>
Loading

0 comments on commit e2f98a8

Please sign in to comment.