Getting Started with IonQ and Cirq

View on QuantumAI Run in Google Colab View source on GitHub Download notebook

This notebook shows how to get up and running with the IonQ API. As of February 2021, this API is limited to partners only. More information about partnerships can be found at ionq.com/get-started.

To get started, first you must install Cirq.

try:
    import cirq
    version = cirq.__version__.split(".")
    assert int(version[0]) > 0 or int(version[1]) > 9, "Cirq version >0.9 required"
except (ImportError, AssertionError):
    print("Installing Cirq...")
    !pip install --quiet cirq
    print("Cirq installed.")

Given that the above cell runs, you have installed Cirq and imported it. To simplify using the ionq api it is also suggested that you import ionq. Notice how nice it is that cirq and ionq are four letter words ending in "q".

import cirq
import cirq_ionq as ionq

Constructing an IonQ Service object

The main object that you use to access the IonQ API is an instance of the cirq_ionq.Service class. To construct this you need an API key. Both should be supplied to partners. Please be careful when using notebooks and version control to not save your API key in a public location!

Given these bits of information you get a service object by simply running

API_KEY = 'tomyheart' # Replace with your IonQ API key

service = ionq.Service(api_key=API_KEY, 
                       default_target='simulator')

Note that we have set the default_target to simulator. The other option would be to set it to qpu.

Running a simple circuit

The IonQ API supports a limited set of gates natively. Circuit built with these gates do not need any modification and can be run directly against the API. For a list of the API supported gates see circuit documentation. One supported gate is the square root of not gate, which we use here in conjunction with a controlled-not gate. The following cell will run the circuit below, blocking until the program has run and results have been returned:

q0, q1 = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
    cirq.X(q0) ** 0.5,            # Square root of X
    cirq.CX(q0, q1),              # CNOT
    cirq.measure(q0, q1, key='b') # Measure both qubits
)
result = service.run(circuit, repetitions=100)
print(result)
b=0100110001000110100000000110101111100110100001110110111010010011001011001100001001100110100011001111, 0100110001000110100000000110101111100110100001110110111010010011001011001100001001100110100011001111

Because we did not specify a target and we ran this against a service with default_target='simulator', this ran against the simulator. To run against the QPU simply add the target to the run method (note that this may take a while since the queue for the qpu is much longer than that for the simulator):

result = service.run(circuit, repetitions=100, target='qpu')
print(result)
b=1101101100001000011111111011110001111011100011101001000110000001001001011100111001000110000110111110, 1101101100001000011111111011110001111011100011101001000110000001001001011100111001000110000110111110

Jobs

In the above section, the run method blocked on awaiting the program to run and return results. A different pattern is to asynchronously create jobs, which return an id that they can be used to identify the job, and fetch the results at a later time.

job = service.create_job(circuit, repetitions=100)
job_id = job.job_id()
print(f'Job id: {job_id}')
Job id: 34be7d9b-1a27-4974-b8ca-2b5941e52cd8

Given the job object above, you can check on the status of the job

print(f'Status: {job.status()}')
Status: completed

Or if you only have the job id, you can use this to get the job and create a new cirq_ionq.Job object to query.

same_job = service.get_job(job_id=job_id)
print(f'Status: {same_job.status()}')
Status: completed

To get the results from the job, you can get the results of the job using the results() method. Note, however that this will block if the job is not completed, polling until the status is completed.

results = same_job.results()
print(results)
00: 0.5000000000000001
11: 0.4999999999999999

Note that the results are not cirq.Result. To convert these to a cirq.Result, you can use to_cirq_result()

print(results.to_cirq_result())
b=0100001001111001110001111100101001010100010011100101011000111100110101100000110010110010001101111101, 0100001001111001110001111100101001010100010011100101011000111100110101100000110010110010001101111101

Next steps

Check out the documentation on fully using the Cirq IonQ integration

Learn how to build circuits for the API

How to use the service API

Learn how to query the performance of a processor by accessing IonQ calibrations