Skip to content

Commit 9eab3b6

Browse files
authored
Add tutorials to notebook tests (#1155)
Adds the new tutorial notebooks to the same tests as the documentation notebooks. Most tutorials run jobs on IBM Quantum so will only be tested fortnightly in the cron job workflow. Part of #1136
1 parent 42a380c commit 9eab3b6

File tree

12 files changed

+103
-55
lines changed

12 files changed

+103
-55
lines changed

.github/workflows/notebook-test.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ name: Test notebooks
1414
on:
1515
pull_request:
1616
paths:
17+
- "tutorials/**/*.ipynb"
1718
- "docs/**/*.ipynb"
1819
- "!docs/api/**/*"
1920
workflow_dispatch:
@@ -28,7 +29,7 @@ jobs:
2829
id: all-changed-files
2930
uses: tj-actions/changed-files@af2816c65436325c50621100d67f6e853cd1b0f1
3031
with:
31-
files: docs/**/*.ipynb
32+
files: "{tutorials,docs}/**/*.ipynb"
3233
separator: "\n"
3334

3435
- name: Check for notebooks that require Linux

scripts/nb-tester/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ ipykernel~=6.29.2
66
qiskit[all]~=1.0
77
qiskit-aer~=0.14.0.1
88
qiskit-ibm-runtime~=0.22.0
9+
qiskit-ibm-provider~=0.10.0
910
squeaky==0.7.0

scripts/nb-tester/test-notebook.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,21 @@
2525
from qiskit_ibm_runtime import QiskitRuntimeService
2626
from squeaky import clean_notebook
2727

28-
NOTEBOOKS_GLOB = "docs/**/*.ipynb"
28+
NOTEBOOKS_GLOB = "{tutorials,docs}/**/*.ipynb"
2929
NOTEBOOKS_EXCLUDE = [
3030
"docs/api/**",
3131
"**/.ipynb_checkpoints/**",
3232
]
3333
NOTEBOOKS_THAT_SUBMIT_JOBS = [
3434
"docs/start/hello-world.ipynb",
3535
"docs/analyze/saving-and-retrieving.ipynb",
36+
"tutorials/build-repitition-codes/notebook.ipynb",
37+
"tutorials/chsh-inequality/notebook.ipynb",
38+
"tutorials/grovers-algorithm/notebook.ipynb",
39+
"tutorials/quantum-approximate-optimization-algorithm/notebook.ipynb",
40+
"tutorials/repeat-until-success/notebook.ipynb",
41+
"tutorials/submitting-transpiled-circuits/notebook.ipynb",
42+
"tutorials/variational-quantum-eigensolver/notebook.ipynb",
3643
]
3744

3845

tox.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ setenv = PYDEVD_DISABLE_FILE_VALIDATION=1
99
commands = python scripts/nb-tester/test-notebook.py {posargs}
1010

1111
[testenv:lint]
12-
commands = squeaky --check --no-advice {posargs:docs/}
12+
commands = squeaky --check --no-advice {posargs:docs tutorials}
1313

1414
[testenv:fix]
15-
commands = squeaky {posargs:docs/}
15+
commands = squeaky {posargs:docs tutorials}

tutorials/build-repitition-codes/notebook.ipynb

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"\n",
1515
"## Background\n",
1616
"\n",
17-
"To enable real-time quantum error correction (QEC), we require the capability to dynamically control quantum program flow during execution so that quantum gates may be conditioned on measurement results. In this tutorial, we will run the bit-flip code, which is a very simple form of QEC. We will demonstrate a dynamic quantum circuit that can protect an encoded qubit from a single bit-flip error, and then evaluate the performance of the bit-flip code. \n",
17+
"To enable real-time quantum error correction (QEC), we require the capability to dynamically control quantum program flow during execution so that quantum gates may be conditioned on measurement results. In this tutorial, we will run the bit-flip code, which is a very simple form of QEC. We will demonstrate a dynamic quantum circuit that can protect an encoded qubit from a single bit-flip error, and then evaluate the performance of the bit-flip code.\n",
1818
"\n",
1919
"We can exploit additional ancilla qubits and entanglement to measure what are known as *stabilizers* that do not transform our encoded quantum information, while still informing us of some classes of errors that may have occurred. A quantum stabilizer code encodes $k$ logical qubits into $n$ physical qubits. Stabilizer codes critically focus on correcting a discrete error set with support from the Pauli group $\\Pi^n$. Assume the set of possible errors are $ \\epsilon \\subset \\Pi^n$. For example, in a bit-flip code with three qubits encoding the quantum state, we will have $\\epsilon = \\{IIX, IXI, XII\\}$. We can measure the stabilizers and observing their eigenvalues to dete"
2020
]
@@ -115,14 +115,14 @@
115115
"\n",
116116
"def measure_syndrome_bit(circuit, qreg_data, qreg_measure, creg_measure):\n",
117117
" \"\"\"\n",
118-
" Measure the syndrome by measuring the parity. \n",
118+
" Measure the syndrome by measuring the parity.\n",
119119
" We reset our ancilla qubits after measuring the stabilizer\n",
120-
" so we can reuse them for repeated stabilizer measurements. \n",
121-
" Because we have already observed the state of the qubit, \n",
122-
" we can write the conditional reset protocol directly to \n",
123-
" avoid another round of qubit measurement if we used \n",
120+
" so we can reuse them for repeated stabilizer measurements.\n",
121+
" Because we have already observed the state of the qubit,\n",
122+
" we can write the conditional reset protocol directly to\n",
123+
" avoid another round of qubit measurement if we used\n",
124124
" the `reset` instruction.\n",
125-
" \"\"\" \n",
125+
" \"\"\"\n",
126126
" circuit.cx(qreg_data[0], qreg_measure[0])\n",
127127
" circuit.cx(qreg_data[1], qreg_measure[0])\n",
128128
" circuit.cx(qreg_data[0], qreg_measure[1])\n",
@@ -179,10 +179,10 @@
179179
" circuit = initialize_qubits(circuit)\n",
180180
" circuit = encode_bit_flip(circuit, state_data, ancillas_data)\n",
181181
" circuit = measure_syndrome_bit(circuit, qreg_data, qreg_measure, creg_syndrome)\n",
182-
" \n",
182+
"\n",
183183
" if apply_correction:\n",
184184
" circuit = apply_correction_bit(circuit, qreg_data, creg_syndrome)\n",
185-
" \n",
185+
"\n",
186186
" circuit = apply_final_readout(circuit, qreg_data, creg_data)\n",
187187
" return circuit\n",
188188
"\n",
@@ -423,7 +423,7 @@
423423
"metadata": {
424424
"celltoolbar": "Slideshow",
425425
"kernelspec": {
426-
"display_name": "Python 3 (ipykernel)",
426+
"display_name": "Python 3",
427427
"language": "python",
428428
"name": "python3"
429429
},
@@ -437,7 +437,7 @@
437437
"name": "python",
438438
"nbconvert_exporter": "python",
439439
"pygments_lexer": "ipython3",
440-
"version": "3.9.6"
440+
"version": "3"
441441
},
442442
"vscode": {
443443
"interpreter": {

tutorials/chsh-inequality/notebook.ipynb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
"id": "fb089249",
1414
"metadata": {},
1515
"source": [
16-
"In this tutorial, you will run an experiment on a quantum computer to demonstrate the violation of the CHSH inequality with the Estimator primitive. \n",
16+
"In this tutorial, you will run an experiment on a quantum computer to demonstrate the violation of the CHSH inequality with the Estimator primitive.\n",
1717
"\n",
18-
"The CHSH inequality, named after the authors Clauser, Horne, Shimony, and Holt, is used to experimentally prove Bell's theorem (1969). This theorem asserts that local hidden variable theories cannot account for some consequences of entanglement in quantum mechanics. The violation of the CHSH inequality is used to show that quantum mechanics is incompatible with local hidden-variable theories. This is an important experiment for understanding the foundation of quantum mechanics. \n",
18+
"The CHSH inequality, named after the authors Clauser, Horne, Shimony, and Holt, is used to experimentally prove Bell's theorem (1969). This theorem asserts that local hidden variable theories cannot account for some consequences of entanglement in quantum mechanics. The violation of the CHSH inequality is used to show that quantum mechanics is incompatible with local hidden-variable theories. This is an important experiment for understanding the foundation of quantum mechanics.\n",
1919
"\n",
2020
"The 2022 Nobel Prize for Physics was awarded to Alain Aspect, John Clauser and Anton Zeilinger in part for their pioneering work in quantum information science, and in particular, for their experiments with entangled photons demonstrating violation of Bell’s inequalities."
2121
]
@@ -152,7 +152,7 @@
152152
"id": "1ab329f2",
153153
"metadata": {},
154154
"source": [
155-
"### Create a parameterized CHSH circuit \n",
155+
"### Create a parameterized CHSH circuit\n",
156156
"\n",
157157
"First, we write the circuit with the parameter $\\theta$, which we call `theta`. The [`Estimator` primitive](https://docs.quantum-computing.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.EstimatorV2) can enormously simplify circuit building and output analysis by directly providing expectation values of observables. Many problems of interest, especially for near-term applications on noisy systems, can be formulated in terms of expectation values. `Estimator` (V2) primitive can automatically change measurement basis based on the supplied observable."
158158
]
@@ -218,7 +218,7 @@
218218
"id": "6e559aed",
219219
"metadata": {},
220220
"source": [
221-
"### Observables \n",
221+
"### Observables\n",
222222
"\n",
223223
"Now we need observables from which to compute the expectation values. In our case we are looking at orthogonal bases for each qubit, letting the parameterized $Y-$ rotation for the first qubit sweep the measurement basis nearly continuously with respect to the second qubit basis. We will therefore choose the observables $ZZ$, $ZX$, $XZ$, and $XX$."
224224
]
@@ -336,7 +336,7 @@
336336
"id": "2d8ad9e1",
337337
"metadata": {},
338338
"source": [
339-
"We can create a [Qiskit Runtime `Estimator`](https://docs.quantum.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.EstimatorV2) primitive to compute our expectation values. The `EstimatorV2.run()` method takes an iterable of `primitive unified blocs (PUBs)`. Each PUB is an iterable in the format `(circuit, observables, parameter_values: Optional, precision: Optional)`. "
339+
"We can create a [Qiskit Runtime `Estimator`](https://docs.quantum.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.EstimatorV2) primitive to compute our expectation values. The `EstimatorV2.run()` method takes an iterable of `primitive unified blocs (PUBs)`. Each PUB is an iterable in the format `(circuit, observables, parameter_values: Optional, precision: Optional)`."
340340
]
341341
},
342342
{
@@ -487,7 +487,7 @@
487487
],
488488
"metadata": {
489489
"kernelspec": {
490-
"display_name": "Python 3 (ipykernel)",
490+
"display_name": "Python 3",
491491
"language": "python",
492492
"name": "python3"
493493
},
@@ -501,7 +501,7 @@
501501
"name": "python",
502502
"nbconvert_exporter": "python",
503503
"pygments_lexer": "ipython3",
504-
"version": "3.11.8"
504+
"version": "3"
505505
},
506506
"vscode": {
507507
"interpreter": {

tutorials/explore-composer/notebook.ipynb

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
{
44
"attachments": {},
55
"cell_type": "markdown",
6+
"id": "b27d7770-0fd4-4173-9b52-99a0898634db",
67
"metadata": {},
78
"source": [
89
"## What is it?\n",
@@ -27,6 +28,7 @@
2728
{
2829
"attachments": {},
2930
"cell_type": "markdown",
31+
"id": "477a3b86-e25f-4966-ae9f-0831482d202f",
3032
"metadata": {},
3133
"source": [
3234
"## Tour of the interface\n",
@@ -65,12 +67,13 @@
6567
"\n",
6668
"11. **Visualizations** - Visualizations characterize your circuit as you build it. They use a single-shot statevector simulator, which is different from the system specified in the Setup and run settings. Note that the visualizations ignore any measurement operations you add. Sign in and click **Setup and run** to get results from the specified backend instead.\n",
6769
"\n",
68-
" To learn about the visualizations, see [Visualizations](#visualizations).\n"
70+
" To learn about the visualizations, see [Visualizations](#visualizations)."
6971
]
7072
},
7173
{
7274
"attachments": {},
7375
"cell_type": "markdown",
76+
"id": "e9207850-523d-410b-9df4-27cd6b320e3e",
7477
"metadata": {},
7578
"source": [
7679
"## Build, edit, and inspect quantum circuits\n",
@@ -191,6 +194,7 @@
191194
{
192195
"attachments": {},
193196
"cell_type": "markdown",
197+
"id": "d106f427-c7f6-4c7e-9f5f-b7dfcca515cb",
194198
"metadata": {},
195199
"source": [
196200
"### 3. Build your circuit with OpenQASM code\n",
@@ -230,6 +234,7 @@
230234
{
231235
"attachments": {},
232236
"cell_type": "markdown",
237+
"id": "8b6551de-ad4e-4b95-bb8a-56b43575764e",
233238
"metadata": {},
234239
"source": [
235240
"#### Create a custom operation in OpenQASM\n",
@@ -284,6 +289,7 @@
284289
{
285290
"attachments": {},
286291
"cell_type": "markdown",
292+
"id": "d4ed95f2-15ad-4e9a-add3-57e227270a5d",
287293
"metadata": {},
288294
"source": [
289295
"## Run circuits and view results\n",
@@ -321,6 +327,7 @@
321327
{
322328
"attachments": {},
323329
"cell_type": "markdown",
330+
"id": "b37d5709-a82a-4453-9cba-6d3cd2b475aa",
324331
"metadata": {},
325332
"source": [
326333
"## Visualizations\n",
@@ -441,12 +448,13 @@
441448
"\n",
442449
"The statevector at the terminus of the above circuit. The color wheel maps phase angle to color. The output state is expressed as a list of complex numbers.\n",
443450
"\n",
444-
"The circuit puts the two qubits into the state $|\\psi\\rangle = (|00\\rangle + |01\\rangle+ |10\\rangle-|11\\rangle) / 2$. The computational basis states are $|00\\rangle$, $|10\\rangle$, $|01\\rangle$, and $|11\\rangle$. The magnitudes of the amplitudes are $1/2$, and the quantum phases with respect to the ground state are $0$ for $|01\\rangle$ and $|10\\rangle$, and $\\pi$ for $|11\\rangle$.\n"
451+
"The circuit puts the two qubits into the state $|\\psi\\rangle = (|00\\rangle + |01\\rangle+ |10\\rangle-|11\\rangle) / 2$. The computational basis states are $|00\\rangle$, $|10\\rangle$, $|01\\rangle$, and $|11\\rangle$. The magnitudes of the amplitudes are $1/2$, and the quantum phases with respect to the ground state are $0$ for $|01\\rangle$ and $|10\\rangle$, and $\\pi$ for $|11\\rangle$."
445452
]
446453
},
447454
{
448455
"attachments": {},
449456
"cell_type": "markdown",
457+
"id": "9c47c5d8-7447-4cc3-b5bb-09cd2f1689bc",
450458
"metadata": {},
451459
"source": [
452460
"## Composer operations glossary\n",
@@ -744,10 +752,23 @@
744752
}
745753
],
746754
"metadata": {
747-
"language_info": {
748-
"name": "python"
755+
"kernelspec": {
756+
"display_name": "Python 3",
757+
"language": "python",
758+
"name": "python3"
749759
},
750-
"orig_nbformat": 4
760+
"language_info": {
761+
"codemirror_mode": {
762+
"name": "ipython",
763+
"version": 3
764+
},
765+
"file_extension": ".py",
766+
"mimetype": "text/x-python",
767+
"name": "python",
768+
"nbconvert_exporter": "python",
769+
"pygments_lexer": "ipython3",
770+
"version": "3"
771+
}
751772
},
752773
"nbformat": 4,
753774
"nbformat_minor": 2

tutorials/grovers-algorithm/notebook.ipynb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"source": [
99
"## Background\n",
1010
"\n",
11-
"Amplitude amplification is a general purpose quantum algorithm, or subroutine, that can be used to obtain a quadratic speedup over a handful of classical algorithms. [Grover’s algorithm](https://arxiv.org/abs/quant-ph/9605043) was the first to demonstrate this speedup on unstructured search problems. Formulating a Grover's search problem requires an oracle function that marks one or more computational basis states as the states we are interested in finding, and an amplification circuit that increases the amplitude of marked states, consequently suppressing the remaining states. \n",
11+
"Amplitude amplification is a general purpose quantum algorithm, or subroutine, that can be used to obtain a quadratic speedup over a handful of classical algorithms. [Grover’s algorithm](https://arxiv.org/abs/quant-ph/9605043) was the first to demonstrate this speedup on unstructured search problems. Formulating a Grover's search problem requires an oracle function that marks one or more computational basis states as the states we are interested in finding, and an amplification circuit that increases the amplitude of marked states, consequently suppressing the remaining states.\n",
1212
"\n",
1313
"Here, we demonstrate how to construct Grover oracles and use the `GroverOperator` from the Qiskit circuit library to easily set up a Grover's search instance. The runtime `Sampler` primitive allows seamless execution of Grover circuits."
1414
]
@@ -419,7 +419,7 @@
419419
],
420420
"metadata": {
421421
"kernelspec": {
422-
"display_name": "Python 3 (ipykernel)",
422+
"display_name": "Python 3",
423423
"language": "python",
424424
"name": "python3"
425425
},
@@ -433,7 +433,7 @@
433433
"name": "python",
434434
"nbconvert_exporter": "python",
435435
"pygments_lexer": "ipython3",
436-
"version": "3.11.8"
436+
"version": "3"
437437
}
438438
},
439439
"nbformat": 4,

tutorials/quantum-approximate-optimization-algorithm/notebook.ipynb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@
169169
"id": "da92068c",
170170
"metadata": {},
171171
"source": [
172-
"The previous image illustrates the ansatz in basic gates for clarity. However, it can be expressed in multiple levels of decomposition by changing the `reps` argument or by drawing the circuit without the `decompose` method. For example, the following representation directly shows the QAOA structure with the default `reps` value, which is `reps=1`. "
172+
"The previous image illustrates the ansatz in basic gates for clarity. However, it can be expressed in multiple levels of decomposition by changing the `reps` argument or by drawing the circuit without the `decompose` method. For example, the following representation directly shows the QAOA structure with the default `reps` value, which is `reps=1`."
173173
]
174174
},
175175
{
@@ -366,7 +366,7 @@
366366
"source": [
367367
"Any classical optimizer can be used to minimize the cost function. On a real quantum system, an optimizer designed for non-smooth cost function landscapes usually does better. Here we use the [COBYLA routine from SciPy through the minimize function](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html).\n",
368368
"\n",
369-
"Because we are iteratively executing many calls to Runtime, we use a [`Session`](https://docs.quantum-computing.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.Session) to execute all calls within a single block. Moreover, for QAOA, the solution is encoded in the output distribution of the ansatz circuit bound with the optimal parameters from the minimization. Therefore, we will need a [`Sampler`](https://docs.quantum-computing.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.SamplerV2) primitive as well, and will instantiate it with the same [`Session`](https://docs.quantum-computing.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.Session).\n"
369+
"Because we are iteratively executing many calls to Runtime, we use a [`Session`](https://docs.quantum-computing.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.Session) to execute all calls within a single block. Moreover, for QAOA, the solution is encoded in the output distribution of the ansatz circuit bound with the optimal parameters from the minimization. Therefore, we will need a [`Sampler`](https://docs.quantum-computing.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.SamplerV2) primitive as well, and will instantiate it with the same [`Session`](https://docs.quantum-computing.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.Session)."
370370
]
371371
},
372372
{
@@ -658,7 +658,7 @@
658658
],
659659
"metadata": {
660660
"kernelspec": {
661-
"display_name": "Python 3 (ipykernel)",
661+
"display_name": "Python 3",
662662
"language": "python",
663663
"name": "python3"
664664
},
@@ -672,7 +672,7 @@
672672
"name": "python",
673673
"nbconvert_exporter": "python",
674674
"pygments_lexer": "ipython3",
675-
"version": "3.11.8"
675+
"version": "3"
676676
}
677677
},
678678
"nbformat": 4,

tutorials/repeat-until-success/notebook.ipynb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
"source": [
1111
"# Repeat until success\n",
1212
"\n",
13-
"## Background \n",
13+
"## Background\n",
1414
"\n",
15-
"This tutorial demonstrates the current capabilities of IBM dynamic-circuit backends to use mid-circuit measurements to produce a circuit that repeatedly attempts its setup until a syndrome measurement reveals that it has been successful. \n",
15+
"This tutorial demonstrates the current capabilities of IBM dynamic-circuit backends to use mid-circuit measurements to produce a circuit that repeatedly attempts its setup until a syndrome measurement reveals that it has been successful.\n",
1616
"\n",
1717
"We will build an abstract circuit that uses the non-parametrized gate set $\\{H,\\,X,\\,S,\\,\\text{Toffoli}\\}$ to construct a heralded $R_X(\\theta)$ gate on a target qubit, where $\\theta$ satisfies $\\cos\\theta = \\frac35$. Each iteration of the circuit only has a finite chance of success, but successes are heralded, so we will use our dynamic-circuit capabilities to repeat the setup until it succeeds."
1818
]
@@ -402,13 +402,13 @@
402402
" state.\"\"\"\n",
403403
" successes = collections.defaultdict(int)\n",
404404
" failures = collections.defaultdict(int)\n",
405-
" \n",
405+
"\n",
406406
" for key, value in counts.items():\n",
407407
" if key.endswith(\"00\"):\n",
408408
" successes[key[0]] += value\n",
409409
" else:\n",
410410
" failures[key[0]] += value\n",
411-
" \n",
411+
"\n",
412412
" return successes, failures"
413413
]
414414
},
@@ -511,7 +511,7 @@
511511
],
512512
"metadata": {
513513
"kernelspec": {
514-
"display_name": "Python 3 (ipykernel)",
514+
"display_name": "Python 3",
515515
"language": "python",
516516
"name": "python3"
517517
},
@@ -525,7 +525,7 @@
525525
"name": "python",
526526
"nbconvert_exporter": "python",
527527
"pygments_lexer": "ipython3",
528-
"version": "3.9.6"
528+
"version": "3"
529529
},
530530
"vscode": {
531531
"interpreter": {

0 commit comments

Comments
 (0)