f64 min/max scan
This commit is contained in:
parent
136c1afacc
commit
1924aee61c
@ -1,6 +1,9 @@
|
||||
#include "../core.h"
|
||||
#include "../utils/mut.h"
|
||||
#include "../builtins.h"
|
||||
#include <math.h>
|
||||
#define F64_MIN -INFINITY
|
||||
#define F64_MAX INFINITY
|
||||
|
||||
#if !USE_VALGRIND
|
||||
static u64 vg_rand(u64 x) { return x; }
|
||||
@ -104,10 +107,11 @@ B scan_add_bool(B x, u64 ia) { // consumes x
|
||||
MM_CASE(i8 ,NAME,C,I8_##INIT ) \
|
||||
MM_CASE(i16,NAME,C,I16_##INIT) \
|
||||
MM_CASE(i32,NAME,C,I32_##INIT) \
|
||||
MM_CASE(f64,NAME,C,F64_##INIT) \
|
||||
} \
|
||||
decG(x); return FL_SET(r, fl_##ORD);
|
||||
static B scan_min_int(B x, u8 xe, usz ia) { MINMAX(min,<,MAX,dsc) }
|
||||
static B scan_max_int(B x, u8 xe, usz ia) { MINMAX(max,>,MIN,asc) }
|
||||
static B scan_min_num(B x, u8 xe, usz ia) { MINMAX(min,<,MAX,dsc) }
|
||||
static B scan_max_num(B x, u8 xe, usz ia) { MINMAX(max,>,MIN,asc) }
|
||||
#undef MM_CASE
|
||||
#undef MINMAX
|
||||
#undef MINMAX_SCAN
|
||||
@ -145,8 +149,8 @@ B scan_c1(Md1D* d, B x) { B f = d->f;
|
||||
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; }
|
||||
}
|
||||
if (rtid==n_floor && xe<el_f64) return scan_min_int(x, xe, ia); // ⌊
|
||||
if (rtid==n_ceil && xe<el_f64) return scan_max_int(x, xe, ia); // ⌈
|
||||
if (rtid==n_floor) return scan_min_num(x, xe, ia); // ⌊
|
||||
if (rtid==n_ceil ) return scan_max_num(x, xe, ia); // ⌈
|
||||
if (rtid==n_ne) { // ≠
|
||||
f64 x0 = IGetU(x,0).f; if (x0!=0 && x0!=1) goto base;
|
||||
if (xe==el_i8 ) { i8* xp=i8any_ptr (x); u64* rp; B r=m_bitarrv(&rp,ia); bool c=x0; rp[0]=c; for (usz i=1; i<ia; i++) { c = c!=xp[i]; bitp_set(rp,i,c); } decG(x); return r; }
|
||||
|
||||
@ -32,7 +32,8 @@ def scan_post{T, init, x:*T, r:*T, len:u64, op, pre} = {
|
||||
def last{v, p} = op{pre{v}, p}
|
||||
def scan{v, p} = {
|
||||
n:= last{v, p}
|
||||
p = sel{[8]i32, spread{n}, broadcast{[8]i32, 7}}
|
||||
p = (if (width{T}<=32) sel{[8]i32, spread{n}, broadcast{[8]i32, 7}};
|
||||
else shuf{[4]u64, n, 4b3333})
|
||||
n
|
||||
}
|
||||
scan_loop{T, init, x, r, len, scan, last}
|
||||
@ -55,6 +56,10 @@ avx2_scan_idem{T, op, id}(x:*T, r:*T, len:u64) : void = {
|
||||
|
||||
scan_post{T, id, x, r, len, op, pre}
|
||||
}
|
||||
avx2_scan_idem{T==f64, op, id}(x:*T, r:*T, len:u64) : void = {
|
||||
def sh{s, a} = op{a, shuf{[4]u64, a, s}}
|
||||
scan_post{T, id, x, r, len, op, {a}=>sh{4b1110,sh{4b2200,a}}}
|
||||
}
|
||||
def avx2_scan_idem{T, op} = {
|
||||
def m = 1 << (width{T}-1)
|
||||
avx2_scan_idem{T, op, (if (match{op,min}) m-1; else -m)}
|
||||
@ -65,6 +70,8 @@ def avx2_scan_idem{T, op} = {
|
||||
'avx2_scan_max_i16' = avx2_scan_idem{i16, max}
|
||||
'avx2_scan_min_i32' = avx2_scan_idem{i32, min}
|
||||
'avx2_scan_max_i32' = avx2_scan_idem{i32, max}
|
||||
'avx2_scan_min_f64' = avx2_scan_idem{f64, min, 'F64_MAX'}
|
||||
'avx2_scan_max_f64' = avx2_scan_idem{f64, max, 'F64_MIN'}
|
||||
|
||||
# Associative scan
|
||||
avx2_scan_assoc_0{T, op}(x:*T, r:*T, len:u64, init:T) : void = {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user