• Stars
    star
    149
  • Rank 247,105 (Top 5 %)
  • Language
    Python
  • License
    Apache License 2.0
  • Created almost 3 years ago
  • Updated 2 days ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

IBM Client for Qiskit Runtime

Qiskit Runtime IBM Client

License CI Code style: black Coverage Status

Qiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.

Qiskit IBM Runtime is a new environment offered by IBM Quantum that streamlines quantum computations and provides optimal implementations of the Qiskit primitives sampler and estimator for IBM Quantum hardware. It is designed to use additional classical compute resources to execute quantum circuits with more efficiency on quantum processors, by including near-time computations such as error suppression and error mitigation. Examples of error suppression include dynamical decoupling, noise-aware compilation, error mitigation including readout mitigation, zero-noise extrapolation (ZNE), and probabilistic error cancellation (PEC).

Using the runtime service, a research team at IBM Quantum was able to achieve a 120x speedup in their lithium hydride simulation. For more information, see the IBM Research blog.

This module provides the interface to access the Qiskit Runtime service on IBM Quantum Platform or IBM Cloud.

Installation

You can install this package using pip:

pip install qiskit-ibm-runtime

Account setup

Qiskit Runtime service on IBM Quantum Platform

You will need your IBM Quantum API token to authenticate with the runtime service:

  1. Create an IBM Quantum account or log in to your existing account by visiting the IBM Quantum login page.

  2. Copy (and optionally regenerate) your API token from your IBM Quantum account page.

Qiskit Runtime service on IBM Cloud

The runtime service is now part of the IBM Quantum Services on IBM Cloud. To use this service, you'll need to create an IBM Cloud account and a quantum service instance. This guide contains step-by-step instructions, including how to find your IBM Cloud API key and Cloud Resource Name (CRN), which you will need for authentication.

Save your account on disk

Once you have the account credentials, you can save them on disk, so you won't have to input them each time. The credentials are saved in the $HOME/.qiskit/qiskit-ibm.json file, where $HOME is your home directory.

⚠️ Account credentials are saved in plain text, so only do so if you are using a trusted device.
from qiskit_ibm_runtime import QiskitRuntimeService

# Save an IBM Cloud account.
QiskitRuntimeService.save_account(channel="ibm_cloud", token="MY_IBM_CLOUD_API_KEY", instance="MY_IBM_CLOUD_CRN")

# Save an IBM Quantum account.
QiskitRuntimeService.save_account(channel="ibm_quantum", token="MY_IBM_QUANTUM_TOKEN")

Once the account is saved on disk, you can instantiate the service without any arguments:

from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()

Loading account from environment variables

Alternatively, the service can discover credentials from environment variables:

export QISKIT_IBM_TOKEN="MY_IBM_CLOUD_API_KEY"
export QISKIT_IBM_INSTANCE="MY_IBM_CLOUD_CRN"
export QISKIT_IBM_CHANNEL="ibm_cloud"

Then instantiate the service without any arguments:

from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()

Enabling account for current Python session

As another alternative, you can also enable an account just for the current session by instantiating the service with your credentials.

from qiskit_ibm_runtime import QiskitRuntimeService

# For an IBM Cloud account.
ibm_cloud_service = QiskitRuntimeService(channel="ibm_cloud", token="MY_IBM_CLOUD_API_KEY", instance="MY_IBM_CLOUD_CRN")

# For an IBM Quantum account.
ibm_quantum_service = QiskitRuntimeService(channel="ibm_quantum", token="MY_IBM_QUANTUM_TOKEN")

Primitives

All quantum applications and algorithms level are fundamentally built using three steps:

  1. Choose a quantum circuit to encode the quantum state.
  2. Define the observable or the classical register to be measured.
  3. Execute the quantum circuits by using a primitive (Estimator or Sampler).

Primitives are base-level functions that serve as building blocks for many quantum algorithms and applications. The primitive interfaces are defined in Qiskit.

The IBM Runtime service offers these primitives with additional features, such as built-in error suppression and mitigation.

