237 lines
9.4 KiB
Plaintext
237 lines
9.4 KiB
Plaintext
---
|
|
title: Get started with primitives
|
|
description: How to use the Estimator and Sampler primitives in Qiskit Runtime.
|
|
|
|
---
|
|
|
|
# Get started with primitives
|
|
|
|
The steps in this topic describes how to set up primitives, explore the options you can use to configure them, and invoke them in a program.
|
|
|
|
<Admonition type="note">
|
|
While this documentation uses the primitives from Qiskit Runtime, which allow you to use IBM® backends, the primitives can be run on any provider by using the [backend primitives](#backend) instead. Additionally, you can use the *reference* primitives to run on a local statevector simulator. See [Exact simulation with Qiskit primitives](simulate-with-qiskit-sdk-primitives) for details.
|
|
</Admonition>
|
|
|
|
<span id="start-estimator"></span>
|
|
## Get started with Estimator
|
|
|
|
{/*Verified the v2 examples 2/29 */}
|
|
|
|
### 1. Initialize the account
|
|
|
|
Because Qiskit Runtime Estimator is a managed service, you first need to initialize your account. You can then select the QPU you want to use to calculate the expectation value.
|
|
|
|
Follow the steps in the [Install and set up topic](install-qiskit) if you don't already have an account.
|
|
|
|
```python
|
|
from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator
|
|
|
|
service = QiskitRuntimeService()
|
|
backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)
|
|
estimator = Estimator(mode=backend)
|
|
```
|
|
|
|
### 2. Create a circuit and an observable
|
|
|
|
You need at least one circuit and one observable as inputs to the Estimator primitive.
|
|
|
|
```python
|
|
import numpy as np
|
|
from qiskit.circuit.library import IQP
|
|
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
|
|
from qiskit.quantum_info import SparsePauliOp, random_hermitian
|
|
|
|
n_qubits = 127
|
|
|
|
mat = np.real(random_hermitian(n_qubits, seed=1234))
|
|
circuit = IQP(mat)
|
|
observable = SparsePauliOp("Z" * n_qubits)
|
|
print(f">>> Observable: {observable.paulis}")
|
|
```
|
|
Output
|
|
```text
|
|
>>> Observable: ['ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ...']
|
|
```
|
|
|
|
The circuit and observable need to be transformed to only use instructions supported by the QPU (referred to as *instruction set architecture (ISA)* circuits). We'll use the transpiler to do this.
|
|
|
|
```python
|
|
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
|
|
isa_circuit = pm.run(circuit)
|
|
isa_observable = observable.apply_layout(isa_circuit.layout)
|
|
```
|
|
|
|
### 3. Initialize Qiskit Runtime Estimator
|
|
|
|
When you initialize the Estimator, use the `mode` parameter to specify the mode you want it to run in. Possible values are `batch`, `session`, or `backend` objects for batch, session, and job execution mode, respectively. For more information, see [Introduction to Qiskit Runtime execution modes.](execution-modes)
|
|
|
|
```python
|
|
from qiskit_ibm_runtime import EstimatorV2 as Estimator
|
|
|
|
estimator = Estimator(mode=backend)
|
|
```
|
|
|
|
### 4. Invoke the Estimator and get results
|
|
|
|
Next, invoke the `run()` method to calculate expectation values for the input circuits and observables. The circuit, observable, and optional parameter value sets are input as *primitive unified bloc* (PUB) tuples.
|
|
|
|
```python
|
|
job = estimator.run([(isa_circuit, isa_observable)])
|
|
print(f">>> Job ID: {job.job_id()}")
|
|
print(f">>> Job Status: {job.status()}")
|
|
```
|
|
Output
|
|
```text
|
|
>>> Job ID: 8874203f-f5a0-4491-b093-3f29a1adcae4
|
|
>>> Job Status: JobStatus.RUNNING
|
|
```
|
|
|
|
```python
|
|
result = job.result()
|
|
print(f">>> {result}")
|
|
print(f" > Expectation value: {result[0].data.evs}")
|
|
print(f" > Metadata: {result[0].metadata}")
|
|
```
|
|
Output
|
|
```text
|
|
>>> PrimitiveResult([PubResult(data=DataBin<>(evs=0.013671875, stds=0.0156235396179561), metadata={'target_precision': 0.015625})], metadata={})
|
|
> Expectation value: 0.013671875
|
|
> Metadata: {'target_precision': 0.015625}
|
|
```
|
|
|
|
<span id="start-sampler"></span>
|
|
## Get started with Sampler
|
|
|
|
### 1. Initialize the account
|
|
|
|
Because Qiskit Runtime Sampler is a managed service, you first need to initialize your account. You can then select the QPU you want to use to calculate the expectation value.
|
|
|
|
Follow the steps in the [Install and set up topic](install-qiskit) if you don't already have an account set up.
|
|
|
|
```python
|
|
from qiskit_ibm_runtime import QiskitRuntimeService
|
|
|
|
service = QiskitRuntimeService()
|
|
backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)
|
|
```
|
|
|
|
### 2. Create a circuit
|
|
|
|
You need at least one circuit as the input to the Sampler primitive.
|
|
|
|
```python
|
|
import numpy as np
|
|
from qiskit.circuit.library import IQP
|
|
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
|
|
from qiskit.quantum_info import random_hermitian
|
|
|
|
n_qubits = 127
|
|
|
|
mat = np.real(random_hermitian(n_qubits, seed=1234))
|
|
circuit = IQP(mat)
|
|
circuit.measure_all()
|
|
```
|
|
|
|
Use the transpiler to get an ISA circuit.
|
|
|
|
```python
|
|
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
|
|
isa_circuit = pm.run(circuit)
|
|
```
|
|
|
|
### 3. Initialize the Qiskit Runtime Sampler
|
|
|
|
When you initialize the Sampler, use the `mode` parameter to specify the mode you want it to run in. Possible values are `batch`, `session`, or `backend` objects for batch, session, and job execution mode, respectively. For more information, see [Introduction to Qiskit Runtime execution modes.](execution-modes)
|
|
|
|
```python
|
|
from qiskit_ibm_runtime import SamplerV2 as Sampler
|
|
|
|
sampler = Sampler(mode=backend)
|
|
```
|
|
|
|
### 4. Invoke the Sampler and get results
|
|
|
|
Next, invoke the `run()` method to generate the output. The circuit and optional parameter value sets are input as *primitive unified bloc* (PUB) tuples.
|
|
|
|
```python
|
|
job = sampler.run([isa_circuit])
|
|
print(f">>> Job ID: {job.job_id()}")
|
|
print(f">>> Job Status: {job.status()}")
|
|
```
|
|
Output
|
|
|
|
```text
|
|
>>> Job ID: 58223448-5100-4dec-a47a-942fb30edced
|
|
>>> Job Status: JobStatus.RUNNING
|
|
```
|
|
```python
|
|
result = job.result()
|
|
|
|
# Get results for the first (and only) PUB
|
|
pub_result = result[0]
|
|
print(f"Counts for the meas output register: {pub_result.data.meas.get_counts()}")
|
|
```
|
|
Output
|
|
```text
|
|
Counts for the meas output register: {'0111': 50, '0000': 243, '0001': 101, '0101': 93, '0100': 188, '0011': 128, '1011': 22, '0110': 13, '1100': 10, '1000': 24, '0010': 29, '1010': 26, '1101': 20, '1110': 45, '1001': 16, '1111': 16}
|
|
```
|
|
|
|
<span id="backend"></span>
|
|
## Get started with the backend primitives
|
|
|
|
Unlike provider-specific primitives, backend primitives are generic implementations that can be used with an arbitrary
|
|
`backend` object, as long as it implements the [`Backend`](/api/qiskit/qiskit.providers.Backend) interface.
|
|
|
|
- The Sampler primitive can be run with any provider by using [`qiskit.primitives.BackendSamplerV2`](/api/qiskit/qiskit.primitives.BackendSamplerV2).
|
|
- The Estimator primitive can be run with any provider by using [`qiskit.primitives.BackendEstimatorV2`](../api/qiskit/qiskit.primitives.BackendEstimatorV2).
|
|
|
|
Some providers implement primitives natively. See the [Qiskit Ecosystem page](https://qiskit.github.io/ecosystem#provider) for details.
|
|
|
|
### Example: BackendEstimator
|
|
|
|
```python
|
|
from qiskit.primitives import BackendEstimatorV2
|
|
from <some_qiskit_provider> import QiskitProvider
|
|
|
|
provider = QiskitProvider()
|
|
backend = provider.get_backend('backend_name')
|
|
estimator = BackendEstimatorV2(backend)
|
|
```
|
|
|
|
### Example: BackendSampler
|
|
|
|
```python
|
|
from qiskit.primitives import BackendSamplerV2
|
|
from <some_qiskit_provider> import QiskitProvider
|
|
|
|
provider = QiskitProvider()
|
|
backend = provider.get_backend('backend_name')
|
|
sampler = BackendSamplerV2(backend)
|
|
```
|
|
|
|
### Similarities and differences between backend and Runtime primitives
|
|
|
|
- The inputs to and outputs from [`qiskit.primitives.BackendSamplerV2`](/api/qiskit/qiskit.primitives.BackendSamplerV2) and [`qiskit.primitives.BackendEstimatorV2`](../api/qiskit/qiskit.primitives.BackendEstimatorV2)
|
|
follow the same PUB format as the primitives in Qiskit Runtime. See [Primitive inputs and outputs](primitive-input-output) for details.
|
|
However, there can be differences in the fields of the returned metadata.
|
|
|
|
- The [`qiskit.primitives.BackendEstimatorV2`](/api/qiskit/qiskit.primitives.BackendEstimatorV2) class offers no measurement or gate error mitigation implementations out-of-the-box, as
|
|
backend primitives are designed to run locally in the user's machine.
|
|
|
|
- The [`qiskit.primitives.BackendSamplerV2`](/api/qiskit/qiskit.primitives.BackendSamplerV2) class requires a backend that supports the `memory` option.
|
|
|
|
- The backend primitive interfaces expose custom [`SamplerV2`](/api/qiskit/qiskit.primitives.BackendSamplerV2) and [`EstimatorV2`](/api/qiskit/qiskit.primitives.BackendEstimatorV2) `Options` that are different from the Runtime implementations.
|
|
|
|
|
|
## Next steps
|
|
|
|
<Admonition type="tip" title="Recommendations">
|
|
- Learn how to [test locally](local-testing-mode) before running on quantum computers.
|
|
- Review detailed [primitives examples.](primitives-examples)
|
|
- Practice with primitives by working through the [Cost function lesson](https://learning.quantum.ibm.com/course/variational-algorithm-design/cost-functions#primitives) in IBM Quantum Learning.
|
|
- 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.
|
|
- Learn how to [use the primitive options.](runtime-options-overview)
|
|
- View the API for [Sampler](/api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.SamplerOptions) and [Estimator](/api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.EstimatorOptions) options.
|
|
- Read [Migrate to V2 primitives](/migration-guides/v2-primitives).
|
|
</Admonition> |