dist-m4ri is a high-performance multithreaded C program and Python library for computing and bracketing the minimum distance of binary classical linear codes, quantum CSS codes, and Stim Detector Error Models (DEMs).
The program implements three main methods:
-
Method 1 (
method=1) - Random Window (RW) Algorithm: Multithreaded random information set search to find low-weight non-trivial codewords and establish an upper distance bound$d_{\max}$ . -
Method 2 (
method=2) - Connected Cluster (CC) Algorithm: Multithreaded exhaustive depth-first cluster enumeration to compute exact distance or establish a certified lower distance bound$d_{\min}$ . -
Method 3 (
method=3) - Bracketing Mode (Artillery Fork / Вилка): Concurrently runs CC and RW on multiple threads, dynamically balancing CPU cores between CC and RW based on current bounds$[d_{\min}, d_{\max}]$ , distance estimate (dexp/dest), remaining RW steps, timeout, and the measured scaling characteristics of CC.
For a classical binary linear code, only the parity-check matrix
For a quantum CSS code, matrix finG) or logical operators finL) are needed.
Alternatively, a detector error model file from stim can be specified using fdem=[str].
All matrices with entries in
dist-m4ri strictly separates machine-parseable results from informational progress logs:
stdout: Outputs three space-separated integers:dmin dmax rw_stepsdmin - 1is the maximum cluster size analyzed without success by CC (dmin = dmaxif CC found a minimum-weight codeword).dmaxis the weight of the smallest non-trivial codeword found by RW (0if none found).rw_stepsis the number of completed RW steps across all threads (0if CC found a minimum-weight codeword, or if RW did not run inmethod=2).- When
dmin = dmax = d, the exact code distance is confirmed.
Note on Compatibility: This 3-number output format (
dmin dmax rw_steps) is specific to the multithreadeddist_m4riand is incompatible with the legacy single-threadeddist_m4ri_old(which returned a single integerdor-w).
stderr: Receives all status banners, thread balancing reports, CC round timings, RW discovery logs, warnings, and confinement profiles.
Searches for low-weight non-trivial binary codewords
Relevant parameters:
-
steps=[int]: Total number of information sets / RW rounds across all threads (default: 1). -
wmin=[int]: Minimum distance of interest (stop immediately when a codeword of weight$w \le w_{\min}$ is found). -
threads=[int]: Number of POSIX threads to run (default: number of CPU cores). -
timeout=[sec]: Maximum execution time in seconds (default: 60.0).
Recursively explores connected clusters starting from each column noscan=0 (default), CC scans weights outC is specified, CC exhausts all columns for weight
Relevant parameters:
-
wmax=[int]: Maximum cluster weight to search (optional iftimeout>0ordmax>0is specified; otherwise required for CC). -
noscan=[int]: If set to 1, start CC directly at$w_{\max}$ without scanning smaller weights. -
cbeg=[int],cend=[int]: Column range$[c_{\text{beg}}, c_{\text{end}}]$ to limit the CC search space. -
start=[int]: Set$c_{\text{beg}} = c_{\text{end}} = \text{start}$ (useful for cyclic or symmetric codes). -
smax=[int]: Maximum syndrome weight to track for confinement profile (default: 5; set 0 to disable).
Dynamically partitions the available thread pool between CC (pushing
-
Target Search Depth:
- Before RW discovers a candidate codeword,
$d_{\max}$ is unknown. Providingdexp=D(alias:dest=D) tells the coordinator to plan CC verification up to target weight$D - 1$ (or$D$ ).
- Before RW discovers a candidate codeword,
-
Predictive Workload Modeling:
- The coordinator measures empirical single-thread speed for RW steps (
$t_{\text{RW}}$ ) and fits exponential growth to completed CC rounds to estimate time$T_{\text{CC}}$ required to reach$\min(d_{\max}, d_{\exp})$ . - It computes the remaining work ratio:
$$\text{ratio} = \frac{T_{\text{CC}}}{T_{\text{CC}} + T_{\text{RW}}}$$ and dynamically splits threads at each round:$$N_{\text{CC}} = \text{round}(N_{\text{threads}} \times \text{ratio}), \quad N_{\text{RW}} = N_{\text{threads}} - N_{\text{CC}}$$ -
Small
$d_{\exp}$ : CC requires little work, so only 1–2 threads run CC while the majority maximize RW sampling speed. -
Heavier rounds: As
$w$ grows toward$d_{\exp}$ ,$T_{\text{CC}}$ increases and additional threads are shifted to CC to ensure both algorithms converge on the exact distance simultaneously.
- The coordinator measures empirical single-thread speed for RW steps (
-
Adaptive Early Cutoff:
- If CC reaches
$w > d_{\exp}$ before a codeword is found, CC halts and yields 100% of threads to RW. - If a projected CC round is estimated to exceed the remaining
timeout, the coordinator terminates CC early and devotes remaining time entirely to RW.
- If CC reaches
Relevant parameters:
-
dexp=[int](alias:dest=[int]): Expected code distance to guide target search depth and thread allocation. -
threads=[int]: Number of worker threads (default: hardware concurrency). -
timeout=[sec]: Maximum execution time in seconds (default: 60.0). -
steps=[int]: Maximum total RW steps (default: 1000). -
dW=[int]: Extra weight window above$d_{\min}$ to continue collecting codewords ($w \le d_{\min} + \text{dW}$ ).
With smax > 0 (default: smax=5), the CC algorithm tracks the minimum non-zero syndrome weight observed for each cluster weight
$ ./src/dist_m4ri method=2 finH=./examples/surf_d5_H.mmx finL=./examples/surf_d5_L.mmx wmax=4 debug=0 threads=4
# confinement: 1,1,1,1
5 0 0With debug=1, detailed per-weight lines are printed to stderr:
# w=1 min non-zero syndrome weight 1
# w=2 min non-zero syndrome weight 1
# w=3 min non-zero syndrome weight 1
# w=4 min non-zero syndrome weight 1
-
outC=[file.nz]: Saves all unique discovered codewords in standard NZLIST format:(Indices are 1-based).%% NZLIST % generated by dist_m4ri <weight> <col_1> <col_2> ... <col_weight> -
finC=[file.nz]: Reads initial codewords from a file to initialize$d_{\max}$ and the codeword hash table. -
dW=[int]: When set (e.g.dW=1), preserves and exports codewords of weight up to$w \le d_{\min} + \text{dW}$ . -
maxC=[int]: Limits collection to at mostmaxCunique codewords.
$ ./src/dist_m4ri --help
./src/dist_m4ri: distance of a classical or quantum CSS code
usage: ./src/dist_m4ri parameter=value [...]
Required parameter:
method=[int]: bitmap for method used (no default):
1: random window (RW) algorithm. Options:
steps=[int]: how many information sets to use (1000)
wmin=[int]: minimum distance of interest (1)
immediately stop and return '-w' on a cw of weight w<=wmin
use this option to quickly scan over a large number of codes
2: connected cluster (CC) algorithm. Options:
wmax=[int]: maximum cluster weight to construct, inclusive (0)
optional if timeout>0 or dmax>0 is set; otherwise required for CC only
smax=[int]: maximum syndrome weight of interest, inclusive (5)
must be non-zero to calculate confinement profile
start=[int]: use only this position to start (equiv. to cbeg=cend=start) (-1)
cbeg=[int]: start column to begin CC search (-1)
cend=[int]: end column to limit CC search (-1)
noscan=[int]: start CC directly with wmax (0)
3: bracketing mode (balanced concurrent RW and CC)
Execution and multithreading parameters:
threads=[int]: number of threads to use (0 for auto CPU count) (0)
timeout=[sec]: timeout in seconds (60.0)
dexp=[int]: expected distance value for method=3 (alias: dest) (0)
Distance bounds parameters:
dmin=[int]: known lower bound on distance, inclusive (w starts from dmin in CC) (1)
dmax=[int]: known upper bound on distance, inclusive (RW ignores codewords of weight >= dmax) (0)
General parameters:
fdem=[str]: detector error model (DEM) file from stim (NULL)
pmin=[float]: minimum error probability to keep for DEM (0.0)
finH=[str]: parity check matrix Hx (NULL)
finG=[str]: matrix Hz (quantum CSS code only) (NULL)
finL=[str]: matrix Lx (quantum CSS code only) (NULL)
Either L=Lx or G=Hz matrix is required for a quantum CSS code
fin=[str]: base name for input files ("try")
set finH->"${fin}X.mtx" finG->"${fin}Z.mtx"
css=[int]: reserved for future use (1)
seed=[int]: rng seed [use 0 for time(NULL)] (0)
debug=[int]: bitmap for aux information to output (3)
0: clear the entire debug bitmap to 0.
1: output misc general info (on by default)
2: output more general info (on by default)
4: debug command line arguments parsing
8: output progress reports every 1000 steps
16: output new min-weight codewords found (cut large vectors)
32: output matrices (unless n is large)
64: debug confinement hash updates (swei changes)
128: debug duplicate syndromes in confinement hash (debug build only)
256: reserved
512: reserved
1024: reserved
2048: allow big matrix / large vector output
see the source code for more options
Multiple 'debug' parameters are XOR combined except for 0.
Use debug=0 as the 1st argument to suppress all debug messages.
-h gives this help (also '--help')# 1. Classical linear code using 8 threads in bracketing mode
$ ./src/dist_m4ri method=3 finH=./examples/c204H.mmx dest=10 steps=100000 threads=8 debug=0
8 8 2340
# 2. Stim Detector Error Model (DEM) with timeout and codeword export
$ ./src/dist_m4ri method=3 fdem=./examples/surf_d3.dem dexp=3 outC=cws.nz threads=4 debug=0
3 3 1000
# 3. Quantum CSS code (Hx and Lx) using pure CC search up to wmax=5
$ ./src/dist_m4ri method=2 finH=./examples/surf_d5_H.mmx finL=./examples/surf_d5_L.mmx wmax=5 debug=0 threads=4
# confinement: 1,1,1,1,1
5 5 0A Python module dist_m4ri.py is included for high-level scripting, NumPy/SciPy integration, and Stim interoperability without manual threading overhead.
-
compute_classical_distance(H, ...): Minimum distance of a classical linear code (from NumPy 2D array, SciPy sparse matrix, or.mtxfile). -
compute_css_distance(Hx, Hz, Lx=None, Lz=None, ...): Distance$d = \min(d_X, d_Z)$ of a CSS quantum code. -
compute_dem_distance(dem=None, circuit=None, ...): Minimum distance directly from astim.DetectorErrorModel,stim.Circuit, or.demfile. -
read_sparse_vectors(filepath): Parses NZLIST files into lists of 0-based integer support indices. - Distance caching:
enable_distance_cache(),disable_distance_cache(),clear_distance_cache(). - Optional solver backend:
solver="codedistance"(uses thecodedistancelibrary if installed).
import numpy as np
import stim
import dist_m4ri
# 1. Classical Code Distance
H = np.array([
[1, 0, 0, 1, 1, 0, 1],
[0, 1, 0, 1, 0, 1, 1],
[0, 0, 1, 0, 1, 1, 1]
], dtype=np.int8)
d = dist_m4ri.compute_classical_distance(H, threads=4)
print(f"Hamming code distance: {d}") # 3
# 2. Stim DEM / Circuit Distance with Codewords
circuit = stim.Circuit.generated(
"surface_code:rotated_memory_z",
rounds=3,
distance=3,
after_clifford_depolarization=0.001
)
dist, dist_list, cws = dist_m4ri.compute_dem_distance(circuit=circuit, do_cws=True, threads=4)
print(f"Surface code distance: {dist}, found {len(cws)} minimum-weight error mechanisms")
# 3. CSS Quantum Code
dist, d_x, d_z = dist_m4ri.compute_css_distance(
Hx="examples/surf_d5_H.mmx",
Hz="examples/surf_d5_H.mmx",
Lz="examples/surf_d5_L.mmx",
Lx="examples/surf_d5_L.mmx",
d_exp=5,
threads=4
)
print(f"CSS distance: {dist}") # 5- Recent
gccwith POSIX threads support (-pthread). libm4ri-devlinear algebra library:sudo apt-get update -y sudo apt-get install -y libm4ri-dev
cd src
# Compile both multithreaded dist_m4ri and single-threaded dist_m4ri_old
make all
# Run full C test suite (34 tests)
make testpytest tests/test_dist_m4ri.py -vIf you use this program, please cite:
- A. Dumer, A. A. Kovalev, and L. P. Pryadko, "Distance verification for classical and quantum LDPC codes," IEEE Transactions on Information Theory, vol. 63, no. 7, pp. 4675-4690, 2017. doi:10.1109/TIT.2017.2690381.
Other related papers and software:
-
vecdec Repository (Random Information Set (RW) algorithm with error weights/probabilities): QEC-pages/vecdec.
-
QDistRnd GAP Package (Random Information Set algorithm for quantum codes over arbitrary finite fields): L. P. Pryadko, V. A. Shabashov, and V. K. Kozin, "QDistRnd: A GAP package for computing the distance of quantum error-correcting codes," Journal of Open Source Software, vol. 7, no. 71, p. 4120, 2022. doi:10.21105/joss.04120.
-
Performance Comparison: M. Webster, A. Jacob, and O. Higgott, "Distance-Finding Algorithms for Quantum Codes and Circuits," arXiv:2603.22532 [quant-ph], 2026. arXiv:2603.22532.