64-bit hashes with float normalization

This commit is contained in:
Marshall Lochbaum 2023-11-07 14:50:26 -05:00
parent a4290b1f5c
commit 8a2190b092
2 changed files with 31 additions and 11 deletions

View File

@ -65,6 +65,13 @@ extern B mul_c2(B,B,B);
extern B join_c2(B,B,B);
extern B select_c2(B,B,B);
B asNormalized(B x, usz n, bool nanBad);
SHOULD_INLINE bool canCompare64_norm(B* w, usz wia, B* x, usz xia) {
B wn=asNormalized(*w,wia,true); if (wn.u == m_f64(0).u) return 0; *w=wn;
B xn=asNormalized(*x,xia,true); if (xn.u == m_f64(0).u) return 0; *x=xn;
return 1;
}
static u64 elRange(u8 eltype) { return 1ull<<(1<<elwBitLog(eltype)); }
#define TABLE(IN, FOR, TY, INIT, SET) \
@ -221,7 +228,9 @@ static NOINLINE usz indexOfOne(B l, B e) {
} else
B indexOf_c2(B t, B w, B x) {
bool split = 0;
if (RARE(!isArr(w) || RNK(w)!=1)) {
split = 1;
B2 t = splitCells(x, w, 1);
w = t.p;
x = t.n;
@ -300,13 +309,15 @@ B indexOf_c2(B t, B w, B x) {
TABLE(w, x, i32, wia, i)
return reduceI32Width(r, wia);
}
if (we==el_i32 && xe==el_i32) {
#if SINGELI
if (we==xe && (we==el_i32 || (we==el_f64 && (split || canCompare64_norm(&w,wia,&x,xia))))) {
i32* rp; B r = m_i32arrc(&rp, x);
if (indexOf_c2_hash32(rp, tyany_ptr(w), wia, tyany_ptr(x), xia)) {
if (si_indexOf_c2_hash[we-el_i32](rp, tyany_ptr(w), wia, tyany_ptr(x), xia)) {
decG(w); decG(x); return reduceI32Width(r, wia);
}
decG(r);
}
#endif
}
i32* rp; B r = m_i32arrc(&rp, x);
@ -325,7 +336,9 @@ B indexOf_c2(B t, B w, B x) {
B enclosed_0, enclosed_1;
B memberOf_c2(B t, B w, B x) {
bool split = 0;
if (isAtm(x) || RNK(x)!=1) {
split = 1;
B2 t = splitCells(w, x, false);
w = t.n;
x = t.p;
@ -403,13 +416,15 @@ B memberOf_c2(B t, B w, B x) {
TABLE(x, w, i8, 0, 1)
return taga(cpyBitArr(r));
}
if (we==el_i32 && xe==el_i32) {
#if SINGELI
if (we==xe && (we==el_i32 || (we==el_f64 && (split || canCompare64_norm(&w,wia,&x,xia))))) {
i8* rp; B r = m_i8arrc(&rp, w);
if (memberOf_c2_hash32(rp, tyany_ptr(x), xia, tyany_ptr(w), wia)) {
if (si_memberOf_c2_hash[we-el_i32](rp, tyany_ptr(x), xia, tyany_ptr(w), wia)) {
decG(w); decG(x); return taga(cpyBitArr(r));
}
decG(r);
}
#endif
}
H_Sb* set = m_Sb(64);
@ -429,7 +444,9 @@ B memberOf_c2(B t, B w, B x) {
#undef CHECK_CHRS_ELSE
B count_c2(B t, B w, B x) {
bool split = 0;
if (RARE(!isArr(w) || RNK(w)!=1)) {
split = 1;
B2 t = splitCells(x, w, 2);
w = t.p;
x = t.n;
@ -469,10 +486,12 @@ B count_c2(B t, B w, B x) {
we-= el_c8-el_i8; xe-= el_c8-el_i8;
goto el8or16;
} else {
if (we==el_i32 && xe==el_i32 &&
count_c2_hash32(rp, tyany_ptr(w), wia, tyany_ptr(x), xia, wnext)) {
#if SINGELI
if (we==xe && (we==el_i32 || (we==el_f64 && (split || canCompare64_norm(&w,wia,&x,xia)))) &&
si_count_c2_hash[we-el_i32](rp, tyany_ptr(w), wia, tyany_ptr(x), xia, wnext)) {
goto dec_nwx;
}
#endif
H_b2i* map = m_b2i(64);
SGetU(x)
SGetU(w)

View File

@ -337,9 +337,10 @@ oper &- ({v:T,m} => v & -promote{T,m}) infix left 35
def rty{name} = if (to_prim{name}=='∊') i8 else i32
def ity{name} = (to_prim{name}=='⊒')**(*u32)
fn hashtab{T, name}(rp:*rty{name}, ip:*T, m:usz, fp:*T, n:usz, links:ity{name}) = {
fn hashtab{T, name}(rp:*rty{name}, iv:*void, m:usz, fv:*void, n:usz, links:ity{name}) = {
def wt = width{T}
def prim = to_prim{name}
ip := *T~~iv; fp := *T~~fv
swap:u1 = 0
if (prim=='⊒' and (swap = n < m)) {
each{{a,b}=>{t:=a; a=b; b=t}, tup{ip,m}, tup{fp,n}}
@ -501,7 +502,7 @@ fn hashtab{T, name}(rp:*rty{name}, ip:*T, m:usz, fp:*T, n:usz, links:ity{name})
i == m # Whether it finished
}
def try_vec_memb{} = {}
def try_vec_memb{..._} = {}
def try_vec_memb{T, hash, hashlen, sh, maxh, has_maxh, rp, fp, n, done
& hasarch{'SSE4.2'} & T==u32} = {
# Hash h wants bin h>>sh, so the offset for h in slot i is (in infite-precision ints)
@ -543,7 +544,7 @@ def try_vec_memb{T, hash, hashlen, sh, maxh, has_maxh, rp, fp, n, done
each{try, tup{1,2}}
}
def exp_hash{T, name} = {
export{merge{name,'_c2_hash',fmtnat{width{T}}}, hashtab{T, name}}
def exp_hash{name} = {
exportT{merge{'si_',name,'_c2_hash'}, each{hashtab{., name}, tup{u32,u64}}}
}
each{{n}=>each{exp_hash{.,n},tup{u32}}, names}
each{exp_hash, names}