Skip to content

Commit

Permalink
Merge b1d8a8d into d8e9788
Browse files Browse the repository at this point in the history
  • Loading branch information
beckykd authored Mar 5, 2024
2 parents d8e9788 + b1d8a8d commit 6303e6d
Show file tree
Hide file tree
Showing 23 changed files with 2,518 additions and 231 deletions.
4 changes: 4 additions & 0 deletions docs/api/migration-guides/_toc.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
}
]
},
{
"title": "Migrate to the Qiskit Runtime V2 primitives",
"url": "/api/migration-guides/v2-primitives"
},
{
"title": "Migrate to Qiskit Runtime",
"children": [
Expand Down
1 change: 1 addition & 0 deletions docs/api/migration-guides/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ These migration guides help you more effectively use Qiskit and Qiskit Runtime:
* Migrate to Qiskit 1.0
* [Qiskit 1.0 packaging changes](/api/migration-guides/qiskit-1.0-installation)
* [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)
* [Examples](./qiskit-runtime-examples)
Expand Down
1,193 changes: 1,193 additions & 0 deletions docs/api/migration-guides/v2-primitives.mdx

Large diffs are not rendered by default.

18 changes: 17 additions & 1 deletion docs/build/bit-ordering.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,27 @@ the value $2^\text{label}$ (label being the qubit's index in
with bit $0$ being `0`, and bit $1$ being `1`. This is interpreted as the
decimal integer `2` (measured with probability `1.0`).

```python
<Tabs>
<TabItem value="SamplerV2" label="V2 Sampler">
```python
from qiskit.primitives import Samplerv2 as Sampler
qc.measure_all()

job = sampler.run([(qc)])
result = job.result()
print(f" > Counts: {result[0].data.meas.get_counts()}")
```
</TabItem>

<TabItem value="SamplerV1" label="Sampler (V1)">
```python
from qiskit.primitives import Sampler
qc.measure_all()

Sampler().run(qc).result().quasi_dists[0]
```
</TabItem>
</Tabs>

```
{2: 1.0}
Expand Down
2 changes: 1 addition & 1 deletion docs/build/circuit-construction.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@
"qc.rx(angle, 0)\n",
"\n",
"from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n",
"qc = generate_preset_pass_manager(3, basis_gates=['u', 'cx']).run(qc)\n",
"qc = generate_preset_pass_manager(optimization_level=3, basis_gates=['u', 'cx']).run(qc)\n",
"\n",
"qc.draw(\"mpl\")"
]
Expand Down
161 changes: 148 additions & 13 deletions docs/run/advanced-runtime-options.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,26 @@ description: Specify options when building with Qiskit runtime primitives

# Advanced Qiskit Runtime options

When calling the primitives, you can pass in options by using the `Options` class or when using the `run` method. In the `Options` class, commonly used options, such as `resilience_level`, are at the first level. Other options are grouped into different categories:
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 all the available options in the [API reference](../api/qiskit-ibm-runtime/options).

<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. Users can still request that the primitives do no optimization of input circuits by specifying `options.transpilation.skip_transpilation`.
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. Users can still request that the primitives do no optimization of input circuits by specifying `optimization_level=0`.
</Admonition>

![The image shows the top-level options categories: transpilation, resilience, execution, environment, and simulation.](/images/build/options.png "Option categories")

<Admonition type="info" title="Attention">
This section focuses on Qiskit Runtime primitive [Options](../api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.Options) (imported from `qiskit_ibm_runtime`). While most of the `primitives` interface is common across implementations, most `Options` are not. Consult the
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>

## Instantiate the Options class
## 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.

Expand All @@ -40,36 +46,122 @@ options.execution.shots = 2048
```
## Pass options to a primitive

### Options class
### 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)

When creating an instance of the `Estimator` or `Sampler` class, you can pass in the `options` you just created. Those options will then be applied when you use `run()` to perform the calculation. Example:
# 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.

Because most users will only overwrite a few options at the job level, it is not necessary to specify the category the options are in. The code below, for example, specifies `shots=1024` instead of `execution={"shots": 1024}` (which is also valid).
<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 category the options are in. 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>

For some algorithms, setting a specific number of shots is a core part of their routines. 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
<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
Expand Down Expand Up @@ -98,6 +190,10 @@ 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
Expand All @@ -109,7 +205,24 @@ The Qiskit Runtime primitives may perform additional runtime compilation to opti
See the Optimization level table in the
[Runtime compilation topic](configure-runtime-compilation#set-the-optimization-level) for further details.

<Admonition>
<Tabs>
<TabItem value="PrimV2" label="V2 Estimator">
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>

Expand Down Expand Up @@ -140,15 +253,33 @@ 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 can also be set through the `resilience_level` option. The method selected for each level is
different for `Sampler` and `Estimator`. You can find more information in the
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="V2 Estimator">
With V2 Estimator, 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.zne_mitigation = True
estimator.options.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
Expand All @@ -163,6 +294,10 @@ options.resilience_level = 2

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



## Next steps

Expand Down
Loading

0 comments on commit 6303e6d

Please sign in to comment.