singeli bit_sel
This commit is contained in:
parent
d60713225b
commit
d3a1fee437
2
makefile
2
makefile
@ -224,7 +224,7 @@ preSingeliBin:
|
||||
@${MAKE} i_singeli=0 singeli=0 force_build_dir=obj/presingeli f= lf= postmsg="singeli sources:" i_t=presingeli i_f='-O1 -DPRE_SINGELI' FFI=0 OUTPUT=obj/presingeli/BQN c
|
||||
|
||||
|
||||
build_singeli: ${addprefix src/singeli/gen/, cmp.c dyarith.c copy.c equal.c squeeze.c scan.c slash.c}
|
||||
build_singeli: ${addprefix src/singeli/gen/, cmp.c dyarith.c copy.c equal.c squeeze.c scan.c slash.c bits.c}
|
||||
@echo $(postmsg)
|
||||
src/singeli/gen/%.c: src/singeli/src/%.singeli preSingeliBin
|
||||
@echo $< | cut -c 17- | sed 's/^/ /'
|
||||
|
||||
@ -60,3 +60,7 @@ def spreadBits{T, a & vcount{T} <= width{eltype{T}} & w256u{T}} = {
|
||||
b:= make{T, 1<<iota{vcount{T}}}
|
||||
b == (b & broadcast{T, a})
|
||||
}
|
||||
|
||||
def loadBatchBit{T, x:*u64, n:(Size)} = { # vector with type T with each element being either all 0s or 1s
|
||||
spreadBits{T, b_getBatch{vcount{T}, x, n}}
|
||||
}
|
||||
|
||||
30
src/singeli/src/bits.singeli
Normal file
30
src/singeli/src/bits.singeli
Normal file
@ -0,0 +1,30 @@
|
||||
include './base'
|
||||
include './f64'
|
||||
include './cbqnDefs'
|
||||
include './sse3'
|
||||
include './avx'
|
||||
include './avx2'
|
||||
include './bitops'
|
||||
include './mask'
|
||||
|
||||
def bitsel{VL, T, r, bits, e0, e1, len} = {
|
||||
def bulk = VL/width{T}
|
||||
def VT = [bulk]T
|
||||
|
||||
e0v:= broadcast{VT, e0}
|
||||
e1v:= broadcast{VT, e1}
|
||||
|
||||
maskedLoop{bulk, len, {i, M} => {
|
||||
cb:= loadBatchBit{VT, bits, i}
|
||||
storeBatch{r, i, blendF{e0v, e1v, cb}, M}
|
||||
}}
|
||||
}
|
||||
|
||||
bitsel_i{VL,T}(r:*u8, bits:*u64, e0:u64, e1:u64, len:u64) : void = {
|
||||
bitsel{VL, T, *T~~r, bits, trunc{T,e0}, trunc{T,e1}, len}
|
||||
}
|
||||
|
||||
'avx2_bitsel_8' =bitsel_i{256, u8}
|
||||
'avx2_bitsel_16'=bitsel_i{256, u16}
|
||||
'avx2_bitsel_32'=bitsel_i{256, u32}
|
||||
'avx2_bitsel_64'=bitsel_i{256, u64}
|
||||
@ -11,9 +11,8 @@ def copyFromBits{T, xp: *u64, rp: *eltype{T}, l:u64} = {
|
||||
def TU = ty_u{T}
|
||||
|
||||
maskedLoop{bulk, l, {i, M} => {
|
||||
x:= b_getBatch{bulk, xp, i} # TODO unroll f64 by two to make b_getBatch not sad
|
||||
y:= spreadBits{TU, x}
|
||||
r:= y & TU~~broadcast{T, 1}
|
||||
x:= loadBatchBit{TU, xp, i}
|
||||
r:= x & TU~~broadcast{T, 1}
|
||||
storeBatch{rp, i, T~~r, M}
|
||||
}}
|
||||
}
|
||||
|
||||
@ -25,10 +25,6 @@ def rootty{T & isvec{T}} = eltype{T}
|
||||
def is_s{X} = issigned{rootty{X}}
|
||||
def is_u{X} = isunsigned{rootty{X}}
|
||||
|
||||
def loadBatchBit{T, x:*u64, n:(Size)} = {
|
||||
spreadBits{T, b_getBatch{vcount{T}, x, n}}
|
||||
}
|
||||
|
||||
def ty_sc{O, R} = R # keep floats as-is
|
||||
def ty_sc{O, R & is_s{O} & is_u{R}} = ty_s{R}
|
||||
def ty_sc{O, R & is_u{O} & is_s{R}} = ty_u{R}
|
||||
|
||||
@ -1,5 +1,20 @@
|
||||
#include "../core.h"
|
||||
|
||||
|
||||
#if SINGELI
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#include "../singeli/gen/bits.c"
|
||||
#pragma GCC diagnostic pop
|
||||
typedef void (*BitselFn)(u8*, u64*, u64, u64, u64);
|
||||
static BitselFn bitselFns[] = {
|
||||
[0]=avx2_bitsel_8,
|
||||
[1]=avx2_bitsel_16,
|
||||
[2]=avx2_bitsel_32,
|
||||
[3]=avx2_bitsel_64,
|
||||
};
|
||||
#endif
|
||||
|
||||
NOINLINE Arr* allZeroes(usz ia) { u64* rp; Arr* r = m_bitarrp(&rp, ia); for (usz i = 0; i < BIT_N(ia); i++) rp[i] = 0; return r; }
|
||||
NOINLINE Arr* allOnes (usz ia) { u64* rp; Arr* r = m_bitarrp(&rp, ia); for (usz i = 0; i < BIT_N(ia); i++) rp[i] = ~0ULL; return r; }
|
||||
|
||||
@ -45,12 +60,16 @@ NOINLINE B bit_sel(B b, B e0, B e1) {
|
||||
|
||||
sel:
|
||||
void* rp = m_tyarrlc(&r, width, b, type);
|
||||
switch(width) {
|
||||
case 0: for (usz i=0; i<ia; i++) (( u8*)rp)[i] = bitp_get(bp,i)? e1i : e0i; break;
|
||||
case 1: for (usz i=0; i<ia; i++) ((u16*)rp)[i] = bitp_get(bp,i)? e1i : e0i; break;
|
||||
case 2: for (usz i=0; i<ia; i++) ((u32*)rp)[i] = bitp_get(bp,i)? e1i : e0i; break;
|
||||
case 3: for (usz i=0; i<ia; i++) ((u64*)rp)[i] = bitp_get(bp,i)? e1i : e0i; break;
|
||||
}
|
||||
#if SINGELI
|
||||
bitselFns[width](rp, bp, e0i, e1i, ia);
|
||||
#else
|
||||
switch(width) {
|
||||
case 0: for (usz i=0; i<ia; i++) (( u8*)rp)[i] = bitp_get(bp,i)? e1i : e0i; break;
|
||||
case 1: for (usz i=0; i<ia; i++) ((u16*)rp)[i] = bitp_get(bp,i)? e1i : e0i; break;
|
||||
case 2: for (usz i=0; i<ia; i++) ((u32*)rp)[i] = bitp_get(bp,i)? e1i : e0i; break;
|
||||
case 3: for (usz i=0; i<ia; i++) ((u64*)rp)[i] = bitp_get(bp,i)? e1i : e0i; break;
|
||||
}
|
||||
#endif
|
||||
goto dec_ret;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user