Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[do not merge] Demo collapsible get started #1468

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
419 changes: 419 additions & 0 deletions docs/guides/_toc.json

Large diffs are not rendered by default.

327 changes: 327 additions & 0 deletions docs/guides/advanced-runtime-options.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,327 @@
---
title: Advanced Qiskit Runtime options
description: Specify options when building with Qiskit Runtime primitives

---

# Advanced Qiskit Runtime options

When calling the primitives, you can pass in options by using an options class or a dictionary. In the options classes, commonly used options, such as `resilience_level`, are at the first level. Other options are grouped into different categories, such as `execution`. See the [options classes section](#options-classes) for details.

<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 primitives except Sampler V2 still optimize the input circuits. To bypass all optimization, 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>

<Admonition type="info" title="Attention">
This section focuses on Qiskit Runtime primitive options. While most of the `primitives` interface is common across implementations, most options are not. Consult the
corresponding API references for information about the `qiskit.primitives` and `qiskit_aer.primitives` options.
</Admonition>

## V2 changes
Options are specified differently in the V2 primitives in these ways:

- `SamplerV2` and `EstimatorV2` now have separate options classes. You can see the available options and update option values during or after primitive initialization.
- Instead of the `set_options()` method, V2 primitive options have the `update()` method that applies changes to the `options` attribute.
- If you do not specify a value for an option, it is given a special value of `Unset` and the server defaults are used.
- For V2 primitives, the `options` attribute is the `dataclass` Python type. You can use the built-in `asdict` method to convert it to a dictionary.

## Instantiate the Options class (V1)

In the example below, we create an instance of the `Options` class. `optimization_level` is a first-level option and can be passed as an input parameter. Options related to the execution environment are passed using the `environment` parameter.

```python
from qiskit_ibm_runtime import Options

options = Options(optimization_level=1, environment={"log_level": "INFO"})
```

The `Options` class supports auto-complete. Once you create an instance of the `Options` class, you can use auto-complete to see what options are available. If you choose one of the categories, you can use auto-complete again to see what options are available under that category.

```python
from qiskit_ibm_runtime import Options

options = Options()
options.resilience_level = 1
options.execution.shots = 2048
```
## Pass options to a primitive

### Options class

When creating an instance of the `Estimator` or `Sampler` class, you can pass in the `options` you created in the options class. Those options will then be applied when you use `run()` to perform the calculation. Example:

<Tabs>
<TabItem value="PrimV2" label="V2 primitives">
`SamplerV2` and `EstimatorV2` have separate options classes that do not need to be instantiated. You can see the available options and update option values during or after primitive initialization. Those options will then be applied when you use `run()` to perform the calculation. Example:

```python
estimator = Estimator(backend=backend)

# Setting options after primitive initialization
# This uses auto complete.
estimator.options.optimization_level = 1
estimator.options.default_shots = 4000
```
</TabItem>

<TabItem value="PrimV1" label="V1 primitives">
When creating an instance of the `Estimator` or `Sampler` class, you can pass in the `options` you created in the options class. Those options will then be applied when you use `run()` to perform the calculation. Example:

```python
estimator = Estimator(session=backend, options=options)
result = estimator.run(circuit, observable).result()
print(f">>> Metadata: {result.metadata[0]}")
```
</TabItem>
</Tabs>

### Primitive initialization

You can specify options when initializing the primitive.


<Tabs>
<TabItem value="PrimV2" label="V2 primitives">
```python
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

# Setting options during primitive initialization
estimator = Estimator(backend, options={"resilience_level": 2})
```
</TabItem>

<TabItem value="PrimV1" label="V1 primitives">
```python
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import Estimator

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

# Setting options during primitive initialization
estimator = Estimator(backend, options={"resilience_level": 2})
```
</TabItem>
</Tabs>

### Run() method

You can pass in options by using the `run()` method. This overwrites the options you specified when creating the `Estimator` or `Sampler` instance for that particular execution.

<Tabs>
<TabItem value="PrimV2" label="V2 primitives">
In V2, the only options you can pass to `run()` are options defined in the interface. That is, `shots` for Sampler and `precision` for Estimator.
```python
# Sample two circuits at 128 shots each.
sampler.run([circuit1, circuit2], shots=128)
```

</TabItem>

<TabItem value="PrimV1" label="V1 primitives">
You can pass any options to `run()`. Because most users will only overwrite a few options at the job level, it is not necessary to specify the options category. The code below, for example, specifies `shots=1024` instead of `execution={"shots": 1024}` (which is also valid).
```python
estimator = Estimator(session=backend, options=options)
result = estimator.run(circuit, observable, shots=1024).result()
print(f">>> Metadata: {result.metadata[0]}")
```
</TabItem>
</Tabs>


## Commonly used options

There are many available options, but the following are the most commonly used:

### Shots
For some algorithms, setting a specific number of shots is a core part of their routines. There are several ways to set and update shots with the primitives.

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

# Setting shots during primitive initialization
sampler = Sampler(backend, options={"default_shots": 4096})

# Setting options after primitive initialization
# This uses auto complete.
sampler.options.default_shots=2000

# 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"})

# Sample two circuits at 128 shots each.
sampler.run([circuit1, circuit2], shots=128)
```
</TabItem>

<TabItem value="v1primitives" label="V1 Primitives">
Previously, shots could be set during the call to `backend.run()`. For example, `backend.run(shots=1024)`. Now, that setting is part of the execution
options ("second level option"). This can be done during the primitive setup:

```python
from qiskit_ibm_runtime import Estimator, Options

options = Options()
options.execution.shots = 1024

estimator = Estimator(session=backend, options=options)
```

If you need to modify the number of shots set between iterations (primitive calls), you can set the
shots directly in the `run()` method. This overwrites the initial `shots` setting.

```python
from qiskit_ibm_runtime import Estimator

estimator = Estimator(session=backend)

estimator.run(circuits=circuits, observables=observables, shots=50)

# other logic

estimator.run(circuits=circuits, observables=observables, shots=100)
```

For more information about the primitive options, refer to the
[Options class API reference](../api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.Options).
</TabItem>
</Tabs>




### Runtime compilation

The Qiskit Runtime primitives expect to be called with circuits already suitable for execution on the target system. This implies that the user has already transpiled their circuits to respect the native gate set and connectivity constraints of the target system.

The Qiskit Runtime primitives may perform additional runtime compilation to optimize circuits, with the degree of optimization controlled by an optimization level option. The optimization level you choose affects the compilation strategy, with higher levels invoking more expensive or aggressive optimizations.

See the Optimization level table in the
[Runtime compilation topic](configure-runtime-compilation#set-the-optimization-level) for further details.

<Tabs>
<TabItem value="PrimV2" label="Estimator V2">
The optimization level option is a "first-level option". Sampler V2 does not currently support `optimization_level`.

```python
from qiskit_ibm_runtime import EstimatorV2 as Estimator

estimator = Estimator(session=backend, options={"optimization_level": 1})

# or..
estimator.options.optimization_level = 1
```

To turn off all optional runtime compilation steps, you must set `optimization_level=0`. V2 primitives do not support any advanced transpilation options.
</TabItem>

<TabItem value="PrimV1" label="V1 primitives">
<Admonition>
In the currently deployed Qiskit Runtime primitives, optimization levels 2 and 3 behave identically to level 1. If you want to use more advanced optimization, use the Qiskit transpiler locally, set [`skip_transpilation=True`](../api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.TranspilationOptions#skip_transpilation), and then pass the transpiled circuits to the primitives. For instructions see the [Submit pre-transpiled circuits](https://learning.quantum.ibm.com/tutorial/submitting-user-transpiled-circuits-using-primitives) tutorial.
</Admonition>

The optimization level option is a "first-level option", and can be set as follows:

```python
from qiskit_ibm_runtime import Estimator, Options

options = Options(optimization_level=1)

# or..
options = Options()
options.optimization_level = 1

estimator = Estimator(session=backend, options=options)
```

Turning off all optional runtime compilation steps requires a "second-level option", as follows:

```python
from qiskit_ibm_runtime import Estimator, Options

options = Options()
options.transpilation.skip_transpilation = True

estimator = Estimator(session=backend, options=options)
```

For more information and a complete list of advanced transpilation options, see the Advanced transpilation options table in the
[Runtime compilation topic](configure-runtime-compilation#transpilation-table).
</TabItem>
</Tabs>

### Error mitigation


You might want to leverage different error mitigation methods and see how these affect the performance of your
algorithm. These methods can be set through the `resilience_level` option. For more information about error mitigation, see the
[Configure error mitigation topic](configure-error-mitigation).

<Tabs>
<TabItem value="PrimV2" label="Estimator V2">
With Estimator V2, you can set resilience levels 0-2 and you can also turn on and off various error mitigation settings for fine-tuning.

```python
estimator = Estimator(backend=backend)

estimator.options.resilience_level = 2
estimator.options.resilience.zne_mitigation = True
estimator.options.resilience.zne.noise_factors = [1, 3, 5]
```
</TabItem>

<TabItem value="PrimV1" label="V1 primitives">
The method selected for each level is
different for `Sampler` and `Estimator`.

The configuration is similar to the other options:

```python
from qiskit_ibm_runtime import Estimator, Options

options = Options(resilience_level = 2)

# or...

options = Options()
options.resilience_level = 2

estimator = Estimator(session=backend, options=options)
```
</TabItem>
</Tabs>

<span id="options-classes"></span>
## Options classes

| Category | Description | Example |
|:-------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------:|:------------------------------------------------------|
| [Resilience](../api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.ResilienceOptionsV2) | Advanced options for configuring error mitigation methods such as measurement error mitigation, ZNE, and PEC. Estimator only. | `estimator.options.resilience.measure_mitigation = True` |
| [Dynamical decoupling](../api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.DynamicalDecouplingOptions) | Options for dynamical decoupling. | `estimator.options.dynamical_decoupling.enable = True` |
| [Execution](../api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.ExecutionOptionsV2) | Primitive execution options, including whether to initialize qubits and the repetition delay. | `estimator.options.execution.init_qubits = False` |
| [Twirling](../api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.TwirlingOptions) | Twirling options, such as whether to apply two-qubit gate twirling and the number of shots to run for each random sample. | `estimator.options.twirling.enable_gates = True` |
| [Environment](../api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.EnvironmentOptions) | Execution environment options such as the logging level to set and job tags to add. | `estimator.options.environment.log_level = 'ERROR'` |
| [Simulator](../api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.SimulatorOptions) | Simulator options, such as the basis gates, simulator seed, and coupling map. Applies to local testing mode only. | `estimator.options.simulator.seed_simulator = 42` |

## Next steps

<Admonition type="tip" title="Recommendations">
- Find more details about the `Estimator` methods in the [Estimator API reference](../api/qiskit-ibm-runtime/qiskit_ibm_runtime.Estimator#estimator).
- Find more details about the `Sampler` methods in the [Sampler API reference](../api/qiskit-ibm-runtime/qiskit_ibm_runtime.Sampler#sampler).
- Find all available options in the [Options API reference](../api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.Options).
- Find details about [runtime compilation](configure-runtime-compilation) and [error mitigation](configure-error-mitigation).
- 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
Loading