Singeli min/max-fold
This commit is contained in:
parent
4b9a21c75f
commit
52608ba6ce
2
makefile
2
makefile
@ -271,7 +271,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
|
@${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 copy.c equal.c squeeze.c scan.c neq.c slash.c constrep.c bits.c}
|
build_singeli: ${addprefix src/singeli/gen/, cmp.c dyarith.c copy.c equal.c squeeze.c fold.c scan.c neq.c slash.c constrep.c bits.c}
|
||||||
@echo $(postmsg)
|
@echo $(postmsg)
|
||||||
src/singeli/gen/%.c: src/singeli/src/%.singeli preSingeliBin
|
src/singeli/gen/%.c: src/singeli/src/%.singeli preSingeliBin
|
||||||
@echo $< | cut -c 17- | sed 's/^/ /'
|
@echo $< | cut -c 17- | sed 's/^/ /'
|
||||||
|
|||||||
@ -1,6 +1,13 @@
|
|||||||
#include "../core.h"
|
#include "../core.h"
|
||||||
#include "../builtins.h"
|
#include "../builtins.h"
|
||||||
|
|
||||||
|
#if SINGELI
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||||
|
#include "../singeli/gen/fold.c"
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool fold_ne(u64* x, u64 am) {
|
static bool fold_ne(u64* x, u64 am) {
|
||||||
u64 r = 0;
|
u64 r = 0;
|
||||||
for (u64 i = 0; i < (am>>6); i++) r^= x[i];
|
for (u64 i = 0; i < (am>>6); i++) r^= x[i];
|
||||||
@ -55,7 +62,13 @@ static f64 (*const sum_fns[])(void*, usz, f64) = { sum_i8, sum_i16, sum_i32, sum
|
|||||||
#define DEF_MIN_MAX(T) \
|
#define DEF_MIN_MAX(T) \
|
||||||
static f64 min_##T(void* xv, usz ia) { MIN_MAX(T,<) } \
|
static f64 min_##T(void* xv, usz ia) { MIN_MAX(T,<) } \
|
||||||
static f64 max_##T(void* xv, usz ia) { MIN_MAX(T,>) }
|
static f64 max_##T(void* xv, usz ia) { MIN_MAX(T,>) }
|
||||||
DEF_MIN_MAX(i8) DEF_MIN_MAX(i16) DEF_MIN_MAX(i32) DEF_MIN_MAX(f64)
|
DEF_MIN_MAX(i8) DEF_MIN_MAX(i16) DEF_MIN_MAX(i32)
|
||||||
|
#if SINGELI
|
||||||
|
static f64 min_f64(void* xv, usz ia) { return avx2_fold_min_f64(xv,ia); }
|
||||||
|
static f64 max_f64(void* xv, usz ia) { return avx2_fold_max_f64(xv,ia); }
|
||||||
|
#else
|
||||||
|
DEF_MIN_MAX(f64)
|
||||||
|
#endif
|
||||||
#undef DEF_MIN_MAX
|
#undef DEF_MIN_MAX
|
||||||
#undef MIN_MAX
|
#undef MIN_MAX
|
||||||
static f64 (*const min_fns[])(void*, usz) = { min_i8, min_i16, min_i32, min_f64 };
|
static f64 (*const min_fns[])(void*, usz) = { min_i8, min_i16, min_i32, min_f64 };
|
||||||
|
|||||||
41
src/singeli/src/fold.singeli
Normal file
41
src/singeli/src/fold.singeli
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
include './base'
|
||||||
|
include './sse3'
|
||||||
|
include './avx'
|
||||||
|
include './avx2'
|
||||||
|
include './mask'
|
||||||
|
|
||||||
|
fold_idem{T==f64, op}(x:*T, len:u64) : T = {
|
||||||
|
def step = 256/width{T}
|
||||||
|
def V = [step]T
|
||||||
|
xv:= *V ~~ x
|
||||||
|
r:V = broadcast{[4]f64, 0}
|
||||||
|
if (len < step) {
|
||||||
|
# Can't overlap like the long case
|
||||||
|
assert{len > 0}
|
||||||
|
r = load{xv}
|
||||||
|
if (len > 1) {
|
||||||
|
if (len > 2) r = op{r, shuf{[4]u64, r, 4b2222}}
|
||||||
|
r = op{r, shuf{[4]u64, r, 4b1111}}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
# Pairwise combination to shorten dependency chains
|
||||||
|
def pairwise{p, i, k} = {
|
||||||
|
def l = k-1
|
||||||
|
op{pairwise{p, i , l},
|
||||||
|
pairwise{p, i+(1<<l), l}}
|
||||||
|
}
|
||||||
|
def pairwise{p, i, k==0} = load{p, i}
|
||||||
|
def pk = 2 # Combine 1<<pk values in a step
|
||||||
|
r = load{*V ~~ (x+len-step)}
|
||||||
|
e:= (len-1)/step
|
||||||
|
f:= e >> pk
|
||||||
|
@for (i to f) r = op{r, pairwise{xv+(i<<pk), 0, pk}}
|
||||||
|
@for (xv over i from f<<pk to e) r = op{r, xv}
|
||||||
|
r = op{r, shuf{[4]u64, r, 4b2301}}
|
||||||
|
r = op{r, shuf{[4]u64, r, 4b1032}}
|
||||||
|
}
|
||||||
|
extract{r, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
'avx2_fold_min_f64' = fold_idem{f64,min}
|
||||||
|
'avx2_fold_max_f64' = fold_idem{f64,max}
|
||||||
Loading…
Reference in New Issue
Block a user