Make self-search special code only depend on cell size

This commit is contained in:
Marshall Lochbaum 2022-09-14 14:48:33 -04:00
parent 5bf4e20ead
commit 57d33990e3
3 changed files with 49 additions and 28 deletions

View File

@ -7,12 +7,11 @@ B memberOf_c1(B t, B x) {
if (isAtm(x) || RNK(x)==0) thrM("∊: Argument cannot have rank 0");
usz n = *SH(x);
if (n==0) { decG(x); return emptyIVec(); }
if (RNK(x)>1) x = toCells(x);
u8 xe = TI(x,elType);
if (elChr(xe)) xe -= el_c8-el_i8;
u8 lw = cellWidthLog(x);
void* xv = tyany_ptr(x);
#define BRUTE(T) \
i##T* xp = tyany_ptr(x); \
i##T* xp = xv; \
u64* rp; B r = m_bitarrv(&rp, n); bitp_set(rp, 0, 1); \
for (usz i=1; i<n; i++) { \
bool c=1; i##T xi=xp[i]; \
@ -22,7 +21,7 @@ B memberOf_c1(B t, B x) {
decG(x); return r;
#define LOOKUP(T) \
usz tn = 1<<T; \
u##T* xp = (u##T*)tyany_ptr(x); \
u##T* xp = (u##T*)xv; \
i8* rp; B r = m_i8arrv(&rp, n); \
TALLOC(u8, tab, tn); \
if (T>8 && n<tn/64) for (usz i=0; i<n; i++) tab[xp[i]]=1; \
@ -30,14 +29,14 @@ B memberOf_c1(B t, B x) {
for (usz i=0; i<n; i++) { u##T j=xp[i]; rp[i]=tab[j]; tab[j]=0; } \
decG(x); TFREE(tab); \
return num_squeeze(r)
if (xe==el_i8) { if (n<8) { BRUTE(8); } else { LOOKUP(8); } }
if (xe==el_i16) { if (n<8) { BRUTE(16); } else { LOOKUP(16); } }
if (lw == 3) { if (n<8) { BRUTE(8); } else { LOOKUP(8); } }
if (lw == 4) { if (n<8) { BRUTE(16); } else { LOOKUP(16); } }
#undef LOOKUP
if (xe==el_i32) {
if (lw == 5) {
if (n<=32) { BRUTE(32); }
// Radix-assisted lookup
usz rx = 256, tn = 1<<16; // Radix; table length
u32* v0 = (u32*)tyany_ptr(x);
u32* v0 = (u32*)xv;
i8* r0; B r = m_i8arrv(&r0, n);
TALLOC(u8, alloc, 6*n+(4+(tn>3*n?tn:3*n)+(2*rx+1)*sizeof(usz)));
@ -81,6 +80,7 @@ B memberOf_c1(B t, B x) {
}
#undef BRUTE
if (RNK(x)>1) x = toCells(x);
u64* rp; B r = m_bitarrv(&rp, n);
H_Sb* set = m_Sb(64);
SGetU(x)
@ -94,12 +94,11 @@ B count_c1(B t, B x) {
usz n = *SH(x);
if (n==0) { decG(x); return emptyIVec(); }
if (n>(usz)I32_MAX+1) thrM("⊒: Argument length >2⋆31 not supported");
if (RNK(x)>1) x = toCells(x);
u8 xe = TI(x,elType);
if (elChr(xe)) xe -= el_c8-el_i8;
u8 lw = cellWidthLog(x);
void* xv = tyany_ptr(x);
#define BRUTE(T) \
i##T* xp = tyany_ptr(x); \
i##T* xp = xv; \
i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \
for (usz i=1; i<n; i++) { \
usz c=0; i##T xi=xp[i]; \
@ -109,7 +108,7 @@ B count_c1(B t, B x) {
decG(x); return r;
#define LOOKUP(T) \
usz tn = 1<<T; \
u##T* xp = (u##T*)tyany_ptr(x); \
u##T* xp = (u##T*)xv; \
i32* rp; B r = m_i32arrv(&rp, n); \
TALLOC(i32, tab, tn); \
if (T>8 && n<tn/16) for (usz i=0; i<n; i++) tab[xp[i]]=0; \
@ -117,14 +116,14 @@ B count_c1(B t, B x) {
for (usz i=0; i<n; i++) rp[i]=tab[xp[i]]++; \
decG(x); TFREE(tab); \
return num_squeeze(r)
if (xe==el_i8) { if (n<12) { BRUTE(8); } else { LOOKUP(8); } }
if (xe==el_i16) { if (n<12) { BRUTE(16); } else { LOOKUP(16); } }
if (lw==3) { if (n<12) { BRUTE(8); } else { LOOKUP(8); } }
if (lw==4) { if (n<12) { BRUTE(16); } else { LOOKUP(16); } }
#undef LOOKUP
if (xe==el_i32) {
if (lw==5) {
if (n<=32) { BRUTE(32); }
// Radix-assisted lookup
usz rx = 256, tn = 1<<16; // Radix; table length
u32* v0 = (u32*)tyany_ptr(x);
u32* v0 = (u32*)xv;
i32* r0; B r = m_i32arrv(&r0, n);
TALLOC(u8, alloc, 6*n+(4+4*(tn>n?tn:n)+(2*rx+1)*sizeof(usz)));
@ -169,6 +168,7 @@ B count_c1(B t, B x) {
}
#undef BRUTE
if (RNK(x)>1) x = toCells(x);
i32* rp; B r = m_i32arrv(&rp, n);
H_b2i* map = m_b2i(64);
SGetU(x)
@ -186,12 +186,11 @@ B indexOf_c1(B t, B x) {
usz n = *SH(x);
if (n==0) { decG(x); return emptyIVec(); }
if (n>(usz)I32_MAX+1) thrM("⊐: Argument length >2⋆31 not supported");
if (RNK(x)>1) x = toCells(x);
u8 xe = TI(x,elType);
if (elChr(xe)) xe -= el_c8-el_i8;
u8 lw = cellWidthLog(x);
void* xv = tyany_ptr(x);
#define BRUTE(T) \
i##T* xp = tyany_ptr(x); \
i##T* xp = xv; \
i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \
TALLOC(i##T, uniq, n); uniq[0]=xp[0]; \
for (usz i=1, u=1; i<n; i++) { \
@ -202,7 +201,7 @@ B indexOf_c1(B t, B x) {
decG(x); TFREE(uniq); return r;
#define LOOKUP(T) \
usz tn = 1<<T; \
u##T* xp = (u##T*)tyany_ptr(x); \
u##T* xp = (u##T*)xv; \
i32* rp; B r = m_i32arrv(&rp, n); \
TALLOC(i32, tab, tn); \
if (T>8 && n<tn/16) for (usz i=0; i<n; i++) tab[xp[i]]=n; \
@ -214,11 +213,11 @@ B indexOf_c1(B t, B x) {
} \
decG(x); TFREE(tab); \
return num_squeeze(r)
if (xe==el_i8) { if (n<12) { BRUTE(8); } else { LOOKUP(8); } }
if (xe==el_i16) { if (n<12) { BRUTE(16); } else { LOOKUP(16); } }
if (lw==3) { if (n<12) { BRUTE(8); } else { LOOKUP(8); } }
if (lw==4) { if (n<12) { BRUTE(16); } else { LOOKUP(16); } }
#undef LOOKUP
if (xe==el_i32) {
if (lw==5) {
if (n<32) { BRUTE(32); }
i32* xp = tyany_ptr(x);
i32 min=I32_MAX, max=I32_MIN;
@ -245,6 +244,7 @@ B indexOf_c1(B t, B x) {
}
#undef BRUTE
if (RNK(x)>1) x = toCells(x);
i32* rp; B r = m_i32arrv(&rp, n);
H_b2i* map = m_b2i(64);
SGetU(x)

View File

@ -54,4 +54,17 @@ extern u8 elType2type[];
extern u8 elTypeWidth[];
#define elWidth(X) elTypeWidth[X]
extern u8 arrTypeWidthLog[];
#define arrTypeWidthLog(X) arrTypeWidthLog[X]
#define arrTypeWidthLog(X) arrTypeWidthLog[X]
extern u8 arrTypeBitsLog[];
#define arrTypeBitsLog(X) arrTypeBitsLog[X]
// Log of width in bits: max of 7, and also return 7 if not power of 2
static u8 cellWidthLog(B x) {
assert(isArr(x) && RNK(x)>=1);
u8 lw = arrTypeBitsLog(TY(x));
if (LIKELY(RNK(x)==1)) return lw;
usz csz = arr_csz(x);
if (csz & (csz-1)) return 7; // Not power of 2
lw += CTZ(csz);
return lw<7? lw : 7;
}

View File

@ -20,6 +20,14 @@ u8 arrTypeWidthLog[] = {
[t_i32arr]=2, [t_i32slice]=2, [t_c32arr]=2, [t_c32slice]=2,
[t_f64arr]=3, [t_f64slice]=3
};
u8 arrTypeBitsLog[] = {
[t_bitarr]=0,
[t_i8arr ]=3, [t_i8slice ]=3, [t_c8arr ]=3, [t_c8slice ]=3,
[t_i16arr]=4, [t_i16slice]=4, [t_c16arr]=4, [t_c16slice]=4,
[t_i32arr]=5, [t_i32slice]=5, [t_c32arr]=5, [t_c32slice]=5,
[t_f64arr]=6, [t_f64slice]=6,
[t_harr ]=6, [t_hslice ]=6, [t_fillarr]=6,[t_fillslice]=6
};
B m_i8(i8 x) { return m_i32(x); } B m_i16(i16 x) { return m_i32(x); }
B m_c8(u8 x) { return m_c32(x); } B m_c16(u16 x) { return m_c32(x); }
@ -87,4 +95,4 @@ void tyarr_init() {
Arr* emptySVec = arr_shVec(m_fillarrp(0));
fillarr_setFill(emptySVec, emptyCVec());
bi_emptySVec = taga(emptySVec); gc_add(bi_emptySVec);
}
}