Week 12 | the code that runs on today's hardware, why bigger becomes better below a threshold, and what it takes to compute on encoded qubits | Lab 6 launches today | reading: Watrous Ch. 15.2–16; Google Quantum AI (2024), abstract and Figs. 1–3
Lecture 22's codes need checks on qubits that may be far apart. Superconducting chips, like most hardware, connect only nearby qubits. The surface code needs only nearest-neighbour checks on a square grid, has one of the highest thresholds of any practical code, and is what Google and others run today. By the end of this lecture you should be able to describe its layout and logical operators, explain how a matching decoder works, state the threshold theorem and use the suppression factor \(\Lambda\) to estimate how large a code must be, interpret the 2024 below-threshold experiment, and explain why fault-tolerant computation needs more than a good memory.
Place qubits on the edges of an \(L\times L\) square grid wrapped into a torus (\(2L^2\) qubits). For each vertex \(v\), the star operator \(A_v\) is \(X\) on the four edges meeting at \(v\); for each face \(f\), the plaquette operator \(B_f\) is \(Z\) on the four edges around \(f\). The toric code is the stabilizer code of all \(A_v\) and \(B_f\).
A star and a plaquette share either zero or two edges, so all checks commute (Proposition 22.1). The product of all stars is \(I\), and so is the product of all plaquettes, so only \(2L^2-2\) checks are independent: \(k=2\) logical qubits. Each check acts on 4 nearby qubits, however large \(L\) is.
A toric code is built on a \(6\times6\) torus. How many physical qubits does it use, and how many of its checks are independent?
The geometry explains everything else. A string of \(Z\) errors along a path of edges anticommutes only with the stars at its two endpoints: the checks light up in pairs, at the ends of error chains. A closed loop of \(Z\)s is invisible. If the loop can be shrunk to a point it is a product of plaquettes, a stabilizer, and harmless. If it wraps around the torus it cannot be shrunk, and it is a logical operator. So the distance is \(L\), the length of the shortest non-contractible loop, and the code has parameters \([[2L^2,2,L]]\).
A closed loop of \(Z\) errors wraps once around the torus. What happens?
Real chips are flat, not toroidal. The surface code cuts the torus open; logical operators then run from one boundary to the opposite one, instead of around a loop. The version used in practice, the rotated surface code, puts data qubits on a \(d\times d\) grid and one measure qubit in each plaquette.
Data qubits sit on a \(d\times d\) grid. The squares between them are coloured like a checkerboard, alternately carrying \(X\)-type and \(Z\)-type stabilizers on their four corner qubits. Along two opposite edges, half-squares (two qubits) carry \(X\)-type checks, and along the other two edges \(Z\)-type checks. For \(d=5\) this gives 25 data qubits and 24 checks, half of each type, each measured with its own measure qubit: 49 physical qubits for one logical qubit of distance 5. (HW12 asks you to count in general.) Logical operators are strings of one Pauli type joining the two boundaries of the other type; the figure marks one of each for \(d=5\).
The code encodes one logical qubit (HW12 Problem 1 checks the count). The logical operators have weight \(d\), and no shorter Pauli connects opposite edges without being caught, so this is a \([[d^2,1,d]]\) code, correcting \(\lfloor(d-1)/2\rfloor\) errors. Distance 5 corrects any 2 errors; distance 7, any 3.
The syndrome of the surface code does not point at an error the way the Hamming syndrome does: it shows only the endpoints of error chains, called defects (checks returning \(-1\)). The decoder's task is to guess chains that explain the defects. A chain may also end on a boundary of the matching type, which lights only one check. Since errors are rare, the most likely explanation is the one with the fewest errors: pair up the defects (or pair a defect with a boundary) so that the total length of the connecting paths is minimal. This is the minimum-weight perfect matching problem on a graph, which Edmonds' blossom algorithm solves in polynomial time.
Four defects sit on a line at positions 0, 1, 5 and 6 (the distance between two defects is the difference of their positions; ignore the boundaries). What is the total length of the minimum-weight matching?
The decoder succeeds when the guessed chains and the real ones together form only closed loops (stabilizers), and fails when together they connect opposite boundaries, completing a logical operator. With \(\lfloor(d-1)/2\rfloor\) or fewer errors the matching always succeeds; with more, it often still does, which is why the code performs better than its distance alone suggests.
The decoder flips a set of qubits that is completely different from the set that actually had errors. Then the encoded qubit is
Real decoders face two extra problems. Measurements themselves fail, so a defect may be a measurement error rather than a data error (Section 6). And decoding must keep up with the hardware: one round every microsecond or so. PyMatching (the decoder of Lab 6) implements a fast "sparse blossom" matching; belief-propagation and neural-network decoders trade speed for accuracy in other ways.
For a family of codes like the surface code, a decoder, and a noise model in which each physical operation fails independently with probability \(p\), there is a threshold \(p_{\text{th}}\gt0\) such that for \(p\lt p_{\text{th}}\) the logical error rate falls exponentially in the distance:
$$\varepsilon_d\approx A\left(\frac p{p_{\text{th}}}\right)^{(d+1)/2}.$$Above threshold, larger codes are worse. For the surface code with matching decoders and realistic circuit-level noise, \(p_{\text{th}}\) is around 1%.
A device runs with \(p\) above \(p_{\text{th}}\). Replacing its distance-5 code by a distance-7 code makes the logical error rate .
The same shape as the repetition code of Lecture 21 (threshold \(\tfrac12\) there): \(\lfloor(d-1)/2\rfloor+1=(d+1)/2\) errors are needed to cause a logical error, each with probability about \(p\). The ratio for each step of 2 in distance is the suppression factor
$$\Lambda=\frac{\varepsilon_d}{\varepsilon_{d+2}}\approx\frac{p_{\text{th}}}{p}.$$\(\Lambda\gt1\) means "below threshold": growing the code helps. Because \(\Lambda\approx p_{\text{th}}/p\), every increase of \(d\) by 2 then divides the logical error rate by \(\Lambda\).
A device has \(p_{\text{th}}=1\%\) and physical error rate \(p=0.2\%\). Estimate \(\Lambda\), and the ratio \(\varepsilon_9/\varepsilon_3\) of logical error rates.
A device achieves a logical error rate of \(10^{-3}\) per round at \(d=3\). An algorithm needs \(10^{-10}\) per round per logical qubit. Find the distance and the number of physical qubits per logical qubit if \(\Lambda=2\), and if \(\Lambda=3\).
We need \(10^{-3}/\Lambda^m\le10^{-10}\), with \(d=3+2m\). For \(\Lambda=2\): \(2^m\ge10^7\), so \(m\ge\log_210^7\approx23.3\), \(m=24\), \(d=51\), and \(2d^2\approx5{,}200\) physical qubits per logical qubit. For \(\Lambda=3\): \(3^m\ge10^7\), \(m\ge14.7\), \(m=15\), \(d=33\), about \(2{,}200\) physical qubits.
In August 2024 Google Quantum AI reported surface-code memories on its 105-qubit Willow processor (published online in Nature in December 2024), and this is the result to read critically.
With Willow's \(\Lambda=2.14\), by what factor is the logical error rate per cycle at \(d=3\) larger than at \(d=7\)?
If \(\Lambda=2.14\) held at larger distances, what distance would bring the per-cycle logical error rate from \(0.143\%\) at \(d=7\) down to \(10^{-6}\)? How many physical qubits is that?
\(1.43\times10^{-3}/2.14^m\le10^{-6}\) needs \(m\ge\ln1430/\ln2.14\approx9.6\), so \(m=10\) and \(d=27\), about \(2d^2\approx1{,}460\) physical qubits for one logical qubit. That is one logical qubit at an error rate still far above what Shor's algorithm needs (Lecture 17), and it assumes that no new error source (cosmic rays, leakage, correlated errors) appears at scale. Google observed rare correlated error bursts that set a floor near \(10^{-10}\) in repetition-code tests.
Noisy syndrome extraction. Each check is measured by a small circuit (four CNOTs or CZs into a measure qubit), and any of its gates can fail. A single measurement error looks exactly like a data error, so one round of checks cannot be trusted. Instead the checks are measured repeatedly, about \(d\) rounds, and the decoder works with detectors: changes of a check's value between consecutive rounds. A data error lights the same detector pair in space; a measurement error lights a pair of detectors in time (the check flips and flips back). Matching then runs on a three-dimensional space–time graph. A circuit is fault tolerant when no single faulty component can cause an uncorrectable error, which requires care with the order of the CNOTs (a single fault on a measure qubit can spread to two data qubits, a "hook" error).
One check's detectors fire in two consecutive rounds, and no other detector nearby fires. The most likely cause is a single .
Logical gates. A memory is not a computer. Some gates are easy on CSS codes: a CNOT between two code blocks, applied qubit by qubit (transversally), is a logical CNOT, and transversal gates cannot spread one error into two errors within a block. On the surface code, logical CNOTs are done by lattice surgery, merging and splitting patches by measuring joint checks along their boundary. But no code has a universal set of transversal gates (the Eastin–Knill theorem), and the Clifford gates alone are classically simulable (Lecture 22). The missing ingredient is a non-Clifford gate such as \(T\).
Magic states. The standard solution prepares special states such as \(T|+\rangle\) ("magic states") at low quality, purifies them (magic-state distillation: for example, 15 noisy copies give 1 better one), and consumes one per \(T\) gate by a teleportation-like circuit. Distillation factories once dominated resource estimates; magic-state cultivation (Gidney, Shutty and Jones, 2024) grows a high-quality magic state inside a single surface-code patch at a fraction of the cost, one of the three ideas behind Gidney's 2025 RSA estimate (HW9).
Tick every true statement about computing with surface-code logical qubits.
The surface code encodes one logical qubit per patch, which is why each logical qubit costs \(\sim2d^2\) physical ones. Quantum LDPC codes keep checks of bounded weight but allow long-range connections, and encode many logical qubits per block. IBM's "gross" bivariate-bicycle code \([[144,12,12]]\) (Bravyi et al., Nature 2024) stores 12 logical qubits at distance 12 in 288 physical qubits (data plus check), roughly a tenth of what the surface code would need, at the price of couplers between distant qubits. Neutral-atom and trapped-ion devices, whose qubits can move, have demonstrated tens of logical qubits running small encoded circuits: for example, up to 48 logical qubits in error-detecting codes on a neutral-atom array (Bluvstein et al., Nature 2024).
import numpy as np, stim, pymatching
d, p = 5, 0.001
circ = stim.Circuit.generated("surface_code:rotated_memory_z", distance=d, rounds=d,
after_clifford_depolarization=p, before_round_data_depolarization=p,
before_measure_flip_probability=p, after_reset_flip_probability=p) # circuit-level noise, all at p
coords = circ.get_final_qubit_coordinates()
print(f"d = {d}: {len(coords)} qubits, {circ.num_detectors} detectors, {circ.num_observables} logical observable")
dem = circ.detector_error_model(decompose_errors=True) # which errors flip which detectors
matcher = pymatching.Matching.from_detector_error_model(dem)
det, obs = circ.compile_detector_sampler(seed=23).sample(200_000, separate_observables=True)
pred = matcher.decode_batch(det)
fails = np.sum(pred[:, 0] != obs[:, 0])
print(f"{fails} logical errors in 200,000 runs of {d} rounds: {fails/200_000:.2e} per run, about {fails/200_000/d:.1e} per round")
print("mean number of detection events per run:", round(det.sum(axis=1).mean(), 2))
d = 5: 49 qubits, 120 detectors, 1 logical observable 27 logical errors in 200,000 runs of 5 rounds: 1.35e-04 per run, about 2.7e-05 per round mean number of detection events per run: 1.76
stim.Circuit.generated writes the whole experiment: reset, \(d\) rounds of syndrome extraction with the chosen noise, and a final measurement of the data qubits, with detectors and the logical observable annotated. detector_error_model lists every fault and the detectors it flips, which is exactly the matching graph. At \(p=10^{-3}\), well below threshold, \(d=5\) fails about once in 7,000 runs of 5 rounds. Lab 6 sweeps \(p\) and \(d\) to find the threshold and \(\Lambda\).
import math
def distance_needed(eps_ref, d_ref, Lam, target):
"""Smallest odd d >= d_ref with eps_ref / Lam**((d - d_ref)/2) <= target."""
m = max(0, math.ceil(math.log(eps_ref / target) / math.log(Lam)))
return d_ref + 2 * m
for name, eps, dref, Lam, target in [("Example 23.1, Lambda = 2", 1e-3, 3, 2, 1e-10),
("Example 23.1, Lambda = 3", 1e-3, 3, 3, 1e-10),
("Willow extrapolated", 1.43e-3, 7, 2.14, 1e-6)]:
d = distance_needed(eps, dref, Lam, target)
print(f"{name:26s}: d = {d:3d}, about 2d^2 = {2 * d * d:6d} physical qubits per logical qubit")
Example 23.1, Lambda = 2 : d = 51, about 2d^2 = 5202 physical qubits per logical qubit Example 23.1, Lambda = 3 : d = 33, about 2d^2 = 2178 physical qubits per logical qubit Willow extrapolated : d = 27, about 2d^2 = 1458 physical qubits per logical qubit
Next time: near-term algorithms and honest advantage, and the course wrap-up. HW11 is due at the start of Week 13; HW12 is posted after Lecture 24.
Lab 6 simulates repetition-code and surface-code memories with Stim, decodes them with PyMatching, finds the thresholds, fits \(\Lambda\) below threshold, compares it with Willow's, and estimates the overhead of one logical qubit at \(10^{-12}\). No hardware: Stim runs millions of shots per second.
all numbers and figures in these notes are computed in python (verify_L23.py, threshold_data.py) and follow the page theme