From 7715cbc1580bae58b8a298192bb093bf8838e8a1 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Wed, 23 Nov 2022 16:24:15 -0500 Subject: [PATCH] =?UTF-8?q?Add=20=E2=80=A2math.Sum=20with=20Singeli=20f64?= =?UTF-8?q?=20implementation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins.h | 2 +- src/builtins/arithm.c | 4 +-- src/builtins/fold.c | 36 ++++++++++++++++++++++++++ src/builtins/sysfn.c | 2 +- src/singeli/src/avx.singeli | 6 ++++- src/singeli/src/fold.singeli | 49 +++++++++++++++++++++++------------- 6 files changed, 77 insertions(+), 22 deletions(-) diff --git a/src/builtins.h b/src/builtins.h index 77e8a1bb..b7b21ebf 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -17,7 +17,7 @@ /*internal.c*/M(itype,"•internal.Type") M(elType,"•internal.ElType") M(refc,"•internal.Refc") M(isPure,"•internal.IsPure") A(info,"•internal.Info") M(heapDump,"•internal.HeapDump") \ /*internal.c*/M(squeeze,"•internal.Squeeze") M(deepSqueeze,"•internal.DeepSqueeze") D(eequal,"•internal.EEqual") A(internalTemp,"•internal.Temp") \ /*internal.c*/D(variation,"•internal.Variation") A(listVariations,"•internal.ListVariations") M(clearRefs,"•internal.ClearRefs") M(unshare,"•internal.Unshare") \ -/* arithm.c*/M(sin,"•math.Sin") M(cos,"•math.Cos") M(tan,"•math.Tan") M(asin,"•math.Asin") M(acos,"•math.Acos") M(atan,"•math.Atan") D(atan2,"•math.Atan2") D(hypot,"•math.Hypot") M(sinh,"•math.Sinh") M(cosh,"•math.Cosh") M(tanh,"•math.Tanh") M(asinh,"•math.Asinh") M(acosh,"•math.Acosh") M(atanh,"•math.Atanh") M(cbrt,"•math.Cbrt") M(log2,"•math.Log2") M(log10,"•math.Log10") M(log1p,"•math.Log1p") M(expm1,"•math.Expm1") M(fact,"•math.Fact") D(comb,"•math.Comb") M(logfact,"•math.LogFact") M(erf,"•math.Erf") M(erfc,"•math.ErfC") D(gcd,"•math.GCD") D(lcm,"•math.LCM") +/* arithm.c*/M(sin,"•math.Sin") M(cos,"•math.Cos") M(tan,"•math.Tan") M(asin,"•math.Asin") M(acos,"•math.Acos") M(atan,"•math.Atan") D(atan2,"•math.Atan2") D(hypot,"•math.Hypot") M(sinh,"•math.Sinh") M(cosh,"•math.Cosh") M(tanh,"•math.Tanh") M(asinh,"•math.Asinh") M(acosh,"•math.Acosh") M(atanh,"•math.Atanh") M(cbrt,"•math.Cbrt") M(log2,"•math.Log2") M(log10,"•math.Log10") M(log1p,"•math.Log1p") M(expm1,"•math.Expm1") M(fact,"•math.Fact") D(comb,"•math.Comb") M(logfact,"•math.LogFact") M(erf,"•math.Erf") M(erfc,"•math.ErfC") D(gcd,"•math.GCD") D(lcm,"•math.LCM") M(sum,"•math.Sum") #define FOR_PM1(A,M,D) \ /*md1.c*/A(tbl,"⌜") A(each,"¨") A(fold,"´") A(scan,"`") A(const,"˙") A(swap,"˜") A(cell,"˘") A(insert,"˝") \ diff --git a/src/builtins/arithm.c b/src/builtins/arithm.c index 7e6b40f4..daebb007 100644 --- a/src/builtins/arithm.c +++ b/src/builtins/arithm.c @@ -113,8 +113,8 @@ static B mathNS; B getMathNS() { if (mathNS.u == 0) { #define F(X) inc(bi_##X), - Body* d = m_nnsDesc("sin","cos","tan","asin","acos","atan","atan2","sinh","cosh","tanh","asinh","acosh","atanh","cbrt","log2","log10","log1p","expm1","hypot","fact","logfact","erf","erfc","comb","gcd","lcm"); - mathNS = m_nns(d, F(sin)F(cos)F(tan)F(asin)F(acos)F(atan)F(atan2)F(sinh)F(cosh)F(tanh)F(asinh)F(acosh)F(atanh)F(cbrt)F(log2)F(log10)F(log1p)F(expm1)F(hypot)F(fact)F(logfact)F(erf)F(erfc)F(comb)F(gcd)F(lcm)); + Body* d = m_nnsDesc("sin","cos","tan","asin","acos","atan","atan2","sinh","cosh","tanh","asinh","acosh","atanh","cbrt","log2","log10","log1p","expm1","hypot","fact","logfact","erf","erfc","comb","gcd","lcm","sum"); + mathNS = m_nns(d, F(sin)F(cos)F(tan)F(asin)F(acos)F(atan)F(atan2)F(sinh)F(cosh)F(tanh)F(asinh)F(acosh)F(atanh)F(cbrt)F(log2)F(log10)F(log1p)F(expm1)F(hypot)F(fact)F(logfact)F(erf)F(erfc)F(comb)F(gcd)F(lcm)F(sum)); #undef F gc_add(mathNS); } diff --git a/src/builtins/fold.c b/src/builtins/fold.c index 8937050a..378a76d4 100644 --- a/src/builtins/fold.c +++ b/src/builtins/fold.c @@ -9,6 +9,8 @@ // COULD implement fast numeric -´ // ∨ on boolean-valued integers, stopping at 1 +// •math.Sum: +´ with faster and more precise SIMD code for i32, f64 + #include "../core.h" #include "../builtins.h" @@ -66,6 +68,40 @@ static f64 sum_f64(void* xv, usz i, f64 r) { static i64 (*const sum_small_fns[])(void*, usz) = { sum_small_i8, sum_small_i16, sum_small_i32 }; static f64 (*const sum_fns[])(void*, usz, f64) = { sum_i8, sum_i16, sum_i32, sum_f64 }; +B sum_c1(B t, B x) { + if (isAtm(x) || RNK(x)!=1) thrF("•math.Sum: Argument must be a list (%H ≡ ≢𝕩)", x); + usz ia = IA(x); + if (ia==0) return m_f64(0); + u8 xe = TI(x,elType); + if (!elNum(xe)) { + x = any_squeeze(x); xe = TI(x,elType); + if (!elNum(xe)) thrF("•math.Sum: Argument elements must be numbers", x); + } + f64 r; + void* xv = tyany_ptr(x); + if (xe == el_bit) { + r = bit_sum(xv, ia); + } else if (xe <= el_i32) { + u8 sel = xe - el_i8; + i64 s = 0; r = 0; + i64 m = 1ull<<48; + usz b = sum_small_max; + for (usz i=0; i= m) { r+=m; s-=m; } + if (s <= -m) { r-=m; s+=m; } + } + r += s; + } else { + #if SINGELI + r = avx2_sum_f64(xv, ia); + #else + r=0; for (usz i=0; i> plog + r:= init + @for (i to f) r = op{r, pairwise{x+(i< 0} r = load{xv} if (len > 1) { - if (len > 2) r = op{r, shuf{[4]u64, r, 4b2222}} - r = op{r, shuf{[4]u64, r, 4b1111}} + if (len > 2) r = opsh{op}{r, 4b2222} + r = opsh{op}{r, 4b1111} } } else { - # Pairwise combination to shorten dependency chains - def pairwise{p, i, k} = { - def l = k-1 - op{pairwise{p, i , l}, - pairwise{p, i+(1<> pk - @for (i to f) r = op{r, pairwise{xv+(i<