Stim handles two of the three tasks in a QEC decoding benchmark: generating the probabilistic error model for the code, and producing batches of noisy syndrome samples. The third task — predicting which logical errors occurred — is performed by an external decoder library. This separation of concerns means you can swap in any decoder without changing your circuit or sampling code.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/quantumlib/Stim/llms.txt
Use this file to discover all available pages before exploring further.
The standard decoding workflow
Build a noisy circuit
Use
stim.Circuit or stim.Circuit.generated to create a circuit annotated with noise, DETECTOR instructions, and OBSERVABLE_INCLUDE instructions.Generate the detector error model
Call The
circuit.detector_error_model(decompose_errors=True) to produce a graphlike DEM that matching decoders can consume directly.decompose_errors=True flag splits hyper-errors (those touching more than two detectors) into pairs of graphlike pieces. This is required by minimum-weight perfect matching decoders such as PyMatching.Configure the decoder from the DEM
Pass the DEM to your decoder of choice. PyMatching, for example, accepts a Stim DEM directly:
Common decoder libraries
PyMatching
Minimum-weight perfect matching decoder. Accepts Stim DEMs directly via
Matching.from_detector_error_model(dem). The most widely used decoder for surface codes and repetition codes.BeliefMatching
Combines belief propagation with matching for improved thresholds on some code families. Also accepts Stim DEMs.
Any decoder that accepts a Tanner graph (or a list of error mechanisms with associated detector sets and probabilities) can be configured from a Stim DEM. The DEM’s
error(p) D… L… instructions map directly to edges in the decoding graph.Full end-to-end example
Verifying circuit correctness before decoding
Before investing in sampling, confirm the circuit has the expected code distance.Shortest graphlike error
circuit.shortest_graphlike_error() finds the minimum-weight set of graphlike errors that create an undetected logical flip. The length of the result equals the graphlike code distance:
Searching for undetectable logical errors (heuristic)
circuit.search_for_undetectable_logical_errors() is a heuristic that can find logical errors involving hyper-edges (non-graphlike errors). It explores the error graph breadth-first but requires truncation parameters to stay tractable:
Tips for production workflows
Pre-generate the DEM once, reuse across batches
Pre-generate the DEM once, reuse across batches
The DEM is deterministic for a fixed circuit. Generate it once, configure the decoder, then call
sampler.sample in a loop across as many batches as needed. Avoid regenerating the DEM inside a hot loop.Use bit-packed arrays for memory efficiency
Use bit-packed arrays for memory efficiency
Pass
bit_packed=True to sampler.sample to receive uint8 arrays instead of bool_ arrays. This reduces memory usage by 8×, which matters at shot counts above ~10^6.Stream shots to disk for very large experiments
Stream shots to disk for very large experiments
Use
sampler.sample_write(shots, filepath=..., format="b8") to stream detection events directly to a file. You can then decode the file in chunks to avoid holding all shots in memory simultaneously.Separate observable output
Separate observable output
Always use
separate_observables=True (or obs_out_filepath with sample_write) to keep ground-truth observable flips separate from the detection events you feed to the decoder. Mixing them causes incorrect error-rate calculations.