From dd7c21ed864133d35135f7422ed82b5118ffdc89 Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 29 May 2025 22:59:05 +0300 Subject: [PATCH] extract cycling reshape implementation from shape_c2 currently somewhat-inefficient, but separating out for reference, to allow the moving commit to largely not change anything --- src/builtins/sfns.c | 158 +++++++++++++++++++++++--------------------- 1 file changed, 84 insertions(+), 74 deletions(-) diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index 038913bf..d994d4b9 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -205,6 +205,7 @@ static void shape_c2_prim0(B c) { } #define SHAPE_C2_PRIM1(ID, GET) if (ID!=n_atop & ID!=n_floor & ID!=n_reverse & ID!=n_take) thrF("𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑ (contained %B)", GET) +B reshape_cycle(usz nia, usz xia, B x, ur nr, ShArr* sh); B shape_c2(B t, B w, B x); B shape_c2_01(usz wia, B w, B x) { switch (wia) { default: UD; @@ -304,87 +305,96 @@ B shape_c2(B t, B w, B x) { if (nia <= xia) { return truncReshape(x, xia, nia, nr, sh); } else { - if (xia <= 1) { - if (RARE(xia == 0)) thrM("𝕨⥊𝕩: Empty 𝕩 and non-empty result"); - x = TO_GET(x, 0); - goto unit; - } - if (xia <= nia/2) x = squeeze_any(x); - - u8 xl = arrTypeBitsLog(TY(x)); - u8 xt = arrNewType(TY(x)); - u8* rp; - u64 bi, bf; // Bytes present, bytes wanted - if (xl == 0) { // Bits - u64* rq; r = m_bitarrp(&rq, nia); - rp = (u8*)rq; - usz nw = BIT_N(nia); - u64* xp = bitany_ptr(x); - u64 b = xia; - if (b % 8) { - if (b < 64) { - // Need to avoid calling bit_cpy with arguments <64 bits apart - u64 v = xp[0] & (~(u64)0 >> (64-b)); - do { v |= v<64 && nia>64) rq[1] = v>>(64-b/2); - } else { - memcpy(rq, xp, (b+7)/8); - } - for (; b%8; b*=2) { - if (b>nw*32) { - if (b=bf since bf is rounded up - break; - } - bit_cpyN(rq, b, rq, 0, b); - } - } else { - memcpy(rp, xp, b/8); - } - bi = b/8; - bf = 8*nw; - if (bi == 1) { memset(rp, rp[0], bf); bi=bf; } - } else { - if (TI(x,elType) == el_B) { - MAKE_MUT_INIT(m, nia, el_B); MUTG_INIT(m); - i64 div = nia/xia; - i64 mod = nia%xia; - for (i64 i = 0; i < div; i++) mut_copyG(m, i*xia, x, 0, xia); - mut_copyG(m, div*xia, x, 0, mod); - B xf = getFillR(x); - decG(x); - return withFill(taga(arr_shSetUO(mut_fp(m), nr, sh)), xf); - } - u8 xk = xl - 3; - if (nia >= USZ_MAX) thrOOM(); - rp = m_tyarrp(&r, 1<> (64-b)); - while (b<64) { v |= v<bf) l=bf; - for (; bi<=l/2; bi+=bi) memcpy(rp+bi, rp, bi); - u64 e=bi; for (; e+bi<=bf; e+=bi) memcpy(rp+e, rp, bi); - if (e xia); + Arr* r; + if (xia <= 1) { + if (RARE(xia == 0)) thrM("𝕨⥊𝕩: Empty 𝕩 and non-empty result"); + x = TO_GET(x, 0); + + r = reshape_one(nia, x); + return taga(arr_shSetUO(r,nr,sh)); + } + if (xia <= nia/2) x = squeeze_any(x); + + u8 xl = arrTypeBitsLog(TY(x)); + u8 xt = arrNewType(TY(x)); + u8* rp; + u64 bi, bf; // Bytes present, bytes wanted + if (xl == 0) { // Bits + u64* rq; r = m_bitarrp(&rq, nia); + rp = (u8*)rq; + usz nw = BIT_N(nia); + u64* xp = bitany_ptr(x); + u64 b = xia; + if (b % 8) { + if (b < 64) { + // Need to avoid calling bit_cpy with arguments <64 bits apart + u64 v = xp[0] & (~(u64)0 >> (64-b)); + do { v |= v<64 && nia>64) rq[1] = v>>(64-b/2); + } else { + memcpy(rq, xp, (b+7)/8); + } + for (; b%8; b*=2) { + if (b>nw*32) { + if (b=bf since bf is rounded up + break; + } + bit_cpyN(rq, b, rq, 0, b); + } + } else { + memcpy(rp, xp, b/8); + } + bi = b/8; + bf = 8*nw; + if (bi == 1) { memset(rp, rp[0], bf); bi=bf; } + } else { + if (TI(x,elType) == el_B) { + MAKE_MUT_INIT(m, nia, el_B); MUTG_INIT(m); + i64 div = nia/xia; + i64 mod = nia%xia; + for (i64 i = 0; i < div; i++) mut_copyG(m, i*xia, x, 0, xia); + mut_copyG(m, div*xia, x, 0, mod); + B xf = getFillR(x); + decG(x); + return withFill(taga(arr_shSetUO(mut_fp(m), nr, sh)), xf); + } + u8 xk = xl - 3; + if (nia >= USZ_MAX) thrOOM(); + rp = m_tyarrp(&r, 1<> (64-b)); + while (b<64) { v |= v<bf) l=bf; + for (; bi<=l/2; bi+=bi) memcpy(rp+bi, rp, bi); + u64 e=bi; for (; e+bi<=bf; e+=bi) memcpy(rp+e, rp, bi); + if (e