Quickstart: Submit a circuit with Qiskit to Azure Quantum
Learn how to use the azure-quantum
Python package to submit Qiskit quantum circuits to an IonQ, Quantinuum, or Rigetti 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. For more information, see Create an Azure Quantum workspace.
Install the latest
azure-quantum
Python package using the [qiskit] tag.Note
Before installing or updating the azure-quantum package, uninstall all versions of pyqir, pyqir-*, and qiskit-qir on your machine to avoid dependency conflicts.
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.yml
This creates a new conda environment that you can activate with the following:
conda activate azurequantum
Start your favorite code editor or interactive Python tool, such as VS Code, Jupyter or iPython.
Note
The examples in this Quickstart use a Jupyter Notebook environment. From your conda environment, run Jupyter Notebook
.
Load the required imports
In Jupyter Notebooks, create a new notebook that uses the Python 3 kernel. In the first cell, run the following code to load the required imports:
from qiskit import QuantumCircuit
from qiskit.visualization import plot_histogram
from qiskit.tools.monitor import job_monitor
from azure.quantum.qiskit import AzureQuantumProvider
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 AzureQuantumProvider
constructor to
create a provider
object that connects to your Azure Quantum workspace.
provider = AzureQuantumProvider(
resource_id="",
location=""
)
List all backends
You can now print all of the quantum computing backends that are available on your workspace:
print("This workspace's targets:")
for backend in provider.backends():
print("- " + backend.name())
This workspace's targets:
- ionq.qpu
- ionq.qpu.aria-1
- ionq.simulator
- microsoft.estimator
- quantinuum.hqs-lt-s1
- quantinuum.hqs-lt-s1-apival
- quantinuum.hqs-lt-s2
- quantinuum.hqs-lt-s2-apival
- quantinuum.hqs-lt-s1-sim
- quantinuum.hqs-lt-s2-sim
- quantinuum.qpu.h1-1
- quantinuum.sim.h1-1sc
- quantinuum.qpu.h1-2
- quantinuum.sim.h1-2sc
- quantinuum.sim.h1-1e
- quantinuum.sim.h1-2e
- rigetti.sim.qvm
- rigetti.qpu.aspen-11
- rigetti.qpu.aspen-m-2
- rigetti.qpu.aspen-m-3
Run a simple circuit
First, create a simple Qiskit circuit to run.
# Create a Quantum Circuit acting on the q register
circuit = QuantumCircuit(3, 3)
circuit.name = "Qiskit Sample - 3-qubit GHZ circuit"
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.measure([0,1,2], [0, 1, 2])
# Print out the circuit
circuit.draw()
┌───┐ ┌─┐
q_0: ┤ H ├──■───────┤M├──────
└───┘┌─┴─┐ └╥┘┌─┐
q_1: ─────┤ X ├──■───╫─┤M├───
└───┘┌─┴─┐ ║ └╥┘┌─┐
q_2: ──────────┤ X ├─╫──╫─┤M├
└───┘ ║ ║ └╥┘
c: 3/════════════════╩══╩══╩═
0 1 2
To get a result back quickly, use provider.get_backend
to create a
Backend
object to connect to the IonQ Simulator backend:
simulator_backend = provider.get_backend("ionq.simulator")
IonQ backends support gates from a defined gateset, which are compiled to run optimally on the hardware. If your circuit contains gates that are not in this list, you'll need to transpile into the supported gateset using the transpile
function provided by Qiskit:
from qiskit import transpile
circuit = transpile(circuit, simulator_backend)
This will return a new circuit object where gates are decomposed into gates that are supported by the specified backend.
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:
job = simulator_backend.run(circuit, shots=100)
job_id = job.id()
print("Job id", job_id)
Job id 00000000-0000-0000-0000-000000000000
To monitor job progress, you can use the Qiskit job_monitor
imported
earlier to keep track of the Job's status. This call will
block until the job completes:
job_monitor(job)
Job Status: job has successfully run
To wait until the job is complete and return the results, run:
result = job.result()
This returns a qiskit.Result
object.
type(result)
qiskit.result.result.Result
print(result)
Result(backend_name='ionq.simulator', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='00000000-0000-0000-0000-000000000000', success=True, results=[ExperimentResult(shots=100, success=True, meas_level=2, data=ExperimentResultData(counts={'000': 50, '111': 50}, probabilities={'000': 0.5, '111': 0.5}), header=QobjExperimentHeader(meas_map='[0, 1, 2]', name='Qiskit Sample - 3-qubit GHZ circuit', num_qubits='3', qiskit='True'))])
Because the result is an object native to the Qiskit package, you can use
Qiskit's result.get_counts
and plot_histogram
to visualize the
results. To make sure that all possible bitstring labels are represented,
add them to counts
.
counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
{'000': 50, '001': 0, '010': 0, '011': 0, '100': 0, '101': 0, '110': 0, '111': 50}
Estimate job cost
Before running a job on the QPU, you can estimate how much it will cost to run. To estimate the cost of running a job on the QPU, you can use the estimate_cost
method:
backend = provider.get_backend("ionq.qpu")
cost = backend.estimate_cost(circuit, shots=1024)
print(f"Estimated cost: {cost.estimated_total}")
This prints the estimated cost in USD.
For the most current pricing details, see IonQ Pricing, or find your workspace and view pricing options in the "Provider" tab of your workspace via: aka.ms/aq/myworkspaces.
Run on IonQ QPU
To connect to real hardware (a Quantum Processor Unit (QPU)), simply
provide the name of the target "ionq.qpu"
to the provider.get_backend
method:
qpu_backend = provider.get_backend("ionq.qpu")
Submit the circuit to run on Azure Quantum.
Note
The time required to run a circuit on the QPU may vary depending on current queue times.
As before, use job_monitor
to keep track of the job
status, and plot_histogram
to plot the results.
# Submit the circuit to run on Azure Quantum
qpu_job = qpu_backend.run(circuit, shots=1024)
job_id = qpu_job.id()
print("Job id", job_id)
# Monitor job progress and wait until complete:
job_monitor(qpu_job)
# Get the job results (this method also waits for the Job to complete):
result = qpu_job.result()
print(result)
counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
Job id 00000000-0000-0000-0000-000000000000
Job Status: job has successfully run
Result(backend_name='ionq.simulator', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='00000000-0000-0000-0000-000000000000', success=True, results=[ExperimentResult(shots=1024, success=True, meas_level=2, data=ExperimentResultData(counts={'0': 505, '1': 6, '2': 1, '3': 1, '4': 1, '5': 10, '6': 11, '7': 488}, probabilities={'0': 0.4932, '1': 0.0059, '2': 0.001, '3': 0.001, '4': 0.001, '5': 0.0098, '6': 0.0117, '7': 0.4766}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit', num_qubits='3', qiskit='True'))])
{'000': 505, '001': 6, '010': 1, '011': 1, '100': 1, '101': 10, '110': 11, '111': 488}
Load the required imports
In Jupyter Notebooks, create a new notebook that uses the Python 3 kernel. In the first cell, run the following code to load the required imports:
from qiskit import QuantumCircuit
from qiskit.visualization import plot_histogram
from qiskit.tools.monitor import job_monitor
from azure.quantum.qiskit import AzureQuantumProvider
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 AzureQuantumProvider
constructor to
create a provider
object that connects to your Azure Quantum workspace.
provider = AzureQuantumProvider(
resource_id="",
location=""
)
List all backends
Note
The target names for the Quantinuum Syntax Checkers, Emulators, and QPUs have recently changed. The updated names are used in this topic. For details, see the Quantinuum provider topic.
You can now print all of the quantum computing backends that are available on your workspace:
print("This workspace's targets:")
for backend in provider.backends():
print("- " + backend.name())
This workspace's targets:
- ionq.qpu
- ionq.qpu.aria-1
- ionq.simulator
- microsoft.estimator
- quantinuum.hqs-lt-s1
- quantinuum.hqs-lt-s1-apival
- quantinuum.hqs-lt-s2
- quantinuum.hqs-lt-s2-apival
- quantinuum.hqs-lt-s1-sim
- quantinuum.hqs-lt-s2-sim
- quantinuum.qpu.h1-1
- quantinuum.sim.h1-1sc
- quantinuum.qpu.h1-2
- quantinuum.sim.h1-2sc
- quantinuum.sim.h1-1e
- quantinuum.sim.h1-2e
- rigetti.sim.qvm
- rigetti.qpu.aspen-11
- rigetti.qpu.aspen-m-2
- rigetti.qpu.aspen-m-3
Run on the syntax checker
To test the program before running it on the hardware, first run it on the Quantinuum syntax checker.
Note
The Quantinuum syntax checker backend will always return 0 on measurement.
# Get Quantinuum's syntax checker backend:
syntax_backend = provider.get_backend("quantinuum.sim.h1-1sc")
# Create a Quantum Circuit acting on the q register
circuit = QuantumCircuit(3, 3)
circuit.name = "Qiskit Sample - 3-qubit GHZ circuit"
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.measure([0,1,2], [0, 1, 2])
# Print out the circuit
circuit.draw()
┌───┐ ┌─┐
q_0: ┤ H ├──■───────┤M├──────
└───┘┌─┴─┐ └╥┘┌─┐
q_1: ─────┤ X ├──■───╫─┤M├───
└───┘┌─┴─┐ ║ └╥┘┌─┐
q_2: ──────────┤ X ├─╫──╫─┤M├
└───┘ ║ ║ └╥┘
c: 3/════════════════╩══╩══╩═
0 1 2
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 1024 shots:
# Submit the circuit to run on Azure Quantum
job = syntax_backend.run(circuit, shots=1024)
job_id = job.id()
print("Job id", job_id)
# Monitor job progress and wait until complete:
job_monitor(job)
# Get the job results (this method also waits for the Job to complete):
result = job.result()
print(result)
counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
Job id 00000000-0000-0000-0000-000000000000
Job Status: job has successfully run
Result(backend_name='quantinuum.qpu.h1-1sc', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='00000000-0000-0000-0000-000000000000', success=True, results=[ExperimentResult(shots=1024, success=True, meas_level=2, data=ExperimentResultData(counts={'000': 1024}, probabilities={'000': 1.0}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit'))])
{'000': 1024, '001': 0, '010': 0, '011': 0, '100': 0, '101': 0, '110': 0, '111': 0}
Note
While the syntax checker ensures that your code will run successfully on Quantinuum hardware, it also returns 0 for every quantum measurement. For a true quantum measurement, you need to run your circuit on quantum hardware.
Estimate job cost
Before running a job on the QPU, you can estimate how much it will cost to run. To estimate the cost of running a job on the QPU, you can use the estimate_cost
method:
qpu_backend = provider.get_backend("quantinuum.qpu.h1-1")
cost = qpu_backend.estimate_cost(circuit, shots=1024)
print(f"Estimated cost: {cost.estimated_total}")
This prints the estimated cost in H-System Quantum Credits (HQCs).
For the most current pricing details, see Azure Quantum pricing, or find your workspace and view pricing options in the Provider tab of your workspace via: aka.ms/aq/myworkspaces.
Run on a Quantinuum QPU
After running successfully on the API validator, you can run your job on one of Quantinuum's hardware processors (a Quantum Processor Unit (QPU)).
Note
The time required to run a circuit on the QPU may vary depending on current queue times.
# Get Quantinuum's QPU backend:
qpu_backend = provider.get_backend("quantinuum.qpu.h1-1")
# Submit the circuit to run on Azure Quantum
job = qpu_backend.run(circuit, shots=1024)
job_id = job.id()
print("Job id", job_id)
# Monitor job progress and wait until complete:
job_monitor(job)
Job id 00000000-0000-0000-0000-000000000000
Job Status: job has successfully run
# Get the job results (this method also waits for the Job to complete):
result = job.result()
print(result)
counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
Result(backend_name='quantinuum.qpu.h1-1', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='00000000-0000-0000-0000-000000000000', success=True, results=[ExperimentResult(shots=1024, success=True, meas_level=2, data=ExperimentResultData(counts={'011': 16, '010': 5, '001': 1, '000': 500, '111': 471, '101': 6, '100': 17, '110': 8}, probabilities={'011': 0.015625, '010': 0.0048828125, '001': 0.0009765625, '000': 0.48828125, '111': 0.4599609375, '101': 0.005859375, '100': 0.0166015625, '110': 0.0078125}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit'))])
{'000': 500, '001': 1, '010': 5, '011': 16, '100': 17, '101': 6, '110': 8, '111': 471}
Load the required imports
In Jupyter Notebooks, create a new notebook that uses the Python 3 kernel. In the first cell, run the following code to load the required imports:
from qiskit import QuantumCircuit
from qiskit.visualization import plot_histogram
from qiskit.tools.monitor import job_monitor
from azure.quantum.qiskit import AzureQuantumProvider
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 AzureQuantumProvider
constructor to
create a provider
object that connects to your Azure Quantum workspace.
provider = AzureQuantumProvider(
resource_id="",
location=""
)
List all backends
You can now print all of the quantum computing backends that are available on your workspace:
print("This workspace's targets:")
for backend in provider.backends():
print("- " + backend.name())
This workspace's targets:
- ionq.qpu
- ionq.qpu.aria-1
- ionq.simulator
- microsoft.estimator
- quantinuum.hqs-lt-s1
- quantinuum.hqs-lt-s1-apival
- quantinuum.hqs-lt-s2
- quantinuum.hqs-lt-s2-apival
- quantinuum.hqs-lt-s1-sim
- quantinuum.hqs-lt-s2-sim
- quantinuum.qpu.h1-1
- quantinuum.sim.h1-1sc
- quantinuum.qpu.h1-2
- quantinuum.sim.h1-2sc
- quantinuum.sim.h1-1e
- quantinuum.sim.h1-2e
- rigetti.sim.qvm
- rigetti.qpu.aspen-11
- rigetti.qpu.aspen-m-2
- rigetti.qpu.aspen-m-3
Run on the QVM simulator
To test the program before running it on the hardware, first run it on the Rigetti QVM simulator.
# Get Rigetti's QVM simulator backend:
qvm_backend = provider.get_backend("rigetti.sim.qvm")
# Create a Quantum Circuit acting on the q register
circuit = QuantumCircuit(3, 3)
circuit.name = "Qiskit Sample - 3-qubit GHZ circuit"
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.measure([0,1,2], [0, 1, 2])
# Print out the circuit
circuit.draw()
┌───┐ ┌─┐
q_0: ┤ H ├──■───────┤M├──────
└───┘┌─┴─┐ └╥┘┌─┐
q_1: ─────┤ X ├──■───╫─┤M├───
└───┘┌─┴─┐ ║ └╥┘┌─┐
q_2: ──────────┤ X ├─╫──╫─┤M├
└───┘ ║ ║ └╥┘
c: 3/════════════════╩══╩══╩═
0 1 2
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 1024 shots:
# Submit the circuit to run on Azure Quantum
job = qvm_backend.run(circuit, shots=1024)
job_id = job.id()
print("Job id", job_id)
# Monitor job progress and wait until complete:
job_monitor(job)
# Get the job results (this method also waits for the Job to complete):
result = job.result()
print(result)
counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
Job id 00000000-0000-0000-0000-000000000000
Job Status: job has successfully run
Result(backend_name='rigetti.sim.qvm"', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='00000000-0000-0000-0000-000000000000', success=True, results=[ExperimentResult(shots=1024, success=True, meas_level=2, data=ExperimentResultData(counts={'000': 1024}, probabilities={'000': 1.0}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit'))])
{'000': 1024, '001': 0, '010': 0, '011': 0, '100': 0, '101': 0, '110': 0, '111': 0}
Run on a Rigetti QPU
After running successfully on the QVM simulator, you can run your job on one of Rigetti's hardware processors (a Quantum Processor Unit (QPU)).
Note
The time required to run a circuit on the QPU may vary depending on current queue times.
# Get Rigetti's QPU backend:
qpu_backend = provider.get_backend("rigetti.qpu.aspen-m-3")
# Submit the circuit to run on Azure Quantum
job = qpu_backend.run(circuit, shots=500)
job_id = job.id()
print("Job id", job_id)
# Monitor job progress and wait until complete:
job_monitor(job)
Job id 00000000-0000-0000-0000-000000000000
Job Status: job has successfully run
# Get the job results (this method also waits for the Job to complete):
result = job.result()
print(result)
counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
Result(backend_name='rigetti.qpu.aspen-m-3', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='00000000-0000-0000-0000-000000000000', success=True, results=[ExperimentResult(shots=1024, success=True, meas_level=2, data=ExperimentResultData(counts={'011': 16, '010': 5, '001': 1, '000': 500, '111': 471, '101': 6, '100': 17, '110': 8}, probabilities={'011': 0.015625, '010': 0.0048828125, '001': 0.0009765625, '000': 0.48828125, '111': 0.4599609375, '101': 0.005859375, '100': 0.0166015625, '110': 0.0078125}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit'))])
{'000': 500, '001': 1, '010': 5, '011': 16, '100': 17, '101': 6, '110': 8, '111': 471}
Important
Submitting multiple circuits on a single job is currently not supported. As a workaround you can call the backend.run
method to submit each circuit asynchronously, then fetch the results of each job. For example:
jobs = []
for circuit in circuits:
jobs.append(backend.run(circuit, shots=N))
results = []
for job in jobs:
results.append(job.result())
Feedback
Submit and view feedback for