Skip to content

Commit bc074d1

Browse files
Update qiskit submission sample notebook to use AzureQuantumProvider method (#2794)
This PR updates the qiskit submission notebook to demonstrate the more streamlined approach to submitting qiskit to azure using the `AzureQuantumProvider` class. It also retains instructions for how to manually convert qiskit to QIR for submission.
1 parent e7ce2d8 commit bc074d1

File tree

3 files changed

+91
-28
lines changed

3 files changed

+91
-28
lines changed

samples/python_interop/submit_qiskit_circuit_to_azure.ipynb

Lines changed: 71 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,29 @@
77
"source": [
88
"# Submitting Qiskit Circuits to Azure Quantum with the QDK\n",
99
"\n",
10-
"This notebook shows how to take an arbitrary Qiskit `QuantumCircuit`, compile it to QIR using the Quantum Development Kit (QDK) Python APIs, and submit it as a job to an Azure Quantum target. It also demonstrates how to handle parameterized circuits by binding parameters before submission."
10+
"This notebook demonstrates two ways to run Qiskit `QuantumCircuit` jobs on Azure Quantum using the QDK: (A) direct submission via `AzureQuantumProvider` for a streamlined workflow, and (B) an explicit OpenQASM 3 → QIR compilation path for transparency and artifact inspection. It also shows how to handle parameterized circuits by binding parameters prior to execution."
1111
]
1212
},
1313
{
1414
"cell_type": "markdown",
1515
"id": "2b838c23",
1616
"metadata": {},
1717
"source": [
18-
"The workflow demonstrated here:\n",
18+
"This workflow demonstrates two methods of submission:\n",
1919
"\n",
20+
"### A. Direct submission via `AzureQuantumProvider` (recommended when available)\n",
21+
"1. Build (or load) a Qiskit `QuantumCircuit`.\n",
22+
"2. Reference an existing Azure Quantum workspace with `qdk.azure.Workspace`.\n",
23+
"3. Instantiate `AzureQuantumProvider(workspace)` and pick a backend (`provider.get_backend(<target_name>)`).\n",
24+
"4. Call `backend.run(circuit, shots, job_name=...)` and fetch results (`job.result().get_counts(circuit)`).\n",
25+
"\n",
26+
"### B. Submit via OpenQASM compilation (explicit OpenQASM → QIR → submit)\n",
2027
"1. Build (or load) a Qiskit `QuantumCircuit`.\n",
2128
"2. Convert it to OpenQASM 3 text (`qiskit.qasm3.dumps`).\n",
22-
"3. Compile that OpenQASM 3 source to QIR with `qdk.openqasm.compile`.\n",
23-
"4. Create (or attach to) an Azure Quantum workspace with `qdk.azure.Workspace`.\n",
29+
"3. Compile the OpenQASM 3 source to QIR with `qdk.openqasm.compile` (choose a `TargetProfile`).\n",
30+
"4. Reference an existing Azure Quantum workspace with `qdk.azure.Workspace`.\n",
2431
"5. Select a target (e.g. a simulator such as `rigetti.sim.qvm`).\n",
25-
"6. Submit the QIR payload and retrieve measurement results.\n",
26-
"\n",
27-
"Why use the QDK in this flow?\n",
28-
"\n",
29-
"- Local compilation: QIR generation happens locally—no external CLI needed.\n",
30-
"- Consistency: The same compiler stack powers Q#, OpenQASM, and (via translation) Qiskit interoperability.\n",
31-
"\n",
32-
"This notebook focuses strictly on submission. For local resource estimation of Qiskit circuits, see the separate estimation sample."
32+
"6. Submit the QIR payload (`target.submit(qir, job_name, shots)`), then retrieve results (`job.get_results()`)."
3333
]
3434
},
3535
{
@@ -128,19 +128,66 @@
128128
"location = 'westus'"
129129
]
130130
},
131+
{
132+
"cell_type": "markdown",
133+
"id": "cdae59f7",
134+
"metadata": {},
135+
"source": [
136+
"### Approach A: Using Azure Quantum Provider\n",
137+
"\n",
138+
"Here we use the recommended submission method with `AzureQuantumProvider` to submit the Qiskit circuit straight to an Azure Quantum backend. This avoids having to explicitly do QASM translation or QIR compilation steps."
139+
]
140+
},
131141
{
132142
"cell_type": "code",
133143
"execution_count": null,
134144
"id": "d9a0f59b",
135145
"metadata": {},
136146
"outputs": [],
147+
"source": [
148+
"from qdk.azure import Workspace\n",
149+
"from qdk.azure.qiskit import AzureQuantumProvider\n",
150+
"\n",
151+
"def submit_qiskit_circuit_to_azure_provider(circuit, target_name, name, shots=100):\n",
152+
"\n",
153+
" workspace = Workspace(\n",
154+
" subscription_id=subscription_id,\n",
155+
" resource_group=resource_group,\n",
156+
" name=workspace_name,\n",
157+
" location=location,\n",
158+
" )\n",
159+
"\n",
160+
" provider = AzureQuantumProvider(workspace)\n",
161+
" backend = provider.get_backend(target_name)\n",
162+
" job = backend.run(circuit, shots, job_name=name)\n",
163+
" return job.result().get_counts(circuit)\n",
164+
"\n",
165+
"provider_counts = submit_qiskit_circuit_to_azure_provider(circuit, \"rigetti.sim.qvm\", \"qiskit-provider-job\")\n",
166+
"print(provider_counts)"
167+
]
168+
},
169+
{
170+
"cell_type": "markdown",
171+
"id": "fbf60412",
172+
"metadata": {},
173+
"source": [
174+
"### Approach B: Submit via OpenQASM compilation\n",
175+
"\n",
176+
"Below we show the longer path that exposes intermediate artifacts. This is useful if you want to inspect or transform OpenQASM/QIR, or integrate with tooling that consumes QIR directly.\n"
177+
]
178+
},
179+
{
180+
"cell_type": "code",
181+
"execution_count": null,
182+
"id": "ee47d6f6",
183+
"metadata": {},
184+
"outputs": [],
137185
"source": [
138186
"from qiskit import qasm3\n",
139187
"from qdk.openqasm import compile\n",
140-
"from qdk.azure import Workspace\n",
141188
"from qdk import TargetProfile\n",
142189
"\n",
143-
"def submit_qiskit_circuit_to_azure(circuit, target_name, name, shots=100):\n",
190+
"def submit_qiskit_circuit_to_azure_via_qasm(circuit, target_name, name, shots=100):\n",
144191
" qasm3_str = qasm3.dumps(circuit)\n",
145192
" qir = compile(qasm3_str, target_profile=TargetProfile.Base)\n",
146193
"\n",
@@ -154,7 +201,7 @@
154201
" job = target.submit(qir, name, shots=shots)\n",
155202
" return job.get_results()\n",
156203
"\n",
157-
"results = submit_qiskit_circuit_to_azure(circuit, \"rigetti.sim.qvm\", \"qiskit-job\")\n",
204+
"results = submit_qiskit_circuit_to_azure_via_qasm(circuit, \"rigetti.sim.qvm\", \"qiskit-via-qasm-job\")\n",
158205
"print(results)"
159206
]
160207
},
@@ -165,7 +212,7 @@
165212
"source": [
166213
"## Parameterized Qiskit circuits\n",
167214
"\n",
168-
"Many algorithms use symbolic parameters. Before compiling to QIR and submitting, all circuit parameters must be bound to numeric values. Below we build a simple entangling ladder, apply a rotation parameterized by θ across all qubits, then uncompute the entanglement and measure the first qubit."
215+
"Many algorithms use symbolic parameters. Before submitting to azure (or before compiling to QIR), all circuit parameters must be bound to numeric values. Below we build a simple entangling ladder, apply a rotation parameterized by `θ` across all qubits, then uncompute the entanglement and measure the first qubit."
169216
]
170217
},
171218
{
@@ -178,7 +225,6 @@
178225
"from qiskit import QuantumCircuit\n",
179226
"from qiskit.circuit import Parameter\n",
180227
"\n",
181-
"\n",
182228
"def get_parameterized_circuit(n = 5) -> QuantumCircuit:\n",
183229
" theta = Parameter(\"θ\")\n",
184230
" qc = QuantumCircuit(n, 1)\n",
@@ -194,10 +240,12 @@
194240
" return qc\n",
195241
"\n",
196242
"# Build the symbolic (parameterized) circuit\n",
197-
"circuit = get_parameterized_circuit()\n",
243+
"parameterized_circuit = get_parameterized_circuit()\n",
198244
"\n",
199245
"# Bind θ to a numeric value, then visualize the bound circuit\n",
200-
"circuit.assign_parameters({\"θ\": 0.5}).draw(output=\"text\")"
246+
"bound_circuit = parameterized_circuit.assign_parameters({\"θ\": 0.5})\n",
247+
"\n",
248+
"bound_circuit.draw(output=\"text\")"
201249
]
202250
},
203251
{
@@ -207,7 +255,7 @@
207255
"source": [
208256
"## Submitting a bound parameterized circuit\n",
209257
"\n",
210-
"Below we reuse the parameterized circuit from above, bind θ to 0.5, and submit the resulting (fully concrete) circuit to the Azure Quantum target using the same helper function as before. The printed result shows the measurement counts. Change the value of θ (or loop over several values) to explore how the outcome distribution varies."
258+
"Here we submit the `bound_circuit` from above using the recommended `AzureQuantumProvider` approach. The printed result shows the measurement counts. Change the value of `θ` (or loop over several values) to explore how the outcome distribution varies."
211259
]
212260
},
213261
{
@@ -217,11 +265,8 @@
217265
"metadata": {},
218266
"outputs": [],
219267
"source": [
220-
"# Reuse the previously defined parameterized circuit\n",
221-
"# (circuit is symbolic and must have θ bound to a value before submission)\n",
222-
"\n",
223-
"results = submit_qiskit_circuit_to_azure(\n",
224-
" circuit.assign_parameters({\"θ\": 0.5}),\n",
268+
"results = submit_qiskit_circuit_to_azure_provider(\n",
269+
" bound_circuit,\n",
225270
" \"rigetti.sim.qvm\",\n",
226271
" \"qiskit-parameterized-job\"\n",
227272
")\n",
@@ -245,7 +290,7 @@
245290
"name": "python",
246291
"nbconvert_exporter": "python",
247292
"pygments_lexer": "ipython3",
248-
"version": "3.13.8"
293+
"version": "3.13.9"
249294
}
250295
},
251296
"nbformat": 4,