There are several different options you can specify when calling the primitives. See qiskit_ibm_runtime.Options class for more information.

Sampler

This primitive takes a list of user circuits (including measurements) as input and generates an error-mitigated readout of quasi-probability distributions. This provides users a way to better evaluate shot results using error mitigation, and enables them to more efficiently evaluate the possibility of multiple relevant data points in the context of destructive interference.

To invoke the Sampler primitive

from qiskit_ibm_runtime import QiskitRuntimeService, Options, Sampler
from qiskit import QuantumCircuit

service = QiskitRuntimeService()
options = Options(optimization_level=1)
options.execution.shots = 1024  # Options can be set using auto-complete.

# 1. A quantum circuit for preparing the quantum state (|00> + |11>)/rt{2}
bell = QuantumCircuit(2)
bell.h(0)
bell.cx(0, 1)

# 2. Map the qubits to a classical register in ascending order
bell.measure_all()

# 3. Execute using the Sampler primitive
backend = service.get_backend('ibmq_qasm_simulator')
sampler = Sampler(backend=backend, options=options)
job = sampler.run(circuits=bell)
print(f"Job ID is {job.job_id()}")
print(f"Job result is {job.result()}")

Estimator

This primitive takes circuits and observables as input, to evaluate expectation values and variances for a given parameter input. This Estimator allows users to efficiently calculate and interpret expectation values of quantum operators required for many algorithms.

To invoke the Estimator primitive:

from qiskit_ibm_runtime import QiskitRuntimeService, Options, Estimator
from qiskit.quantum_info import SparsePauliOp
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
import numpy as np

service = QiskitRuntimeService()
options = Options(optimization_level=1)
options.execution.shots = 1024  # Options can be set using auto-complete.

# 1. A quantum circuit for preparing the quantum state (|000> + e^{itheta} |111>)/rt{2}
theta = Parameter('θ')
qc_example = QuantumCircuit(3)
qc_example.h(0) # generate superposition
qc_example.p(theta, 0) # add quantum phase
qc_example.cx(0, 1) # condition 1st qubit on 0th qubit
qc_example.cx(0, 2) # condition 2nd qubit on 0th qubit

# 2. the observable to be measured
M1 = SparsePauliOp.from_list([("XXY", 1), ("XYX", 1), ("YXX", 1), ("YYY", -1)])

# batch of theta parameters to be executed
points = 50
theta1 = []
for x in range(points):
    theta = [x*2.0*np.pi/50]
    theta1.append(theta)

# 3. Execute using the Estimator primitive
backend = service.get_backend('ibmq_qasm_simulator')
estimator = Estimator(backend, options=options)
job = estimator.run(circuits=[qc_example]*points, observables=[M1]*points, parameter_values=theta1)
print(f"Job ID is {job.job_id()}")
print(f"Job result is {job.result().values}")

This code batches together 50 parameters to be executed in a single job. If a user wanted to find the theta that optimized the observable, they could plot and observe it occurs at theta=np.pi/2. For speed we recommend batching results together (note that depending on your access, there may be limits on the number of circuits, objects, and parameters that you can send).

Session

In many algorithms and applications, an Estimator needs to be called iteratively without incurring queuing delays on each iteration. To solve this, the IBM Runtime service provides a Session. A session starts when the first job within the session is started, and subsequent jobs within the session are prioritized by the scheduler.

You can use the qiskit_ibm_runtime.Session class to start a session. Consider the same example above and try to find the optimal theta. The following example uses the golden search method to iteratively find the optimal theta that maximizes the observable.

To invoke the Estimator primitive within a session:

from qiskit_ibm_runtime import QiskitRuntimeService, Session, Options, Estimator
from qiskit.quantum_info import SparsePauliOp
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
import numpy as np

service = QiskitRuntimeService()
options = Options(optimization_level=1)
options.execution.shots = 1024  # Options can be set using auto-complete.

