From 87a7d066c8db14f9a7c4511b9e09cbe13704287b Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Sat, 1 Mar 2025 08:42:36 -0500 Subject: [PATCH] =?UTF-8?q?Strided=20=E2=8C=8A=E2=8C=88=20scans=20with=20s?= =?UTF-8?q?huffles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/scan.c | 7 ++++ src/singeli/src/scan.singeli | 67 ++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/builtins/scan.c b/src/builtins/scan.c index d0418dea..5de4cf58 100644 --- a/src/builtins/scan.c +++ b/src/builtins/scan.c @@ -273,6 +273,13 @@ B scan_c1(Md1D* d, B x) { B f = d->f; if (neg) r = bit_negate(r); decG(x); return r; } + if (rtid==n_floor | rtid==n_ceil) { + // boolean was handled as CASE_N_AND + B r; void* rp = m_tyarrc(&r, elWidth(xe), x, el2t(xe)); + void* xp = tyany_ptr(x); + si_scan_stride_minmax[4*(rtid==n_ceil) + xe-el_i8](xp, rp, ia, csz); + decG(x); return r; + } #endif goto base; }} diff --git a/src/singeli/src/scan.singeli b/src/singeli/src/scan.singeli index 9420957b..1d98c5bf 100644 --- a/src/singeli/src/scan.singeli +++ b/src/singeli/src/scan.singeli @@ -98,6 +98,73 @@ def shift_first{c:V=[l]_, p:V} = { else blend_first{c, rotate_right{p}} } + +# Strided scans +fn scan_stride_assoc{op, T}(xv:*void, rv:*void, ia:usz, l:usz) : void = { + def id = match (op) { {(min)} => maxvalue; {(max)} => minvalue } + def f = width{T}/8; def vl = 16/f + x:= *T~~xv; r:= *T~~rv + def has_shuf = hasarch{'SSSE3'} or hasarch{'AARCH64'} + if (has_shuf and T<=i32 and l= I**fq; def bl = blend_hom{..., bv} + def V = [vl]T + c:= V**id{T} + o:= l - q + if (l == 2*vl) { o = vl; bv = ~bv } + if (o == vl) { + p:= load{*V~~x}; store{*V~~r, 0, p} + @for_masked{vl} (x in tup{V, x+o}, r in tup{V, r+o} over ia-o) { + p = rot{p} + r = op{bl{c, p}, x} + c = p; p = r + } + } else { + @for_masked{vl} (x in tup{V, x+o}, r in tup{V, r+o}, p in tup{V, r} over ia-o) { + q:= rot{p} + r = op{bl{c, q}, x} + c = q + } + } + } else { + @for (r, x, p in r-l over _ from l to ia) r = op{p, x} + } + } +} +export_tab{'si_scan_stride_minmax', + flat_table{scan_stride_assoc, tup{min,max}, tup{i8,i16,i32,f64}} +} + + # xor scan def vec_prefix_byshift{op, sh} = { def pre{v:V, k} = if (k < elwidth{V}) pre{op{v, sh{v,k}}, 2*k} else v