58 long long int dbg_ll=0;
63 for (
int i=1; i<argc;i++)
64 if((strcmp(argv[i],
"--help")==0)||(strcmp(argv[i],
"-h")==0)){
65 printf(
USAGE,argv[0],argv[0]);
71 for(
int i=1; i<argc; i++){
72 if(sscanf(argv[i],
"debug=%d",& dbg)==1){
73 if(debug_set &&
p->
debug != dbg){
74 ERROR(
"debug parameter specified multiple times with conflicting values (%d vs %d)\n",
p->
debug, dbg);
79 fprintf(stderr,
"# read %s, debug=%d octal=%o\n",argv[i],
p->
debug,
p->
debug);
81 else if (sscanf(argv[i],
"css=%d",&dbg)==1){
84 fprintf(stderr,
"# read %s, css=%d\n",argv[i],
p->
css);
86 else if (0==strncmp(argv[i],
"finH=",5)){
92 fprintf(stderr,
"# read %s, finH=%s; setting finH=\"\"\n",argv[i],
p->
finH);
95 else if (0==strncmp(argv[i],
"finL=",5)){
101 fprintf(stderr,
"# read %s, finL=%s; setting finL=\"\"\n",argv[i],
p->
finL);
104 else if (0==strncmp(argv[i],
"finG=",5)){
105 if(strlen(argv[i])>5)
110 fprintf(stderr,
"# read %s, finG=%s; setting finG=\"\"\n",argv[i],
p->
finG);
113 else if (0==strncmp(argv[i],
"fin=",4)){
115 ERROR(
"arg[%d]='%s' in conflict with finH=%s\n",i,argv[i],
p->
finH);
117 ERROR(
"arg[%d]='%s' in conflict with finG=%s\n",i,argv[i],
p->
finG);
119 ERROR(
"arg[%d]='%s' in conflict with finL=%s\n",i,argv[i],
p->
finL);
120 if (strlen(argv[i])>4)
126 ERROR(
"argv[%d]='%s', empty string for 'fin'\n",i,argv[i]);
129 else if (sscanf(argv[i],
"method=%d",&dbg)==1){
132 fprintf(stderr,
"# read %s, method=%d\n",argv[i],
p->
method);
136 else if (sscanf(argv[i],
"smax=%d",&dbg)==1){
139 fprintf(stderr,
"# read %s, smax=%d\n",argv[i],
p->
smax);
141 else if (sscanf(argv[i],
"wmax=%d",&dbg)==1){
144 fprintf(stderr,
"# read %s, wmax=%d\n",argv[i],
p->
wmax);
146 else if (sscanf(argv[i],
"dmin=%d",&dbg)==1){
149 fprintf(stderr,
"# read %s, dmin=%d\n",argv[i],
p->
dmin);
151 else if (sscanf(argv[i],
"dmax=%d",&dbg)==1){
154 fprintf(stderr,
"# read %s, dmax=%d\n",argv[i],
p->
dmax);
156 else if (sscanf(argv[i],
"start=%d",&dbg)==1){
159 fprintf(stderr,
"# read %s, start=%d\n",argv[i],
p->
start);
161 else if (sscanf(argv[i],
"cbeg=%d",&dbg)==1){
164 fprintf(stderr,
"# read %s, cbeg=%d\n",argv[i],
p->
cbeg);
166 else if (sscanf(argv[i],
"cend=%d",&dbg)==1){
169 fprintf(stderr,
"# read %s, cend=%d\n",argv[i],
p->
cend);
171 else if (sscanf(argv[i],
"wmin=%d",&dbg)==1){
174 fprintf(stderr,
"# read %s, wmin=%d\n",argv[i],
p->
wmin);
176 else if (sscanf(argv[i],
"steps=%d",&dbg)==1){
179 fprintf(stderr,
"# read %s, steps=%d\n",argv[i],
p->
steps);
181 else if (sscanf(argv[i],
"seed=%d",&dbg)==1){
184 fprintf(stderr,
"# read %s, seed=%d\n",argv[i],
p->
seed);
186 else if (sscanf(argv[i],
"noscan=%d",&dbg)==1){
189 fprintf(stderr,
"# read %s, noscan=%d\n",argv[i],
p->
noscan);
191 else if (0==strncmp(argv[i],
"fdem=",5)){
192 if(strlen(argv[i])>5)
197 fprintf(stderr,
"# read %s, fdem=%s\n",argv[i],
p->
fdem);
199 else if (sscanf(argv[i],
"pmin=%lg",&prob)==1){
202 fprintf(stderr,
"# read %s, pmin=%g\n",argv[i],
p->
pmin);
204 else if (0==strncmp(argv[i],
"finC=",5)){
205 if(strlen(argv[i])>5)
210 fprintf(stderr,
"# read %s, finC=%s\n",argv[i],
p->
finC);
212 else if (0==strncmp(argv[i],
"outC=",5)){
213 if(strlen(argv[i])>5)
218 fprintf(stderr,
"# read %s, outC=%s\n",argv[i],
p->
outC);
220 else if (sscanf(argv[i],
"maxC=%lld",&dbg_ll)==1){
223 fprintf(stderr,
"# read %s, maxC=%lld\n",argv[i],
p->
maxC);
225 else if (sscanf(argv[i],
"dW=%d",&dbg)==1){
228 fprintf(stderr,
"# read %s, dW=%d\n",argv[i],
p->
dW);
230 else if (sscanf(argv[i],
"classical=%d",&dbg)==1){
233 fprintf(stderr,
"# read %s, classical=%d\n",argv[i],
p->
classical);
235 else if (sscanf(argv[i],
"threads=%d",&dbg)==1){
238 fprintf(stderr,
"# read %s, threads=%d\n",argv[i],
p->
threads);
240 else if (sscanf(argv[i],
"dexp=%d",&dbg)==1){
243 fprintf(stderr,
"# read %s, dexp=%d\n",argv[i],
p->
dexp);
245 else if (sscanf(argv[i],
"dest=%d",&dbg)==1){
248 fprintf(stderr,
"# read %s, dest=%d (alias for dexp)\n",argv[i],
p->
dexp);
250 else if (sscanf(argv[i],
"timeout=%lf",&prob)==1){
253 fprintf(stderr,
"# read %s, timeout=%g\n",argv[i],
p->
timeout);
256 fprintf(stderr,
"# unrecognized parameter \"%s\" at position %d\n",argv[i],i);
257 ERROR(
"try \"%s -h\" for options",argv[0]);
262 ERROR(
"noscan=1 only works with method=2");
266 p->
fin =
"../examples/try";
271 ERROR(
"Cannot specify matrix files (fin, finH, finG, finL) along with fdem");
275 ERROR(
"pmin can only be used when fdem is specified");
279 ERROR(
"parameter dmin=%d cannot be negative\n",
p->
dmin);
282 ERROR(
"parameter dmax=%d cannot be negative\n",
p->
dmax);
285 ERROR(
"parameter dmin=%d cannot be larger than dmax=%d\n",
p->
dmin,
p->
dmax);
288 ERROR(
"parameter dmin=%d cannot be larger than wmax=%d\n",
p->
dmin,
p->
wmax);
292 ERROR(
"parameter wmin=%d cannot be larger than wmax=%d\n",
p->
wmin,
p->
wmax);
296 ERROR(
"Cannot specify start along with cbeg or cend\n");
304 ERROR(
"Parameters start, cbeg, and cend only work with CC method (method=2 or method=3)\n");
312 fprintf(stderr,
"# WARNING: smax=%d disabled (set to 0) because noscan=1 skips small cluster weights\n",
p->
smax);
315 fprintf(stderr,
"# WARNING: smax=%d disabled (set to 0) because dmin=%d skips small cluster weights\n",
p->
smax,
p->
dmin);
321 fprintf(stderr,
"# WARNING: steps=%d is ignored for CC method\n",
p->
steps);
333 int len = strlen(
p->
fin);
334 char *s = (
char *) malloc((len+6)*
sizeof(char));
336 ERROR(
"memory allocation");
337 sprintf(s,
"%s%s",
p->
fin,swit>0?
"X.mtx":
"Z.mtx");
339 s = (
char *) malloc((len+6)*
sizeof(char));
341 ERROR(
"memory allocation");
342 sprintf(s,
"%s%s",
p->
fin,swit>0?
"Z.mtx":
"X.mtx");
345 fprintf(stderr,
"# read 'fin=%s'; "
346 "assigning \n# finH=%s\n# finG=%s\n",
361 fprintf(stderr,
"# read H <- file '%s'\n",
p->
finH);
368 ERROR(
"need to specify H=Hx input file name; use fin=[str] or finH=[str]\n");
371 ERROR(
"either G=Hz or L=Lx matrix should be specified but not both! finG='%s' finL='%s'\n",
378 fprintf(stderr,
"# read G <- file '%s'\n",
p->
finG);
380 ERROR(
"rows of H and G matrices are not orthogonal");
390 fprintf(stderr,
"# read L <- file '%s'\n",
p->
finL);
406 ERROR(
"either parameter wmax>0 or timeout>0 should be specified for CC method=%d",
p->
method);
411 ERROR(
"increase MAX_W=%d defined in 'util_io.h'",
MAX_W);
412 for(
int i=0; i<
MAX_W; i++)
417 p->
seed = time(NULL) - 1000 *
p->
seed + 10*getpid();
419 fprintf(stderr,
"# initializing rng from time(NULL), seed=%d\n",
p->
seed);
422 fprintf(stderr,
"# initializing rng from seed=%d\n",
p->
seed);
426 rci_t n = (
p->
spaH)-> cols;
428 ERROR(
"Column count mismatch in H and G matrices: %d != %d",
433 ERROR(
"Non-CSS codes are currently not supported, css=%d",
p->
css);
436 ERROR(
"cbeg=%d cannot be larger than nvar-1=%d\n",
p->
cbeg,
p->
nvar-1);
439 ERROR(
"cend=%d cannot be larger than nvar-1=%d\n",
p->
cend,
p->
nvar-1);
451 ERROR(
"Conflict: classical=1 specified, but finL or finG was also provided.");
453 if (
p->
spaL != NULL) {
455 fprintf(stderr,
"# Warning: classical=1 specified, discarding L matrix (logical operators)\n");
460 if (
p->
spaL == NULL) {
461 ERROR(
"L matrix (logical operators) is required for quantum code (classical=0).\n"
462 "Provide finL, fdem, or finG to construct it. Alternatively, set classical=1 to find the distance of the stabilizer code as a classical code.");
467 printf(
"invalid method=%d specified\n",
p->
method);
480 if (strlen(
p->
fin) != 0) {
505 FILE *f = fopen(fnam,
"r");
507 printf(
"FILE I/O ERROR: %s\n", strerror(errno));
508 ERROR(
"can't open the (DEM) file %s for reading\n", fnam);
520 while ((linelen = getline(&buf, &bufsiz, f)) >= 0) {
521 if (linelen > 0 && buf[linelen - 1] ==
'\n') {
522 buf[linelen - 1] =
'\0';
536 for (
int i = 0; i < prog->
size; i++) {
537 free(prog->
lines[i]);
543static void parse_instructions(
dem_program_t *prog,
int *p_line_idx,
544 int *p_iD,
int_pair **p_inH,
int *p_maxH,
int *p_r,
545 int *p_iL,
int_pair **p_inL,
int *p_maxL,
int *p_k,
546 int *p_n,
double pmin,
int *p_detector_shift,
int debug) {
547 while (*p_line_idx < prog->size) {
548 char *line = prog->
lines[*p_line_idx];
552 while (isspace(*c)) c++;
554 if (*c ==
'\0' || *c ==
'#')
continue;
565 if (sscanf(c,
"repeat %d { %n", &val, &num) == 1) {
566 int start_idx = *p_line_idx;
567 int temp_idx = start_idx;
568 for (
int r = 0; r < val; r++) {
569 temp_idx = start_idx;
570 parse_instructions(prog, &temp_idx,
571 p_iD, p_inH, p_maxH, p_r,
572 p_iL, p_inL, p_maxL, p_k,
573 p_n, pmin, p_detector_shift, debug);
576 *p_line_idx = temp_idx;
579 while (*p_line_idx < prog->size && depth > 0) {
580 char *s = prog->
lines[*p_line_idx];
582 while (isspace(*s)) s++;
583 if (strncmp(s,
"repeat", 6) == 0 && strchr(s,
'{')) depth++;
584 if (*s ==
'}') depth--;
592 if (sscanf(c,
"shift_detectors ( %*[^)] ) %d %n", &shift_val, &num) == 1) {
593 *p_detector_shift += shift_val;
595 }
else if (sscanf(c,
"shift_detectors %d %n", &shift_val, &num) == 1) {
596 *p_detector_shift += shift_val;
601 if (sscanf(c,
"error( %lg ) %n", &prob, &num) == 1) {
602 if ((prob <= 0) || (prob >= 1))
603 ERROR(
"probability should be in (0,1) exclusive p=%g\n"
604 "line %d: '%s'\n", prob, *p_line_idx, line);
612 while (isspace(c[0])) c++;
613 if (c[0] ==
'\0' || c[0] ==
'#' || c[0] ==
'\n')
break;
616 if (sscanf(c,
"D%d%n", &val, &num) == 1) {
619 int shifted_val = val + *p_detector_shift;
620 if (shifted_val >= *p_r)
621 *p_r = shifted_val + 1;
622 if (*p_iD >= *p_maxH) {
623 *p_maxH = 2 * (*p_maxH);
624 *p_inH = realloc(*p_inH, (*p_maxH) *
sizeof(**p_inH));
626 (*p_inH)[*p_iD].a = shifted_val;
627 (*p_inH)[*p_iD].b = *p_n;
629 }
else if (sscanf(c,
"L%d%n", &val, &num) == 1) {
634 if (*p_iL >= *p_maxL) {
635 *p_maxL = 2 * (*p_maxL);
636 *p_inL = realloc(*p_inL, (*p_maxL) *
sizeof(**p_inL));
638 (*p_inL)[*p_iL].a = val;
639 (*p_inL)[*p_iL].b = *p_n;
641 }
else if (c[0] ==
'^') {
644 ERROR(
"unrecognized entry %s in error line %d: '%s'\n", c, *p_line_idx, line);
651 if (strncmp(c,
"detector", 8) == 0) {
655 if (strncmp(c,
"logical_observable", 18) == 0) {
659 ERROR(
"unrecognized DEM entry in line %d: '%s'\n", *p_line_idx, line);
666 int maxH=100, maxL=100;
670 ERROR(
"memory allocation failed\n");
674 int detector_shift = 0;
677 parse_instructions(prog, &line_idx,
678 &iD, &inH, &maxH, &r,
679 &iL, &inL, &maxL, &k,
680 &n, pmin, &detector_shift, debug);
682 if (line_idx < prog->size) {
683 ERROR(
"Unmatched '}' in DEM file %s at line %d\n", fnam, line_idx);
687 fprintf(stderr,
"# read DEM %s: rows_H=%d rows_L=%d cols=%d; nz_H=%d nz_L=%d\n",fnam,r,k,n,iD,iL);
688 if((r<=0)||(k<=0)||(n<=0))
689 ERROR(
"invalid DEM file %s: rows_H=%d rows_L=%d cols=%d; nz_H=%d nz_L=%d\n",
697 free_dem_program(prog);
701 FILE *f=fopen(fnam,
"w");
703 fprintf(stderr,
"FILE I/O ERROR: %s\n", strerror(errno));
704 ERROR(
"can't open file %s for writing",fnam);
706 fprintf(f,
"%%%% NZLIST\n");
708 fprintf(f,
"%% %s\n",comment);
713 assert(vec && vec->
weight >0 );
716 if(fprintf(f,
"%d ",w)<=0)
717 ERROR(
"can't write to `NZLIST` file");
718 for(
int i=0; i < w; i++)
719 if(fprintf(f,
" %d%s", 1 + vec->
arr[i], i+1 < w ?
"" :
"\n")<=0)
720 ERROR(
"can't write to `NZLIST` file");
725 FILE *f=fopen(fnam,
"r");
746 if ( ferror (f)|| feof(f) )
763 if(fscanf(f,
" %d",&w) != 1){
764 if (feof(f))
return NULL;
765 fprintf(stderr,
"%s:%lld: invalid NZLIST entry\n", fnam, *lineno);
766 ERROR(
"expected an integer");
768 if ((vec!=NULL) && (vec->
weight<w)){
773 vec = calloc(
sizeof(
cw_vec_t)+w*
sizeof(
int),
sizeof(
char));
775 ERROR(
"memory allocation");
779 for(
int i=0; i<w; i++){
780 if(fscanf(f,
" %d ",vec->
arr + i) != 1){
781 fprintf(stderr,
"%s:%lld: invalid entry of weight w=%d\n",fnam, *lineno, w);
782 ERROR(
"expected an integer i=%d of %d",i,w);
787 for(
int i=1; i<w; i++){
788 if((vec->
arr[i-1] < 0) || (vec->
arr[i-1] >= vec->
arr[i])){
789 fprintf(stderr,
"%s:%lld: invalid entry of weight w=%d\n",fnam, *lineno, w);
790 ERROR(
"expected strictly increasing positive entries");
803 if (weight > max_allowed_w) {
807 const size_t keylen = weight *
sizeof(int);
812 if (!entry)
ERROR(
"memory allocation");
815 for (
int i = 0; i < weight; i++) {
816 entry->
arr[i] = arr[i];
822 if (weight < p->min_w) {
827 if (cw->
weight > prune_w) {
841 long long int count = 0, lineno;
842 long long int skipped_invalid = 0;
846 if ((
p->
outC ==NULL) || (strcmp(fnam,
p->
outC)!=0)){
847 fprintf(stderr,
"codeword input file I/O ERROR: %s, outC=%s\n", strerror(errno),
p->
outC);
848 ERROR(
"can't open file %s for reading",fnam);
861 if (sparse_syndrome_non_zero(
p->
spaH, entry->
weight, entry->
arr)) {
865 if (valid &&
p->
spaL) {
866 if (!sparse_syndrome_non_zero(
p->
spaL, entry->
weight, entry->
arr)) {
885 if (skipped_invalid > 0) {
886 fprintf(stderr,
"# Warning: skipped %lld invalid codewords (not orthogonal to H or orthogonal to L)\n", skipped_invalid);
889 fprintf(stderr,
"# read %lld codewords from %s, total %lld\n",count, fnam,
p->
num_cws);
894 long long int count=0;
int swei[MAX_W]
int max_row_wt; /* WARNING: this is defined in util_io.h as static const int */
#define HASH_DEL(head, delptr)
#define HASH_ITER(hh, head, el, tmp)
#define HASH_ADD(hh, head, fieldname, keylen_in, add)
#define HASH_FIND(hh, head, keyptr, keylen, out)
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.
int nzlist_w_append(FILE *f, const cw_vec_t *const vec)
FILE * nzlist_w_new(const char fnam[], const char comment[])
void var_kill(params_t *const p)
Clean up and free memory allocated in the params_t structure.
FILE * nzlist_r_open(const char fnam[], long long int *lineno)
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.
cw_vec_t * nzlist_r_one(FILE *f, cw_vec_t *vec, const char fnam[], long long int *lineno)
cw_vec_t * codeword_add_maybe(params_t *const p, const int arr[], int weight)
Add a candidate codeword to the hash table if it meets weight limits.
long long int nzlist_write(const char fnam[], const char comment[], params_t *p)
Write the found codewords from the hash table to a .nz file.
void var_init(int argc, char **argv, params_t *const p)
Initialize parameters and load matrices from command line arguments.
int csr_csr_mul_non_zero(const csr_t *const A, const csr_t *const B)
Check if the product of two sparse matrices A * B^T is non-zero.
csr_t * csr_from_pairs(csr_t *mat, const int nz, int_pair *const prs, const int nrows, const int ncols)
Construct a CSR sparse matrix from an array of coordinate pairs.
csr_t * csr_mm_read(char *fin, csr_t *mat, int transpose)
Read a sparse matrix from a Matrix Market (.mtx) file into CSR format.
csr_t * Lx_for_CSS_code(const csr_t *const Hx, const csr_t *const Hz)
Compute logical generator matrix Lx for a CSS code.
void csr_print(const csr_t *const smat, const char str[])
Print a CSR matrix with a label string (formatted output).
csr_t * csr_free(csr_t *p)
Free memory allocated for a CSR sparse matrix.