Getting started with Cirq
Learn how to use the Cirq SDK to submit quantum circuits to IonQ’s simulators and quantum computers.
What is Cirq?
Cirq is an open source Python framework for writing, modifying, and running programs for quantum computers. It was developed by the quantum software team at Google, and is now supported by a vibrant open source community beyond Google. If you’re new to the framework, this tutorial gives a great introduction to the basics of Cirq and its philosophy.
The cirq-ionq
module provides support for IonQ’s trapped-ion systems. This means that you can write quantum circuits and run them on IonQ’s simulators and trapped-ion quantum computers, all from within the Cirq framework.
Before you begin
You’ll need an account on the IonQ Quantum Cloud, and you’ll need to create an API key. We also have a guide about setting up and managing your API keys if you need some help.
You’ll also need Python 3.11 or higher running locally on your machine.
Run python --version
from your command line if you aren’t sure which version
you have running.
Set up Cirq
For a simple install, you can install cirq-ionq
from the Python Package Index (PyPI) using pip
:
This will also install the core functionality of cirq
. For more details and advanced features, we recommend following the complete Cirq installation guide.
Note: We 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 you.
Set up the IonQ Service
Open a file up in whatever IDE or notebook you prefer, and add the following:
Cirq will automatically look for your API key in the environment variable IONQ_API_KEY
when setting up the cirq_ionq.Service()
. If you need to pass in your API key directly, you can instead use:
Build a circuit
Next, construct a circuit. Each qubit is represented by a cirq.LineQubit
with a unique integer identifier. While we use LineQubit
objects to represent the chain of trapped-ion qubits in an IonQ system, the qubit identifier does not indicate the position of a particular qubit in the chain. Also note that all IonQ systems have all-to-all connectivity, so two-qubit gates can be performed directly on any pair of qubits, whether or not their LineQubit
identifiers are adjacent.
Here’s a basic Bell state circuit:
Submit a circuit to the ideal simulator
After we’ve built a quantum circuit, we can submit it to IonQ’s ideal simulator. Here, we’ll use repetitions
to request 1000 shots and name
to give the circuit a name that will show up in the IonQ Cloud Console.
This returns:
The cirq.Result
object shows 502 counts for the 0 state (00
) and 498 for the 3 state (11
).
Submit a circuit to the noisy simulator
This process is almost the same as the ideal simulator example above, except when calling service.run()
, we’ll use the extra_query_params
to add {"noise": {"model": "aria-1"}}
for the Aria 1 noise model.
The available noise models are harmony
(legacy), aria-1
, aria-2
, and forte-1
. You can read more about these noise models here.
Or, to supply both a circuit name and a noise model:
Submit a circuit to a QPU
For the QPU, we’ll use service.create_job()
instead of service.run()
. This will submit the job, but won’t wait for it to finish, so our code won’t be blocked waiting for the result to return. In most cases, a QPU job will wait in the queue for some time before running.
The available QPU targets may include qpu.aria-1
, qpu.aria-2
, and qpu.forte-1
. You can view your access to these systems on the “Backends” tab of the IonQ Cloud Console.
You can check the status of your job:
If the job is waiting in the queue, this will print 'ready'
. If the job is finished, this will print 'completed'
.
You can also print and record the job’s unique ID, which can be used to retrieve the job (including its status and results) at a later time.
Once the job is completed, you can retrieve its results:
You can cancel a job while it’s waiting in the queue:
Retrieve a job
You can retrieve results for a previously run job using its job ID. You can save the job ID after submitting a job (as in the QPU example above) or copy it from the “ID” column in the “My Jobs” tab on the IonQ Cloud Console.
Supported gates
Note that some gates supported by Cirq aren’t accepted by IonQ backends. The supported gates include:
cirq.XPowGate
,cirq.YPowGate
,cirq.ZPowGate
- This includes
cirq.rx
,cirq.ry
, andcirq.rz
and Pauli gatescirq.X
,cirq.Y
, andcirq.Z
.
- This includes
cirq.H
cirq.XXPowGate
,cirq.YYPowGate
,cirq.ZZPowGate
cirq.CNOT
,cirq.SWAP
cirq.MeasurementGate
: usually viacirq.measure
Other gates available in Cirq, such as the Toffoli gate, are not directly supported by IonQ systems. However, you can decompose a circuit to IonQ-supported gates.
Construct a circuit containing an unsupported gate:
This circuit looks like:
Get the IonQ target gateset and decompose the unsupported gates in the circuit:
The resulting circuit has more gates, but all of these gates can be submitted to an IonQ backend:
From here, we can run circuit2
using service.run()
or service.create_job()
as shown in the previous examples.
Note that prior to cirq-ionq
v0.15, this step was performed using cirq_ionq.decompose_to_device(qc)
instead.
IonQ’s native gates (GPi, GPi2, and MS) are also supported in Cirq. See our native gates introduction and guide to using native gates in Cirq for more details and examples.
Full code examples
Here’s full, copy-paste-friendly code examples for building a circuit and submitting it to the simulator, noisy simulator, or QPU.
Additional resources
A Jupyter notebook for getting started with Cirq on IonQ hardware is available here.
Full documentation for the Cirq-IonQ integration can be found on the Cirq documentation site. This site also includes numerous tutorials and documentation about writing and running quantum circuits in Cirq, many of which you’ll be able to be run on IonQ hardware with minimal modification.
The IonQ hardware section of Cirq’s documentation includes additional topics and resources specific to Cirq-IonQ.
You can find the source code for the cirq-ionq package on GitHub.
Was this page helpful?