39 const csr_t *
const spaH0 =
p->spaH;
40 const csr_t *
const spaL0 =
p->spaL;
41 const int steps =
p->steps;
42 const int wmin =
p->wmin;
43 const int wmax =
p->wmax;
44 const int classical =
p->classical;
45 const int debug =
p->debug;
47 const int nvar = spaH0->
cols;
48 if(((!classical)&&(spaL0==NULL)) ||
49 ((classical)&&(spaL0!=NULL))){
50 printf(
"L0 %s NULL classical=%d\n",spaL0==NULL ?
"=" :
"!=", classical);
51 ERROR(
"L0 should be non-NULL only for classical code!\n");
55 if (
p->dmax > 0 &&
p->dmax < minW) {
58 if (
p->min_w != INT_MAX &&
p->min_w < minW) {
63 printf(
"# running do_RW_dist() with steps=%d wmin=%d wmax=%d classical=%d nvar=%d\n",
64 steps, wmin, wmax, classical, nvar);
69 rci_t *ee = malloc(nvar*
sizeof(rci_t));
72 ERROR(
"memory allocation failed!\n");
75 mzp_t * perm=mzp_init(nvar);
76 mzp_t * pivs=mzp_init(nvar);
77 word * piv_mask=calloc(mH->width,
sizeof(word));
78 if((!pivs) || (!perm) || (!piv_mask))
79 ERROR(
"memory allocation failed!\n");
80 int eff_nrows = spaH0->
rows;
87 if (2 * spaH0->
rows < nvar) {
90 "# Warning: ksub=%d requested, but m=%d < n-m=%d (<= nu); "
91 "falling back to full-matrix RW (ksub=0)\n",
92 p->ksub, spaH0->
rows, nvar - spaH0->
rows);
97 nu = N_ker ? N_ker->nrows : 0;
98 if (spaH0->
rows < nu || nu <= 0) {
101 "# Warning: ksub=%d requested, but m=%d < nu=%d; "
102 "falling back to full-matrix RW (ksub=0)\n",
103 p->ksub, spaH0->
rows, nu);
112 ksub_eff = minint(
p->ksub, nu);
114 M_sub = mzd_init(ksub_eff, nvar);
120 csr_t *mHT_csr = NULL;
121 int *visited_cols = NULL;
122 int *visited_checks = NULL;
123 int *col_queue = NULL;
124 int visit_marker = 0;
125 uint64_t rng_state = (uint64_t)
p->seed + 0x517cc1b727220a95ULL;
126 if ((
p->kwin > 0 &&
p->kwin < nvar) || nvar >= 500) {
128 visited_cols = calloc(nvar,
sizeof(
int));
129 visited_checks = calloc(spaH0->
rows,
sizeof(
int));
130 col_queue = calloc(nvar,
sizeof(
int));
133 for (
int ii=0; ii< steps; ii++){
134 int eff_kwin =
p->kwin;
135 int eff_win_mode =
p->win_mode;
136 if (eff_kwin == 0 && nvar >= 500 && (ii & 1) == 1) {
137 eff_kwin = rw_hybrid_window(
p, nvar);
142 if (eff_kwin > 0 && eff_kwin < nvar) {
145 spaH0, mHT_csr, visited_cols, visited_checks,
146 col_queue, &visit_marker, &rng_state);
154 if (ksub_eff <= 0)
break;
155 for (
int i = 0; i < ksub_eff; i++) {
157 mzd_copy_row(M_sub, i, N_ker, r);
160 for (
int i = 0; i < nvar && rank < ksub_eff; i++) {
161 int col = perm->values[i];
162 if (gauss_one(M_sub, col, rank)) {
166 for (
int ir = 0; ir < rank; ir++) {
168 const int cur_d = (minW <= nvar) ? minW : 0;
170 word *rawrow = mzd_row(M_sub, ir);
172 while (cnt < limit) {
173 j = nextelement(rawrow, M_sub->width, j);
174 if (j == -1 || j >= nvar)
break;
177 if (cnt > 0 && cnt < limit) {
178 int nz = classical ? 1 : sparse_syndrome_non_zero(spaL0, cnt, ee);
181 if (cnt < minW) minW = cnt;
191 if (
p->refresh > 0 && (ii + 1) %
p->refresh == 0) {
193 if (
p->codewords &&
p->min_w < nvar) {
198 for (
int k = 0; k < cw_wt; k++) ee[k] = cw->
arr[k];
209 memset(piv_mask, 0, mH->width *
sizeof(word));
211 for (
int i = 0; i < nvar && rank < eff_nrows; i++) {
212 int col = perm->values[i];
213 if (gauss_one_rows(mH, col, rank, eff_nrows)) {
214 pivs->values[rank++] = col;
215 piv_mask[col >> 6] |= (word)1 << (col & 63);
225 mHT = mzd_transpose(mHT,mH);
233 for (
int col = 0, ir = 0; col < nvar; col++){
234 if ((piv_mask[col >> 6] >> (col & 63)) & 1)
continue;
238 const int cur_d = (minW <= nvar) ? minW : 0;
242 for(
int ix=0; ix<rank; ix++){
243 if(mzd_read_bit(mH,ix,col))
244 ee[cnt++] = pivs->values[ix];
256 int res = mzd_find_pivot(mH, ix, col, &ix, &ic);
257 if((res)&&(ic==col)){
258 ee[cnt++] = pivs->values[ix++];
267 word * rawrow = mzd_row(mHT,col);
269 const int active_width = (rank + 63) >> 6;
271 j=nextelement(rawrow,active_width,j);
272 if(j==-1 || j >= rank)
274 ee[cnt++] = pivs->values[j++];
279 rci_quick_sort(ee, cnt);
282 if(sparse_syndrome_non_zero(spaH0, cnt, ee)){
283 printf(
"# cw of weight %d: [",cnt);
284 for(
int i=0; i<cnt;i++)
285 printf(
"%d%s",ee[i],i+1==cnt?
" ":
"]\n");
286 ERROR(
"this should not happen: cw not orthogonal to H");
295 nz = sparse_syndrome_non_zero(spaL0, cnt, ee);
301 printf(
"# step=%d row=%d minW=%d found cw of W=%d: [",ii,ir,minW,cnt);
302 const int max = ((cnt<25) || (debug &
DBG_LARGE)) ? cnt : 25 ;
303 for(
int i=0; i< max; i++)
304 printf(
"%d%s", ee[i], i+1!=max?
" ": (cnt==max ?
"]\n" :
"...]\n"));
324 printf(
"# round=%d of %d minW=%d\n", ii+1, steps, minW);
332 if (M_sub) mzd_free(M_sub);
333 if (N_ker) mzd_free(N_ker);
336 free(visited_checks);
349 if (
p->min_w == INT_MAX) {
352 if (wmax > 0 &&
p->min_w > wmax) {
void localized_window_perm(mzp_t *perm, int nvar, int seed_col, int kwin, int win_mode, const csr_t *spaH, const csr_t *mHT, int *visited_cols, int *visited_checks, int *col_queue, int *visit_marker, uint64_t *rng_state)
Construct a column permutation with a localized window at the front.