Skip to content

Commit

Permalink
Merge branch 'main' into kjf/custom-passmanagers
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinsung committed Nov 20, 2023
2 parents 2876ff5 + 64d6737 commit 11d8cc1
Show file tree
Hide file tree
Showing 28 changed files with 576 additions and 126 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/external-link-checker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# This code is a Qiskit project.
#
# (C) Copyright IBM 2023.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

# This Action validates all the links in the documentation, including
# external links. This Action will be run at 00:00 (UTC) every day.

name: Check external links
on:
schedule:
- cron: "0 0 * * *"

jobs:
external-link-checker:
runs-on: ubuntu-latest
if: github.repository_owner == 'Qiskit'
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install Node.js dependencies
run: npm ci

- name: Check external links
run: npm run check:links -- --external
2 changes: 1 addition & 1 deletion .github/workflows/learning-uploader-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ on:
jobs:
e2e:
name: End-to-end test
if: github.event.pull_request.head.repo.full_name == github.repository
if: ${{ github.event_name == 'schedule' || github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- name: Spellcheck
run: npm run check:spelling
- name: Link checker
run: npm run check:links -- --external
run: npm run check:links
- name: Formatting
run: npm run check:fmt
- name: Typecheck
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ CI will check for broken links. You can also check locally:
# Only check for internal broken links
npm run check:links

# Only check for internal and external broken links
# Enable the validation of external links
npm run check:links -- --external

# Or, run all the checks
Expand Down
2 changes: 2 additions & 0 deletions cSpell.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"Chebyshev",
"Choi",
"Chong",
"CHSH",
"Chuang",
"qubit",
"qubits",
Expand All @@ -44,6 +45,7 @@
"Hamiltonians",
"Eigensolver",
"Eigensolvers",
"EPLG",
"Factorizers",
"exponentials",
"Hadamard",
Expand Down
6 changes: 5 additions & 1 deletion docs/run/_toc.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
]
},
{
"title": "Sessions",
"title": "Execution modes",
"children": [
{
"title": "About sessions",
Expand All @@ -50,6 +50,10 @@
{
"title": "Run jobs in a session",
"url": "/run/run-jobs-in-session"
},
{
"title": "Run jobs in a batch",
"url": "/run/run-jobs-batch"
}
]
},
Expand Down
12 changes: 6 additions & 6 deletions docs/run/configure-error-mitigation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ expectation values.
</Admonition>


| Resilience Level | Definition | Estimator | Sampler |
|------------------|-------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------|---------|
| 0 | No mitigation | None | None |
| 1 [Default] | Minimal mitigation costs: Mitigate error associated with readout errors | Twirled Readout Error eXtinction (TREX interpreted-text readout errors ) | M3 |
| 2 | Medium mitigation costs. Typically reduces bias in estimators, but is not guaranteed to be zero bias. | Zero Noise Extrapolation (ZNE interpreted-text) | - |-
| 3 | Heavy mitigation with layer sampling. Theoretically expected to deliver zero bias estimators. ) | Probabilistic Error cancelation (PEC interpreted-text) | - |-|
| Resilience Level | Definition | Estimator | Sampler |
|------------------|-------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------|----------------------------------------|
| 0 | No mitigation | None | None |
| 1 [Default] | Minimal mitigation costs: Mitigate error associated with readout errors | Twirled Readout Error eXtinction (TREX) | Matrix-free Measurement Mitigation (M3)|
| 2 | Medium mitigation costs. Typically reduces bias in estimators, but is not guaranteed to be zero-bias. | Zero Noise Extrapolation (ZNE) | - |
| 3 | Heavy mitigation with layer sampling. Theoretically expected to deliver zero-bias estimators. | Probabilistic Error cancelation (PEC) | - |


<Admonition type="info" title="Attention">
Expand Down
94 changes: 57 additions & 37 deletions docs/run/primitives.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,68 +6,88 @@ description: Introduction to primitives in Qiskit and Qiskit Runtime, and an exp

# Introduction to primitives

In computing, a primitive is the smallest processing instruction for a given abstraction level. Put simply, they are the simplest building blocks from which a user can create something useful - and since primitives abstract away implementation details, users can accomplish tasks without needing to worry about low-level specifics. The computational model proposed by primitives moves quantum programming one step closer to where classical programming is today, where the focus is less on the hardware details and more on the results you are trying to achieve.
Computing systems are built upon multiple layers of **abstraction**. Abstractions allow to focus on a
particular level of detail relevant to the task at hand. The closer you get to the hardware,
the lower the level of abstraction you'll need (for example, you could
want to manipulate electrical signals), and vice versa, the more complex the task you want to perform,
the higher-level the abstractions will be (for example, you could be using a programming library to perform
algebraic calculations).

