Sinter is a companion library built on top of Stim for high-throughput Monte Carlo sampling of quantum error correction circuits. It handles the repetitive bookkeeping of a QEC experiment — distributing work across CPU cores, adaptively sizing batches, recording running statistics in a resumable CSV file, and plotting results — so you can focus on the circuits and decoders you care about.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.
Installation
sinter also makes the sinter command available on your PATH inside the active virtual environment. You will also need a decoder, for example:
How Sinter works
Sinter takes one or more Stim circuits annotated with noise, detectors, and logical observables. For each circuit it:- Generates the detector error model using
stim.Circuit.detector_error_model(decompose_errors=True). - Configures the specified decoder from the DEM.
- Uses
stimto sample detection events in batches. - Passes each batch to the decoder and counts logical errors.
- Records cumulative statistics (
shots,errors,discards,seconds) per circuit in CSV format. - Repeats until the per-circuit stopping criteria (
max_shotsormax_errors) are satisfied.
Python API workflow
1. Define tasks
Asinter.Task bundles a circuit with optional metadata and decoder hints:
2. Collect statistics
Pass the tasks tosinter.collect(). It returns a list of sinter.TaskStats objects when all stopping criteria are met:
| Parameter | Description |
|---|---|
num_workers | Number of parallel worker processes |
max_shots | Stop sampling a circuit after this many shots |
max_errors | Stop sampling a circuit after this many logical errors |
tasks | Iterable of sinter.Task objects |
decoders | List of decoder names (e.g. ['pymatching']) |
3. Print and plot results
The code inside
sinter.collect() calls must be inside a function guarded by if __name__ == '__main__':. Sinter uses Python multiprocessing, and without this guard the worker subprocesses will re-execute module-level code on startup.Complete example
The following reproduces the example from the Sinter README:CLI usage
- sinter collect
- sinter combine
- sinter plot
Generate circuit files and collect statistics across all of them in parallel:
--metadata_func auto parses filenames like d=3,p=0.001,b=X,type=rotated_surface_memory.stim into a JSON dictionary automatically.--save_resume_filepath enables merge mode: if the process is interrupted, restart it and it will pick up from where it left off without losing data.CSV output format
Each row in the CSV file describes statistics accumulated for one (circuit, decoder) pair over some number of shots. Multiple rows with the samestrong_id can be summed to get total statistics.
| Column | Type | Description |
|---|---|---|
shots | int | Total number of times the circuit was sampled |
errors | int | Number of shots where the decoder predicted the wrong logical observable |
discards | int | Shots discarded due to postselection (not counted as errors) |
seconds | float | Total CPU core-seconds spent sampling and decoding |
decoder | str | Name of the decoder used |
strong_id | str | Cryptographic hash of the circuit, DEM, decoder, and metadata — prevents accidentally merging rows from different circuits |
json_metadata | json | Free-form metadata associated with the task (e.g. {"d": 3, "p": 0.001}) |