Singeli integer ⌊ and ⌈
This commit is contained in:
parent
1fcc3b0030
commit
56a1d9ec4c
@ -176,14 +176,26 @@ B scan_c1(Md1D* d, B x) { B f = d->f;
|
||||
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) { // ⌊
|
||||
if (xe==el_i8 ) { i8* xp=i8any_ptr (x); i8* rp; B r=m_i8arrv (&rp, ia); i8 c=I8_MAX ; for (usz i=0; i<ia; i++) { if (xp[i]<c)c=xp[i]; rp[i]=c; } decG(x); return r; }
|
||||
if (xe==el_i16) { i16* xp=i16any_ptr(x); i16* rp; B r=m_i16arrv(&rp, ia); i16 c=I16_MAX; for (usz i=0; i<ia; i++) { if (xp[i]<c)c=xp[i]; 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=I32_MAX; for (usz i=0; i<ia; i++) { if (xp[i]<c)c=xp[i]; rp[i]=c; } decG(x); return r; }
|
||||
#if SINGELI
|
||||
if (xe==el_i8 ) { i8* rp; B r=m_i8arrv (&rp, ia); avx2_scan_min8 (i8any_ptr (x), rp, ia); decG(x); return r; }
|
||||
if (xe==el_i16) { i16* rp; B r=m_i16arrv(&rp, ia); avx2_scan_min16(i16any_ptr(x), rp, ia); decG(x); return r; }
|
||||
if (xe==el_i32) { i32* rp; B r=m_i32arrv(&rp, ia); avx2_scan_min32(i32any_ptr(x), rp, ia); decG(x); return r; }
|
||||
#else
|
||||
if (xe==el_i8 ) { i8* xp=i8any_ptr (x); i8* rp; B r=m_i8arrv (&rp, ia); i8 c=I8_MAX ; for (usz i=0; i<ia; i++) { if (xp[i]<c)c=xp[i]; rp[i]=c; } decG(x); return r; }
|
||||
if (xe==el_i16) { i16* xp=i16any_ptr(x); i16* rp; B r=m_i16arrv(&rp, ia); i16 c=I16_MAX; for (usz i=0; i<ia; i++) { if (xp[i]<c)c=xp[i]; 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=I32_MAX; for (usz i=0; i<ia; i++) { if (xp[i]<c)c=xp[i]; rp[i]=c; } decG(x); return r; }
|
||||
#endif
|
||||
}
|
||||
if (rtid==n_ceil) { // ⌈
|
||||
if (xe==el_i8 ) { i8* xp=i8any_ptr (x); i8* rp; B r=m_i8arrv (&rp, ia); i8 c=I8_MIN ; for (usz i=0; i<ia; i++) { if (xp[i]>c)c=xp[i]; rp[i]=c; } decG(x); return r; }
|
||||
if (xe==el_i16) { i16* xp=i16any_ptr(x); i16* rp; B r=m_i16arrv(&rp, ia); i16 c=I16_MIN; for (usz i=0; i<ia; i++) { if (xp[i]>c)c=xp[i]; 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=I32_MIN; for (usz i=0; i<ia; i++) { if (xp[i]>c)c=xp[i]; rp[i]=c; } decG(x); return r; }
|
||||
#if SINGELI
|
||||
if (xe==el_i8 ) { i8* rp; B r=m_i8arrv (&rp, ia); avx2_scan_max8 (i8any_ptr (x), rp, ia); decG(x); return r; }
|
||||
if (xe==el_i16) { i16* rp; B r=m_i16arrv(&rp, ia); avx2_scan_max16(i16any_ptr(x), rp, ia); decG(x); return r; }
|
||||
if (xe==el_i32) { i32* rp; B r=m_i32arrv(&rp, ia); avx2_scan_max32(i32any_ptr(x), rp, ia); decG(x); return r; }
|
||||
#else
|
||||
if (xe==el_i8 ) { i8* xp=i8any_ptr (x); i8* rp; B r=m_i8arrv (&rp, ia); i8 c=I8_MIN ; for (usz i=0; i<ia; i++) { if (xp[i]>c)c=xp[i]; rp[i]=c; } decG(x); return r; }
|
||||
if (xe==el_i16) { i16* xp=i16any_ptr(x); i16* rp; B r=m_i16arrv(&rp, ia); i16 c=I16_MIN; for (usz i=0; i<ia; i++) { if (xp[i]>c)c=xp[i]; 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=I32_MIN; for (usz i=0; i<ia; i++) { if (xp[i]>c)c=xp[i]; rp[i]=c; } decG(x); return r; }
|
||||
#endif
|
||||
}
|
||||
if (rtid==n_ne) { // ≠
|
||||
f64 x0 = IGetU(x,0).f; if (x0!=0 && x0!=1) goto base;
|
||||
|
||||
@ -4,6 +4,59 @@ include './avx'
|
||||
include './avx2'
|
||||
include './mask'
|
||||
|
||||
def sel8{v, t} = sel{[16]u8, v, make{[32]i8, t}}
|
||||
def sel8{v, t & istup{t} & tuplen{t}==16} = sel8{v, merge{t,t}}
|
||||
|
||||
def base{b,l} = { if (0==tuplen{l}) 0; else tupsel{0,l}+b*base{b,slice{l,1}} }
|
||||
def shuf{T, v, n & istup{n}} = shuf{T, v, base{4,n}}
|
||||
|
||||
# Associative scan ?` if a?b?a = a?b = b?a, used for ⌊⌈
|
||||
avx2_scan_idem{T, op, id}(x:*T, r:*T, len:u64) : void = {
|
||||
def w = width{T}
|
||||
|
||||
# Within each lane, scan using shifts by powers of 2. First k elements
|
||||
# when shifting by k don't need to change, so leave them alone.
|
||||
def shift{k,l} = merge{iota{k},iota{l-k}}
|
||||
def c8 {k, a} = op{a, shuf{[4]u32, a, shift{k,4}}}
|
||||
def c32{k, a} = (if (w<=8*k) op{a, sel8{a, shift{k,16}}}; else a)
|
||||
# Fill last 4 bytes with last element, in each lane
|
||||
def spread{a} = {
|
||||
def b = w/8
|
||||
if (w<=16) sel8{a,merge{iota{12},(16-b)+iota{4}%b}}; else a
|
||||
}
|
||||
# Prefix op on entire AVX register
|
||||
def pre{a} = {
|
||||
b:= c8{2, c8{1, c32{2, c32{1, a}}}}
|
||||
# After lanewise scan, broadcast end of lane 0 to entire lane 1
|
||||
op{b, sel{[8]i32, spread{b}, make{[8]i32, 3*(3<iota{8})}}}
|
||||
}
|
||||
|
||||
def step = 256/w
|
||||
def V = [step]T
|
||||
p:= broadcast{V, id}
|
||||
xv:= *V ~~ x
|
||||
rv:= *V ~~ r
|
||||
e:= len/step
|
||||
@for (xv, rv over e) {
|
||||
n:= op{pre{xv}, p}
|
||||
p = sel{[8]i32, spread{n}, broadcast{[8]i32, 7}}
|
||||
rv = n
|
||||
}
|
||||
q:= len & (step-1)
|
||||
if (q) maskstoreF{rv, maskOf{V, q}, e, op{pre{load{xv,e}}, p}}
|
||||
}
|
||||
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)}
|
||||
}
|
||||
'avx2_scan_min8' = avx2_scan_idem{i8 , min}
|
||||
'avx2_scan_max8' = avx2_scan_idem{i8 , max}
|
||||
'avx2_scan_min16' = avx2_scan_idem{i16, min}
|
||||
'avx2_scan_max16' = avx2_scan_idem{i16, max}
|
||||
'avx2_scan_min32' = avx2_scan_idem{i32, min}
|
||||
'avx2_scan_max32' = avx2_scan_idem{i32, max}
|
||||
|
||||
# Boolean cumulative sum
|
||||
avx2_bcs32(x:*u64, r:*i32, l:u64) : void = {
|
||||
rv:= *[8]u32~~r
|
||||
xv:= *u32~~x
|
||||
@ -11,7 +64,6 @@ avx2_bcs32(x:*u64, r:*i32, l:u64) : void = {
|
||||
|
||||
def ii32 = iota{32}; def bit{k}=bit{k,ii32}; def tail{k}=tail{k,ii32}
|
||||
def sums{n} = (if (n==0) tup{0}; else { def s=sums{n-1}; merge{s,s+1} })
|
||||
def sel8{v, t} = sel{[16]u8, v, make{[32]i8, t}}
|
||||
def widen{v:T} = unpackQ{shuf{[4]u64, v, 4b3120}, broadcast{T, 0}}
|
||||
|
||||
def step{x:u32, i, store1} = {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user