## Primitives in Qiskit
In this context, a **primitive** is the smallest processing instruction, the simplest building block from which
one can create something **useful** for a given **abstraction** level.

The existing Qiskit interface to backends (`backend.run()`) was originally designed to accept a list of circuits and return counts for every job. Over time, it became clear that users have diverse purposes for quantum computing, and therefore the ways in which they define the requirements for their computing jobs are expanding. Therefore, their results also look different.
The recent progress in quantum computing has increased the need to work at higher levels of abstraction.
As we move towards larger systems and more complex workflows, the focus shifts from interacting with individual
qubit signals to viewing quantum devices as systems that perform tasks we need.

For example, an algorithm researcher and developer cares about information beyond counts; they are more focused on efficiently calculating quasi-probability distributions and expectation values of observables.
The two most common tasks quantum computers are used for are sampling quantum states and calculating expectation values.
These tasks motivated the design of *the first two Qiskit primitives: Sampler and Estimator*.

Our primitives provide methods that make it easier to build modular algorithms and other higher-order programs. Rather than simply returning counts, they return more immediately meaningful information. Additionally, they provide a seamless way to access the latest optimizations in IBM Quantum hardware and software.
In short, the computational model introduced by the Qiskit primitives moves quantum programming one step closer
to where classical programming is today, where the focus is less on the hardware details and more on the results
you are trying to achieve.

The basic operations that one can perform with a probability distribution is to sample from it or to estimate quantities on it. Therefore, these operations form the fundamental building blocks of quantum algorithm development. Our first two Qiskit Runtime primitives (Sampler and Estimator) use these sampling and estimating operations as core interfaces to our quantum systems.
## Implementation of Qiskit primitives

The following primitives are available:
The Qiskit primitives are defined by open-source primitive base-classes, from
which different providers can derive their own Sampler and Estimator implementations. Among the implementations
using Qiskit, you can find reference primitive implementations for local simulation in the `qiskit.primitives` module.
Providers like IBM’s Qiskit Runtime enable access to appropriate backends through native implementations of
their own primitives.

| Primitive | Description | Example output |
|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------|
| Estimator | Computes expectation values of observables with respect to states prepared by quantum circuits. Users generally specify a list of circuits, observables, and possibly some additional configuration, with which the program can efficiently evaluate expectation values and variances. | ![estimator](/images/build/estimator.svg) |
| Sampler | Calculates probabilities or quasi-probability distributions of bitstrings from quantum circuits. Quasi-probability distributions are similar to regular probabilities, except they may include negative values, which can occur when using certain error mitigation techniques. | ![sampler](/images/build/sampler.svg) |
## Benefits of Qiskit primitives

Primitives work most effectively when they are supported by both Qiskit and the backend provider. The Qiskit module `qiskit.primitives` provides the required support on the Qiskit side, and providers like IBM Qiskit Runtime enable access to appropriate backends through native implementations of their own primitives.
For Qiskit users, primitives allow you to write quantum code for a specific backend without having to explicitly
manage every detail. In addition, because of the additional layer of abstraction, you may be able to more easily
access advanced hardware capabilities of a given provider. For example, with Qiskit Runtime primitives,
you can leverage the latest advancements in error mitigation and suppression by toggling options such as
`optimization_level` and `resilience_level`, rather than building your own implementation of these techniques.

For hardware providers, implementing primitives natively means you can provide your users with a more “out-of-the-box”
way to access your hardware features. It is therefore easier for your users to benefit from your hardware's
best capabilities.

## Benefits of Qiskit primitives

For Qiskit users, primitives allow you to write quantum code for a specific backend without having to explicitly manage every detail. In addition, because of the additional layer of abstraction, you may be able to more easily access advanced hardware capabilities of a given provider. For example, with Qiskit Runtime primitives, you can leverage the latest advancements in error mitigation and suppression by toggling options such as `optimization_level` and `resilience_level`, rather than building your own implementation of these techniques.
## Estimator

