Exercises: Debugging Quantum Programs
These need qiskit, qiskit-aer, and qiskit-ibm-runtime (for the fake backends). Solutions to
starred exercises are in Answers to Selected Exercises.
A standing rule for this chapter: any tool you build here must be tested against a case where you already know the answer, in both directions — one circuit it should pass and one it should fail. Case Study 2 is what happens otherwise.
Seeing the state
26.1 ★ Write prefix(qc, k) and use it to print the state after every instruction of a
five-gate circuit. Confirm the last prefix equals the whole circuit.
26.2 ★ Use save_statevector to capture the state at three points inside an Aer run, and confirm
the values match what prefix gives.
26.3 ★ Assert norm preservation at every prefix of a circuit. Then break it by appending a hand-built non-unitary matrix and confirm the assertion fires.
26.4 ★★ Compute the memory a state vector needs at 20, 30, 34, and 40 qubits. At what qubit count does statevector debugging stop being possible on your machine? Measure it, do not estimate.
26.5 ★★ For a Clifford-only circuit at 30 qubits, compare the runtime of Aer's statevector and
stabilizer methods (Chapter 11). Which debugging techniques survive the switch?
Which equality test
26.6 ★ Build $XZXZ$ and the identity, and evaluate all four equality tests from §26.3. Explain why they disagree.
26.7 ★ Control both circuits and re-run the tests. Which results change, and why?
26.8 ★★ Write equality_verdict(a, b, will_be_controlled) with no default for the flag.
Explain in a docstring why a default would be wrong.
26.9 ★★ Find a pair of circuits that Statevector.equiv calls equal but process_fidelity does
not, or prove no such pair exists.
26.10 ★★★ Chapter 18 found that framework translation loses global phase. Translate a circuit Qiskit → Cirq → Qiskit, confirm the global phase changed, then control the result and show the change became observable.
Bisection
26.11 ★ Implement operator-based bisection and use it to find a deliberately planted wrong angle in a seven-gate circuit.
26.12 ★ Confirm the comparison count is $\lceil\log_2 n\rceil + 1$ rather than $n$.
26.13 ★★ Verify that divergence is monotone — compute it at every prefix and confirm that once it becomes true it stays true. Why does bisection require this?
26.14 ★★ Reproduce §26.4's failure: bisect on states from $|000\rangle$ and confirm no divergence is found for a circuit that definitely differs.
26.15 ★★ Do the same from $|{+}{+}{+}\rangle$. Trace through the circuit and explain why this one is blind for a different reason than $|000\rangle$.
26.16 ★★ Count the blind fraction: all 8 computational basis states, all 27 states over $\{0,1,+\}$, and 100 random states. Reproduce 4/8, 11/27, and 0/100.
26.17 ★★ Characterize the blind basis states. What do 000, 010, 100, 110 have in common,
and why does that make them blind to this bug?
26.18 ★★★ Plant the bug on a different pair of qubits and re-count. Does the blind fraction stay at 41%? What determines it?
26.19 ★★★ Extend bisection to circuits of different instruction counts (the reference was rewritten, not just edited). What is the right notion of "first divergence" then, and what does your answer cost?
The gallery
26.20 ★ Build two circuits differing only by qubit-ordering convention and confirm
Operator(a) == Operator(b.reverse_bits()). Then confirm the test correctly rejects a pair that
genuinely differ.
26.21 ★ Reproduce the dirty-ancilla measurement: purity 1.0000 with uncomputation and 0.6250 without. Derive 0.6250 by hand.
26.22 ★★ Build all four QFT conventions and score them against QFTGate with process_fidelity.
Confirm exactly one scores 1.0, and explain why the other three score 0.2500, 0.1547, 0.2500.
26.23 ★★ Write count_ops_diff and use it to catch the deleted id gate from Chapter 25.
26.24 ★★ Write ancilla_report and apply it to Chapter 19's oracles. Do any of them leave an
ancilla dirty?
26.25 ★★★ Build a circuit whose only defect is a dirty ancilla, run it on a noisy simulator, and show that the output is indistinguishable from the clean circuit run with more noise. This is why §26.1's fourth claim matters.
What actually runs
26.26 ★ Transpile a 3-qubit circuit for FakeManilaV2 and print initial_index_layout() and
final_index_layout(). Which physical qubit holds your logical qubit 0 at the start? At the end?
26.27 ★★ Reproduce Case Study 2: compute the fidelity ignoring the layout (0.001406) and with
Operator.from_circuit (1.0000000000).
26.28 ★★ Transpile the same circuit for FakeSherbrooke and confirm Operator.from_circuit
raises. What is the largest backend for which the check is possible on your machine?
26.29 ★★ Give your verify_transpilation a positive and a negative control, as §Case Study 2
recommends. What does the negative control need to be to be meaningful?
26.30 ★★★ Transpile a circuit at optimization levels 0–3 and verify each. Do all four preserve the unitary? Should they?
Project
26.31 ★★ (Project Checkpoint) Build vqelab/debugging.py with prefix, bisect returning a
BisectionResult with a three-valued verdict, equality_verdict, ancilla_report, count_ops_diff,
is_bit_order_only, and verify_transpilation. Write tests asserting:
prefixtruncates correctly and rejects out-of-range $k$.- Operator bisection finds the planted bug at instruction 5.
- The comparison count is logarithmic.
- Identical circuits report
AGREE. - Bisecting from $|000\rangle$ reports
BLIND, notAGREE, andtrustworthyisFalse. - $|{+}{+}{+}\rangle$ reports
BLINDtoo. - Exactly 4 of the 8 computational basis states are blind, and they are
000/010/100/110. - 11 of 27 structured states are blind; 0 of 100 random ones are.
- Divergence is monotone.
bisectrejects mismatched instruction counts.equality_verdictgives opposite answers for controlled and uncontrolled use, and has no default for the flag (check withinspect.signature).ancilla_reportgives purity 1.0000 clean and 0.6250 dirty.is_bit_order_onlyaccepts a convention mismatch and rejects a real difference.count_ops_difffinds the deletedid.- Exactly one QFT convention scores 1.0.
verify_transpilationreturns 1.0 with the layout applied, and the naive comparison returns below 0.01.verify_transpilationRAISES on a 127-qubit backend rather than returning a wrong number.
Tests 5, 7, 8, 11 and 17 are the ones this chapter exists to encode.
26.32 ★★★ Add bisect_hardware(suspect, reference, backend, shots) that bisects using measured
distributions rather than states, with a statistical test for divergence. How many shots does each
comparison need, and what is the total cost against §26.4's operator version?
Going further
26.33 ★★ Implement state tomography for one and two qubits, and confirm the $3^n$ setting count. Extrapolate to 20 qubits.
26.34 ★★★ Take a bug from any earlier chapter — Chapter 16's barren-plateau artifact, Chapter 22's non-monotonic estimator, Chapter 23's factor-of-160 — and write the one diagnostic that would have caught it immediately. Which of them are catchable by anything in this chapter, and which needed something else?
26.35 ★★★ §26.9's protocol is simulator-first. Design the hardware-side equivalent: given only counts from a device, list the checks you can actually run and what each one rules out. Then apply it to Chapter 24's VQE.