From 633e790099b75a503c50e82a2964ea6b73ee094b Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Tue, 23 Aug 2022 21:48:10 -0400 Subject: [PATCH 01/14] =?UTF-8?q?Radix-assisted=20lookup=20implementation?= =?UTF-8?q?=20for=20=E2=88=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/fns.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/builtins/fns.c b/src/builtins/fns.c index 4912d416..aa83f32c 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -239,6 +239,55 @@ 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); + + // Radix-assisted lookup + if (xia>=256 && TI(x,elType)==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 (; e Date: Wed, 24 Aug 2022 10:28:19 -0400 Subject: [PATCH 02/14] Table lookups for self-search functions --- src/builtins/fns.c | 51 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/src/builtins/fns.c b/src/builtins/fns.c index aa83f32c..12ba4943 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -126,7 +126,26 @@ 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(); } - if (RNK(x)==1 && TI(x,elType)==el_i32) { + + 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++) { @@ -239,9 +258,22 @@ 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 && TI(x,elType)==el_i32) { + if (xia>=256 && xe==el_i32) { usz rx = 256, tn = 1<<16; // Radix; table length usz n = xia; u32* v0 = (u32*)i32any_ptr(x); @@ -367,6 +399,21 @@ B count_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 && 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) From 9d402c1bdd644c1ef6e3c3836eadbf06c5e64d4b Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Wed, 24 Aug 2022 10:47:04 -0400 Subject: [PATCH 03/14] Move self-search functions to selfsearch.c --- makefile | 2 +- src/builtins/fns.c | 202 ------------------------------------ src/builtins/selfsearch.c | 212 ++++++++++++++++++++++++++++++++++++++ src/opt/single.c | 1 + 4 files changed, 214 insertions(+), 203 deletions(-) create mode 100644 src/builtins/selfsearch.c 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" From efe2e862710327a27e25efba72d286fb54b04632 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Wed, 24 Aug 2022 11:00:49 -0400 Subject: [PATCH 04/14] Unify search function preambles, so all have empty and rank>1 cases --- src/builtins/selfsearch.c | 80 +++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 42 deletions(-) diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c index 044d789a..2a166357 100644 --- a/src/builtins/selfsearch.c +++ b/src/builtins/selfsearch.c @@ -5,8 +5,9 @@ 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); + if (RNK(x)>1) x = toCells(x); usz xia = IA(x); + if (xia==0) { decG(x); return emptyIVec(); } u8 xe = TI(x,elType); #define LOOKUP(T) \ @@ -16,7 +17,7 @@ B memberOf_c1(B t, B x) { TALLOC(u8, tab, tn); \ for (usz j=0; j=16 && xe==el_i8) { LOOKUP(8); } if (xia>=256 && xe==el_i16) { LOOKUP(16); } @@ -82,6 +83,7 @@ B count_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); + if (xia==0) { decG(x); return emptyIVec(); } u8 xe = TI(x,elType); #define LOOKUP(T) \ @@ -91,7 +93,7 @@ B count_c1(B t, B x) { TALLOC(i32, tab, tn); \ for (usz j=0; j=16 && xe==el_i8 && xia<=(usz)I32_MAX+1) { LOOKUP(8); } if (xia>=256 && xe==el_i16 && xia<=(usz)I32_MAX+1) { LOOKUP(16); } @@ -110,11 +112,12 @@ B count_c1(B t, B x) { extern B rt_indexOf; B indexOf_c1(B t, B x) { - if (isAtm(x)) thrM("⊐: 𝕩 cannot have rank 0"); + if (isAtm(x) || RNK(x)==0) thrM("⊐: 𝕩 cannot have rank 0"); + if (RNK(x)>1) x = toCells(x); 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); } + if (xia>=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 - if (RNK(x)==1 && xe==el_i32) { + if (xe==el_i32) { i32* xp = i32any_ptr(x); i32 min=I32_MAX, max=I32_MIN; for (usz i = 0; i < xia; i++) { @@ -156,49 +159,42 @@ B indexOf_c1(B t, B x) { return r; } } - // if (RNK(x)==1) { // relies on equal hashes implying equal objects, which has like a 2⋆¯64 chance of being false per item - // // u64 s = nsTime(); - // i32* rp; B r = m_i32arrv(&rp, xia); - // u64 size = xia*2; - // wyhashmap_t idx[size]; - // i32 val[size]; - // for (i64 i = 0; i < size; i++) { idx[i] = 0; val[i] = -1; } - // SGet(x) - // i32 ctr = 0; - // for (usz i = 0; i < xia; i++) { - // u64 hash = bqn_hash(Get(x,i), wy_secret); - // u64 p = wyhashmap(idx, size, &hash, 8, true, wy_secret); - // if (val[p]==-1) val[p] = ctr++; - // rp[i] = val[p]; - // } - // dec(x); - // // u64 e = nsTime(); q1+= e-s; - // return r; + // // relies on equal hashes implying equal objects, which has like a 2⋆¯64 chance of being false per item + // i32* rp; B r = m_i32arrv(&rp, xia); + // u64 size = xia*2; + // wyhashmap_t idx[size]; + // i32 val[size]; + // for (i64 i = 0; i < size; i++) { idx[i] = 0; val[i] = -1; } + // SGet(x) + // i32 ctr = 0; + // for (usz i = 0; i < xia; i++) { + // u64 hash = bqn_hash(Get(x,i), wy_secret); + // u64 p = wyhashmap(idx, size, &hash, 8, true, wy_secret); + // if (val[p]==-1) val[p] = ctr++; + // rp[i] = val[p]; // } - if (RNK(x)==1) { - // u64 s = nsTime(); - i32* rp; B r = m_i32arrv(&rp, xia); - H_b2i* map = m_b2i(64); - SGetU(x) - i32 ctr = 0; - for (usz i = 0; i < xia; i++) { - bool had; u64 p = mk_b2i(&map, GetU(x,i), &had); - if (had) rp[i] = map->a[p].val; - else rp[i] = map->a[p].val = ctr++; - } - free_b2i(map); decG(x); - // u64 e = nsTime(); q1+= e-s; - return r; + // dec(x); + // return r; + i32* rp; B r = m_i32arrv(&rp, xia); + H_b2i* map = m_b2i(64); + SGetU(x) + i32 ctr = 0; + for (usz i = 0; i < xia; i++) { + bool had; u64 p = mk_b2i(&map, GetU(x,i), &had); + if (had) rp[i] = map->a[p].val; + else rp[i] = map->a[p].val = ctr++; } - return c1(rt_indexOf, x); + free_b2i(map); decG(x); + return r; } extern B rt_find; B find_c1(B t, B x) { if (isAtm(x) || RNK(x)==0) thrM("⍷: Argument cannot have rank 0"); + if (RNK(x)>1) return c1(rt_find, x); usz xia = IA(x); + if (xia<=1) return x; B xf = getFillQ(x); - if (RNK(x)!=1) return c1(rt_find, x); B r = emptyHVec(); H_Sb* set = m_Sb(64); From 7ffa0dac4a275bb34fbed44fb5badcd0bdb216fd Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Wed, 24 Aug 2022 11:08:27 -0400 Subject: [PATCH 05/14] Switch from using IA to *SH for length --- src/builtins/selfsearch.c | 65 +++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c index 2a166357..f2d79d0a 100644 --- a/src/builtins/selfsearch.c +++ b/src/builtins/selfsearch.c @@ -5,13 +5,13 @@ 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); - 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) { LOOKUP(8); } - if (xia>=256 && xe==el_i16) { LOOKUP(16); } + if (n>=16 && xe==el_i8) { LOOKUP(8); } + if (n>=256 && xe==el_i16) { LOOKUP(16); } #undef LOOKUP // Radix-assisted lookup - if (xia>=256 && xe==el_i32) { + if (n>=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); @@ -71,23 +70,23 @@ B memberOf_c1(B t, B x) { return num_squeeze(r); } - u64* rp; B r = m_bitarrv(&rp, xia); + u64* rp; B r = m_bitarrv(&rp, n); H_Sb* set = m_Sb(64); SGetU(x) - for (usz i = 0; i < xia; i++) bitp_set(rp, i, !ins_Sb(&set, GetU(x,i))); + for (usz i = 0; i < n; i++) bitp_set(rp, i, !ins_Sb(&set, GetU(x,i))); free_Sb(set); decG(x); return r; } B count_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); - 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 (xia>=256 && xe==el_i16 && xia<=(usz)I32_MAX+1) { LOOKUP(16); } + if (n>=16 && xe==el_i8 && n<=(usz)I32_MAX+1) { LOOKUP(8); } + if (n>=256 && xe==el_i16 && n<=(usz)I32_MAX+1) { LOOKUP(16); } #undef LOOKUP - i32* rp; B r = m_i32arrv(&rp, xia); + i32* rp; B r = m_i32arrv(&rp, n); H_b2i* map = m_b2i(64); SGetU(x) - for (usz i = 0; i < xia; i++) { + for (usz i = 0; i < n; i++) { bool had; u64 p = mk_b2i(&map, GetU(x,i), &had); rp[i] = had? ++map->a[p].val : (map->a[p].val = 0); } @@ -113,13 +112,13 @@ B count_c1(B t, B x) { extern B rt_indexOf; B indexOf_c1(B t, B x) { if (isAtm(x) || RNK(x)==0) thrM("⊐: 𝕩 cannot have rank 0"); + usz n = *SH(x); + if (n==0) { decG(x); return emptyIVec(); } if (RNK(x)>1) x = toCells(x); - 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 (xia>=256 && xe==el_i16 && xia<=(usz)I32_MAX+1) { LOOKUP(16); } + if (n>=16 && xe==el_i8 && n<=(usz)I32_MAX+1) { LOOKUP(8); } + if (n>=256 && xe==el_i16 && n<=(usz)I32_MAX+1) { LOOKUP(16); } #undef LOOKUP if (xe==el_i32) { i32* xp = i32any_ptr(x); i32 min=I32_MAX, max=I32_MIN; - for (usz i = 0; i < xia; i++) { + for (usz i = 0; i < n; 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++; @@ -191,15 +190,15 @@ B indexOf_c1(B t, B 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 n = *SH(x); + if (n<=1) return x; if (RNK(x)>1) return c1(rt_find, x); - usz xia = IA(x); - if (xia<=1) return x; B xf = getFillQ(x); B r = emptyHVec(); H_Sb* set = m_Sb(64); SGetU(x) - for (usz i = 0; i < xia; i++) { + for (usz i = 0; i < n; i++) { B c = GetU(x,i); if (!ins_Sb(&set, c)) r = vec_add(r, inc(c)); } From 5cd2cab26ebf267a9ced95214dbb0acf676704b1 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Wed, 24 Aug 2022 18:27:11 -0400 Subject: [PATCH 06/14] =?UTF-8?q?Small-number=20integer=20=E2=88=8A=20with?= =?UTF-8?q?=20all-pairs=20comparison=20and=202-byte=20radix+table?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/selfsearch.c | 52 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c index f2d79d0a..2d3c0169 100644 --- a/src/builtins/selfsearch.c +++ b/src/builtins/selfsearch.c @@ -10,6 +10,15 @@ B memberOf_c1(B t, B x) { if (RNK(x)>1) x = toCells(x); u8 xe = TI(x,elType); + #define BRUTE(T) \ + i##T* xp = i##T##any_ptr(x); \ + u64* rp; B r = m_bitarrv(&rp, n); bitp_set(rp, 0, 1); \ + for (usz i=1; i=16 && xe==el_i8) { LOOKUP(8); } - if (n>=256 && xe==el_i16) { LOOKUP(16); } + if (xe==el_i8) { if (n<8) { BRUTE(8); } else { LOOKUP(8); } } + if (xe==el_i16) { + if (n<16) { BRUTE(16); } + if (n>=256) { LOOKUP(16); } + // Radix-assisted lookup + usz rx = 256, tn = 256; // Radix; table length + u16* v0 = (u16*)i16any_ptr(x); + i8* r0; B r = m_i8arrv(&r0, n); + TALLOC(u8, alloc, 4*n+(tn+rx)); + u8 *c0 = alloc; + u8 *k0 = c0+rx; + u16 *v1 = (u16*)(k0+n); + u8 *r1 = (u8*)(v1+n); + u8 *tab= r1+n; + // Count keys + for (usz j=0; j>8)]++; + // Exclusive prefix sum + usz s=0; for (usz j=0; j>8); usz c=c0[k]++; v1[c]=v; } + // Table lookup + for (usz j=0; j>8; + for (usz i=0, e=0; i>8; + if (tv!=t0) { for (; e=256 && xe==el_i32) { usz rx = 256, tn = 1<<16; // Radix; table length u32* v0 = (u32*)i32any_ptr(x); @@ -69,6 +112,7 @@ B memberOf_c1(B t, B x) { decG(x); TFREE(alloc); return num_squeeze(r); } + #undef BRUTE u64* rp; B r = m_bitarrv(&rp, n); H_Sb* set = m_Sb(64); @@ -93,7 +137,7 @@ B count_c1(B t, B x) { for (usz j=0; j=16 && xe==el_i8 && n<=(usz)I32_MAX+1) { LOOKUP(8); } if (n>=256 && xe==el_i16 && n<=(usz)I32_MAX+1) { LOOKUP(16); } #undef LOOKUP @@ -129,7 +173,7 @@ B indexOf_c1(B t, B x) { if (t==n) rp[i]=tab[j]=u++; else rp[i]=t; \ } \ decG(x); TFREE(tab); \ - return r + return num_squeeze(r) if (n>=16 && xe==el_i8 && n<=(usz)I32_MAX+1) { LOOKUP(8); } if (n>=256 && xe==el_i16 && n<=(usz)I32_MAX+1) { LOOKUP(16); } #undef LOOKUP From ad8570be118bd1e1724164e514fd041ae56a08a2 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Wed, 24 Aug 2022 20:26:02 -0400 Subject: [PATCH 07/14] Wait, sparse initialization with a pass through the argument is faster than radix stuff --- src/builtins/selfsearch.c | 40 ++++----------------------------------- 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c index 2d3c0169..949e0936 100644 --- a/src/builtins/selfsearch.c +++ b/src/builtins/selfsearch.c @@ -24,45 +24,13 @@ B memberOf_c1(B t, B x) { u##T* xp = (u##T*)i##T##any_ptr(x); \ i8* rp; B r = m_i8arrv(&rp, n); \ TALLOC(u8, tab, tn); \ - for (usz j=0; j8 && n=256) { LOOKUP(16); } - // Radix-assisted lookup - usz rx = 256, tn = 256; // Radix; table length - u16* v0 = (u16*)i16any_ptr(x); - i8* r0; B r = m_i8arrv(&r0, n); - TALLOC(u8, alloc, 4*n+(tn+rx)); - u8 *c0 = alloc; - u8 *k0 = c0+rx; - u16 *v1 = (u16*)(k0+n); - u8 *r1 = (u8*)(v1+n); - u8 *tab= r1+n; - // Count keys - for (usz j=0; j>8)]++; - // Exclusive prefix sum - usz s=0; for (usz j=0; j>8); usz c=c0[k]++; v1[c]=v; } - // Table lookup - for (usz j=0; j>8; - for (usz i=0, e=0; i>8; - if (tv!=t0) { for (; e Date: Wed, 24 Aug 2022 21:05:39 -0400 Subject: [PATCH 08/14] Make first initialization in radix 4-byte lookup sparse too --- src/builtins/selfsearch.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c index 949e0936..1b2ae2c9 100644 --- a/src/builtins/selfsearch.c +++ b/src/builtins/selfsearch.c @@ -32,14 +32,14 @@ B memberOf_c1(B t, B x) { if (xe==el_i8) { if (n<8) { BRUTE(8); } else { LOOKUP(8); } } if (xe==el_i16) { if (n<8) { BRUTE(16); } else { LOOKUP(16); } } #undef LOOKUP - // Radix-assisted lookup - if (n<=32 && xe==el_i32) { BRUTE(32); } - if (n>=256 && xe==el_i32) { + if (xe==el_i32) { + if (n<=32) { BRUTE(32); } + // Radix-assisted lookup usz rx = 256, tn = 1<<16; // Radix; table length u32* v0 = (u32*)i32any_ptr(x); i8* r0; B r = m_i8arrv(&r0, n); - TALLOC(u8, alloc, 9*n+(tn+2*rx*sizeof(usz))); + TALLOC(u8, alloc, 9*n+(1+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 @@ -49,7 +49,7 @@ B memberOf_c1(B t, B 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 + u8 *tab= (u8 *)(v2+n+1); // tn // Count keys for (usz j=0; j<2*rx; j++) c0[j] = 0; @@ -65,13 +65,10 @@ B memberOf_c1(B t, B x) { for (usz i=0; i>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 (; e>16; v2[n]=~v2[n-1]; + for (usz l=0, i=0; l>16; if (tv!=t0) break; tab[(u16)v]=1; } + for (; i Date: Thu, 25 Aug 2022 10:39:38 -0400 Subject: [PATCH 09/14] =?UTF-8?q?Port=20all=20the=20integer=20monadic=20?= =?UTF-8?q?=E2=88=8A=20methods=20to=20=E2=8A=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/selfsearch.c | 78 ++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 10 deletions(-) diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c index 1b2ae2c9..2c219045 100644 --- a/src/builtins/selfsearch.c +++ b/src/builtins/selfsearch.c @@ -39,7 +39,7 @@ B memberOf_c1(B t, B x) { u32* v0 = (u32*)i32any_ptr(x); i8* r0; B r = m_i8arrv(&r0, n); - TALLOC(u8, alloc, 9*n+(1+tn+2*rx*sizeof(usz))); + TALLOC(u8, alloc, 9*n+(4+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 @@ -94,18 +94,76 @@ B count_c1(B t, B x) { if (RNK(x)>1) x = toCells(x); u8 xe = TI(x,elType); + #define BRUTE(T) \ + i##T* xp = i##T##any_ptr(x); \ + i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \ + for (usz i=1; i8 && n=16 && xe==el_i8 && n<=(usz)I32_MAX+1) { LOOKUP(8); } - if (n>=256 && xe==el_i16 && n<=(usz)I32_MAX+1) { LOOKUP(16); } + if (n<=(usz)I32_MAX+1) { + if (xe==el_i8) { if (n<12) { BRUTE(8); } else { LOOKUP(8); } } + if (xe==el_i16) { if (n<12) { BRUTE(16); } else { LOOKUP(16); } } + } #undef LOOKUP + if (xe==el_i32) { + if (n<=32) { BRUTE(32); } + // Radix-assisted lookup + usz rx = 256, tn = 1<<16; // Radix; table length + u32* v0 = (u32*)i32any_ptr(x); + i32* r0; B r = m_i32arrv(&r0, n); + + TALLOC(u8, alloc, 10*n+(4+4*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); // n X-X + u32 *v2 = (u32*)(v1+n); // n X----------X + u32 *r2 = (u32*)v2; + u32 *r1 = (u32*)v1; + u32 *tab= (u32*)(v2+n+1); // 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 + u32 tv=v2[0]>>16; v2[n]=~v2[n-1]; + for (usz l=0, i=0; l>16; if (tv!=t0) break; tab[(u16)v]=0; } + for (; i Date: Thu, 25 Aug 2022 10:46:19 -0400 Subject: [PATCH 10/14] =?UTF-8?q?1-=20and=202-byte=20methods=20for=20monad?= =?UTF-8?q?ic=20=E2=8A=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/selfsearch.c | 47 +++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c index 2c219045..fa2a466b 100644 --- a/src/builtins/selfsearch.c +++ b/src/builtins/selfsearch.c @@ -91,6 +91,7 @@ B count_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 (n>(usz)I32_MAX+1) thrM("⊒: Argument length >2⋆31 not supported"); if (RNK(x)>1) x = toCells(x); u8 xe = TI(x,elType); @@ -113,10 +114,8 @@ B count_c1(B t, B x) { for (usz i=0; i(usz)I32_MAX+1) thrM("⊐: Argument length >2⋆31 not supported"); if (RNK(x)>1) x = toCells(x); u8 xe = TI(x,elType); + #define BRUTE(T) \ + i##T* xp = i##T##any_ptr(x); \ + 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; i8 && n=16 && xe==el_i8 && n<=(usz)I32_MAX+1) { LOOKUP(8); } - if (n>=256 && xe==el_i16 && n<=(usz)I32_MAX+1) { LOOKUP(16); } + if (xe==el_i8) { if (n<12) { BRUTE(8); } else { LOOKUP(8); } } + if (xe==el_i16) { if (n<12) { BRUTE(16); } else { LOOKUP(16); } } #undef LOOKUP if (xe==el_i32) { + if (n<32) { BRUTE(32); } i32* xp = i32any_ptr(x); i32 min=I32_MAX, max=I32_MIN; for (usz i = 0; i < n; i++) { @@ -225,6 +237,7 @@ B indexOf_c1(B t, B x) { return r; } } + #undef BRUTE // // relies on equal hashes implying equal objects, which has like a 2⋆¯64 chance of being false per item // i32* rp; B r = m_i32arrv(&rp, n); // u64 size = n*2; From c590d730302708d81da3735ae341693045e8c65f Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Thu, 25 Aug 2022 11:25:59 -0400 Subject: [PATCH 11/14] Missed TFREE --- src/builtins/selfsearch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c index fa2a466b..27e99e61 100644 --- a/src/builtins/selfsearch.c +++ b/src/builtins/selfsearch.c @@ -193,7 +193,7 @@ B indexOf_c1(B t, B x) { for (usz j=0; j Date: Thu, 25 Aug 2022 20:27:30 +0300 Subject: [PATCH 12/14] more diagram --- src/builtins/selfsearch.c | 78 +++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c index 27e99e61..37e2cf81 100644 --- a/src/builtins/selfsearch.c +++ b/src/builtins/selfsearch.c @@ -9,7 +9,7 @@ B memberOf_c1(B t, B x) { if (n==0) { decG(x); return emptyIVec(); } if (RNK(x)>1) x = toCells(x); u8 xe = TI(x,elType); - + #define BRUTE(T) \ i##T* xp = i##T##any_ptr(x); \ u64* rp; B r = m_bitarrv(&rp, n); bitp_set(rp, 0, 1); \ @@ -38,19 +38,20 @@ B memberOf_c1(B t, B x) { usz rx = 256, tn = 1<<16; // Radix; table length u32* v0 = (u32*)i32any_ptr(x); i8* r0; B r = m_i8arrv(&r0, n); - + TALLOC(u8, alloc, 9*n+(4+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+1); // tn - + // timeline + // Allocations len count radix hash deradix bytes layout: + usz *c0 = (usz*)(alloc); // rx [+++................] c0 rx # + usz *c1 = (usz*)(c0+rx); // rx [++................] c1 rx # + u8 *k0 = (u8 *)(c1+rx); // n [+.............] k0 n ## + u8 *k1 = (u8 *)(k0+n); // n [+............] k1 n ## + u32 *v1 = (u32*)(k1); // n [+-] v1 4*n ######## + u32 *v2 = (u32*)(k1+4*n); // n [+.......] v2 4*n ######## + u8 *r2 = (u8 *)(k1+ n); // n [+.....] r2 n ## + u8 *r1 = (u8 *)(k1+2*n); // n [+..] r1 n ## + u8 *tab= (u8 *)(k1+8*n+1); // tn [+] tab tn ##### + // Count keys for (usz j=0; j<2*rx; j++) c0[j] = 0; for (usz i=0; i>24)]++; c1[(u8)(v>>16)]++; } @@ -94,7 +95,7 @@ B count_c1(B t, B x) { 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); - + #define BRUTE(T) \ i##T* xp = i##T##any_ptr(x); \ i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \ @@ -123,19 +124,21 @@ B count_c1(B t, B x) { usz rx = 256, tn = 1<<16; // Radix; table length u32* v0 = (u32*)i32any_ptr(x); i32* r0; B r = m_i32arrv(&r0, n); - + TALLOC(u8, alloc, 10*n+(4+4*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); // n X-X - u32 *v2 = (u32*)(v1+n); // n X----------X - u32 *r2 = (u32*)v2; - u32 *r1 = (u32*)v1; - u32 *tab= (u32*)(v2+n+1); // tn - + + // timeline + // Allocations len count radix hash deradix bytes layout: + usz *c0 = (usz*)(alloc); // rx [+++................] c0 rx # + usz *c1 = (usz*)(c0+rx); // rx [++................] c1 rx # + u8 *k0 = (u8 *)(c1+rx); // n [+.............] k0 n ## + u8 *k1 = (u8 *)(k0+n); // n [+............] k1 n ## + u32 *v1 = (u32*)(k1+n); // n [+..] v1 4*n ######## + u32 *v2 = (u32*)(v1+n); // n [+....-] v2 4*n ######## + u32 *r2 = (u32*)v2; // n [+.....] r2 4*n ######## + u32 *r1 = (u32*)v1; // n [+..] r1 4*n ######## + u32 *tab= (u32*)(v2+n+1); // tn [+] tab 4*tn ########### + // Count keys for (usz j=0; j<2*rx; j++) c0[j] = 0; for (usz i=0; i>24)]++; c1[(u8)(v>>16)]++; } @@ -163,7 +166,7 @@ B count_c1(B t, B x) { return num_squeeze(r); } #undef BRUTE - + i32* rp; B r = m_i32arrv(&rp, n); H_b2i* map = m_b2i(64); SGetU(x) @@ -183,7 +186,7 @@ B indexOf_c1(B t, B x) { 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); - + #define BRUTE(T) \ i##T* xp = i##T##any_ptr(x); \ i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \ @@ -211,7 +214,7 @@ B indexOf_c1(B t, B x) { if (xe==el_i8) { if (n<12) { BRUTE(8); } else { LOOKUP(8); } } if (xe==el_i16) { if (n<12) { BRUTE(16); } else { LOOKUP(16); } } #undef LOOKUP - + if (xe==el_i32) { if (n<32) { BRUTE(32); } i32* xp = i32any_ptr(x); @@ -238,22 +241,7 @@ B indexOf_c1(B t, B x) { } } #undef BRUTE - // // relies on equal hashes implying equal objects, which has like a 2⋆¯64 chance of being false per item - // i32* rp; B r = m_i32arrv(&rp, n); - // u64 size = n*2; - // wyhashmap_t idx[size]; - // i32 val[size]; - // for (i64 i = 0; i < size; i++) { idx[i] = 0; val[i] = -1; } - // SGet(x) - // i32 ctr = 0; - // for (usz i = 0; i < n; i++) { - // u64 hash = bqn_hash(Get(x,i), wy_secret); - // u64 p = wyhashmap(idx, size, &hash, 8, true, wy_secret); - // if (val[p]==-1) val[p] = ctr++; - // rp[i] = val[p]; - // } - // dec(x); - // return r; + i32* rp; B r = m_i32arrv(&rp, n); H_b2i* map = m_b2i(64); SGetU(x) From 34950339c242777c6ca126b9da9a952d593f1795 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Thu, 25 Aug 2022 14:00:28 -0400 Subject: [PATCH 13/14] Improve radix+table allocation layout --- src/builtins/selfsearch.c | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c index 37e2cf81..79bdb2a5 100644 --- a/src/builtins/selfsearch.c +++ b/src/builtins/selfsearch.c @@ -39,18 +39,18 @@ B memberOf_c1(B t, B x) { u32* v0 = (u32*)i32any_ptr(x); i8* r0; B r = m_i8arrv(&r0, n); - TALLOC(u8, alloc, 9*n+(4+tn+2*rx*sizeof(usz))); + TALLOC(u8, alloc, 7*n+(4+(tn>2*n?tn:2*n)+(2*rx+1)*sizeof(usz))); // timeline - // Allocations len count radix hash deradix bytes layout: - usz *c0 = (usz*)(alloc); // rx [+++................] c0 rx # - usz *c1 = (usz*)(c0+rx); // rx [++................] c1 rx # - u8 *k0 = (u8 *)(c1+rx); // n [+.............] k0 n ## - u8 *k1 = (u8 *)(k0+n); // n [+............] k1 n ## - u32 *v1 = (u32*)(k1); // n [+-] v1 4*n ######## - u32 *v2 = (u32*)(k1+4*n); // n [+.......] v2 4*n ######## - u8 *r2 = (u8 *)(k1+ n); // n [+.....] r2 n ## - u8 *r1 = (u8 *)(k1+2*n); // n [+..] r1 n ## - u8 *tab= (u8 *)(k1+8*n+1); // tn [+] tab tn ##### + // Allocations len count radix hash deradix bytes layout: + usz *c0 = (usz*)(alloc+1); // rx [+++................] c0 rx # + usz *c1 = (usz*)(c0+rx); // rx [++................] c1 rx # + u8 *k0 = (u8 *)(c1+rx); // n [+.............] k0 n ## + u32 *v2 = (u32*)(k0+n); // n+1 [+.......] v2 4*n+4 ######## + u8 *k1 = (u8 *)(v2+n+1); // n [+............] k1 n ## + u32 *v1 = (u32*)(k1); // n [+-] v1 4*n ######## + u8 *r2 = (u8 *)(k1+ n); // n [+.....] r2 n ## + u8 *r1 = (u8 *)(k1+2*n); // n [+..] r1 n ## + u8 *tab= (u8 *)(r1); // tn [+] tab tn ##### // Count keys for (usz j=0; j<2*rx; j++) c0[j] = 0; @@ -72,7 +72,7 @@ B memberOf_c1(B t, B x) { for (; in?tn:n)+(2*rx+1)*sizeof(usz))); // timeline // Allocations len count radix hash deradix bytes layout: - usz *c0 = (usz*)(alloc); // rx [+++................] c0 rx # + usz *c0 = (usz*)(alloc+1); // rx [+++................] c0 rx # usz *c1 = (usz*)(c0+rx); // rx [++................] c1 rx # u8 *k0 = (u8 *)(c1+rx); // n [+.............] k0 n ## u8 *k1 = (u8 *)(k0+n); // n [+............] k1 n ## - u32 *v1 = (u32*)(k1+n); // n [+..] v1 4*n ######## - u32 *v2 = (u32*)(v1+n); // n [+....-] v2 4*n ######## - u32 *r2 = (u32*)v2; // n [+.....] r2 4*n ######## - u32 *r1 = (u32*)v1; // n [+..] r1 4*n ######## - u32 *tab= (u32*)(v2+n+1); // tn [+] tab 4*tn ########### + u32 *v2 = (u32*)(k1+n); // n+1 [+....-] v2 4*n ######## + u32 *v1 = (u32*)(v2+n+1); // n [+..] v1 4*n ######## + u32 *r2 = (u32*)v2; // n [+.....] r2 4*n ######## + u32 *r1 = (u32*)v1; // n [+..] r1 4*n ######## + u32 *tab= (u32*)v1; // tn [+] tab 4*tn ########### // Count keys for (usz j=0; j<2*rx; j++) c0[j] = 0; @@ -159,7 +159,7 @@ B count_c1(B t, B x) { for (; i Date: Thu, 25 Aug 2022 14:09:10 -0400 Subject: [PATCH 14/14] Another allocation improvement --- src/builtins/selfsearch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c index 79bdb2a5..1c15d939 100644 --- a/src/builtins/selfsearch.c +++ b/src/builtins/selfsearch.c @@ -39,7 +39,7 @@ B memberOf_c1(B t, B x) { u32* v0 = (u32*)i32any_ptr(x); i8* r0; B r = m_i8arrv(&r0, n); - TALLOC(u8, alloc, 7*n+(4+(tn>2*n?tn:2*n)+(2*rx+1)*sizeof(usz))); + TALLOC(u8, alloc, 6*n+(4+(tn>3*n?tn:3*n)+(2*rx+1)*sizeof(usz))); // timeline // Allocations len count radix hash deradix bytes layout: usz *c0 = (usz*)(alloc+1); // rx [+++................] c0 rx # @@ -48,9 +48,9 @@ B memberOf_c1(B t, B x) { u32 *v2 = (u32*)(k0+n); // n+1 [+.......] v2 4*n+4 ######## u8 *k1 = (u8 *)(v2+n+1); // n [+............] k1 n ## u32 *v1 = (u32*)(k1); // n [+-] v1 4*n ######## - u8 *r2 = (u8 *)(k1+ n); // n [+.....] r2 n ## - u8 *r1 = (u8 *)(k1+2*n); // n [+..] r1 n ## - u8 *tab= (u8 *)(r1); // tn [+] tab tn ##### + u8 *r2 = (u8 *)(v2); // n [+.....] r2 n ## + u8 *r1 = (u8 *)(k1+n); // n [+..] r1 n ## + u8 *tab= (u8 *)(r1); // tn [+] tab tn ##### // Count keys for (usz j=0; j<2*rx; j++) c0[j] = 0;