This first guide needs nothing but Glean itself — no Stim, no NumPy. You will construct a toric code, hand it a known error, recover a correction, and then measure a logical error rate by Monte-Carlo. It is the plumbing warmup before the real circuit-level workflow.
1 · Build & import
Glean is a Rust core exposed through Python. Build it into your active environment and confirm the import works:
maturin develop --release
python -c "import glean; print(glean.__version__)"That compiles the extension (glean.glean) and installs the glean package.
A plain import glean pulls in no third-party dependencies.
2 · Construct a code
glean.toric_code(l) builds the distance-l toric code [[2l², 2, l]]. The returned Code object carries its parity-check
structure and a decoder. Decoding here targets the X-error sector: the syndrome comes from the
Z-stabilizers (Hz), and a logical failure is measured against rowspace(Hx).
3 · Inject an error
An X error is a length-n bitstring over the qubits. Its syndrome is the
set of Z-stabilizers it violates — that is the only thing a real decoder ever sees. code.hz_syndrome(error) computes it.
4 · Decode & verify
code.decode(syndrome, p=...) runs belief propagation with the validated
OSD-CS-10 post-processor and returns a correction. Two checks matter, and they are different:
- The syndrome is explained —
hz_syndrome(correction) == syndrome. A correct decoder always satisfies this. - The correction is in the right coset —
is_logical_failure(error, correction)isFalse. This is what actually counts: a correction can explain the syndrome yet still apply a logical operator.
import glean
code = glean.toric_code(4) # [[32, 2, 4]] toric code
error = [0] * code.n
error[5] = 1 # a single-qubit X error
syndrome = code.hz_syndrome(error)
correction = code.decode(syndrome, p=0.05) # BP + OSD-CS-10
assert code.hz_syndrome(correction) == syndrome # the syndrome is explained
failed = code.is_logical_failure(error, correction) # did we land in the wrong coset?p is the per-qubit prior the decoder assumes. It need not equal the true physical
error rate, but matching it is the usual choice.
5 · Measure a logical error rate
A single decode is an anecdote; the number researchers report is a logical error rate (LER) over many random errors. glean.simulate_toric runs that code-capacity
Monte-Carlo for you and returns the count, the rate, and its standard error.
failures, shots, ler, stderr = glean.simulate_toric(l=6, p=0.05, shots=5000)
print(f"logical error rate = {ler:.2e} +/- {stderr:.1e} ({failures}/{shots})")This is exactly how Benchmark B1 is built. Sweeping l and p and finding where the curves cross reproduces Roffe 2020's
9.9 ± 0.2% toric threshold — Glean lands at ≈10.0–10.1%, in-band.
B1 — toric threshold reproduced in-band.
Where to next
Code-capacity noise is the warmup. Real devices emit a stream of syndrome measurements with correlated, circuit-level noise — and that is described by a Stim detector error model. The next guide ingests one and decodes batches of real syndromes entirely in Rust.