Exercises: OpenQASM
Text in, text out. Most of these are quick, and several of them will show you something about your circuits that no other view does.
Difficulty: ⭐ warm-up · ⭐⭐ standard · ⭐⭐⭐ deeper.
Solutions: worked answers to the daggered (†) and odd-numbered problems are in
appendices/answers-to-selected.md; runnable code in
code/exercise-solutions.py.
Part A — Warm-ups ⭐
6.1 † What role does OpenQASM play in the quantum software stack, and what is its closest classical analogue?
6.2 Write the four mandatory or near-mandatory opening lines of an OpenQASM 3 program that uses two qubits and two classical bits.
6.3 † Give the QASM 3 and QASM 2 syntax for measuring qubit 0 into classical bit 0. Which reads as an assignment, and why does that difference matter beyond aesthetics?
6.4 Which Qiskit function replaced qc.qasm()? Name both the QASM 2 and QASM 3 forms.
6.5 † Name two things a QASM 3 round trip does not preserve. Which of the two fails silently?
Part B — Export and Import ⭐⭐
6.6 † Export the Bell circuit to both QASM 2 and QASM 3. List three concrete syntactic differences.
6.7 Write a 4-qubit GHZ state directly in OpenQASM 3 by hand, load it with qasm3.loads, draw it,
and verify the measurement probabilities are what you expect.
6.8 † Build a circuit with one free Parameter and export it to both formats. What does QASM 3
emit? What does QASM 2 do? State the practical consequence for variational work.
6.9 Transpile the Bell circuit for FakeSherbrooke at optimization level 1 and dump the QASM.
From the text alone, report: which physical qubits were used, which gates were defined inline, the
total instruction count, and the number of real pulses (recall rz is virtual).
6.10 † Produce a unified diff of the QASM at optimization levels 0 and 3 for the same circuit. How many lines does each produce? Name two specific things the optimizer removed.
Part C — What Gets Lost ⭐⭐⭐
6.11 † Set global_phase = π/4 on a one-qubit circuit, round-trip it through QASM 3, and report
the phase before and after. Then check the circuit with Operator.equiv and with
np.allclose(Operator(a).data, Operator(b).data). Explain why one passes and one fails, and why that
means an equiv-based round-trip test cannot catch this bug.
6.12 Build a circuit using a ParameterVector of length 3, round-trip it, and report the
parameter names before and after. Then try assign_parameters({"theta[0]": 0.5}) on the restored
circuit and record the exact error. Finally, write a normalize() function that lets you match
original names to mangled ones, and verify it on all three.
6.13 † Build a circuit containing a custom gate (via to_gate()), export it, and examine the
QASM. Does the custom gate survive as a named gate or get flattened? Verify the unitary is preserved.
6.14 Write check_round_trip(qc, mod, exact) that asserts a circuit survives serialization, with
exact controlling whether global phase is compared. Test it on three circuits: a plain Bell state,
one with a nonzero global phase, and one containing a Toffoli. Which circuit distinguishes the two
settings, and what does that tell you about choosing a default?
6.15 † Demonstrate the consequence of the global-phase loss. Build a one-qubit subcircuit with
global_phase = π, archive and restore it through QASM, then use both versions as a controlled
operation inside h(0); c-U; h(0); measure(0). Report both count dictionaries. Explain the result in
terms of phase kickback.
Part D — Interchange and Tooling ⭐⭐⭐
6.16 Compare QASM 2 and QASM 3 on five axes of your choosing and produce a decision table. For each of these tasks, state which format you would use and why: (a) archiving a variational ansatz, (b) sending a static circuit to a collaborator using an unknown toolchain, (c) recording exactly what ran on hardware, (d) expressing a dynamic circuit with mid-circuit measurement.
6.17 † Take a circuit containing if_test classical control. Export to QASM 3 (it works) and to
QASM 2 (it does not). Report the exact error. Then explain what property of QASM 2 makes this
impossible rather than merely unimplemented.
6.18 Serialize the same circuit with QASM 3 and with QPY (qiskit.qpy). Compare: file size,
human readability, whether the global phase survives, and whether the file would be readable by a
non-Qiskit tool. Write a two-sentence policy for when to use each.
6.19 † The chapter warns that specification-valid QASM 3 may still be rejected by a tool claiming QASM 3 support. Design a minimal compatibility test suite — a set of small circuits exercising increasingly advanced features — that you could run against any new tool to find out what it actually supports. List at least five circuits and what each one probes.
6.20 Write a function that takes a transpiled circuit and returns a structured report from its QASM alone: physical qubits used, inline gate definitions, operation counts split into real and virtual, and whether any SWAPs were inserted relative to the original. Test it on a 5-qubit GHZ circuit at two optimization levels.
Part E — Project ⭐⭐
6.21 † Implement the Chapter 6 🧱 Project Checkpoint: vqelab/qasm.py with to_qasm,
from_qasm, archive, restore, and check_round_trip, recording both the global phase and the
original parameter names as comments.
6.22 Archive your Chapter 4 two-qubit ansatz to a file and restore it. Verify that the parameter
names come back as theta[0] through theta[3] and that the circuit is exactly equivalent.
6.23 ⭐⭐⭐ The checkpoint records lost information in comments. Argue both sides: what is good about using comments (portability, parsers ignore them) and what is fragile about it (nothing enforces them, a reformatting tool could strip them, another tool will not know to look). Then propose a more robust alternative and say what it costs.