AVX2 counting function for small-range 1-byte /⁼
This commit is contained in:
parent
a0cdcdc898
commit
b655dd4771
@ -604,6 +604,7 @@ cachedBin‿linkerCache ← {
|
||||
"2.."‿"src/builtins/select.c"‿"select", "2.."‿"src/builtins/scan.c"‿"scan",
|
||||
"2.."‿"src/builtins/fold.c"‿"fold", "2.."‿"src/builtins/slash.c"‿"slash",
|
||||
"2.."‿"src/builtins/slash.c"‿"constrep", "2.."‿"src/builtins/scan.c"‿"neq",
|
||||
"2.."‿"src/builtins/slash.c"‿"count"
|
||||
⟩
|
||||
objs ← ⟨⟩
|
||||
|
||||
|
||||
2
makefile
2
makefile
@ -352,7 +352,7 @@ endif
|
||||
@"${MAKE}" i_singeli=0 singeli=0 force_build_dir=build/obj/presingeli REPLXX=0 f= lf= postmsg="singeli sources:" i_t=presingeli i_f='-O1 -DPRE_SINGELI' FFI=0 OUTPUT=build/obj/presingeli/BQN c
|
||||
|
||||
|
||||
build_singeli: ${addprefix src/singeli/gen/, cmp.c dyarith.c monarith.c copy.c equal.c squeeze.c select.c fold.c scan.c neq.c slash.c constrep.c bits.c transpose.c}
|
||||
build_singeli: ${addprefix src/singeli/gen/, cmp.c dyarith.c monarith.c copy.c equal.c squeeze.c select.c fold.c scan.c neq.c slash.c constrep.c count.c bits.c transpose.c}
|
||||
@echo $(postmsg)
|
||||
src/singeli/gen/%.c: src/singeli/src/%.singeli preSingeliBin
|
||||
@echo $< | cut -c 17- | sed 's/^/ /'
|
||||
|
||||
@ -850,6 +850,14 @@ B slash_c2(B t, B w, B x) {
|
||||
return c2rt(slash, w, x);
|
||||
}
|
||||
|
||||
#if SINGELI_AVX2
|
||||
#define SINGELI_FILE count
|
||||
#include "../utils/includeSingeli.h"
|
||||
#define SINGELI_COUNT_OR(N) \
|
||||
if (N==8) avx2_count_i8(t, (u8*)xp, xia); else
|
||||
#else
|
||||
#define SINGELI_COUNT_OR(N)
|
||||
#endif
|
||||
|
||||
B slash_im(B t, B x) {
|
||||
if (!isArr(x) || RNK(x)!=1) thrM("/⁼: Argument must be an array");
|
||||
@ -907,7 +915,7 @@ B slash_im(B t, B x) {
|
||||
} else { \
|
||||
TALLOC(usz, t, m); \
|
||||
for (usz j=0; j<m/2; j++) t[j]=0; \
|
||||
for (usz i=0; i<xia; i++) t[(u##N)xp[i]]++; \
|
||||
SINGELI_COUNT_OR(N) for (usz i=0; i<xia; i++) t[(u##N)xp[i]]++; \
|
||||
t[m/2]=xia; usz ria=0; for (u64 s=0; s<xia; ria++) s+=t[ria]; \
|
||||
if (ria>m/2) thrM("/⁼: Argument cannot contain negative numbers"); \
|
||||
i32* rp; r = m_i32arrv(&rp, ria); for (usz i=0; i<ria; i++) rp[i]=t[i]; \
|
||||
|
||||
71
src/singeli/src/count.singeli
Normal file
71
src/singeli/src/count.singeli
Normal file
@ -0,0 +1,71 @@
|
||||
include './base'
|
||||
include './sse'
|
||||
include './avx'
|
||||
include './avx2'
|
||||
include 'util/tup'
|
||||
|
||||
# TODO merge with squeeze
|
||||
def fold{F, x:T} = {
|
||||
show{'WARNING: using fallback fold'}
|
||||
def E = eltype{T}
|
||||
r:E = 0
|
||||
each{{i} => { r = F{r, extract{x, i}} }, iota{vcount{T}}}
|
||||
r
|
||||
}
|
||||
def fold{F, x:T & width{T}==128 & hasarch{'X86_64'}} = {
|
||||
c:= x
|
||||
def EW = elwidth{T}
|
||||
if (EW<=64) c = F{c, shuf{[4]u32, c, 4b1032}}
|
||||
if (EW<=32) c = F{c, shuf{[4]u32, c, 4b2301}}
|
||||
if (EW<=16) c = F{c, sel{[16]u8, c, make{[16]i8, iota{16}^2}}}
|
||||
if (EW<=8) c = F{c, sel{[16]u8, c, make{[16]i8, iota{16}^1}}}
|
||||
extract{c, 0}
|
||||
}
|
||||
def fold{F, x:T & width{T}==256 & hasarch{'X86_64'}} = fold{F, F{half{x, 0}, half{x, 1}}}
|
||||
|
||||
def inc{ptr, ind, v} = store{ptr, ind, v + load{ptr, ind}}
|
||||
def inc{ptr, ind} = inc{ptr, ind, 1}
|
||||
|
||||
fn count{T}(tab:*usz, x:*ty_u{T}, n:u64) : u1 = {
|
||||
def vbits = 256
|
||||
def vec = vbits/width{T}
|
||||
def uT = ty_u{T}
|
||||
def V = [vec]uT
|
||||
def iV = [vec]T
|
||||
def block = (1024*8) / vbits # Desired vectors per block
|
||||
i:u64 = 0
|
||||
while (i < n) {
|
||||
r:u64 = n - i
|
||||
b := r / vec
|
||||
xv := *V~~x
|
||||
used_eq:u1 = 0
|
||||
if (r >= 256) {
|
||||
b = block; if (r < vec*b) b = r / vec
|
||||
mv := V**0
|
||||
@for (xv over b) mv = max{mv, xv}
|
||||
mi := iV~~mv
|
||||
if (homAny{mi < iV**0}) return{1}
|
||||
if (homAll{mi <= iV**32}) {
|
||||
used_eq = 1
|
||||
r = b * vec
|
||||
m := fold{max, mv}
|
||||
total := b*vec
|
||||
@for (j to promote{u64,m}) {
|
||||
c := V**0
|
||||
e := V**trunc{uT, j}
|
||||
@for (xv over b) c -= xv == e
|
||||
s := fold{+, [vec/2]i16~~fold{+, unpackQ{iV~~c, iV**0}}}
|
||||
total -= promote{u64, s}
|
||||
inc{tab, j, promote{usz, s}}
|
||||
}
|
||||
inc{tab, m, trunc{usz,total}}
|
||||
}
|
||||
}
|
||||
if (not used_eq) @for (x over r) inc{tab, x}
|
||||
i += r
|
||||
x += r
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
export{'avx2_count_i8', count{i8}}
|
||||
Loading…
Reference in New Issue
Block a user