diff --git a/makefile b/makefile index 317394a9..cfae1da0 100644 --- a/makefile +++ b/makefile @@ -192,7 +192,7 @@ ${bd}/%.o: src/jit/%.c @echo $< | cut -c 5- @$(CC_INC) $@.d -o $@ -c $< -builtins: ${addprefix ${bd}/, arithm.o arithd.o cmp.o sfns.o squeeze.o select.o sort.o md1.o md2.o fns.o sysfn.o internal.o inverse.o} +builtins: ${addprefix ${bd}/, arithm.o arithd.o cmp.o sfns.o squeeze.o select.o sort.o selfsearch.o md1.o md2.o fns.o sysfn.o internal.o inverse.o} ${bd}/%.o: src/builtins/%.c @echo $< | cut -c 5- @$(CC_INC) $@.d -o $@ -c $< diff --git a/src/builtins/fns.c b/src/builtins/fns.c index 12ba4943..9f1e55a4 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -122,89 +122,6 @@ B fne_c2(B t, B w, B x) { extern B rt_indexOf; -B indexOf_c1(B t, B x) { - if (isAtm(x)) thrM("⊐: 𝕩 cannot have rank 0"); - usz xia = IA(x); - if (xia==0) { decG(x); return emptyIVec(); } - - u8 xe = TI(x,elType); - #define LOOKUP(T) \ - usz tn = 1<=16 && xe==el_i8 && xia<=(usz)I32_MAX+1) { LOOKUP(8); } - if (RNK(x)==1 && xia>=256 && xe==el_i16 && xia<=(usz)I32_MAX+1) { LOOKUP(16); } - #undef LOOKUP - - if (RNK(x)==1 && xe==el_i32) { - i32* xp = i32any_ptr(x); - i32 min=I32_MAX, max=I32_MIN; - for (usz i = 0; i < xia; i++) { - i32 c = xp[i]; - if (cmax) max = c; - } - i64 dst = 1 + (max-(i64)min); - if ((dsta[p].val; - else rp[i] = map->a[p].val = ctr++; - } - free_b2i(map); decG(x); - // u64 e = nsTime(); q1+= e-s; - return r; - } - return c1(rt_indexOf, x); -} B indexOf_c2(B t, B w, B x) { if (!isArr(w) || RNK(w)==0) thrM("⊐: 𝕨 must have rank at least 1"); if (RNK(w)==1) { @@ -254,80 +171,6 @@ B indexOf_c2(B t, B w, B x) { B enclosed_0; B enclosed_1; extern B rt_memberOf; -B memberOf_c1(B t, B x) { - if (isAtm(x) || RNK(x)==0) thrM("∊: Argument cannot have rank 0"); - if (RNK(x)!=1) x = toCells(x); - usz xia = IA(x); - u8 xe = TI(x,elType); - - #define LOOKUP(T) \ - usz tn = 1<=16 && xe==el_i8) { LOOKUP(8); } - if (xia>=256 && xe==el_i16) { LOOKUP(16); } - #undef LOOKUP - // Radix-assisted lookup - if (xia>=256 && xe==el_i32) { - usz rx = 256, tn = 1<<16; // Radix; table length - usz n = xia; - u32* v0 = (u32*)i32any_ptr(x); - i8* r0; B r = m_i8arrv(&r0, n); - - TALLOC(u8, alloc, 9*n+(tn+2*rx*sizeof(usz))); - // Allocations count radix hash deradix - usz *c0 = (usz*)(alloc); // rx X-----------------X - usz *c1 = (usz*)(c0+rx); // rx X-----------------X - u8 *k0 = (u8 *)(c1+rx); // n X-----------------X - u8 *k1 = (u8 *)(k0+n); // --/----------X - u32 *v1 = (u32*)(k1); // n X-X - u32 *v2 = (u32*)(v1+n); // n X----------X - u8 *r2 = (u8 *)(k1+n); - u8 *r1 = (u8 *)(r2+n); - u8 *tab= (u8 *)(v2+n); // tn - - // Count keys - for (usz j=0; j<2*rx; j++) c0[j] = 0; - for (usz i=0; i>24)]++; c1[(u8)(v>>16)]++; } - // Exclusive prefix sum - usz s0=0, s1=0; - for (usz j=0; j>24); usz c=c0[k]++; v1[c]=v; } - for (usz i=0; i>16); usz c=c1[k]++; v2[c]=v; } - // Table lookup - for (usz j=0; j>16; usz e=0; - for (usz i=0; i>16; - // Clear table when top bytes change - if (RARE(tv!=t0)) { for (; e1) x = toCells(x); - usz xia = IA(x); - u8 xe = TI(x,elType); - - #define LOOKUP(T) \ - usz tn = 1<=16 && xe==el_i8 && xia<=(usz)I32_MAX+1) { LOOKUP(8); } - if (xia>=256 && xe==el_i16 && xia<=(usz)I32_MAX+1) { LOOKUP(16); } - #undef LOOKUP - - i32* rp; B r = m_i32arrv(&rp, xia); - H_b2i* map = m_b2i(64); - SGetU(x) - for (usz i = 0; i < xia; i++) { - bool had; u64 p = mk_b2i(&map, GetU(x,i), &had); - rp[i] = had? ++map->a[p].val : (map->a[p].val = 0); - } - decG(x); free_b2i(map); - return r; -} B count_c2(B t, B w, B x) { return c2(rt_count, w, x); } diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c new file mode 100644 index 00000000..044d789a --- /dev/null +++ b/src/builtins/selfsearch.c @@ -0,0 +1,212 @@ +#include "../core.h" +#include "../utils/hash.h" +#include "../utils/mut.h" +#include "../utils/talloc.h" + +B memberOf_c1(B t, B x) { + if (isAtm(x) || RNK(x)==0) thrM("∊: Argument cannot have rank 0"); + if (RNK(x)!=1) x = toCells(x); + usz xia = IA(x); + u8 xe = TI(x,elType); + + #define LOOKUP(T) \ + usz tn = 1<=16 && xe==el_i8) { LOOKUP(8); } + if (xia>=256 && xe==el_i16) { LOOKUP(16); } + #undef LOOKUP + // Radix-assisted lookup + if (xia>=256 && xe==el_i32) { + usz rx = 256, tn = 1<<16; // Radix; table length + usz n = xia; + u32* v0 = (u32*)i32any_ptr(x); + i8* r0; B r = m_i8arrv(&r0, n); + + TALLOC(u8, alloc, 9*n+(tn+2*rx*sizeof(usz))); + // Allocations count radix hash deradix + usz *c0 = (usz*)(alloc); // rx X-----------------X + usz *c1 = (usz*)(c0+rx); // rx X-----------------X + u8 *k0 = (u8 *)(c1+rx); // n X-----------------X + u8 *k1 = (u8 *)(k0+n); // --/----------X + u32 *v1 = (u32*)(k1); // n X-X + u32 *v2 = (u32*)(v1+n); // n X----------X + u8 *r2 = (u8 *)(k1+n); + u8 *r1 = (u8 *)(r2+n); + u8 *tab= (u8 *)(v2+n); // tn + + // Count keys + for (usz j=0; j<2*rx; j++) c0[j] = 0; + for (usz i=0; i>24)]++; c1[(u8)(v>>16)]++; } + // Exclusive prefix sum + usz s0=0, s1=0; + for (usz j=0; j>24); usz c=c0[k]++; v1[c]=v; } + for (usz i=0; i>16); usz c=c1[k]++; v2[c]=v; } + // Table lookup + for (usz j=0; j>16; usz e=0; + for (usz i=0; i>16; + // Clear table when top bytes change + if (RARE(tv!=t0)) { for (; e1) x = toCells(x); + usz xia = IA(x); + u8 xe = TI(x,elType); + + #define LOOKUP(T) \ + usz tn = 1<=16 && xe==el_i8 && xia<=(usz)I32_MAX+1) { LOOKUP(8); } + if (xia>=256 && xe==el_i16 && xia<=(usz)I32_MAX+1) { LOOKUP(16); } + #undef LOOKUP + + i32* rp; B r = m_i32arrv(&rp, xia); + H_b2i* map = m_b2i(64); + SGetU(x) + for (usz i = 0; i < xia; i++) { + bool had; u64 p = mk_b2i(&map, GetU(x,i), &had); + rp[i] = had? ++map->a[p].val : (map->a[p].val = 0); + } + decG(x); free_b2i(map); + return r; +} + +extern B rt_indexOf; +B indexOf_c1(B t, B x) { + if (isAtm(x)) thrM("⊐: 𝕩 cannot have rank 0"); + usz xia = IA(x); + if (xia==0) { decG(x); return emptyIVec(); } + + u8 xe = TI(x,elType); + #define LOOKUP(T) \ + usz tn = 1<=16 && xe==el_i8 && xia<=(usz)I32_MAX+1) { LOOKUP(8); } + if (RNK(x)==1 && xia>=256 && xe==el_i16 && xia<=(usz)I32_MAX+1) { LOOKUP(16); } + #undef LOOKUP + + if (RNK(x)==1 && xe==el_i32) { + i32* xp = i32any_ptr(x); + i32 min=I32_MAX, max=I32_MIN; + for (usz i = 0; i < xia; i++) { + i32 c = xp[i]; + if (cmax) max = c; + } + i64 dst = 1 + (max-(i64)min); + if ((dsta[p].val; + else rp[i] = map->a[p].val = ctr++; + } + free_b2i(map); decG(x); + // u64 e = nsTime(); q1+= e-s; + return r; + } + return c1(rt_indexOf, x); +} + +extern B rt_find; +B find_c1(B t, B x) { + if (isAtm(x) || RNK(x)==0) thrM("⍷: Argument cannot have rank 0"); + usz xia = IA(x); + B xf = getFillQ(x); + if (RNK(x)!=1) return c1(rt_find, x); + + B r = emptyHVec(); + H_Sb* set = m_Sb(64); + SGetU(x) + for (usz i = 0; i < xia; i++) { + B c = GetU(x,i); + if (!ins_Sb(&set, c)) r = vec_add(r, inc(c)); + } + free_Sb(set); decG(x); + return withFill(r, xf); +} diff --git a/src/opt/single.c b/src/opt/single.c index 8737219d..fd4224b6 100644 --- a/src/opt/single.c +++ b/src/opt/single.c @@ -18,6 +18,7 @@ #include "../builtins/select.c" #include "../builtins/sysfn.c" #include "../builtins/sort.c" +#include "../builtins/selfsearch.c" #include "../builtins/arithm.c" #include "../builtins/arithd.c" #include "../builtins/cmp.c"