Quickstart: Submit a circuit with Cirq to Azure Quantum
Learn how to use the azure-quantum Python package to submit Cirq quantum circuits to an IonQ or Honeywell quantum computing target via the Azure Quantum service. For more information, see Quantum circuits.
Prerequisites
An Azure account with an active subscription. Create an account for free.
Create an Azure Quantum workspace and enable your preferred provider, Honeywell or IonQ (or both), for this scenario. For more information, see Create an Azure Quantum workspace.
Install the latest
azure-quantumPython package.Tip
If you are using Miniconda or Anaconda, you can optionally create a new environment by downloading environment.yml and running the following:
conda env create -f environment.ymlThis creates a new conda environment that you can activate with the following:
conda activate azurequantumStart your favorite code editor or interactive Python tool, such as VS Code, Jupyter or iPython.
Load the required imports
First, run the following cell to load the required imports:
from azure.quantum.cirq import AzureQuantumService
Connect to the Azure Quantum service
To connect to the Azure Quantum service, your program will need the resource ID and the location of your Azure Quantum workspace. Log in to your Azure account, https://portal.azure.com, navigate to your Azure Quantum workspace, and copy the values from the header.

Paste the values into the following AzureQuantumService constructor to
create a service object that connects to your Azure Quantum workspace.
Optionally, you can specify a default target, in this case the IonQ simulator:
service = AzureQuantumService(
resource_id="",
location="",
default_target="ionq.simulator"
)
List all targets
You can now list all the targets that you have access to, including the current queue time and availability.
print(service.targets())
[<Target name="ionq.qpu", avg. queue time=345 s, Available>,
<Target name="ionq.simulator", avg. queue time=4 s, Available>,
<Target name="honeywell.hqs-lt-s1", avg. queue time=0 s, Available>,
<Target name="honeywell.hqs-lt-s1-apival", avg. queue time=0 s, Available>,
<Target name="honeywell.hqs-lt-s2", avg. queue time=313169 s, Available>,
<Target name="honeywell.hqs-lt-s2-apival", avg. queue time=0 s, Available>,
<Target name="honeywell.hqs-lt-s1-sim", avg. queue time=1062 s, Available>]
Run a simple circuit
Next, create a simple Cirq circuit to run. This circuit uses the square root of X gate, native to the IonQ hardware system.
import cirq
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
)
print(circuit)
0: ───X^0.5───@───M────────
│ │
1: ───────────X───M────────
You can now run the program via the Azure Quantum service and get the result. The following cell submits a job (to the default IonQ simulator) that runs the circuit with 100 shots, waits until the job is complete, and returns the results.
result = service.run(program=circuit, repetitions=100)
This returns a cirq.Result object.
print(result)
b=1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010, 1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010
Run on IonQ QPU
The previous job ran on the default simulator, "ionq.simulator". However, you can also run it on IonQ's hardware processor (a Quantum Processor Unit (QPU)). To run on the IonQ QPU, provide "ionq.qpu" as the
target argument:
result = service.run(
program=circuit,
repetitions=100,
target="ionq.qpu",
timeout_seconds=500 # Set timeout to accommodate queue time on QPU
)
Again, this returns a cirq.Result object.
print(result)
b=0101011011011111100001011101101011011110100010000000011110111000100100110110101100110001001111101111, 0101011011011111100001011101101011011110100010000000011110111000100100110110101100110001001111101111
Asynchronous model using Jobs
For long-running circuits, it can be useful to run them asynchronously.
The service.create_job method returns a Job object, which you can use to
get the results after the job has run successfully.
job = service.create_job(
program=circuit,
repetitions=100,
target="ionq.simulator"
)
To check on the job status, use job.status():
print(job.status())
'completed'
To wait for the job to complete and then get the results, use the blocking
call job.results():
result = job.results()
print(result)
00: 0.5
11: 0.5
Note that this does not return a cirq.Result object. Instead it
returns a result object that is specific to the IonQ simulator and uses
state probabilities instead of shot data.
type(result)
cirq_ionq.results.SimulatorResult
To convert this to a cirq.Result object, use result.to_cirq_result():
print(result.to_cirq_result())
b=1110101111111110111000011101011111001100010000001011011101001111001111001101100111010000001100011100, 1110101111111110111000011101011111001100010000001011011101001111001111001101100111010000001100011100
Load the required imports
First, run the following cell to load the required imports:
from azure.quantum.cirq import AzureQuantumService
Connect to the Azure Quantum service
To connect to the Azure Quantum service, your program will need the resource ID and the location of your Azure Quantum workspace. Log in to your Azure account, https://portal.azure.com, navigate to your Azure Quantum workspace, and copy the values from the header.

Paste the values into the following AzureQuantumService constructor to
create a service object that connects to your Azure Quantum workspace.
Optionally, specify a default target:
from azure.quantum.cirq import AzureQuantumService
service = AzureQuantumService(
resource_id="",
location="",
default_target="honeywell.hqs-lt-s1-apival"
)
List all targets
You can now list all the targets that you have access to, including the current queue time and availability.
print(service.targets())
[<Target name="ionq.qpu", avg. queue time=345 s, Available>,
<Target name="ionq.simulator", avg. queue time=4 s, Available>,
<Target name="honeywell.hqs-lt-s1", avg. queue time=0 s, Available>,
<Target name="honeywell.hqs-lt-s1-apival", avg. queue time=0 s, Available>,
<Target name="honeywell.hqs-lt-s2", avg. queue time=313169 s, Available>,
<Target name="honeywell.hqs-lt-s2-apival", avg. queue time=0 s, Available>,
<Target name="honeywell.hqs-lt-s1-sim", avg. queue time=1062 s, Available>]
Run a simple circuit on the API validator
Note
The Honeywell API validator target will always return 0 on measurement.
Next, create a simple Cirq circuit to run.
import cirq
q0, q1 = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
cirq.H(q0), # Hadamard
cirq.CNOT(q0, q1), # CNOT
cirq.measure(q0, q1, key='b') # Measure both qubits
)
print(circuit)
0: ───H───@───M────────
│ │
1: ───────X───M────────
You can now run the program via the Azure Quantum service and get the result. The following cell submits a job that runs the circuit with 100 shots, waits until the job is complete, and returns the results.
result = service.run(program=circuit, repetitions=100)
This returns a cirq.Result object.
print(result)
b=0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
You can plot the results in a histogram:
pl.hist(result.data)
pl.ylabel("Counts")
pl.xlabel("Result")
Asynchronous workflow using Jobs
For long-running circuits, it can be useful to run them asynchronously.
The service.create_job method returns a Job object, which you can use to
get the results after the job has run successfully.
job = service.create_job(
program=circuit,
repetitions=100
)
To check on the job status, use job.status():
print(job.status())
'Waiting'
To wait for the job to complete and then get the results, use the blocking
call job.results():
result = job.results()
print(result)
{'m_b': ['00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00']}
Note that this does not return a cirq.Result object. Instead, it
returns a dictionary of bitstring measurement results indexed by measurement key.