Basic strided ∧∨≠= scan implementations

This commit is contained in:
Marshall Lochbaum 2025-02-28 14:24:58 -05:00
parent 90d0f3015a
commit ee6b91be8a
2 changed files with 51 additions and 1 deletions

View File

@ -258,7 +258,24 @@ B scan_c1(Md1D* d, B x) { B f = d->f;
return C2(shape, s, taga(r)); return C2(shape, s, taga(r));
} }
if (xe > el_f64) goto base; if (xe > el_f64) goto base;
if (xr!=1 && arr_csz(x)!=1) goto base; if (xr != 1) { usz csz = arr_csz(x); if (csz != 1) {
#if SINGELI
i8 t = -1; bool neg = 0;
if (xe==el_bit) switch (rtid) {
CASE_N_OR: t=0; break;
CASE_N_AND: t=1; break;
case n_eq: neg=1; case n_ne: t=2; break;
}
if (t != -1) {
if (neg) x = bit_negate(x);
u64* rp; B r=m_bitarrc(&rp,x);
si_scan_bool_stride[t](bitany_ptr(x), rp, ia, csz);
if (neg) r = bit_negate(r);
decG(x); return r;
}
#endif
goto base;
}}
if (xe==el_bit) switch (rtid) { default: goto base; if (xe==el_bit) switch (rtid) { default: goto base;
case n_add: return scan_add_bool(x, ia); // + case n_add: return scan_add_bool(x, ia); // +

View File

@ -620,3 +620,36 @@ export{'si_scan_rows_and', scan_rows_andor{0}}
export{'si_scan_rows_or', scan_rows_andor{1}} export{'si_scan_rows_or', scan_rows_andor{1}}
export{'si_scan_rows_ne', scan_rows_neq} export{'si_scan_rows_ne', scan_rows_neq}
export{'si_scan_rows_ltack', scan_rows_left} export{'si_scan_rows_ltack', scan_rows_left}
# Strided boolean scans
fn scan_stride_bool_assoc{op}(x:*u64, r:*u64, nl:usz, l:usz) : void = {
assert{l > 1}
def {flip,opf} = if (same{op, &}) tup{~,|} else tup{{x}=>x,op}
nw:= cdiv{nl, 64}
if (l <= 64) {
c:u64 = 0 # carry l bits, no matter the alignment
@for (r, x over nw) {
c = opf{flip{x}, c >> (64-l)}
s:= l; while (s < 64) { c = opf{c, c<<s}; s += s }
r = flip{c}
}
} else {
fw:= cdiv{l, 64} # words in first cell
@for (r, x over fw) r = x
if (l%64 == 0) {
@for (r, x, p in r-fw over _ from fw to nw) r = op{x, p}
} else {
q:= l%64
c:= flip{u64~~0}
@for (r, x, p in r-(fw-1) over _ from fw-1 to nw) {
r = op{x, c>>(64-q) | p<<q}
c = p
}
}
}
}
export_tab{
'si_scan_bool_stride',
each{scan_stride_bool_assoc, tup{|, &, ^}}
}