Guides · 1 of 5 · 5 min read

Quick start

Build a toric code, inject an error, decode it, and measure a logical error rate — with no external dependencies.

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:

shell
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 explainedhz_syndrome(correction) == syndrome. A correct decoder always satisfies this.
  • The correction is in the right cosetis_logical_failure(error, correction) is False. This is what actually counts: a correction can explain the syndrome yet still apply a logical operator.
quickstart.py
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.

ler.py
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.