singeli chr_squeeze
This commit is contained in:
parent
75bfa5d905
commit
859be5efb2
@ -73,7 +73,7 @@ B num_squeeze(B x) {
|
||||
if (xp==NULL) return num_squeezeF(x, ia);
|
||||
|
||||
#if SINGELI
|
||||
or = avx2_squeeze_B((u8*)xp, ia);
|
||||
or = avx2_squeeze_numB((u8*)xp, ia);
|
||||
if (or==0xfffffffe) goto r_f64;
|
||||
goto r_orF64;
|
||||
r_orF64: if (or==0xffffffff) goto r_x; else goto r_or;
|
||||
@ -98,31 +98,48 @@ B num_squeeze(B x) {
|
||||
B chr_squeeze(B x) {
|
||||
usz ia = a(x)->ia;
|
||||
u8 xe = TI(x,elType);
|
||||
if (xe==el_c8) goto r_x;
|
||||
usz i = 0;
|
||||
i32 or = 0;
|
||||
if (xe==el_c16) {
|
||||
u16* xp = c16any_ptr(x);
|
||||
for (; i < ia; i++) if (xp[i] != (u8)xp[i]) goto r_x;
|
||||
goto r_c8;
|
||||
}
|
||||
if (xe==el_c32) {
|
||||
u32* xp = c32any_ptr(x);
|
||||
bool c8 = true;
|
||||
for (; i < ia; i++) {
|
||||
if (xp[i] != (u16)xp[i]) goto r_c32;
|
||||
if (xp[i] != (u8 )xp[i]) c8 = false;
|
||||
switch(xe) { default: UD;
|
||||
case el_c8: goto r_x;
|
||||
#if SINGELI
|
||||
case el_c16: { u32 t = avx2_squeeze_c16((u8*)c16any_ptr(x), ia); if (t==0) goto r_c8; else goto r_x; }
|
||||
case el_c32: { u32 t = avx2_squeeze_c32((u8*)c32any_ptr(x), ia); if (t==0) goto r_c8; else if (t==1) goto r_c16; else if (t==2) goto r_x; else UD; }
|
||||
#else
|
||||
case el_c16: {
|
||||
u16* xp = c16any_ptr(x);
|
||||
for (; i < ia; i++) if (xp[i] != (u8)xp[i]) goto r_x;
|
||||
goto r_c8;
|
||||
}
|
||||
if (c8) goto r_c8;
|
||||
else goto r_c16;
|
||||
case el_c32: {
|
||||
u32* xp = c32any_ptr(x);
|
||||
bool c8 = true;
|
||||
for (; i < ia; i++) {
|
||||
if (xp[i] != (u16)xp[i]) goto r_x;
|
||||
if (xp[i] != (u8 )xp[i]) c8 = false;
|
||||
}
|
||||
if (c8) goto r_c8;
|
||||
else goto r_c16;
|
||||
}
|
||||
#endif
|
||||
case el_bit: case el_i8: case el_i16: case el_i32: case el_f64: case el_B:; /*fallthrough*/
|
||||
}
|
||||
|
||||
B* xp = arr_bptr(x);
|
||||
if (xp!=NULL) {
|
||||
#if SINGELI
|
||||
u32 t = avx2_squeeze_chrB((u8*)xp, ia);
|
||||
if (t==0) goto r_c8;
|
||||
else if (t==1) goto r_c16;
|
||||
else if (t==2) goto r_c32;
|
||||
else if (t==3) goto r_x;
|
||||
else UD;
|
||||
#else
|
||||
for (; i < ia; i++) {
|
||||
if (!isC32(xp[i])) goto r_x;
|
||||
or|= o2cu(xp[i]);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
SGetU(x)
|
||||
for (; i < ia; i++) {
|
||||
@ -133,8 +150,8 @@ B chr_squeeze(B x) {
|
||||
}
|
||||
if (or<=U8_MAX ) r_c8: return FL_SET(toC8Any(x), fl_squoze);
|
||||
else if (or<=U16_MAX) r_c16: return FL_SET(toC16Any(x), fl_squoze);
|
||||
else r_c32: return FL_SET(toC32Any(x), fl_squoze);
|
||||
r_x: return FL_SET(x, fl_squoze);
|
||||
else goto r_c32; r_c32: return FL_SET(toC32Any(x), fl_squoze);
|
||||
/*when known typed:*/ r_x: return FL_SET(x, fl_squoze);
|
||||
}
|
||||
|
||||
B any_squeeze(B x) {
|
||||
|
||||
@ -20,6 +20,18 @@ def assert{x & x==0} = assert{'failed assertion'}
|
||||
def assert{x & x==1} = 1
|
||||
def assert{x:u1} = emit{void, 'si_assert', x}
|
||||
|
||||
|
||||
|
||||
def tern{c, T, F & anyInt{c}} = {
|
||||
if(c) T
|
||||
else F
|
||||
}
|
||||
def tern{c, t:T, f:T & anyInt{c}} = {
|
||||
res:T = f
|
||||
if (c) res = t
|
||||
res
|
||||
}
|
||||
|
||||
def min{a, b & knum{a} & knum{b}} = tern{a<b, a, b}
|
||||
def max{a, b & knum{a} & knum{b}} = tern{a>b, a, b}
|
||||
|
||||
@ -48,12 +60,6 @@ def anyInt{x & isreg{x}|isconst{x}} = isint{x}
|
||||
def trunc{T, x:U & isint{T} & isint{U} & T<=U} = emit{T, '', x}
|
||||
def trunc{T, x & knum{x}} = cast{T, x}
|
||||
|
||||
def tern{c, T, F & anyInt{c}} = {
|
||||
if(c) T
|
||||
else F
|
||||
}
|
||||
|
||||
|
||||
def ty_s{w== 8} = i8; def ty_u{w== 8} = u8
|
||||
def ty_s{w==16} = i16; def ty_u{w==16} = u16
|
||||
def ty_s{w==32} = i32; def ty_u{w==32} = u32
|
||||
|
||||
@ -3,23 +3,25 @@ include './sse3'
|
||||
include './avx'
|
||||
include './avx2'
|
||||
include './mask'
|
||||
include './cbqnDefs'
|
||||
include 'util/tup'
|
||||
|
||||
def preserve_negative_zero = 0
|
||||
|
||||
def inRangeLen{x:T, start, count & issigned{eltype{T}}} = {
|
||||
def TU = ty_u{T}
|
||||
(TU~~(x-broadcast{T,start})) < broadcast{TU,count}
|
||||
def inRangeLen{x:TS, start, count & issigned{eltype{TS}}} = {
|
||||
def TU = ty_u{TS}
|
||||
TU~~(x-broadcast{TS,start}) < broadcast{TU,count}
|
||||
}
|
||||
def inRangeLen{x:T, start, count & isunsigned{eltype{T}}} = {
|
||||
def TS = ty_s{T}
|
||||
def h = 1 << (width{eltype{T}}-1)
|
||||
(TS~~x)-broadcast{TS,start-h} < broadcast{TS,count-h}
|
||||
def inRangeLen{x:TU, start, count & isunsigned{eltype{TU}}} = {
|
||||
def TS = ty_s{TU}
|
||||
def h = 1 << (width{eltype{TU}}-1)
|
||||
TS~~(x-broadcast{TU,start-h}) < broadcast{TS,count-h}
|
||||
}
|
||||
def inRangeIncl{x:T, start, end} = inRangeLen{x, start, end-start+1}
|
||||
def inRangeExcl{x:T, start, end} = inRangeLen{x, start, end-start}
|
||||
|
||||
def isSNaN{x:T & isunsigned{eltype{T}}} = inRangeLen{x<<1, (0xFFE<<52)+2, (1<<52)-2}
|
||||
def q_chr{x:T & isvec{T} & eltype{T}==u64} = inRangeLen{x, cbqn_c32Tag{}<<48, 1<<48}
|
||||
|
||||
def fold{F, x:T} = {
|
||||
show{'WARNING: using fallback fold'}
|
||||
@ -39,52 +41,76 @@ def fold{F, x:T & w128{T}} = {
|
||||
}
|
||||
def fold{F, x:T & w256{T}} = fold{F, F{half{x, 0}, half{x, 1}}}
|
||||
|
||||
squeeze{vw, X0}(x0:*u8, len:Size) : u32 = {
|
||||
def X = tern{X0==u64, f64, X0}
|
||||
squeeze{vw, X, CHR, B}(x0:*u8, len:Size) : u32 = {
|
||||
def bulk = vw / width{X}
|
||||
def XV = [bulk]X
|
||||
def E = tern{X==f64, u32, ty_u{X}}
|
||||
def EV = [bulk]E
|
||||
show{XV, EV, CHR, B}
|
||||
xp:= *X~~x0
|
||||
r1:= broadcast{EV, 0}
|
||||
if (X==i8) {
|
||||
if (CHR) {
|
||||
def hw = width{E}/2
|
||||
maskedLoop{bulk, len, {i, M} => {
|
||||
v0:= loadBatch{xp, i, XV}
|
||||
if (anyne{broadcast{EV, 0xfe} & EV~~v0, broadcast{EV, 0}, M}) return{2}
|
||||
c:= EV~~loadBatch{xp, i, XV}
|
||||
if (X!=u16) r1|= M{c} # for u64, just accept the garbage top 32 bits and deal with them at the end
|
||||
if (B) {
|
||||
if (any{M{~q_chr{c}}}) return{3}
|
||||
} else {
|
||||
if (anyne{broadcast{EV, (1<<hw-1)<<hw} & c, broadcast{EV,0}, M}) return{lb{hw}-2}
|
||||
}
|
||||
}}
|
||||
r2:= cast_i{u32, fold{|, r1}}
|
||||
if (X>u32 and r2>=65536) return{2}
|
||||
if (X>u16 and r2>=256) return{1}
|
||||
0
|
||||
} else {
|
||||
maskedLoop{bulk, len, {i, M} => {
|
||||
v0:= loadBatch{xp, i, XV}
|
||||
def toint{x:T & isint{eltype{T}}} = x
|
||||
def toint{flt:T & X==f64} = {
|
||||
int:= cvt2{i32, flt}
|
||||
|
||||
def conv{x} = tern{preserve_negative_zero, ty_u{x}, x}
|
||||
|
||||
if (anyne{conv{flt}, conv{cvt2{f64, int}}, M}) { # is any not an integer
|
||||
if (X0==f64) return{0xffff_ffff}
|
||||
|
||||
maskedLoop{bulk, i, len, {i, M} => {
|
||||
def XU = [bulk]u64
|
||||
v:= XU ~~ loadBatch{xp, i, XV}
|
||||
if (any{M{isSNaN{v}}}) return{0xffff_ffff} # is any not even a float
|
||||
}}
|
||||
return{0xffff_fffe}
|
||||
if (X==i8) {
|
||||
maskedLoop{bulk, len, {i, M} => {
|
||||
v0:= loadBatch{xp, i, XV}
|
||||
if (anyne{broadcast{EV, 0xfe} & EV~~v0, broadcast{EV, 0}, M}) return{2}
|
||||
}}
|
||||
0
|
||||
} else {
|
||||
maskedLoop{bulk, len, {i, M} => {
|
||||
v0:= loadBatch{xp, i, XV}
|
||||
if (isunsigned{X}) {
|
||||
r1|= EV~~v0
|
||||
} else {
|
||||
def toint{x:T & isint{eltype{T}}} = x
|
||||
def toint{flt:T & X==f64} = {
|
||||
int:= cvt2{i32, flt}
|
||||
|
||||
def conv{x} = tern{preserve_negative_zero, ty_u{x}, x}
|
||||
|
||||
if (anyne{conv{flt}, conv{cvt2{f64, int}}, M}) { # is any not an integer
|
||||
if (~B) return{0xffff_ffff} # f64arr→f64arr
|
||||
|
||||
maskedLoop{bulk, i, len, {i, M} => {
|
||||
def XU = [bulk]u64
|
||||
v:= XU ~~ loadBatch{xp, i, XV}
|
||||
if (any{M{isSNaN{v}}}) return{0xffff_ffff} # is any not even a float
|
||||
}}
|
||||
return{0xffff_fffe}
|
||||
}
|
||||
int
|
||||
}
|
||||
v1:= toint{v0}
|
||||
r1|= M{(broadcast{EV, ~E~~1} & EV~~v1) ^ EV~~(v1 >> (width{X}-1))}
|
||||
}
|
||||
int
|
||||
}
|
||||
v1:= toint{v0}
|
||||
r1|= M{(broadcast{EV, ~E~~1} & EV~~v1) ^ EV~~(v1 >> (width{X}-1))}
|
||||
}}
|
||||
promote{u32, fold{|, r1}}
|
||||
}}
|
||||
|
||||
promote{u32, fold{|, r1}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
'avx2_squeeze_i8' = squeeze{256, i8 }
|
||||
'avx2_squeeze_i16' = squeeze{256, i16}
|
||||
'avx2_squeeze_i32' = squeeze{256, i32}
|
||||
'avx2_squeeze_f64' = squeeze{256, f64}
|
||||
'avx2_squeeze_B' = squeeze{256, u64}
|
||||
#'avx2_squeeze_u16' = squeeze{256, u16}
|
||||
#'avx2_squeeze_u32' = squeeze{256, u32}
|
||||
'avx2_squeeze_i8' = squeeze{256, i8, 0, 0}
|
||||
'avx2_squeeze_i16' = squeeze{256, i16, 0, 0}
|
||||
'avx2_squeeze_i32' = squeeze{256, i32, 0, 0}
|
||||
'avx2_squeeze_f64' = squeeze{256, f64, 0, 0}
|
||||
'avx2_squeeze_numB'= squeeze{256, f64, 0, 1}
|
||||
|
||||
'avx2_squeeze_c16' = squeeze{256, u16, 1, 0}
|
||||
'avx2_squeeze_c32' = squeeze{256, u32, 1, 0}
|
||||
'avx2_squeeze_chrB'= squeeze{256, u64, 1, 1}
|
||||
@ -14,28 +14,37 @@ ctv ← "Ac8"‿"Ac16"‿"Ac32"
|
||||
cmax ← 1114112⌊2⋆8×2⋆↕3
|
||||
|
||||
⟨specF64⟩ ← ⟨r⟩ •Import "utils.bqn"
|
||||
spec ← specF64∾{⇐}∾"a⍉𝕨"∾<"foo"
|
||||
spec ← specF64∾{⇐}∾"a⍉𝕨"∾(@+1114111-↕5)∾<"foo"
|
||||
|
||||
RandEl ← r.Range∘3◶⟨
|
||||
{𝕊: r.Range∘≠⊸⊑ spec} # some special values
|
||||
{𝕊: -⍟(r.Range 2) × (¯5+r.Range 10) + 2⋆r.Range 64} # random near-power-of-two number
|
||||
{𝕊: @+0⌈1114111⌊(¯5+r.Range 10) + 2⋆2+r.Range 20} # random near-power-of-two character
|
||||
⟩
|
||||
|
||||
# currently tests an array of 0s, with only one outstanding element
|
||||
Do ← { 𝕊:
|
||||
val ← {r.Range∘≠◶𝕩𝕩} ⟨
|
||||
{𝕊: r.Range∘≠⊸⊑ spec}
|
||||
{𝕊: (¯5+r.Range 10) + 2⋆r.Range 64}
|
||||
⟩
|
||||
base ← 0
|
||||
val ← RandEl@
|
||||
base ← RandEl@
|
||||
|
||||
len ← 1+r.Range 2⋆3+r.Range 7
|
||||
pos ← r.Range len
|
||||
arr ← "Ah" Variation val⌾(pos⊸⊑) len⥊<base
|
||||
|
||||
vals ← ∾⟜⟨base⟩⍟(len>1) ⟨val⟩
|
||||
expg ← (∧´⊑=⊢)◶3‿⊑ {
|
||||
1=𝕩? 1;
|
||||
2=𝕩? 2;
|
||||
3
|
||||
}∘•type¨ vals
|
||||
|
||||
tOut‿tIn ← {
|
||||
1=•Type val?
|
||||
msk ← ((¬int) ∨ val≡⌊val) ∧ 1∾˜ (≥⟜nmin∧≤⟜nmax)val
|
||||
expg=1?
|
||||
msk ← ∧´ {((¬int) ∨ 𝕩≡⌊𝕩) ∧ 1∾˜ (≥⟜nmin∧≤⟜nmax)𝕩}¨ vals
|
||||
⟨1↑msk/ntn ⋄ "Ah"‿"Af"∾msk/ntv⟩;
|
||||
(2≡•Type val) ∧ 1≡len?
|
||||
msk ← {2≡•Type val? (1≡len) ∧ (val-@)<cmax; 0}
|
||||
expg=2?
|
||||
msk ← ∧´ {cmax>𝕩-@}¨ vals
|
||||
⟨1↑msk/ctn ⋄ "Ah"‿"Af"∾msk/ctv⟩;
|
||||
# else
|
||||
expg=3?
|
||||
⟨"h"‿"fill" ⋄ "Ah"‿"Af"⟩
|
||||
}
|
||||
tIn ↩ {'S'∾1↓𝕩}¨⊸∾ ∾⟜"Inc"¨⊸∾ tIn
|
||||
@ -50,10 +59,11 @@ Do ← { 𝕊:
|
||||
}
|
||||
¬ (arrv EEqual arr) ∧ (arrv EEqual sq) ∧ (⊑(<sqt) ∊ tOut)?
|
||||
•Out "Fail:"
|
||||
•Show arrv
|
||||
•Show sq
|
||||
•Show Type sq
|
||||
•Show tOut‿𝕩
|
||||
•Out "Array: "∾•Fmt arr
|
||||
•Out "Squeezed: "∾•Fmt sq
|
||||
•Out "Testing variation "∾•Fmt 𝕩
|
||||
•Out "Got: "∾•Fmt Type sq
|
||||
•Out "Expected one of: "∾•Fmt tOut
|
||||
•Exit 1
|
||||
;@
|
||||
}¨ tIn
|
||||
|
||||
Loading…
Reference in New Issue
Block a user