24#define _maybe_unused __attribute__((unused))
36#define DBG_CODEWORDS 32
38#define DBG_MATRICES 128
41#define DBG_LEGACY 4096
42#define DBG_DEFAULT (DBG_SUMMARY | DBG_PROGRESS)
158static inline int minint(
const int a,
const int b) {
return (a < b) ? a : b; }
163static inline int col_orig_index(
const params_t *
const p,
const int j) {
return p->col_orig ?
p->col_orig[j] : j; }
271static inline int rw_hybrid_window(
const params_t *
const p,
const int nvar) {
272 const int w = (
p->win_hyb > 0) ?
p->win_hyb : (
p->fdem ? 256 : 512);
273 const int cap = (nvar * 3) / 4;
274 return (w < cap) ? w : cap;
278#define RW_PAIRS_MAX_BITS 64
282#define RW_PAIRS_KEEP 0.8
288#define RW_PAIRS_WORK 16.0
292#define RW_PAIRS_FREE 1048576.0
298static inline double rw_pairs_keep(
const int rank,
const int w,
const int l) {
300 for (
int i = 0; i < w - 2; i++) {
301 if (rank - l - i <= 0)
return 0.0;
302 q *= (double)(rank - l - i) / (double)(rank - i);
318static inline int rw_pairs_min_bits(
const int nvar,
const int rank) {
319 const double k = (double)(nvar - rank);
323 double pairs = k * k / 4.0;
343static inline int rw_pairs_bits(
const params_t *
const p,
const int nvar,
const int rank,
const int w) {
344 const int k = nvar - rank;
345 if ((
p->pairs == 0) || (k < 2) || (rank < 1) || (w < 2))
return 0;
350 const int lmin = rw_pairs_min_bits(nvar, rank);
351 while ((l > 1) && (l > lmin) && (rw_pairs_keep(rank, w, l) <
RW_PAIRS_KEEP)) l--;
353 return (l < rank) ? l : rank;
386static inline int codeword_rw_limit(
const params_t *
const p,
const int cur_dmax,
const int feed) {
387 const int lim_max =
p->nvar + 1;
388 if (cur_dmax <= 0)
return lim_max;
389 long long int lim = cur_dmax;
390 if ((
p->outC != NULL ||
p->maxC > 0) &&
p->dW >= 0) lim = (
long long int)cur_dmax +
p->dW + 1;
391 if (feed > lim) lim = feed;
392 return (lim < lim_max) ? (int)lim : lim_max;
493 const long steps,
const long steps_total,
const double t_step,
const int pairs_l);
505 double *avg_cnt,
double *stdev_cnt);
529void print_codeword_support(FILE *stream,
const char *prefix,
const int arr[],
const int weight,
const int debug);
542void csr_dump(FILE *stream,
const csr_t *
const M,
const char name[],
const int debug);
544#define DIST_M4RI_VERSION "0.16.1"
554 "%s (version %s): calculate distance of a classical or quantum CSS code\n" \
555 "Usage: %s [method=1|2|3] [parameter=value ...]\n\n" \
556 "Allowed parameters:\n" \
557 " method, finH, finG, finL, fin, fdem, pmin, merge, drop, outD, classical, css,\n" \
558 " steps, wmin, wmax, dmin, dmax, dstop, dexp (dest), smax, start, start_scan,\n" \
559 " sort_rows, cc_prune, cbeg, cend, noscan, threads, timeout, nothrottle,\n" \
560 " chunk_size (batch), ksub, kwin (win), win_mode, win_hyb, pairs, min_hits,\n" \
561 " cov_cws, refresh, finC, outC, maxC, dW, irred, ortho, seed, debug\n\n" \
563 " -h, --help : display help for commonly used parameters (fits 80 rows; --help TOPIC: as --morehelp TOPIC)\n" \
564 " --morehelp : display full help for all available parameters (or for TOPIC: --morehelp TOPIC)\n"
567 "%s (version %s): calculate distance of a classical or quantum CSS code\n" \
568 "Usage: %s [method=1|2|3] [parameter=value ...]\n\n" \
569 "Calculation method:\n" \
570 " method=[int] 1: Random Window (RW) algorithm (upper bound)\n" \
571 " 2: Connected Cluster (CC) algorithm (lower bound / exact)\n" \
572 " 3: Bracketing mode (concurrent RW and CC) (default: 3)\n\n" \
573 "Input matrices (Matrix Market .mmx/.mtx format or Stim DEM):\n" \
574 " finH=[file] Parity check matrix H (classical) or Hx (CSS quantum)\n" \
575 " finG=[file] Hz check matrix (quantum CSS code only)\n" \
576 " finL=[file] Lx logical operator matrix (quantum CSS code only)\n" \
577 " Note: Either L=Lx or G=Hz is required for quantum CSS codes\n" \
578 " fin=[str] Base name for CSS matrices (loads ${fin}X.mtx, ${fin}Z.mtx)\n" \
579 " fdem=[file] Stim detector error model (DEM) file\n" \
580 " pmin=[float] Minimum error probability threshold to keep for DEM (0.0)\n" \
581 " merge=[0|1] Merge equal DEM columns (exact; codewords use the first one) (1)\n" \
582 " drop=[auto|file] DEM detectors to drop if exact: auto=1 (default), 0 (none), or a file\n" \
583 " outD=[file] Write the DEM detectors dropped (0-based) to file\n" \
584 " classical=[0|1] 1: classical code (Hx only), 0: quantum CSS (auto-detected)\n\n" \
585 "Distance bounds and guidance:\n" \
586 " dmin=[int] Certified lower bound on distance (CC starts from dmin) (1)\n" \
587 " dmax=[int] Known upper bound on distance (CC up to w=dmax-1 only) (0)\n" \
588 " dstop=[int] Stop once CC certifies dmin>=dstop (not an upper bound) (0)\n" \
589 " dexp=[int] Expected distance for method=3 thread allocation (alias: dest) (0)\n\n" \
590 "Search limits and stopping criteria:\n" \
591 " steps=[int] Maximum RW decoding steps / information sets (100000)\n" \
592 " wmax=[int] Maximum cluster weight to search in CC (0=until bound/timeout)\n" \
593 " wmin=[int] Stop immediately if cw with weight <= wmin is found (1)\n" \
594 " min_hits=[int] Stop RW when lowest-wt cws are hit min_hits times on average (5)\n" \
595 " timeout=[sec] Execution timeout in seconds, 0 for infinite (60.0)\n\n" \
596 "Multithreading and RW optimization:\n" \
597 " threads=[int] Max worker threads to use (0: all logical CPUs) (0)\n" \
598 " ksub=[int] EXPERIMENTAL, do not use: subspace dimension sampled from ker(H) for RW (0)\n" \
599 " kwin=[int] Localized column permutation window size W (0: auto/hybrid) (0)\n\n" \
600 "Codeword collection:\n" \
601 " outC=[file] Export found min-weight codewords (up to +dW) to file (.nz format)\n" \
602 " finC=[file] Import initial codewords from file (.nz format)\n" \
603 " maxC=[int] Maximum number of codewords to collect (0 for unlimited) (0)\n" \
604 " dW=[int] Collect codewords up to the minimum weight found + dW (0)\n\n" \
605 "Extra parameters (see --morehelp for details):\n" \
606 " smax=[int] (0) Max syndrome weight for confinement profile (0 to disable)\n" \
607 " noscan=[0|1] (0) Expert, method 2: CC at w=wmax only (no lower bound!)\n" \
608 " start=[list] (-1) Expert: CC from listed columns only, e.g. start=0,48\n" \
609 " start_scan=[0|1] (0) Expert, with start: clusters from column c use only columns > c\n" \
610 " cbeg/cend=[int] (-1) Expert: CC start column range, for split runs\n" \
611 " irred=[0|1] (1) Expert: 0 records also reducible codewords (cw + disjoint 0-syndrome vector)\n" \
612 " ortho=[0|1] (1) Expert: 0 skips the check H G^T = 0 of finG (valid only if it holds)\n" \
613 " sort_rows=[0|1] (1) Sort the rows of H by weight for CC (default 0 with fdem)\n" \
614 " cc_prune=[0|1|2] (1) CC search: 0 first-row walk, 1 branch and bound, 2 also cover bounds\n" \
615 " nothrottle=[0|1] (0) Disable thread throttling (also --no-throttle)\n" \
616 " chunk_size=[int] (0) RW batch chunk size (0: auto, alias: batch)\n" \
617 " win_mode=[0|1] (0) Window mode: 0=Tanner BFS, 1=index proximity\n" \
618 " win_hyb=[int] (0) Hybrid RW window size (0: 256 for a DEM, 512 otherwise)\n" \
619 " pairs=[int] (-1) RW pairs of non-pivot columns (p=2; -1: auto, 0: off)\n" \
620 " cov_cws=[int] (100) Number of lowest-wt cws used for the min_hits statistic\n" \
621 " refresh=[int] (0) RW steps between ker(H) basis refreshes (experimental ksub only; 5000 if ksub>0)\n" \
622 " seed=[int] (0) RNG seed [0 for time(NULL)]\n" \
623 " debug=[int] (3) Debug bitmask (0: silent, 1: summary, 2: progress, ...)\n\n" \
625 " -h, --help Display this help message (--help TOPIC: the same as --morehelp TOPIC)\n" \
626 " --morehelp Display full help for all parameters (--morehelp TOPIC: only TOPIC, e.g., maxC or windows)\n" \
627 " --version Display program version\n"
630 "%s (version %s): calculate distance of a classical or quantum CSS code\n" \
631 "Usage: %s [method=1|2|3] [parameter=value ...]\n\n" \
632 "Calculation method:\n" \
633 " method=[int] Bitmap / identifier for calculation method (default: 3):\n" \
634 " 1: Random Window (RW) algorithm (upper bound)\n" \
635 " Finds an upper bound on distance by testing random\n" \
636 " information sets. Fast for finding small codewords.\n" \
637 " 2: Connected Cluster (CC) algorithm (lower bound / exact)\n" \
638 " Exhaustive cluster search finding a lower bound or exact\n" \
639 " minimum distance. Guaranteed to find the true code\n" \
640 " distance if run to completion.\n" \
641 " 3: Bracketing mode (concurrent RW and CC)\n" \
642 " Dynamically balances CC (lower bound) and RW (upper\n" \
643 " bound) worker threads based on measured CC and RW times,\n" \
644 " current bounds [dmin, dmax], remaining timeout, and the\n" \
645 " distance estimate (dexp).\n\n" \
646 "Input matrices and code specification:\n" \
647 " finH=[file] Parity check matrix H (for classical codes) or Hx (for\n" \
648 " quantum CSS codes) in Matrix Market (.mmx / .mtx) format.\n" \
649 " finG=[file] Generator / Hz matrix for quantum CSS codes in Matrix Market\n" \
650 " format. Used to verify orthogonality (see ortho) and\n" \
651 " construct logicals.\n" \
652 " ortho=[0|1] Expert option: 1 (default) checks that the rows of H and G\n" \
653 " (finG) are orthogonal, H G^T = 0, and stops with an error\n" \
654 " otherwise; 0 skips the check (a WARNING is printed), e.g.,\n" \
655 " to screen many codes which are orthogonal by construction\n" \
656 " (the check takes O(nnz(G) times the column weight of H)\n" \
657 " operations). The result is valid only if H G^T = 0.\n" \
658 " Ignored (with a WARNING) without finG.\n" \
659 " finL=[file] Logical operator matrix Lx for quantum CSS codes in Matrix\n" \
660 " Market format.\n" \
661 " Note: For a quantum CSS code, either finL (Lx) or finG (Hz)\n" \
662 " must be provided.\n" \
663 " fin=[str] Base name for the matrix files (default: ../examples/try).\n" \
664 " Automatically looks for \"${fin}X.mtx\" as finH and\n" \
665 " \"${fin}Z.mtx\" as finG. A later finH, finG, or finL\n" \
666 " cancels fin (with a warning; then no file is taken from\n" \
667 " fin, so that finH must be given); fin after them is an\n" \
669 " fdem=[file] Detector Error Model file (.dem) generated by Stim.\n" \
670 " Automatically constructs H and L matrices. Cannot be\n" \
671 " combined with finH, finG, finL, or fin.\n" \
672 " pmin=[float] Minimum error probability threshold for DEM parsing (0.0).\n" \
673 " Error mechanisms with probability < pmin are ignored.\n" \
674 " Only valid when fdem is specified. The column indices\n" \
675 " (start, finC, outC) count only the error mechanisms kept:\n" \
676 " they change with pmin.\n" \
677 " merge=[0|1] Merge the equal columns of a DEM (error mechanisms with the\n" \
678 " same detectors and observables) when reading it (default:\n" \
679 " 1; ignored without fdem). Exact: dropping two equal columns\n" \
680 " of a codeword gives a lighter one, so the distance does not\n" \
681 " change. Column indices (outC, finC, start, cbeg, cend, and\n" \
682 " the printed codewords) are those of the DEM; the codewords\n" \
683 " found use the first one of each set of equal columns (use\n" \
684 " merge=0 to enumerate the codewords with each of them, or\n" \
685 " expand=1 of dist_m4ri.py to expand the list found).\n" \
686 " drop=[auto|file] Detectors of a DEM to drop if this is verified to be exact\n" \
687 " (default: auto; also drop=1; drop=0 keeps all detectors;\n" \
688 " only with fdem; not with classical=1): every column\n" \
689 " touching them has a twin, a column with the same other\n" \
690 " detectors which touches none of them (no column if it has\n" \
691 " no other detector), with observables L + A H for one\n" \
692 " matrix A. Then the twins replace the columns touching the\n" \
693 " dropped detectors in any codeword, without increasing its\n" \
694 " weight, and the search runs on the other detectors and the\n" \
695 " columns which touch none of them: every codeword found\n" \
696 " (outC) is a codeword of the full DEM (using only these\n" \
697 " columns), and the distance is exact. finC codewords are\n" \
698 " mapped to the twins.\n" \
699 " auto: a search for the largest such set (with A = 0) in the\n" \
700 " DEM, e.g., the minority-basis detectors of a CSS circuit\n" \
701 " (with the usual noise): a column which contains no other\n" \
702 " column with the same observables is dropped all or nothing,\n" \
703 " and the detectors of the other columns follow by propagation\n" \
704 " (see README.md).\n" \
705 " file: the detectors listed (0-based, k for Dk, separated by\n" \
706 " white space or commas; lines starting with '#' or '%%' are\n" \
707 " comments; write ./1 for a file named 1); if dropping them is\n" \
708 " not exact, a note is printed and the full DEM is used.\n" \
709 " outD=[file] Write the detectors dropped from the DEM (0-based, in the\n" \
710 " format of a drop file; only the comment line if none) to\n" \
711 " file. Only valid with fdem.\n" \
712 " classical=[0|1] Code type override:\n" \
713 " 1: Treat as a classical linear code (H only: finG,\n" \
714 " finL, or fin is an error, and the observables L of a\n" \
715 " DEM are discarded).\n" \
716 " 0: Treat as a quantum CSS code (requires L or G matrix).\n" \
717 " Default: 1 if only finH is given; 0 if finG, finL, fin,\n" \
718 " or fdem is provided.\n" \
719 " css=[int] Reserved for future non-CSS quantum code support (1).\n\n" \
720 "Distance bounds and search guidance:\n" \
721 " dmin=[int] Known certified lower bound on distance (default: 1).\n" \
722 " In CC (method 2/3), cluster search begins at w = dmin.\n" \
723 " dmax=[int] Known upper bound on distance (default: 0).\n" \
724 " CC (method 2/3) ends once dmin = dmax (with outC, after the\n" \
725 " rounds w = dmax..dmax+dW). In RW (method 1/3), codewords\n" \
726 " of weight >= dmax are ignored unless collecting codewords\n" \
727 " or needed for min_hits.\n" \
728 " dstop=[int] Stop target for the lower bound (default: 0 = off): the run\n" \
729 " (method 2/3) ends once CC has certified dmin >= dstop, that\n" \
730 " is, that there is no codeword of weight < dstop (with outC,\n" \
731 " after the rounds w = dstop..dstop+dW), unless a lighter\n" \
732 " codeword is found (then the search goes on as usual).\n" \
733 " Unlike dmax, dstop is not an upper bound and is not\n" \
734 " reported as dmax: the output is 'dmin w steps', where w is\n" \
735 " the weight of the lightest codeword found (0: none). E.g.,\n" \
736 " dstop=U wmin=U-1 decides whether d >= U, and for a CSS code\n" \
737 " with d = min(dX, dZ) <= U, dstop=U is all that is needed.\n" \
738 " With method=1, it only applies to a supplied dmin >= dstop.\n" \
739 " dexp=[int] Expected code distance (alias: dest) (default: 0).\n" \
740 " Hint for method=3 (bracketing): as long as RW has found no\n" \
741 " codeword, CC rounds at w > dexp run only on threads which\n" \
742 " cannot run RW (CC pauses if RW can use all threads); CC\n" \
743 " resumes once RW finds a codeword or ends.\n\n" \
744 "Search limits and Connected Cluster (CC) options:\n" \
745 " steps=[int] Maximum number of RW decoding steps / information sets\n" \
746 " (default: 100000). Ignored in method=2.\n" \
747 " wmin=[int] Minimum distance threshold (default: 1).\n" \
748 " If a codeword of weight w <= wmin is found, execution\n" \
749 " terminates immediately (not when collecting codewords with\n" \
750 " outC or maxC). Useful for screening codes.\n" \
751 " wmax=[int] Maximum cluster weight to analyze in CC (default: 0).\n" \
752 " In method=2, CC terminates after checking weight wmax.\n" \
753 " 0 means continue until a codeword is found, the bounds\n" \
754 " meet, dmin >= dstop, or timeout (method=2 then needs\n" \
755 " timeout>0, dmax>0, or dstop>0).\n" \
756 " smax=[int] Maximum syndrome weight for confinement profile (default: 0).\n" \
757 " When smax > 0, tracks minimum syndrome weights for each\n" \
758 " error weight. When smax=0, confinement is not computed.\n" \
759 " Disabled (with a WARNING) with noscan=1 or dmin > 1, as the\n" \
760 " small cluster weights are then skipped.\n" \
761 " sort_rows=[0|1] Sort the rows of H by increasing weight (stable) after\n" \
762 " reading the input (default: 1 for matrices, finH or fin;\n" \
763 " 0 for a DEM, fdem). With cc_prune=0, CC extends a cluster\n" \
764 " by the columns of the first row of its syndrome (in row\n" \
765 " order), so that light rows first reduce the CC work for\n" \
766 " matrices with very different row weights, e.g., 1.7-4x\n" \
767 " with the hook columns of an extended CSS distance, while\n" \
768 " the detectors of a DEM are in time order, which is better\n" \
769 " (sorting them made CC 1.3-4x slower). With cc_prune=1 or\n" \
770 " 2, the order of the rows only breaks ties. The distance\n" \
771 " and RW do not depend on the order of the rows; CC finds the\n" \
772 " same codewords (outC), possibly in another order (with\n" \
773 " cc_prune=0, also with other hit counts).\n" \
774 " cc_prune=[0|1|2] The CC search with smax=0 (default: 1). 0: the walk of\n" \
775 " the versions before 0.15.0: a cluster is extended by the\n" \
776 " columns of the first unsatisfied row of its syndrome, and\n" \
777 " a branch is pruned if its syndrome weight exceeds what the\n" \
778 " columns left can cancel. 1: branch and bound: it branches\n" \
779 " on the unsatisfied row with the fewest available columns,\n" \
780 " the columns of the earlier branches are forbidden in the\n" \
781 " later ones (each codeword is found once: one CC hit), and\n" \
782 " a branch is pruned by lower bounds on the number of columns\n" \
783 " needed (an unsatisfied row without available columns, or a\n" \
784 " packing of unsatisfied rows with disjoint sets of available\n" \
785 " columns). 2: also the coverage and fractional cover bounds\n" \
786 " (fewer nodes, more work per node). All values find the\n" \
787 " same codewords and distances (doc/cc_completeness.tex);\n" \
788 " with the expert start list (and start_scan=0), cc_prune=1\n" \
789 " and 2 forbid the columns listed before the start column.\n" \
790 " noscan=[0|1] Expert option: 1: run CC only at weight w = wmax, skipping\n" \
791 " the scan over weights w < wmax (default: 0). Only valid for\n" \
792 " method=2. WARNING: lower weights are not checked, so a\n" \
793 " codeword found only sets dmax, and dmin is not raised above\n" \
794 " the supplied dmin. Certified only if dmin=wmax is given.\n" \
795 " start=[list] Expert option: comma-separated list of CC start columns,\n" \
796 " e.g., start=0,48,96 (default: -1 = all columns). Clusters\n" \
797 " grown from a listed column are NOT limited to larger column\n" \
798 " indices (unless start_scan=1). Use, e.g., one column per\n" \
799 " block of a quasi-cyclic code. WARNING: dmin is valid only\n" \
800 " if a code symmetry maps every minimum-weight codeword to one\n" \
801 " containing a listed column. Cannot be combined with\n" \
803 " start_scan=[0|1] Expert option, with start (default: 0). 1: a cluster grown\n" \
804 " from a listed column c only uses the columns > c, as in the\n" \
805 " scan of all columns (see cbeg). WARNING: dmin is valid\n" \
806 " only if a code symmetry maps every minimum-weight codeword\n" \
807 " to one whose smallest column is listed, e.g., if the listed\n" \
808 " columns are the smallest columns of the orbits of a group of\n" \
809 " code automorphisms, one per orbit (start=0,l for the two\n" \
810 " blocks of a two-block group-algebra code of length 2l over\n" \
811 " an abelian group). The later start columns then need less\n" \
812 " work, the least if each orbit is a range of consecutive\n" \
813 " columns. Not with fdem.\n" \
814 " cbeg=[int] Expert option for split runs: first CC start column\n" \
815 " (default: -1 = column 0). A cluster started at column i\n" \
816 " only uses columns > i, so every codeword is found starting\n" \
817 " from its smallest column.\n" \
818 " cend=[int] Expert option for split runs: last CC start column\n" \
819 " (default: -1 = column n-1). WARNING: with cbeg/cend, dmin\n" \
820 " only covers codewords whose smallest column is in\n" \
821 " [cbeg,cend]; combine runs covering all columns 0..n-1 by\n" \
822 " taking the minimum of dmin (and of dmax) over the runs.\n\n" \
823 "Codeword collection and export:\n" \
824 " outC=[file] Export found codewords of weight up to min_w + dW (min_w:\n" \
825 " minimum weight found) to file in .nz list format. In\n" \
826 " method=2/3, once dmin = dmax = d, CC rounds w = d..d+dW\n" \
827 " enumerate all such irreducible codewords (see irred; unless\n" \
828 " the timeout is hit; for a DEM, up to the choice of equal\n" \
829 " columns: see merge).\n" \
830 " finC=[file] Import initial candidate codewords from file in .nz format.\n" \
831 " A reducible codeword is replaced by an irreducible part with\n" \
832 " a nonzero syndrome of L (see irred). If finC is the same\n" \
833 " file name as outC, a missing file is not an error.\n" \
834 " maxC=[int] Maximum number of codewords to collect (default: 0).\n" \
835 " 0 means collect all valid codewords found up to wmax or stop\n" \
836 " flag. If maxC > 0, halts when maxC codewords are collected.\n" \
837 " dW=[int] Extra weight window above minimum distance (default: 0).\n" \
838 " Collects codewords with weight up to min_w + dW.\n" \
839 " irred=[0|1] Expert option: 1 (default) records only irreducible\n" \
840 " codewords: a codeword which is the union of a codeword and a\n" \
841 " disjoint nonzero vector with zero syndrome (e.g., a trivial\n" \
842 " weight-3 vector of a circuit DEM, from weight d+3 on) is not\n" \
843 " recorded. Minimum-weight codewords are always irreducible.\n" \
844 " Tested for the CC codewords (the rank of their columns of\n" \
845 " H) and for the RW pairs (the sum of two disjoint vectors\n" \
846 " with zero syndrome is skipped); a finC codeword is replaced\n" \
847 " by an irreducible part with a nonzero syndrome of L.\n" \
848 " 0: all codewords are recorded, as before version 0.14.8.\n" \
849 " (dist_m4ri_old: finC only.)\n\n" \
850 "Execution, multithreading, and timing:\n" \
851 " threads=[int] Maximum number of worker threads to use (default: 0 = all\n" \
852 " logical CPUs available, i.e., the CPU affinity mask, e.g.,\n" \
853 " with taskset). Subject to throttling for small codes or\n" \
854 " large matrices unless nothrottle=1 is set.\n" \
855 " timeout=[sec] Execution timeout in seconds (default: 60.0, 0 = infinite).\n" \
856 " In method=3, it guides the CC vs RW thread balance, and a\n" \
857 " CC round predicted not to finish in time is not started\n" \
858 " while RW runs (in method=2, and with steps=0, it is started\n" \
859 " anyway: it may still find a codeword of weight w=dmin).\n" \
860 " nothrottle=[0|1] Disable automatic thread throttling (default: 0).\n" \
861 " Aliases: --no-throttle, -no-throttle, nothrottle.\n" \
862 " By default, threads are throttled for very small codes or\n" \
863 " large matrices to avoid cache and memory bus thrashing.\n" \
864 " The limits for small codes (by the RW work) apply in methods\n" \
865 " 1 and 3; method=2 starts 4 threads, and the others once a CC\n" \
866 " round takes longer (> 2 ms). The limits for large matrices\n" \
867 " (above 15 MB of dense RW memory per thread: at most 32 RW\n" \
868 " threads, within a quarter of the physical memory) and for\n" \
869 " small step counts (ceil(steps/10)) apply to RW threads only;\n" \
870 " in method=3, CC rounds can use all threads.\n" \
871 " chunk_size=[int] Maximum RW batch per claim of a worker (default: 0 = adaptive,\n" \
872 " 25 to 500 steps by n and steps). Near the end of the steps,\n" \
873 " batches shrink to ceil(remaining/(4*RW threads)) steps, so\n" \
874 " that the RW threads finish together. Alias: batch=[int].\n" \
875 " ksub=[int] EXPERIMENTAL, should not be used (a warning is printed):\n" \
876 " subspace dimension sampled from ker(H) in RW (default: 0 =\n" \
877 " original full-matrix RW). E.g. ksub=32 or 64 keeps working\n" \
878 " matrices inside L1/L2 cache. Automatically falls back to\n" \
879 " ksub=0 if m < nu = dim(ker(H)) (with a warning if debug&1).\n" \
880 " Each step reduces the span of ksub distinct rows of a fixed\n" \
881 " basis of ker(H), so that a few codewords are found much\n" \
882 " more often than others, and min_hits may end RW early.\n" \
883 " kwin=[int] Localized column permutation window size W, used in every RW\n" \
884 " step (alias: win=[int]). Default: 0 = automatic hybrid for\n" \
885 " n>=500: every other step uses an index window (win_mode=1)\n" \
886 " of win_hyb columns, the other steps uniform random\n" \
887 " permutations (also for codewords which are not local).\n" \
888 " kwin=-1 (any negative value): no windows, uniform random\n" \
889 " permutations in every step.\n" \
890 " win_mode=[0|1] Window construction mode when kwin > 0 (default: 0):\n" \
891 " 0: Tanner graph BFS neighbors around random seed column.\n" \
892 " 1: Contiguous index proximity window around seed column.\n" \
893 " win_hyb=[int] Window size of the hybrid RW steps (kwin=0, n>=500; at most\n" \
894 " 3n/4). Default: 0 = 256 columns for a DEM, 512 for\n" \
895 " matrices. The window columns come first in the elimination\n" \
896 " order; in a DEM, they are errors close in time, which touch\n" \
897 " few detectors: windows of 192-256 columns find circuit\n" \
898 " codewords 2-10 times faster than 512, and windows of one\n" \
899 " round of columns much slower. With debug&1, the binary\n" \
900 " prints the rounds of a DEM (estimated from the time\n" \
901 " translation of its errors: D detectors and L columns per\n" \
902 " round) and the codewords found by the uniform and by the\n" \
904 " pairs=[int] RW pairs of non-pivot columns (p=2, as in Lee-Brickell and\n" \
905 " Stern): a RW step also finds the codewords with exactly two\n" \
906 " non-pivot columns, checking only the pairs of columns which\n" \
907 " agree on pairs=l random pivot rows (at most 64; 0 = off).\n" \
908 " Default: -1 = auto, about one non-pivot column per bucket,\n" \
909 " with fewer rows while a codeword of the weight of the upper\n" \
910 " bound would be kept with probability below 0.8, but enough\n" \
911 " rows to keep the pairs of a step within about the work of\n" \
912 " its elimination (e.g., l >= 6 for large circuit DEMs while\n" \
913 " the upper bound is far above the distance). The pairs\n" \
914 " find the minimum-weight codewords of circuit DEMs 7 to 26\n" \
915 " times faster, and lighter codewords of codes with a large\n" \
916 " distance. Not with ksub. With debug&1, the binary prints\n" \
917 " the pairs checked per step and the codewords found by pairs\n" \
918 " and by single columns.\n" \
919 " min_hits=[int] QDistRnd-style RW stopping criterion (default: 5, 0 = off;\n" \
920 " alias: max_hits). Stops RW when the average number of hits\n" \
921 " <n> per codeword (by all RW steps, with or without windows,\n" \
922 " and by CC or finC) reaches min_hits, both for the codewords\n" \
923 " of the minimum weight found and for a representative set of\n" \
924 " cov_cws lowest-weight codewords (heavier codewords are kept\n" \
925 " until enough lighter ones are found). A single codeword\n" \
926 " suffices. A lighter codeword is missed with probability\n" \
927 " about exp(-<n>), assuming that lighter codewords are found\n" \
928 " at least as often. With debug&1, a warning is printed at\n" \
929 " the end if the hit counts of codewords of the same weight\n" \
930 " are strongly non-uniform (then exp(-<n>) is optimistic),\n" \
931 " together with an information-set estimate (uniform random\n" \
932 " information sets) of the probability to miss a lighter\n" \
933 " codeword and of the RW steps needed for 1%%.\n" \
934 " With min_hits=0, RW records only the codewords lighter than\n" \
935 " the upper bound (unless collecting codewords with outC or\n" \
936 " maxC), so that the repeated hits are not counted.\n" \
937 " cov_cws=[int] Size of the representative set of lowest-weight codewords\n" \
938 " for min_hits (default: 100; 0 = only the minimum weight).\n" \
939 " Without outC and maxC, at most cov_cws minimum-weight\n" \
940 " codewords are tracked (all if cov_cws=0). With fewer\n" \
941 " minimum-weight codewords, a smaller cov_cws may stop RW\n" \
943 " refresh=[int] RW steps interval for adaptive ker(H) basis refresh via\n" \
944 " low-weight codeword exchange and re-echelonization, only\n" \
945 " with the experimental ksub > 0 (default: 5000 when\n" \
946 " ksub > 0, 0 = off).\n" \
947 " seed=[int] Random number generator seed (default: 0; seed<=0 is\n" \
948 " replaced by time(NULL) + 10*pid - 1000*seed).\n\n" \
949 "Debug output bitmap (debug=[int], default: 3):\n" \
950 " Diagnostic output goes to stderr (stdout only has the result line); lower\n" \
951 " bits are more informative. The value is decimal or hexadecimal (0x...).\n" \
952 " Multiple debug arguments are OR-combined, where the first one replaces the\n" \
953 " default: e.g., debug=0 alone is silent, while debug=4 and debug=0 debug=4\n" \
954 " both give only the periodic status.\n" \
955 " 0 : Silent: errors, warnings on the validity of the result (expert\n" \
956 " options, experimental ksub, invalid finC codewords) and on ignored\n" \
957 " or overridden parameters, and the confinement profile with smax > 0\n" \
958 " 1 : Summary (default): input matrices (and the rounds of a DEM, RW\n" \
959 " windows), warnings, stop reason, codeword and hit statistics,\n" \
960 " RW information sets, pairs, and step types, export\n" \
961 " 2 : Progress (default): run plan (threads, steps, timeout, seed),\n" \
962 " finished CC rounds, new upper bounds, RW convergence\n" \
963 " 4 : Periodic status (after 1, 2, 4, ... s, then every 60 s): bounds,\n" \
964 " RW steps and rate, <n>, progress of the current CC round\n" \
965 " 8 : Thread allocation and timing: throttling, CC round planning and\n" \
966 " re-planning, waits for RW, predicted vs measured CC work, and the\n" \
967 " nodes of each CC round (calls of the recursion)\n" \
968 " 16 : Code parameters rank(H), rank(L) or rank(G), and k (dense\n" \
969 " elimination at startup, slow for large matrices)\n" \
970 " 32 : Support (1-based) of each new lightest codeword (RW, CC, finC)\n" \
971 " 64 : Command-line arguments, rng seed, and files read\n" \
972 " 128 : Matrices H, G, L (if n < 150, unless 2048 is set)\n" \
973 " 256 : All codewords in hash with their hit counts (at the end)\n" \
974 " 2048 : No size cutoff for matrices, codeword supports, and per-weight\n" \
975 " codeword statistics\n" \
976 " 4096 : dist_m4ri_old only: CC recursion and confinement hash traces\n" \
977 " Bits 512, 1024, and 8192 to 32768 are reserved. Bits 65536 and above are\n" \
978 " reserved for the Python wrapper dist_m4ri.py (ignored by the binary).\n" \
979 " E.g., debug=7 adds the periodic status to the default output, and debug=11\n" \
980 " the thread allocation and timing.\n\n" \
981 "Output format (stdout):\n" \
982 " Standard output produces a single line with three space-separated integers:\n" \
983 " dmin dmax rw_steps\n" \
985 " dmin-1 : Maximum cluster weight analyzed by CC without finding any codeword.\n" \
986 " If CC finds an exact minimum-weight codeword, dmin = dmax = weight.\n" \
987 " With the expert options noscan, start, or cbeg/cend, see the\n" \
988 " warnings above for the validity of dmin.\n" \
989 " dmax : Smallest weight of a codeword found (by RW or CC, or read with\n" \
990 " finC), or the supplied dmax if smaller (0 if none).\n" \
991 " rw_steps : Number of completed RW steps (0 if CC found exact or method=2).\n\n" \
992 "Option groups (--help GROUP prints all entries of GROUP):\n" \
993 " windows kwin, win_mode, win_hyb\n" \
994 " stopping, stop steps, wmin, timeout, min_hits, cov_cws\n" \
995 " bounds dmin, dmax, dstop, dexp, wmax\n" \
996 " dem fdem, pmin, merge, drop, outD\n" \
997 " matrices, matrix finH, finG, finL, fin, classical, ortho\n" \
998 " codewords outC, finC, maxC, dW, irred\n" \
999 " threading threads, nothrottle, chunk_size\n" \
1000 " expert noscan, start, start_scan, cbeg, cend\n" \
1001 " experimental ksub, refresh\n\n" \
1003 " -h, --help Display help for commonly used parameters (fits 80 rows);\n" \
1004 " --help TOPIC is the same as --morehelp TOPIC.\n" \
1005 " --morehelp Display this full help message listing all parameters;\n" \
1006 " --morehelp TOPIC (also --morehelp=TOPIC) displays only the\n" \
1007 " entries of TOPIC, e.g., --morehelp maxC: one or more names\n" \
1008 " separated by commas (e.g., maxC,dW), case-insensitive,\n" \
1009 " without '-' or '_' (and '=VALUE' in --help=TOPIC and\n" \
1010 " --morehelp=TOPIC: a separate argument with '=' is not a\n" \
1011 " TOPIC), including aliases such as dest or batch (and debug\n" \
1012 " for the debug output bitmap); an unknown name gives the\n" \
1013 " closest names on stderr, and the exit code 1. A group\n" \
1014 " name (see Option groups, also as singular or plural, e.g.,\n" \
1015 " window) gives all entries of the group, and a parameter of\n" \
1016 " a group also the other entries of its group (see also).\n" \
1017 " --version Display program version\n"
1020 "try \"%s -h\" for help"
Hit statistics for the min_hits stopping criterion, see codeword_hit_stats().
long long int * cw_hits_w
int swei[MAX_W]
int max_row_wt; /* WARNING: this is defined in util_io.h as static const int */
Utility functions for use with uthash.h.
void read_dem_file(char *fnam, csr_t **p_spaH, csr_t **p_spaL, double pmin, int debug)
Read a Detector Error Model (DEM) file and construct H and L matrices.
long long int codeword_window_count(const params_t *const p)
Number of codewords in the collection window (weight up to min_w + dW with outC or maxC,...
void compute_min_w_hit_stats(const params_t *const p, int *min_cnt, int *max_cnt, double *avg_cnt, double *stdev_cnt)
Compute hit count statistics (min, max, avg, stdev) for minimum-weight codewords.
void codeword_hit_stats(const params_t *const p, cw_hit_stats_t *const st)
Compute the hit statistics of the min_hits stopping criterion.
int check_min_hits_convergence(const params_t *const p)
Check whether the QDistRnd-style hit count stopping condition is met.
void print_short_help(const char *prog)
Print short help message listing all allowed parameters to stderr.
void var_kill(params_t *const p)
Clean up and free memory allocated in the params_t structure.
double rw_infoset_find_prob(const int n, const int rank, const int w, const int pairs_l)
Information-set estimate of the probability that a RW step finds a given codeword of weight w.
long long int nzlist_read(const char fnam[], params_t *p)
Read codewords from a .nz list file and add them to the codeword hash.
#define RW_PAIRS_FREE
The number of pairs of a RW step allowed with pairs=-1 (auto) whatever the work of its elimination (s...
int codeword_maxc_reached(const params_t *const p)
Returns 1 if maxC > 0 and maxC codewords of the collection window are collected.
int codeword_feed_limit(const params_t *const p)
Weight limit (exclusive) of RW codewords needed for the min_hits statistic.
void print_rw_infoset_estimate(FILE *stream, const int n, const int rank, const int w_lo, const int w_hi, const long steps, const long steps_total, const double t_step, const int pairs_l)
Print the information-set estimate of the probability that RW missed a codeword lighter than the uppe...
#define RW_PAIRS_MAX_BITS
The largest number of random pivot rows of the buckets of the RW pairs (pairs, a 64-bit key).
#define RW_PAIRS_WORK
The elimination of a RW step (rank r, n columns) takes about r^2 n / (64 RW_PAIRS_WORK) word operatio...
void print_codeword_support(FILE *stream, const char *prefix, const int arr[], const int weight, const int debug)
Print the support of a codeword (1-based column indices) in one line, for DBG_CODEWORDS.
int codeword_hit_check(FILE *stream, const params_t *const p)
Check the uniformity of the hit counts within each weight class of the representative set.
#define RW_PAIRS_KEEP
The smallest chance to keep a codeword of the weight of the upper bound in the buckets of the RW pair...
void print_rw_step_stats(FILE *stream, const params_t *const p)
DBG_SUMMARY: the codewords of the lowest three weights in hash found by the RW steps with a uniform r...
long long int nzlist_write(const char fnam[], const char comment[], params_t *p)
Write the collected codewords from the hash table to a .nz file.
cw_vec_t * codeword_add_maybe(params_t *const p, const int arr[], int weight, int src)
Add a candidate codeword to the hash table, or count one more hit of a known codeword.
void print_codeword_stats(FILE *stream, const params_t *const p)
Print accumulated codeword and hit statistics to the given stream.
void csr_dump(FILE *stream, const csr_t *const M, const char name[], const int debug)
Print a binary CSR matrix row by row ('1': nonzero, '.': zero), for DBG_MATRICES.
void var_init(int argc, char **argv, params_t *const p)
Initialize parameters and load matrices from command line arguments.