terminal
Docs

Get started with Qiskit on IonQ Hardware

Last updated: January 30, 2024
IonQ Staff

With the help of our friends at Qiskit, we’ve just published Qiskit IonQ Provider, an extension to the Qiskit ecosystem that creates a plug-and-play integration between one of the leading open source quantum development kits and IonQ’s trapped-ion systems. We’re excited to be able to give back to this vibrant community and enable more people to easily use our hardware.

This plugin will allow you to run Qiskit projects on IonQ systems by changing only a few lines of code, effortlessly combining the power of IonQ hardware with Qiskit’s expressive circuit building tools and extensive (and growing!) set of libraries for quantum machine learning, chemistry, optimization and more.

Before we jump into some example code, a bit of background and context on Qiskit and its provider architecture:

About Qiskit

Qiskit, if you’re not familiar, is an open source SDK, written in Python, for working with quantum computers at a variety of levels — from the “metal” itself to pulses, gates, circuits and higher-order application areas like quantum machine learning and quantum chemistry.

If you’re just beginning to learn about quantum computing, the Qiskit textbook is a great resource for learning about the basics of quantum algorithms, including the math behind gates and circuits, and code samples for running basic experiments.

Providers in Qiskit

Providers are the plugins that allow you to actually compute with Qiskit code by running on external resources, called backends, for use from within the Qiskit ecosystem. The most obvious type of backend is a quantum computer, but there are also local quantum simulator backends, and cloud-based simulator backends as well, for situations when running on a real quantum processing unit isn’t necessary or desirable.

The two providers that are included by default in Qiskit are the Qiskit Aer provider, which creates and exposes a local quantum simulator, and the provider for the IBM Quantum Experience, which provides access to the hardware backends listed on their website.

However, because Qiskit is an extensible, open-source plugin framework, other providers can be installed separately, imported, and used with minimal additional effort.

This is where the Qiskit IonQ Provider comes in — by installing and importing the provider package, you run code on two additional backends from IonQ: our 11-qubit trapped-ion system and our high-performance cloud simulator.

The IonQ provider is the first non-default provider to be available via the Qiskit Partners Program, a select group of quantum hardware and software vendors that are verified for Qiskit compatibility and validity, expand the reach of Qiskit and usage by the Qiskit community, and follow software best practices.

Using the Qiskit IonQ Provider

Installing the Provider

You can install the Qiskit IonQ Provider from PyPI, the Python Package Index, using pip.

pip install qiskit-ionq

We’d encourage doing this inside an environment management system like virtualenv or conda so as to avoid this fate, but do what makes the most sense for your setup and context.

Provider Setup

To instantiate the provider, make sure you have an access token, then create a provider:

from qiskit_ionq import IonQProvider
provider = IonQProvider("token")

Because the Qiskit IonQ Provider integrates directly with the IonQ API, you will need an IonQ API access token to use it. You can create a token by signing up for our self-service quantum cloud via Google Cloud Marketplace, or by reaching out to [email protected] for more information on custom plans and reserved access.

Credentials In Environment Variables

Alternatively, the provider can discover your access token from environment variables:

export QISKIT_IONQ_API_TOKEN="token"

Then instantiate the provider without any arguments:

from qiskit_ionq import IonQProvider
provider = IonQProvider()

Once the provider has been instantiated, it may be used to access supported backends:

# Show all backends:
print(provider.backends())
[<IonQSimulatorBackend('ionq_simulator')>, <IonQQPUBackend('ionq_qpu')>]
# Get IonQ's simulator backend:
simulator_backend = provider.get_backend("ionq_simulator")

Submitting a Circuit

Once a backend has been specified, it may be used to submit circuits. For example, here’s a simple Bell state:

from qiskit import QuantumCircuit

# Create a basic Bell State circuit:
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0, 1], [0, 1])

# Run the circuit on IonQ's platform:
job = simulator_backend.run(qc, shots=10000) 

# Print the counts
print(job.get_counts())
{'00': 5025, '11': 4975}
# The simulator provides the ideal probabilities from the circuit, and the provider
# creates “counts” by randomly sampling from these probabilities. The raw (“true”)
# probabilities are also accessible by calling get_probabilities():
print(job.get_probabilities())
{'00': 0.4999999999999999, '11': 0.4999999999999999}

Running on hardware

We can now run the same circuit on IonQ hardware just by choosing a different backend:

qpu_backend = provider.get_backend("ionq_qpu.harmony")
qpu_job = qpu_backend.run(qc) # if you don’t pass a shots kwarg, it defaults to 1024

Because QPU time is a limited resource, QPU jobs are handled in a queue, and may take a little bit of time to return. We recommend setting up a block like this to poll for status, but you can also just call `qpu_job.result()` and wait — it will block until the job is done.

from qiskit.providers.jobstatus import JobStatus
import time
# Check if job is done
while qpu_job.status() is not JobStatus.DONE:
	print("Job status is", qpu_job.status() )
	time.sleep(60)

# grab a coffee! This can take up to a few minutes.
# once we break out of that while loop, we know our job is finished
print("Job status is", qpu_job.status() )
print(qpu_job.get_counts()) # these counts are the “true” counts from the actual QPU Run
Job status is JobStatus.QUEUED
Job status is JobStatus.QUEUED
Job status is JobStatus.QUEUED
Job status is  JobStatus.DONE
{'00': 485, '01': 9, '0011': 530}
# for ease of use, the output probabilities (counts/shots) are still available:
print(qpu_job.get_probabilities())
{'00': 0.4737, '01': 0.0087, '11': 0.5175}

Additional resources

Full documentation for the Qiskit IonQ Provider can be found here.

The provider repo on GitHub also includes an extensive readme that replicates much of this guide, as well as an example jupyter notebook with some more detailed usage examples.

For additional resources on setting up and using Qiskit, we recommend their getting started page and learning resources. For more detailed information on Qiskit, we recommend the Qiskit documentation.

Special thanks

Thank you to the Qiskit maintainers for shepherding us through the process of building a ready-for-primetime provider and getting it into the Qiskit Partner Program. Thank you to the IonQ employees, Sungkyunkwan University Q Center students and faculty, and other IonQ customers and users who used the alpha version and provided valuable feedback and bug reports, and thank you to the vibrant and growing Qiskit community for investing your time and energy into a more open and democratized vision of our quantum future. We’re proud to officially be a part of it.

Licensing for the Qiskit IonQ Provider is Apache 2.0. API keys and access to IonQ services must be obtained under separate terms from IonQ.

The IonQ logo and Q mark are trademarks of IonQ, Inc. Copyright IonQ © 2021. All rights reserved.