For hardware providers, implementing primitives natively means you can provide your users with a more “out-of-the-box” way to access your hardware features. It is therefore easier for your users to benefit from your hardware's best capabilities.
The Estimator primitive computes expectation values of observables with respect to states prepared by quantum circuits.
The Estimator receives circuit-observable pairs (with the observable expressed as a
weighted sum of Pauli operators) as inputs, and returns the computed expectation values per pair, as well as their
variances. Different Estimator implementations support various configuration options. The circuits
can be parametrized, as long as the parameter values are also provided as input to the primitive.

## Should I use Estimator or Sampler?

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).
## 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.
The Sampler primitive samples from the classical output registers resulting from execution of quantum circuits.
For this reason, the inputs to the Sampler are (parametrized) quantum circuits, for which it returns the corresponding
quasi-probability distributions of sampled bitstrings. Quasi-probability distributions are similar to regular
probabilities, except they may include negative values, which can occur when using certain error mitigation techniques.

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.

## What is the difference between the open-source primitives and primitives available through Qiskit Runtime?
## How to use Qiskit primitives

The open-source primitives contain the base classes (to define interfaces) and a reference implementation. The Qiskit Runtime primitives provide a more sophisticated implementation (such as with error mitigation) as a cloud-based service.
The `qiskit.primitives` module enables the development of primitive-style quantum programs and was specifically
designed to simplify switching between different types of backends. The module provides three separate classes
for each primitive type:

<span id="import-primitives"></span>
## Where should I import the primitive from?
1. `Sampler` and `Estimator`

There are different primitive implementations in the ``qiskit``, ``qiskit_aer``, and ``qiskit_ibm_runtime`` libraries.
Each implementation serves a specific purpose:
These classes are reference implementations of both primitives and use Qiskit’s built-in simulator. They leverage Qiskit’s `quantum_info` module in the background, producing results based on ideal statevector simulations.

* The primitives in ``qiskit`` can perform local statevector simulations - useful for quickly prototyping algorithms.
* The `qiskit.primitives` module enables the development of primitive-style quantum programs and was specifically designed to simplify switching between different types of backends. The module provides three separate classes for each primitive type:
2. `BaseSampler` and `BaseEstimator`

1. `Sampler` and `Estimator`
These classes are reference implementations of both primitives and use Qiskit’s built-in simulator. They leverage Qiskit’s `quantum_info` module in the background, producing results based on ideal statevector simulations.
These are abstract base classes that define a common interface for implementing primitives. All other classes in the `qiskit.primitives` module inherit from these base classes, and developers should use these if they are interested in developing their own primitives-based execution model for a specific backend provider. These classes may also be useful for those who want to do highly customized processing and find the existing primitives implementations too simple for their needs.

2. `BaseSampler` and `BaseEstimator`
These are abstract base classes that define a common interface for implementing primitives. All other classes in the `qiskit.primitives` module inherit from these base classes, and developers should use these if they are interested in developing their own primitives-based execution model for a specific backend provider. These classes may also be useful for those who want to do highly customized processing and find the existing primitives implementations too simple for their needs.
3. `BackendSampler` and `BackendEstimator`

3. `BackendSampler` and `BackendEstimator`
If a provider does not support primitives natively, you can use these classes to “wrap” any backend into a primitive. Users can write primitive-style code for providers that don’t yet have a primitives-based interface. These classes can be used just like the regular Sampler and Estimator, except they should be initialized with an additional backend argument for selecting which backend to run on.
If a provider does not support primitives natively, you can use these classes to “wrap” any backend into a primitive. Users can write primitive-style code for providers that don’t yet have a primitives-based interface. These classes can be used just like the regular Sampler and Estimator, except they should be initialized with an additional backend argument for selecting which backend to run on.

* 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 Qiskit Runtime primitives provide a more sophisticated implementation (such as with error mitigation) as a cloud-based service.

## Next steps

<Admonition type="tip" title="Recommendations">
- Review detailed [primitives examples.](../run/primitives-examples)
- Read [Get started with primitives](primitives-get-started) to implement primitives in your work.
- Review detailed [primitives examples.](primitives-examples)
- Practice with primitives by working through the [Cost function lesson](https://learning.quantum-computing.ibm.com/course/variational-algorithm-design/cost-functions#primitives) in IBM Quantum Learning.
</Admonition>
</Admonition>
Loading

0 comments on commit 11d8cc1

Please sign in to comment.