singeli chr_squeeze

This commit is contained in:
dzaima 2022-06-30 01:47:57 +03:00
parent 75bfa5d905
commit 859be5efb2
4 changed files with 140 additions and 81 deletions

View File

@ -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) {

View File

@ -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

View File

@ -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}

View File

@ -14,28 +14,37 @@ ctv ← "Ac8"‿"Ac16"‿"Ac32"
cmax 111411228×23
specF64 r •Import "utils.bqn"
spec specF64{}"a⍉𝕨"<"foo"
spec specF64{}"a⍉𝕨"(@+1114111-5)<"foo"
RandEl r.Range3
{𝕊: r.Range spec} # some special values
{𝕊: -(r.Range 2) × (¯5+r.Range 10) + 2r.Range 64} # random near-power-of-two number
{𝕊: @+01114111(¯5+r.Range 10) + 22+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) + 2r.Range 64}
base 0
val RandEl@
base RandEl@
len 1+r.Range 23+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
tOuttIn {
1=•Type val?
msk ((¬int) valval) 1˜ (nminnmax)val
expg=1?
msk ´ {((¬int) 𝕩𝕩) 1˜ (nminnmax)𝕩}¨ vals
1msk/ntn "Ah""Af"msk/ntv;
(2•Type val) 1len?
msk {2•Type val? (1len) (val-@)<cmax; 0}
expg=2?
msk ´ {cmax>𝕩-@}¨ vals
1msk/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