# 1. A quantum circuit for preparing the quantum state (|000> + e^{itheta} |111>)/rt{2}
theta = Parameter('θ')
qc_example = QuantumCircuit(3)
qc_example.h(0) # generate superpostion
qc_example.p(theta,0) # add quantum phase
qc_example.cx(0, 1) # condition 1st qubit on 0th qubit
qc_example.cx(0, 2) # condition 2nd qubit on 0th qubit

# 2. the observable to be measured
M1 = SparsePauliOp.from_list([("XXY", 1), ("XYX", 1), ("YXX", 1), ("YYY", -1)])


gr = (np.sqrt(5) + 1) / 2 # golden ratio
thetaa = 0 # lower range of theta
thetab = 2*np.pi # upper range of theta
tol = 1e-1 # tol

# 3. Execute iteratively using the Estimator primitive
with Session(service=service, backend="ibmq_qasm_simulator") as session:
    estimator = Estimator(session=session, options=options)
    #next test range
    thetac = thetab - (thetab - thetaa) / gr
    thetad = thetaa + (thetab - thetaa) / gr
    while abs(thetab - thetaa) > tol:
        print(f"max value of M1 is in the range theta = {[thetaa, thetab]}")
        job = estimator.run(circuits=[qc_example]*2, observables=[M1]*2, parameter_values=[[thetac],[thetad]])
        test =job.result().values
        if test[0] > test[1]:
            thetab = thetad
        else:
            thetaa = thetac
        thetac = thetab - (thetab - thetaa) / gr
        thetad = thetaa + (thetab - thetaa) / gr

    # Final job to evaluate Estimator at midpoint found using golden search method
    theta_mid = (thetab + thetaa) / 2
    job = estimator.run(circuits=qc_example, observables=M1, parameter_values=theta_mid)
    print(f"Session ID is {session.session_id}")
    print(f"Final Job ID is {job.job_id()}")
    print(f"Job result is {job.result().values} at theta = {theta_mid}")

This code returns Job result is [4.] at theta = 1.575674623307102 using only nine iterations. This is a very powerful extension to the primitives. However, using too much code between iterative calls can lock the QPU and use excessive QPU time, which is expensive. We recommend only using sessions when needed. The Sampler can also be used within a session, but there are not any well-defined examples for this.

Instances

Access to IBM Quantum Platform channel is controlled by the instances (previously called providers) to which you are assigned. An instance is defined by a hierarchical organization of hub, group, and project. A hub is the top level of a given hierarchy (organization) and contains within it one or more groups. These groups are in turn populated with projects. The combination of hub/group/project is called an instance. Users can belong to more than one instance at any time.

NOTE: IBM Cloud instances are different from IBM Quantum Platform instances. IBM Cloud does not use the hub/group/project structure for user management. To view and create IBM Cloud instances, visit the IBM Cloud Quantum Instances page.

To view a list of your instances, visit your account settings page or use the instances() method.

You can specify an instance when initializing the service or provider, or when picking a backend:

# Optional: List all the instances you can access.
service = QiskitRuntimeService(channel='ibm_quantum')
print(service.instances())

# Optional: Specify the instance at service level. This becomes the default unless overwritten.
service = QiskitRuntimeService(channel='ibm_quantum', instance="hub1/group1/project1")
backend1 = service.backend("ibmq_manila")

# Optional: Specify the instance at the backend level, which overwrites the service-level specification when this backend is used.
backend2 = service.backend("ibmq_manila", instance="hub2/group2/project2")

sampler1 = Sampler(backend=backend1)    # this will use hub1/group1/project1
sampler2 = Sampler(backend=backend2)    # this will use hub2/group2/project2

If you do not specify an instance, then the code will select one in the following order:

  1. If your account only has access to one instance, it is selected by default.
  2. If your account has access to multiple instances, but only one can access the requested backend, the instance with access is selected.
  3. In all other cases, the code selects the first instance other than ibm-q/open/main that has access to the backend.

Access your IBM Quantum backends

A backend is a quantum device or simulator capable of running quantum circuits or pulse schedules.

You can query for the backends you have access to. Attributes and methods of the returned instances provide information, such as qubit counts, error rates, and statuses, of the backends.