source/qdk_package/pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ dependencies = ["qsharp==0.0.0"]
1414

1515
[project.optional-dependencies]
1616
jupyter = ["qsharp-widgets==0.0.0", "qsharp-jupyterlab==0.0.0"]
17-
azure = ["azure-quantum>=3.2.0"]
17+
azure = ["azure-quantum>=3.5.0"]
1818
qiskit = ["qiskit>=1.2.2,<3.0.0"]
1919
all = [
2020
"qsharp-widgets==0.0.0",
21-
"azure-quantum>=3.2.0",
21+
"azure-quantum>=3.5.0",
2222
"qiskit>=1.2.2,<3.0.0",
2323
"qsharp-jupyterlab==0.0.0",
2424
]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
"""qdk.azure.qiskit: re-export of azure.quantum.qiskit symbols.
5+
6+
Requires installation: ``pip install \"qdk[azure,qiskit]\"``.
7+
8+
Example:
9+
from qdk.azure.qiskit import <symbol>
10+
11+
"""
12+
13+
try:
14+
from azure.quantum.qiskit import * # pyright: ignore[reportWildcardImportFromLibrary]
15+
except Exception as ex:
16+
raise ImportError(
17+
"qdk.azure.qiskit requires the azure and qiskit extras. Install with 'pip install \"qdk[azure,qiskit]\"'."
18+
) from ex

0 commit comments

Comments
 (0)