singeli +`
This commit is contained in:
parent
826e9c693a
commit
cd431d3338
2
makefile
2
makefile
@ -140,7 +140,7 @@ preSingeliBin:
|
||||
@${MAKE} singeli=0 postmsg="singeli sources:" t=presingeli f='-O1' OUTPUT=obj/presingeli/BQN c
|
||||
|
||||
|
||||
gen-singeli: ${addprefix src/singeli/gen/, cmp.c dyarith.c slash.c equal.c}
|
||||
gen-singeli: ${addprefix src/singeli/gen/, cmp.c dyarith.c slash.c equal.c scan.c}
|
||||
@echo $(postmsg)
|
||||
src/singeli/gen/%.c: src/singeli/src/%.singeli preSingeliBin
|
||||
@echo $< | cut -c 17- | sed 's/^/ /'
|
||||
|
||||
@ -119,6 +119,14 @@ B scan_ne(u64 p, B x, u64 ia) {
|
||||
decG(x); return r;
|
||||
}
|
||||
|
||||
|
||||
#if SINGELI
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#include "../singeli/gen/scan.c"
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
B scan_c1(Md1D* d, B x) { B f = d->f;
|
||||
if (isAtm(x) || rnk(x)==0) thrM("`: Argument cannot have rank 0");
|
||||
ur xr = rnk(x);
|
||||
@ -129,8 +137,13 @@ B scan_c1(Md1D* d, B x) { B f = d->f;
|
||||
if (xr==1 && xe<=el_f64 && isFun(f) && v(f)->flags) {
|
||||
u8 rtid = v(f)->flags-1;
|
||||
if (rtid==n_add) { // +
|
||||
if (ia<I32_MAX) \
|
||||
if (xe==el_bit) { u64* xp=bitarr_ptr(x); i32* rp; B r=m_i32arrv(&rp, ia); i32 c=0; for (usz i=0; i<ia; i++) { c+= bitp_get(xp,i); rp[i]=c; } decG(x); return r; }
|
||||
if (xe==el_bit && ia<I32_MAX) { u64* xp=bitarr_ptr(x); i32* rp; B r=m_i32arrv(&rp, ia);
|
||||
#if SINGELI
|
||||
avx2_bcs32(xp, rp, ia);
|
||||
#else
|
||||
i32 c=0; for (usz i=0; i<ia; i++) { c+= bitp_get(xp,i); rp[i]=c; }
|
||||
#endif
|
||||
decG(x); return r; }
|
||||
if (xe==el_i8 ) { i8* xp=i8any_ptr (x); i32* rp; B r=m_i32arrv(&rp, ia); i32 c=0; for (usz i=0; i<ia; i++) { if(addOn(c,xp[i]))goto base; rp[i]=c; } decG(x); return r; }
|
||||
if (xe==el_i16) { i16* xp=i16any_ptr(x); i32* rp; B r=m_i32arrv(&rp, ia); i32 c=0; for (usz i=0; i<ia; i++) { if(addOn(c,xp[i]))goto base; rp[i]=c; } decG(x); return r; }
|
||||
if (xe==el_i32) { i32* xp=i32any_ptr(x); i32* rp; B r=m_i32arrv(&rp, ia); i32 c=0; for (usz i=0; i<ia; i++) { if(addOn(c,xp[i]))goto base; rp[i]=c; } decG(x); return r; }
|
||||
|
||||
@ -61,6 +61,7 @@ def make{T,a,b,c,d & w256i{T}} = makeGen{T, '_mm256_setr_epi64x', tup{a,b,c,d}}
|
||||
def make{T,a,b,c,d,e,f,g,h & w256i{T}} = makeGen{T, '_mm256_setr_epi32', tup{a,b,c,d,e,f,g,h}}
|
||||
def make{T,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p & w256i{T}} = makeGen{T, '_mm256_setr_epi16', tup{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p}}
|
||||
def make{T,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P & w256i{T}} = makeGen{T, '_mm256_setr_epi8', tup{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P}}
|
||||
def make{T,x & w256{T} & istup{x}} = apply{make, merge{tup{T}, x}}
|
||||
|
||||
def iota{T & w256{T,64}} = make{T,0,1,2,3}
|
||||
def iota{T & w256{T,32}} = make{T,0,1,2,3,4,5,6,7}
|
||||
|
||||
@ -124,7 +124,7 @@ def blendF{f:T, t:T, m:M & w256{T} & w256{M,16}} = blend{f, t, cast_v{[32]i8,m}}
|
||||
|
||||
def shuf{I==[4]u32, x:T, n & w256{T} & knum{n}} = cast_v{T, emit{[8]i32, '_mm256_shuffle_epi32', v2i{x}, n}}
|
||||
def shuf{I==[4]u64, x:T, n & w256{T} & knum{n}} = cast_v{T, emit{[4]f64, '_mm256_permute4x64_pd', v2d{x}, n}}
|
||||
def shufHalves{x:T, y:T, n & w256{T} & knum{n}} = T~~emit{[4]f64, '_mm256_permute2x128_si256', v2i{x}, v2i{y}, n}
|
||||
def shufHalves{x:T, y:T, n & w256{T} & knum{n}} = T~~emit{[4]i64, '_mm256_permute2x128_si256', v2i{x}, v2i{y}, n}
|
||||
|
||||
def sel{I, x:T, i:[8]i32 & w256{I,32}} = cast_v{T, emit{[32]u8, '_mm256_permutevar8x32_epi32', v2i{x}, i}}
|
||||
def sel{I, x:T, i:[32]i8 & w128{I, 8}} = cast_v{T, emit{[32]u8, '_mm256_shuffle_epi8', v2i{x}, i}}
|
||||
|
||||
@ -9,7 +9,16 @@ def ext {T, x:U & isint{T} & isint{U} & T>=U} = emit{T, '', x}
|
||||
def trunc{T, x & knum{x}} = cast{T, x}
|
||||
def ext {T, x & knum{x}} = cast{T, x}
|
||||
|
||||
# basic ceiling divide
|
||||
def cdiv{a,b} = (a+b-1)/b
|
||||
|
||||
# base-2 log of a constant power of two
|
||||
def lb{n & knum{n} & (n>>1<<1) == n & n>0} = lb{n>>1}+1
|
||||
def lb{n==1} = 0
|
||||
|
||||
# get the n least significant bits
|
||||
def lsbs{x, n} = x - (x>>n << n)
|
||||
|
||||
def rare{x:u1} = emit{u1, '__builtin_expect', x, 0}
|
||||
def isunsigned{T} = isint{T} & ~issigned{T}
|
||||
def assert{x:u1} = emit{void, 'si_assert', x}
|
||||
@ -88,6 +97,7 @@ def isfloatv{T} = isfloat{eltype{T}}
|
||||
def issignedv{T} = issigned{eltype{T}}
|
||||
def isunsignedv{T} = isunsigned{eltype{T}}
|
||||
def istype{T} = match{kind{T},'type'}
|
||||
def istup{T} = match{kind{T},'tuple'}
|
||||
def isvec{T} = 0
|
||||
def isvec{T & istype{T}} = match{typekind{T},'vector'}
|
||||
|
||||
|
||||
6
src/singeli/src/bmi2.singeli
Normal file
6
src/singeli/src/bmi2.singeli
Normal file
@ -0,0 +1,6 @@
|
||||
def pdep{x:u64, m:u64} = emit{u64, '_pdep_u64', x, m}
|
||||
def pdep{x:u32, m:u32} = emit{u32, '_pdep_u32', x, m}
|
||||
def pext{x:u64, m:u64} = emit{u64, '_pext_u64', x, m}
|
||||
def pext{x:u32, m:u32} = emit{u32, '_pext_u32', x, m}
|
||||
def popc{x:T & isint{T} & width{T}==64} = emit{u8, '__builtin_popcountll', x}
|
||||
def popc{x:T & isint{T} & width{T}<=32} = emit{u8, '__builtin_popcount', x}
|
||||
36
src/singeli/src/scan.singeli
Normal file
36
src/singeli/src/scan.singeli
Normal file
@ -0,0 +1,36 @@
|
||||
include '/home/dzaima/D/cbqn/src/singeli/src/base'
|
||||
# def Size = u64
|
||||
include '/home/dzaima/D/cbqn/src/singeli/src/sse3'
|
||||
include '/home/dzaima/D/cbqn/src/singeli/src/avx'
|
||||
include '/home/dzaima/D/cbqn/src/singeli/src/avx2'
|
||||
include '/home/dzaima/D/cbqn/src/singeli/src/bmi2'
|
||||
include '/home/dzaima/D/cbqn/src/singeli/src/mask'
|
||||
|
||||
avx2_bcs32(x:*u64, r:*i32, l:u64) : void = {
|
||||
rv:= *[8]u32~~r
|
||||
xv:= *u8~~x
|
||||
|
||||
def step{x} = {
|
||||
m:u32 = 2b0001_0001_0001_0001_0001_0001_0001_0001
|
||||
a:= pdep{promote{u32,x},m}
|
||||
d:= a*m # b:= a + a<<16; c:= b + b<<8; d:= c + c<<4
|
||||
e:= broadcast{[8]u32, d}
|
||||
f:= e >> make{[8]u32, iota{8}*4}
|
||||
tup{f & broadcast{[8]u32, 0xf}, d, e}
|
||||
}
|
||||
|
||||
c:= broadcast{[8]u32, 0}
|
||||
e:= l/8
|
||||
@for(x in xv, r in rv over _ to e) {
|
||||
def sr = step{x}
|
||||
r = tupsel{0, sr}+c
|
||||
# c+= broadcast{[8]u32, popc{x}}
|
||||
# c+= broadcast{[8]u32, tupsel{1, sr}>>28}
|
||||
c+= tupsel{2, sr}>>28
|
||||
}
|
||||
if (e*8 != l) {
|
||||
r:= c+tupsel{0, step{load{xv, e}}}
|
||||
maskstoreF{rv, maskOf{[8]i32, l - e*8}, e, r}
|
||||
}
|
||||
}
|
||||
'avx2_bcs32' = avx2_bcs32
|
||||
@ -1,11 +1,6 @@
|
||||
include './base'
|
||||
include './bmi2'
|
||||
|
||||
def pdep{x:u64, m:u64} = emit{u64, '_pdep_u64', x, m}
|
||||
def pdep{x:u32, m:u32} = emit{u32, '_pdep_u32', x, m}
|
||||
def pext{x:u64, m:u64} = emit{u64, '_pext_u64', x, m}
|
||||
def pext{x:u32, m:u32} = emit{u32, '_pext_u32', x, m}
|
||||
def popc{x:T & isint{T} & width{T}==64} = emit{u8, '__builtin_popcountll', x}
|
||||
def popc{x:T & isint{T} & width{T}<=32} = emit{u8, '__builtin_popcount', x}
|
||||
|
||||
def comp8{w:*u64, X, r:*i8, l:u64} = {
|
||||
@for(w in reinterpret{*u8,w} over i to cdiv{l,8}) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user