Teaching Quantum Computing with Q# and Azure Quantum at Northeastern University
This post is part of the Q# Holiday Calendar 2022. Check out the calendar for more great posts!
This fall I taught an “Introduction to Quantum Computing” course at Northeastern University. It was my second time teaching this course at NEU, after the first run in spring 2020. As always, it was a unique experience that taught me a lot – though, hopefully, it taught my students more! – so I decided to share the highlights of my experience with you.
In this course, I introduce quantum computing to graduate students at the College of Engineering at Northeastern University who pursue a non-physics major. This allowed me to teach the contents through the lens of software engineering rather than physics, spending only a bit of time on an overview of physical implementations of quantum devices and instead spend more time on the algorithm implementation and quantum software stack. In fact, my approach was based on the one our team took when teaching at University of Washington back in 2019: introduce the basic concepts of quantum computing and simple algorithms, focusing on using them for solving problems and implementing and evaluating algorithms. Same as back then, I used Q# and Microsoft Quantum Development Kit as the software tools for the course, adding Azure Quantum for running programs on cloud simulators and hardware.
The three-month course consisted of two parts:
- In the first two months, we went through the typical introductory topics – the basics of single- and multi-qubit systems, quantum communication algorithms (teleportation, superdense coding, and BB84 protocol), oracular algorithms such as Deutsch-Jozsa and Bernstein-Vazirani, reversible computing, and Grover’s search algorithm. Each week the lecture was followed by a set of practice exercises from the Quantum Katas – an open-source collection of tutorials and programming problems on quantum computing – and a graded programming assignment (more on the assignments later).
- During the last month, the students worked on their final projects, choosing a problem to solve using Grover’s search, implementing the solution, and evaluating it. In the lectures we reviewed more advanced topics, such as Shor’s algorithm, the software and hardware stacks required for building a quantum computer, and fault-tolerant quantum computing, without accompanying weekly assignments.
Let’s take a closer look at the three different kinds of assignments that the course offered: solving programming problems, debugging code, and running code on Azure Quantum.
Solving programming problems (with automatic grading)
This type of assignment requires the students to apply the theoretical concepts and algorithms they have learned to solve simple programming problems. To give you some examples,
- When we discuss single- and multi-qubit quantum systems and gates, the problems might ask to prepare a certain quantum state or to run a measurement to figure out which of the given quantum states you are given.
- In the communication algorithms week, the problems require to implement the last step of a variation of teleportation or superdense coding algorithms that used a different entangled state than the standard 1/√2 (|00⟩ + |11⟩).
- For the topics of oracular algorithms and reversible computing, the problems focus on implementing oracles of different types for the given classical functions.
Same as in the exercises in the Quantum Katas, each problem describes the task and provides the signature of a Q# operation that matches the description of the given problem. The student has to implement the operation that solves the task and turn in their code. The grading is done automatically using a testing harness – Q# code that runs the solutions on a set of tests using quantum simulators and checks that their results match the expected ones.
We’ve used similar assignments in the past courses as well, but this time I took them one step further. In the past we didn’t share the testing harnesses with the students, since they often included solutions to the problems (see “Inside the Quantum Katas” blog series for examples of testing code that relies on reference solutions), and you don’t really want to include the solution as part of the graded assignment! This meant that the instructors and teaching assistants could use the testing harness to automate the grading process, but the students had to come up with other ways to test their work. This could be challenging at times, especially in the first weeks when the students were exposed to a lot of completely new concepts at once.
For this course, I took the feedback from the past courses to heart and modified the projects to conceal the testing code while allowing the students to execute it. This allowed me to share it with my students without revealing the solutions, and my students – to test their code themselves and to figure out which tasks they needed to focus on.
Debugging quantum programs
Debugging assignments offer the students a quantum program that has a number of bugs of different kinds and ask them to identify and fix them. They aim to improve the students’ familiarity with the software tools they use and with the algorithms covered in the course. I used them during the weeks that covered well-studied algorithms such as BB84 quantum key distribution protocol or Grover’s search, when the students are already familiar with the basics of quantum programming and can focus on the logic behind the program.
Tracking down different types of errors emphasize different aspects of writing and running quantum programs:
- Syntax errors allow the instructor to bring attention to the common mistakes made when writing the code, such as the syntax of the Controlled functor.
- Runtime errors can highlight the requirements to the behavior of quantum programs, for example, the need to measure or uncompute all qubits before releasing them.
- Tracking down logical errors requires the student to focus on understanding the expected algorithm behavior and identifying the deviations from it, such as unexpected results of the key distribution protocol in a small percentage of cases.
Running quantum programs on Azure Quantum
The final type of assignment encourages the students to explore the behavior of quantum programs on the cloud simulators and quantum devices available via Azure Quantum using the free Azure Quantum credits. The tasks were mostly introductory, teaching the students to run Q# programs on cloud targets and to interpret the results rather than diving deep into the hardware.
- For the first two assignments the students had to run a quantum random number generator on the IonQ simulator and quantum device, and to observe the difference between the results: the IonQ simulator produces a perfect 50-50 distribution of probabilities based on the quantum state of the program before measurement, and the quantum device runs the program multiple times and aggregates the outcomes, resulting in a slightly uneven distribution.
- The next assignment introduced the concept of noise in quantum systems, asking the students to run a program that prepared a Bell state and measured both qubits on a quantum device. In addition to the uneven frequencies of 00 and 11 measurement outcomes, the results included non-zero probabilities of 01 and 10 outcomes, which are not possible theoretically and only appear due to the existence of noise.
- In the last assignment the students further explored the behavior of the program on a noisy device, running Grover’s search algorithm for problem instances of increasing size and observing the increasing levels of noise that eventually rendered the correct answers undetectable from the noise-induced ones.
This semester was the first time I introduced Azure Quantum-based assignments. I’m looking forward to improving them and including new tools, such as the recently released Azure Quantum resource estimation tool, in the course!
Check out Azure Quantum for Educators page to see examples of materials developed for the course.