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 (xp==NULL) return num_squeezeF(x, ia);
|
||||||
|
|
||||||
#if SINGELI
|
#if SINGELI
|
||||||
or = avx2_squeeze_B((u8*)xp, ia);
|
or = avx2_squeeze_numB((u8*)xp, ia);
|
||||||
if (or==0xfffffffe) goto r_f64;
|
if (or==0xfffffffe) goto r_f64;
|
||||||
goto r_orF64;
|
goto r_orF64;
|
||||||
r_orF64: if (or==0xffffffff) goto r_x; else goto r_or;
|
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) {
|
B chr_squeeze(B x) {
|
||||||
usz ia = a(x)->ia;
|
usz ia = a(x)->ia;
|
||||||
u8 xe = TI(x,elType);
|
u8 xe = TI(x,elType);
|
||||||
if (xe==el_c8) goto r_x;
|
|
||||||
usz i = 0;
|
usz i = 0;
|
||||||
i32 or = 0;
|
i32 or = 0;
|
||||||
if (xe==el_c16) {
|
switch(xe) { default: UD;
|
||||||
u16* xp = c16any_ptr(x);
|
case el_c8: goto r_x;
|
||||||
for (; i < ia; i++) if (xp[i] != (u8)xp[i]) goto r_x;
|
#if SINGELI
|
||||||
goto r_c8;
|
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; }
|
||||||
if (xe==el_c32) {
|
#else
|
||||||
u32* xp = c32any_ptr(x);
|
case el_c16: {
|
||||||
bool c8 = true;
|
u16* xp = c16any_ptr(x);
|
||||||
for (; i < ia; i++) {
|
for (; i < ia; i++) if (xp[i] != (u8)xp[i]) goto r_x;
|
||||||
if (xp[i] != (u16)xp[i]) goto r_c32;
|
goto r_c8;
|
||||||
if (xp[i] != (u8 )xp[i]) c8 = false;
|
|
||||||
}
|
}
|
||||||
if (c8) goto r_c8;
|
case el_c32: {
|
||||||
else goto r_c16;
|
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);
|
B* xp = arr_bptr(x);
|
||||||
if (xp!=NULL) {
|
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++) {
|
for (; i < ia; i++) {
|
||||||
if (!isC32(xp[i])) goto r_x;
|
if (!isC32(xp[i])) goto r_x;
|
||||||
or|= o2cu(xp[i]);
|
or|= o2cu(xp[i]);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
SGetU(x)
|
SGetU(x)
|
||||||
for (; i < ia; i++) {
|
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);
|
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 if (or<=U16_MAX) r_c16: return FL_SET(toC16Any(x), fl_squoze);
|
||||||
else r_c32: return FL_SET(toC32Any(x), fl_squoze);
|
else goto r_c32; r_c32: return FL_SET(toC32Any(x), fl_squoze);
|
||||||
r_x: return FL_SET(x, fl_squoze);
|
/*when known typed:*/ r_x: return FL_SET(x, fl_squoze);
|
||||||
}
|
}
|
||||||
|
|
||||||
B any_squeeze(B x) {
|
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 & x==1} = 1
|
||||||
def assert{x:u1} = emit{void, 'si_assert', x}
|
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 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}
|
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:U & isint{T} & isint{U} & T<=U} = emit{T, '', x}
|
||||||
def trunc{T, x & knum{x}} = cast{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== 8} = i8; def ty_u{w== 8} = u8
|
||||||
def ty_s{w==16} = i16; def ty_u{w==16} = u16
|
def ty_s{w==16} = i16; def ty_u{w==16} = u16
|
||||||
def ty_s{w==32} = i32; def ty_u{w==32} = u32
|
def ty_s{w==32} = i32; def ty_u{w==32} = u32
|
||||||
|
|||||||
@ -3,23 +3,25 @@ include './sse3'
|
|||||||
include './avx'
|
include './avx'
|
||||||
include './avx2'
|
include './avx2'
|
||||||
include './mask'
|
include './mask'
|
||||||
|
include './cbqnDefs'
|
||||||
include 'util/tup'
|
include 'util/tup'
|
||||||
|
|
||||||
def preserve_negative_zero = 0
|
def preserve_negative_zero = 0
|
||||||
|
|
||||||
def inRangeLen{x:T, start, count & issigned{eltype{T}}} = {
|
def inRangeLen{x:TS, start, count & issigned{eltype{TS}}} = {
|
||||||
def TU = ty_u{T}
|
def TU = ty_u{TS}
|
||||||
(TU~~(x-broadcast{T,start})) < broadcast{TU,count}
|
TU~~(x-broadcast{TS,start}) < broadcast{TU,count}
|
||||||
}
|
}
|
||||||
def inRangeLen{x:T, start, count & isunsigned{eltype{T}}} = {
|
def inRangeLen{x:TU, start, count & isunsigned{eltype{TU}}} = {
|
||||||
def TS = ty_s{T}
|
def TS = ty_s{TU}
|
||||||
def h = 1 << (width{eltype{T}}-1)
|
def h = 1 << (width{eltype{TU}}-1)
|
||||||
(TS~~x)-broadcast{TS,start-h} < broadcast{TS,count-h}
|
TS~~(x-broadcast{TU,start-h}) < broadcast{TS,count-h}
|
||||||
}
|
}
|
||||||
def inRangeIncl{x:T, start, end} = inRangeLen{x, start, end-start+1}
|
def inRangeIncl{x:T, start, end} = inRangeLen{x, start, end-start+1}
|
||||||
def inRangeExcl{x:T, start, end} = inRangeLen{x, start, end-start}
|
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 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} = {
|
def fold{F, x:T} = {
|
||||||
show{'WARNING: using fallback fold'}
|
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}}}
|
def fold{F, x:T & w256{T}} = fold{F, F{half{x, 0}, half{x, 1}}}
|
||||||
|
|
||||||
squeeze{vw, X0}(x0:*u8, len:Size) : u32 = {
|
squeeze{vw, X, CHR, B}(x0:*u8, len:Size) : u32 = {
|
||||||
def X = tern{X0==u64, f64, X0}
|
|
||||||
def bulk = vw / width{X}
|
def bulk = vw / width{X}
|
||||||
def XV = [bulk]X
|
def XV = [bulk]X
|
||||||
def E = tern{X==f64, u32, ty_u{X}}
|
def E = tern{X==f64, u32, ty_u{X}}
|
||||||
def EV = [bulk]E
|
def EV = [bulk]E
|
||||||
|
show{XV, EV, CHR, B}
|
||||||
xp:= *X~~x0
|
xp:= *X~~x0
|
||||||
r1:= broadcast{EV, 0}
|
r1:= broadcast{EV, 0}
|
||||||
if (X==i8) {
|
if (CHR) {
|
||||||
|
def hw = width{E}/2
|
||||||
maskedLoop{bulk, len, {i, M} => {
|
maskedLoop{bulk, len, {i, M} => {
|
||||||
v0:= loadBatch{xp, i, XV}
|
c:= EV~~loadBatch{xp, i, XV}
|
||||||
if (anyne{broadcast{EV, 0xfe} & EV~~v0, broadcast{EV, 0}, M}) return{2}
|
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
|
0
|
||||||
} else {
|
} else {
|
||||||
maskedLoop{bulk, len, {i, M} => {
|
if (X==i8) {
|
||||||
v0:= loadBatch{xp, i, XV}
|
maskedLoop{bulk, len, {i, M} => {
|
||||||
def toint{x:T & isint{eltype{T}}} = x
|
v0:= loadBatch{xp, i, XV}
|
||||||
def toint{flt:T & X==f64} = {
|
if (anyne{broadcast{EV, 0xfe} & EV~~v0, broadcast{EV, 0}, M}) return{2}
|
||||||
int:= cvt2{i32, flt}
|
}}
|
||||||
|
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}
|
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 (anyne{conv{flt}, conv{cvt2{f64, int}}, M}) { # is any not an integer
|
||||||
if (X0==f64) return{0xffff_ffff}
|
if (~B) return{0xffff_ffff} # f64arr→f64arr
|
||||||
|
|
||||||
maskedLoop{bulk, i, len, {i, M} => {
|
maskedLoop{bulk, i, len, {i, M} => {
|
||||||
def XU = [bulk]u64
|
def XU = [bulk]u64
|
||||||
v:= XU ~~ loadBatch{xp, i, XV}
|
v:= XU ~~ loadBatch{xp, i, XV}
|
||||||
if (any{M{isSNaN{v}}}) return{0xffff_ffff} # is any not even a float
|
if (any{M{isSNaN{v}}}) return{0xffff_ffff} # is any not even a float
|
||||||
}}
|
}}
|
||||||
return{0xffff_fffe}
|
return{0xffff_fffe}
|
||||||
|
}
|
||||||
|
int
|
||||||
|
}
|
||||||
|
v1:= toint{v0}
|
||||||
|
r1|= M{(broadcast{EV, ~E~~1} & EV~~v1) ^ EV~~(v1 >> (width{X}-1))}
|
||||||
}
|
}
|
||||||
int
|
}}
|
||||||
}
|
|
||||||
v1:= toint{v0}
|
promote{u32, fold{|, r1}}
|
||||||
r1|= M{(broadcast{EV, ~E~~1} & EV~~v1) ^ EV~~(v1 >> (width{X}-1))}
|
}
|
||||||
}}
|
|
||||||
promote{u32, fold{|, r1}}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
'avx2_squeeze_i8' = squeeze{256, i8 }
|
'avx2_squeeze_i8' = squeeze{256, i8, 0, 0}
|
||||||
'avx2_squeeze_i16' = squeeze{256, i16}
|
'avx2_squeeze_i16' = squeeze{256, i16, 0, 0}
|
||||||
'avx2_squeeze_i32' = squeeze{256, i32}
|
'avx2_squeeze_i32' = squeeze{256, i32, 0, 0}
|
||||||
'avx2_squeeze_f64' = squeeze{256, f64}
|
'avx2_squeeze_f64' = squeeze{256, f64, 0, 0}
|
||||||
'avx2_squeeze_B' = squeeze{256, u64}
|
'avx2_squeeze_numB'= squeeze{256, f64, 0, 1}
|
||||||
#'avx2_squeeze_u16' = squeeze{256, u16}
|
|
||||||
#'avx2_squeeze_u32' = squeeze{256, u32}
|
'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
|
cmax ← 1114112⌊2⋆8×2⋆↕3
|
||||||
|
|
||||||
⟨specF64⟩ ← ⟨r⟩ •Import "utils.bqn"
|
⟨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 ← { 𝕊:
|
Do ← { 𝕊:
|
||||||
val ← {r.Range∘≠◶𝕩𝕩} ⟨
|
val ← RandEl@
|
||||||
{𝕊: r.Range∘≠⊸⊑ spec}
|
base ← RandEl@
|
||||||
{𝕊: (¯5+r.Range 10) + 2⋆r.Range 64}
|
|
||||||
⟩
|
|
||||||
base ← 0
|
|
||||||
|
|
||||||
len ← 1+r.Range 2⋆3+r.Range 7
|
len ← 1+r.Range 2⋆3+r.Range 7
|
||||||
pos ← r.Range len
|
pos ← r.Range len
|
||||||
arr ← "Ah" Variation val⌾(pos⊸⊑) len⥊<base
|
arr ← "Ah" Variation val⌾(pos⊸⊑) len⥊<base
|
||||||
|
|
||||||
|
vals ← ∾⟜⟨base⟩⍟(len>1) ⟨val⟩
|
||||||
|
expg ← (∧´⊑=⊢)◶3‿⊑ {
|
||||||
|
1=𝕩? 1;
|
||||||
|
2=𝕩? 2;
|
||||||
|
3
|
||||||
|
}∘•type¨ vals
|
||||||
|
|
||||||
tOut‿tIn ← {
|
tOut‿tIn ← {
|
||||||
1=•Type val?
|
expg=1?
|
||||||
msk ← ((¬int) ∨ val≡⌊val) ∧ 1∾˜ (≥⟜nmin∧≤⟜nmax)val
|
msk ← ∧´ {((¬int) ∨ 𝕩≡⌊𝕩) ∧ 1∾˜ (≥⟜nmin∧≤⟜nmax)𝕩}¨ vals
|
||||||
⟨1↑msk/ntn ⋄ "Ah"‿"Af"∾msk/ntv⟩;
|
⟨1↑msk/ntn ⋄ "Ah"‿"Af"∾msk/ntv⟩;
|
||||||
(2≡•Type val) ∧ 1≡len?
|
expg=2?
|
||||||
msk ← {2≡•Type val? (1≡len) ∧ (val-@)<cmax; 0}
|
msk ← ∧´ {cmax>𝕩-@}¨ vals
|
||||||
⟨1↑msk/ctn ⋄ "Ah"‿"Af"∾msk/ctv⟩;
|
⟨1↑msk/ctn ⋄ "Ah"‿"Af"∾msk/ctv⟩;
|
||||||
# else
|
expg=3?
|
||||||
⟨"h"‿"fill" ⋄ "Ah"‿"Af"⟩
|
⟨"h"‿"fill" ⋄ "Ah"‿"Af"⟩
|
||||||
}
|
}
|
||||||
tIn ↩ {'S'∾1↓𝕩}¨⊸∾ ∾⟜"Inc"¨⊸∾ tIn
|
tIn ↩ {'S'∾1↓𝕩}¨⊸∾ ∾⟜"Inc"¨⊸∾ tIn
|
||||||
@ -50,10 +59,11 @@ Do ← { 𝕊:
|
|||||||
}
|
}
|
||||||
¬ (arrv EEqual arr) ∧ (arrv EEqual sq) ∧ (⊑(<sqt) ∊ tOut)?
|
¬ (arrv EEqual arr) ∧ (arrv EEqual sq) ∧ (⊑(<sqt) ∊ tOut)?
|
||||||
•Out "Fail:"
|
•Out "Fail:"
|
||||||
•Show arrv
|
•Out "Array: "∾•Fmt arr
|
||||||
•Show sq
|
•Out "Squeezed: "∾•Fmt sq
|
||||||
•Show Type sq
|
•Out "Testing variation "∾•Fmt 𝕩
|
||||||
•Show tOut‿𝕩
|
•Out "Got: "∾•Fmt Type sq
|
||||||
|
•Out "Expected one of: "∾•Fmt tOut
|
||||||
•Exit 1
|
•Exit 1
|
||||||
;@
|
;@
|
||||||
}¨ tIn
|
}¨ tIn
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user