from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()

# Display all backends you have access.
print(service.backends())

# Get a specific backend.
backend = service.backend('ibmq_qasm_simulator')

# Print backend coupling map.
print(backend.coupling_map)

Next Steps

Now you're set up and ready to check out some of the tutorials.

Contribution guidelines

If you'd like to contribute to qiskit-ibm-runtime, please take a look at our contribution guidelines. This project adheres to Qiskit's code of conduct. By participating, you are expected to uphold to this code.

We use GitHub issues for tracking requests and bugs. Please use our slack for discussion and simple questions. To join our Slack community use the invite link at Qiskit.org. For questions that are more suited for a forum we use the Qiskit tag in Stack Exchange.

License

Apache License 2.0.

More Repositories

1

qiskit

Qiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
Python
5,001
star
2

qiskit-metapackage

Qiskit is an open-source SDK for working with quantum computers at the level of circuits, algorithms, and application modules.
OpenQASM
3,033
star
3

qiskit-tutorials

A collection of Jupyter notebooks showing how to use the Qiskit SDK
Jupyter Notebook
2,303
star
4

rustworkx

A high performance Python graph library implemented in Rust.
Rust
1,033
star
5

qiskit-aer

Aer is a high performance simulator for quantum circuits that includes noise models
C++
476
star
6

textbook

Source content for the Qiskit Textbook
Jupyter Notebook
308
star
7

qiskit-ibmq-provider

Qiskit Provider for accessing the quantum devices and simulators at IBM Quantum.
Python
241
star
8

platypus

Qiskit Textbook (beta)
Jupyter Notebook
134
star
9

qiskit.org

The Qiskit official website
TypeScript
101
star
10

ecosystem

The Ecosystem consists of projects, tools, utilities, libraries and tutorials from a broad community of developers and researchers. The goal of the Ecosystem is to recognize, support and accelerate development of quantum technologies using Qiskit.
Python
98
star
11

qiskit-ibm-provider

Qiskit Provider for accessing the IBM Quantum Services: Online Systems and Simulators
Python
78
star
12

qiskit-serverless

A programming model for leveraging quantum and classical resources
Python
63
star
13

feedback

A place to share your feedback on Qiskit; stay up to date with release planning and DemoDays; and find out where to get support
Jupyter Notebook
60
star
14

qiskit-code-assistant-vscode

Simplifying Qiskit to make developing quantum circuits and applications faster
HTML
59
star
15

documentation

The documentation content home for https://docs.quantum.ibm.com.
TypeScript
36
star
16

RFCs

RFCs for changes to Qiskit ecosystem
34
star
17

web-components

Qiskit Web Components
TypeScript
21
star
18

red-queen

Quantum software benchmarking tool
OpenQASM
18
star
19

benchpress

OpenQASM
18
star
20

qiskit-bot

Github bot to automate various aspects of Qiskit development
Python
17
star
21

ibm-quantum-schemas

IBM Quantum API Schemas
Python
16
star
22

qiskit-qasm3-import

Importer from OpenQASM 3 to Qiskit's QuantumCircuit
Python
15
star
23

qiskit_sphinx_theme

A Sphinx theme and documentation guidelines for Qiskit and Qiskit Ecosystem projects
SCSS
14
star
24

qiskit-neko

An integration test suite for Qiskit
Python
10
star
25

openqasm3_parser

Parser and semantic analyzer for the OpenQASM3 language
Rust
10
star
26

saiba

Qiskit Learning
Vue
9
star
27

gh-actions

Reusable workflows and composite actions
4
star
28

platypus-binder

Repository that handles the binder configuration for platypus
Python
3
star
29

qiskit-addon-dice-solver

2
star
30

qiskit-addon-sqd

2
star
31

qiskit-addon-mpf

2
star
32

qiskit-addon-obp

2
star
33

qiskit-ibm-transpiler

Jupyter Notebook
2
star
34

qiskit-code-assistant-jupyterlab

1
star
35

qiskit-addon-utils

1
star