Clean up scan_rows_bit logic and implement -˘ as (2×⊣˘)-+`˘

This commit is contained in:
Marshall Lochbaum 2024-06-03 18:49:32 -04:00
parent efde979fe9
commit 6d27dd391b
2 changed files with 45 additions and 39 deletions

View File

@ -9,7 +9,7 @@ B shape_c2(B, B, B);
B transp_c2(B, B, B); B transp_c2(B, B, B);
B fold_rows(Md1D* d, B x); // from fold.c B fold_rows(Md1D* d, B x); // from fold.c
B fold_rows_bit(Md1D* d, B x); // from fold.c B fold_rows_bit(Md1D* d, B x); // from fold.c
B scan_rows_bit(Md1D* d, B x); // from scan.c B scan_rows_bit(u8, B x); // from scan.c
B takedrop_highrank(bool take, B w, B x); // from sfns.c B takedrop_highrank(bool take, B w, B x); // from sfns.c
B try_interleave_cells(B w, B x, ur xr, ur xk, usz* xsh); // from transpose.c B try_interleave_cells(B w, B x, ur xr, ur xk, usz* xsh); // from transpose.c
@ -470,7 +470,7 @@ B for_cells_c1(B f, u32 xr, u32 cr, u32 k, B x, u32 chr) { // F⎉cr x, with arr
u8 frtid = v(fd->f)->flags-1; u8 frtid = v(fd->f)->flags-1;
if (frtid==n_rtack) return x; if (frtid==n_rtack) return x;
if (k==1 && xr==2 && (isPervasiveDyExt(fd->f)||frtid==n_ltack) && TI(x,elType)==el_bit) { if (k==1 && xr==2 && (isPervasiveDyExt(fd->f)||frtid==n_ltack) && TI(x,elType)==el_bit) {
B r = scan_rows_bit(fd, x); if (!q_N(r)) return r; B r = scan_rows_bit(frtid, x); if (!q_N(r)) return r;
} }
} }
} else if (TY(f) == t_md2D) { } else if (TY(f) == t_md2D) {

View File

@ -12,8 +12,9 @@ static u64 vg_rand(u64 x) { return x; }
B slash_c1(B, B); B slash_c1(B, B);
B shape_c2(B, B, B); B shape_c2(B, B, B);
B fne_c1(B, B); B fne_c1(B, B);
B sub_c2(B, B, B);
B add_c2(B, B, B); B add_c2(B, B, B);
B sub_c2(B, B, B);
B mul_c2(B, B, B);
#if SINGELI #if SINGELI
#define SINGELI_FILE scan #define SINGELI_FILE scan
@ -340,45 +341,50 @@ B scan_c2(Md1D* d, B w, B x) { B f = d->f;
return withFill(r.b, wf); return withFill(r.b, wf);
} }
B scan_rows_bit(Md1D* fd, B x) { B scan_rows_bit(u8 rtid, B x) {
assert(isArr(x) && RNK(x)==2 && TI(x,elType)==el_bit); assert(isArr(x) && RNK(x)==2 && TI(x,elType)==el_bit);
#if SINGELI #if SINGELI
if (!v(fd->f)->flags) return bi_N; switch (rtid) { default: return bi_N;
u8 rtid = v(fd->f)->flags-1; case n_eq: return bit_negate(scan_rows_bit(n_ne, bit_negate(x)));
if (rtid==n_and|rtid==n_or|rtid==n_ne|rtid==n_eq|rtid==n_ltack) { case n_and: case n_or: case n_ne: case n_ltack: {
if (rtid==n_eq) x = bit_negate(x); usz *sh = SH(x); usz n = sh[0]; usz m = sh[1];
usz *sh = SH(x); usz n = sh[0]; usz m = sh[1]; u64* xp = bitarr_ptr(x);
u64* xp = bitarr_ptr(x); u64* rp; B r = m_bitarrc(&rp, x);
u64* rp; B r = m_bitarrc(&rp, x); switch (rtid) { default:UD;
if (rtid==n_and ) si_scan_rows_and (xp, rp, n, m); case n_and: si_scan_rows_and (xp, rp, n, m); break;
else if (rtid==n_or ) si_scan_rows_or (xp, rp, n, m); case n_or: si_scan_rows_or (xp, rp, n, m); break;
else if (rtid==n_ltack) si_scan_rows_ltack(xp, rp, n, m); case n_ne: si_scan_rows_ne (xp, rp, n, m); break;
else si_scan_rows_ne (xp, rp, n, m); case n_ltack: si_scan_rows_ltack(xp, rp, n, m); break;
decG(x); return rtid==n_eq ? bit_negate(r) : r; }
} decG(x); return r;
if (rtid==n_add && SH(x)[1]<128) { }
usz ia = IA(x); usz m = SH(x)[1]; case n_add: case n_sub: {
usz bl = 128; // block size usz ia = IA(x); usz m = SH(x)[1];
i8 buf[bl]; i8 c = 0; if (m >= 128) return bi_N;
u64* xp = bitarr_ptr(x); usz bl = 128; // block size
i8* rp; B r = m_i8arrc(&rp, x); i8 buf[bl]; i8 c = 0;
u64 ms[7] = { 0x00ff00ff00ff00ff, 0x00ff0000ff0000ff, 0x000000ff000000ff, 0x0000ff00000000ff, 0x00ff0000000000ff, 0xff000000000000ff, 0 }; u64* xp = bitarr_ptr(x);
u64 mm = ms[m-2>6? 6 : m-2]; usz mk = m*(POPC(mm)/8); i8* rp; B r = m_i8arrc(&rp, x);
for (usz i = 0, j = m; i < ia; i += bl) { u64 ms[7] = { 0x00ff00ff00ff00ff, 0x00ff0000ff0000ff, 0x000000ff000000ff, 0x0000ff00000000ff, 0x00ff0000000000ff, 0xff000000000000ff, 0 };
usz len = ia - i; if (len > bl) len = bl; u64 mm = ms[m-2>6? 6 : m-2]; usz mk = m*(POPC(mm)/8);
usz e = i + len; for (usz i = 0, j = m; i < ia; i += bl) {
si_bcs8(xp + i/64, buf, len); usz len = ia - i; if (len > bl) len = bl;
memset(rp+i, -c, len); usz e = i + len;
i8* bi = buf-i; si_bcs8(xp + i/64, buf, len);
assert(j > i); memset(rp+i, -c, len);
if (mk) while (j+mk <= e) { *(u64*)(rp+j) = *(u64*)(bi+j-1) & mm; j+=mk; } i8* bi = buf-i;
for (; j < e; j += m) rp[j] = bi[j-1]; assert(j > i);
si_scan_max_init_i8(rp+i, rp+i, len, I8_MIN); if (mk) while (j+mk <= e) { *(u64*)(rp+j) = *(u64*)(bi+j-1) & mm; j+=mk; }
for (usz k = i; k < e; k++) rp[k] = bi[k] - rp[k]; for (; j < e; j += m) rp[j] = bi[j-1];
if (j == e) { j += m; c = 0; } else c = rp[e-1]; si_scan_max_init_i8(rp+i, rp+i, len, I8_MIN);
for (usz k = i; k < e; k++) rp[k] = bi[k] - rp[k];
if (j == e) { j += m; c = 0; } else c = rp[e-1];
}
if (rtid!=n_sub) { decG(x); return r; }
return C2(sub, C2(mul, m_f64(2), scan_rows_bit(n_ltack, x)), r);
} }
decG(x); return r;
} }
#endif #else
return bi_N; return bi_N;
#endif
} }