From 2bb6750d7d2468834b3627bd0dd78b7266ca5ded Mon Sep 17 00:00:00 2001 From: dzaima Date: Sat, 24 Sep 2022 19:31:46 +0300 Subject: [PATCH] better bitarr fill --- src/builtins/internal.c | 8 +++++++- src/utils/mut.c | 20 +++++++++++++++++++- src/utils/mut.h | 3 +++ test/README.md | 1 + test/mut.bqn | 21 +++++++++++++++++++++ 5 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 test/mut.bqn diff --git a/src/builtins/internal.c b/src/builtins/internal.c index e72be746..e40c0b7e 100644 --- a/src/builtins/internal.c +++ b/src/builtins/internal.c @@ -286,7 +286,13 @@ B internalTemp_c1(B t, B x) { return x; } -B internalTemp_c2(B t, B w, B x) { dec(w); return x; } +B internalTemp_c2(B t, B w, B x) { + #ifdef TEST_MUT + SGetU(x) + FILL_TO(tyarr_ptr(w), o2s(GetU(x,0)), o2s(GetU(x,1)), GetU(x,2), o2s(GetU(x,3))); + #endif + return x; +} B heapDump_c1(B t, B x) { cbqn_heapDump(); diff --git a/src/utils/mut.c b/src/utils/mut.c index 695c9ba0..fabf6c25 100644 --- a/src/utils/mut.c +++ b/src/utils/mut.c @@ -101,7 +101,23 @@ DEF_S(void, set, f64, q_f64(x), x, (void* a, usz ms, B x), ms, x) { ((f64*)a)[ms DEF_G(void, set, B, (void* a, usz ms, B x), ms, x) { (( B*)a)[ms] = x; } DEF_S(void, fill, MAX, false, x, (void* a, usz ms, B x, usz l), ms, x, l) { err("m_fillG_MAX"); } -DEF_S(void, fill, bit, q_bit(x), x, (void* a, usz ms, B x, usz l), ms, x, l) { u64* p = (u64*)a;bool v = o2bG(x); for (usz i = 0; i < l; i++) bitp_set(p, ms+i, v); } +DEF_S(void, fill, bit, q_bit(x), x, (void* a, usz ms, B x, usz l), ms, x, l) { u64* p = (u64*)a; bool v = o2bG(x); + usz me = ms+l; + if (ms>>6 == me>>6) { + u64 m = ((1ULL<<(me&63)) - (1ULL<<(ms&63))); + if (v) p[ms>>6]|= m; + else p[ms>>6]&= ~m; + } else { + u64 vx = bitx(x); + u64 m0 = (1ULL<<(ms&63)) - 1; + if (v) p[ms>>6]|= ~m0; + else p[ms>>6]&= m0; + for (usz i = (ms>>6)+1; i < (me>>6); i++) p[i] = vx; + u64 m1 = (1ULL<<(me&63)) - 1; + if (v) p[me>>6]|= m1; + else p[me>>6]&= ~m1; + } +} DEF_S(void, fill, i8 , q_i8 (x), x, (void* a, usz ms, B x, usz l), ms, x, l) { i8* p = ms+( i8*)a; i8 v = o2iG(x); for (usz i = 0; i < l; i++) p[i] = v; } DEF_S(void, fill, i16, q_i16(x), x, (void* a, usz ms, B x, usz l), ms, x, l) { i16* p = ms+(i16*)a; i16 v = o2iG(x); for (usz i = 0; i < l; i++) p[i] = v; } DEF_S(void, fill, i32, q_i32(x), x, (void* a, usz ms, B x, usz l), ms, x, l) { i32* p = ms+(i32*)a; i32 v = o2iG(x); for (usz i = 0; i < l; i++) p[i] = v; } @@ -396,6 +412,7 @@ static B m_getU_f64(Mut* m, usz ms) { return m_f64(m->af64[ms]); } static B m_getU_B (Mut* m, usz ms) { return m->aB[ms]; } M_CopyF copyFns[el_MAX]; +M_FillF fillFns[el_MAX]; MutFns mutFns[el_MAX+1]; u8 el_orArr[el_MAX*16 + el_MAX+1]; @@ -427,4 +444,5 @@ void mutF_init() { mutFns[el_B ].elType = el_B ; mutFns[el_B ].valType = t_harr; mutFns[el_MAX].elType = el_MAX; mutFns[el_MAX].valType = t_COUNT; for (u8 i = 0; i < el_MAX; i++) copyFns[i] = mutFns[i].m_copyG; + for (u8 i = 0; i < el_MAX; i++) fillFns[i] = mutFns[i].m_fillG; } diff --git a/src/utils/mut.h b/src/utils/mut.h index a1f9ffec..ad162fdc 100644 --- a/src/utils/mut.h +++ b/src/utils/mut.h @@ -162,6 +162,9 @@ B vec_join(B w, B x); // consumes both extern M_CopyF copyFns[el_MAX]; #define COPY_TO(WHERE, ELT, MS, X, XS, LEN) copyFns[ELT](WHERE, MS, X, XS, LEN) +extern M_FillF fillFns[el_MAX]; +#define FILL_TO(WHERE, ELT, MS, X, LEN) fillFns[ELT](WHERE, MS, X, LEN) + // if `consume==true`, consumes w,x and expects both args to be vectors // else, doesn't consume x, and decrements refcount of w iif *reusedW (won't free because the result will be w) FORCE_INLINE B arr_join_inline(B w, B x, bool consume, bool* reusedW) { diff --git a/test/README.md b/test/README.md index ce26a358..8eb0b1af 100644 --- a/test/README.md +++ b/test/README.md @@ -10,6 +10,7 @@ test/moreCfgs.sh path/to/mlochbaum/BQN // run "2+2" in a bunch of configurations ./BQN test/equal.bqn // fuzz-test 𝕨≡𝕩 ./BQN test/copy.bqn // fuzz-test creating new arrays with elements copied from another ./BQN test/bitcpy.bqn // fuzz-test bit_cpy; requires a CBQN build with -DTEST_BITCPY +./BQN test/mut.bqn // fuzz-test mut.h (currently just bitarr fill); requires a CBQN build with -DTEST_MUT ./BQN test/hash.bqn // fuzz-test hashing ./BQN test/squeezeValid.bqn // fuzz-test squeezing giving a correct result; requires a CBQN build with -DEEQUAL_NEGZERO ./BQN test/squeezeExact.bqn // fuzz-test squeezing giving the exact smallest result; requires a CBQN build with -DEEQUAL_NEGZERO diff --git a/test/mut.bqn b/test/mut.bqn new file mode 100644 index 00000000..520a5c9b --- /dev/null +++ b/test/mut.bqn @@ -0,0 +1,21 @@ +u ← ⌊100×(•UnixTime+1|100וMonoTime)@ +Range ← (•MakeRand •Show u).Range + +Do ← {𝕊: + orig ← (1000⌊𝕩) Range 2 + s ← Range 1+≠orig + mut ← "Ab"•internal.Variation orig + l ← Range (1+≠orig)-s + v ← Range 2 + mut •internal.Temp ⟨0,s,0,l⟩ + exp ← 0¨⌾((s+↕l)⊸⊏) orig + mut ≢ exp? + •Show '0'+orig + •Show '0'+mut + •Show '0'+exp + •Show s‿l‿v + •Exit 1; + 𝕩 +} + +Do¨ ↕500000 \ No newline at end of file