Merge pull request #137 from mlochbaum/scalreduce
Scalar-based arithmetic insert and stride-1 scan-cells for short rows
This commit is contained in:
commit
dfce405111
@ -102,6 +102,21 @@ B select_cells_base(B inds, B x0, ux csz, ux cam) { // consumes inds,x0; Used by
|
|||||||
return taga(APD_SH_GET(r, '\0'));
|
return taga(APD_SH_GET(r, '\0'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static B scan_cells_stride1(B f, B x, usz m) {
|
||||||
|
// m is cell size == scan axis length
|
||||||
|
B xf = getFillR(x);
|
||||||
|
HArr_p r = m_harr0c(x);
|
||||||
|
SGet(x)
|
||||||
|
FC2 fc2 = c2fn(f);
|
||||||
|
for (usz i=0, ia=IA(x); i<ia; ) {
|
||||||
|
usz e = i + m;
|
||||||
|
r.a[i] = Get(x, i); i++;
|
||||||
|
for (; i<e; i++) r.a[i] = fc2(f, inc(r.a[i-1]), Get(x, i));
|
||||||
|
}
|
||||||
|
decG(x);
|
||||||
|
return withFill(r.b, xf);
|
||||||
|
}
|
||||||
|
|
||||||
B scan_arith(B f, B w, B x, usz* xsh) { // Used by scan.c
|
B scan_arith(B f, B w, B x, usz* xsh) { // Used by scan.c
|
||||||
bool has_w = w.u != m_f64(0).u;
|
bool has_w = w.u != m_f64(0).u;
|
||||||
assert(isArr(x) && (!has_w || isArr(w)));
|
assert(isArr(x) && (!has_w || isArr(w)));
|
||||||
@ -537,12 +552,15 @@ B for_cells_c1(B f, u32 xr, u32 cr, u32 k, B x, u32 chr) { // F⎉cr x; array x,
|
|||||||
if (cr==0) break;
|
if (cr==0) break;
|
||||||
usz m = xsh[k];
|
usz m = xsh[k];
|
||||||
if (m<=1 || IA(x)==0) return x;
|
if (m<=1 || IA(x)==0) return x;
|
||||||
if (!isFun(fd->f)) break;
|
B f = fd->f;
|
||||||
u8 frtid = RTID(fd->f);
|
if (!isFun(f)) break;
|
||||||
|
u8 frtid = RTID(f);
|
||||||
if (frtid==n_rtack) return x;
|
if (frtid==n_rtack) return x;
|
||||||
if (TI(x,elType)==el_bit && (isPervasiveDyExt(fd->f)||frtid==n_ltack)
|
if (cr==1 || cam*m == IA(x)) {
|
||||||
&& 1==shProd(xsh, k+1, xr)) {
|
if (TI(x,elType)==el_bit && (isPervasiveDy(f) || frtid==n_ltack)) {
|
||||||
B r = scan_rows_bit(frtid, x, m); if (!q_N(r)) return r;
|
B r = scan_rows_bit(frtid, x, m); if (!q_N(r)) return r;
|
||||||
|
}
|
||||||
|
if (m <= 6) return scan_cells_stride1(f, x, m);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -383,6 +383,68 @@ static B m1c1(B t, B f, B x) { // consumes x
|
|||||||
}
|
}
|
||||||
extern B insert_base(B f, B x, bool has_w, B w); // from cells.c
|
extern B insert_base(B f, B x, bool has_w, B w); // from cells.c
|
||||||
|
|
||||||
|
static bool fillNumeric(B x) {
|
||||||
|
if (x.u==0) return true;
|
||||||
|
if (isAtm(x)) return false;
|
||||||
|
u8 xe = TI(x,elType);
|
||||||
|
usz ia = IA(x);
|
||||||
|
if (xe!=el_B) return ia==0 || elNum(xe);
|
||||||
|
if (!fillNumeric(getFillN(x))) return false;
|
||||||
|
if (ia==0) return true;
|
||||||
|
SGetU(x)
|
||||||
|
for (usz i=0; i<ia; i++) if (!fillNumeric(GetU(x,i))) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do arithmetic 𝔽˝ with short rows like 𝔽¨˝ to cut per-row overhead
|
||||||
|
static B insert_scal(B f, FC2 fc2, B x, bool has_w, B fxw, usz xia, ur rr) {
|
||||||
|
usz csz = arr_csz(x);
|
||||||
|
HArr_p r = m_harr0p(csz);
|
||||||
|
usz* rsh = arr_shAlloc((Arr*)r.c, rr);
|
||||||
|
if (rr>1) shcpy(rsh, SH(x)+1, rr);
|
||||||
|
usz xi = xia - csz;
|
||||||
|
|
||||||
|
B xf = getFillN(x);
|
||||||
|
B rf;
|
||||||
|
if (has_w) {
|
||||||
|
// fxw is (⊢˝𝕩)𝔽𝕨 so shape errors have been caught
|
||||||
|
rf = getFillR(fxw);
|
||||||
|
COPY_TO(r.a, el_B, 0, fxw, 0, csz);
|
||||||
|
decG(fxw);
|
||||||
|
} else {
|
||||||
|
rf = inc(xf);
|
||||||
|
COPY_TO(r.a, el_B, 0, x, xi, csz);
|
||||||
|
}
|
||||||
|
|
||||||
|
SGet(x)
|
||||||
|
while (xi) {
|
||||||
|
xi -= csz;
|
||||||
|
for (usz i=0; i<csz; i++) r.a[i] = fc2(f, Get(x, xi+i), r.a[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill might oscillate between 0 and ' ' or error if either argument
|
||||||
|
// has characters in its fill
|
||||||
|
if (!noFill(rf) && !(fillNumeric(rf) && (!has_w || fillNumeric(xf)))) {
|
||||||
|
usz n = *SH(x);
|
||||||
|
assert(n > 2);
|
||||||
|
#if SEMANTIC_CATCH
|
||||||
|
if (CATCH) {
|
||||||
|
freeThrown();
|
||||||
|
rf = bi_noFill;
|
||||||
|
} else {
|
||||||
|
if (!has_w) rf = fc2(f, inc(xf), rf);
|
||||||
|
if (n%2 == !has_w) rf = fc2(f, inc(xf), rf);
|
||||||
|
else fc2(f, inc(xf), inc(rf)); // could error, -˜˝"abc"
|
||||||
|
popCatch();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (n%2 == 0) { dec(rf); rf = bi_noFill; }
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
decG(x);
|
||||||
|
return withFill(r.b, rf);
|
||||||
|
}
|
||||||
|
|
||||||
B insert_c1(Md1D* d, B x) { B f = d->f;
|
B insert_c1(Md1D* d, B x) { B f = d->f;
|
||||||
ur xr;
|
ur xr;
|
||||||
if (isAtm(x) || (xr=RNK(x))==0) thrM("𝔽˝𝕩: 𝕩 must have rank at least 1");
|
if (isAtm(x) || (xr=RNK(x))==0) thrM("𝔽˝𝕩: 𝕩 must have rank at least 1");
|
||||||
@ -410,7 +472,8 @@ B insert_c1(Md1D* d, B x) { B f = d->f;
|
|||||||
if (RARE(!isFun(f))) { decG(x); if (isMd(f)) thrM("Calling a modifier"); return inc(f); }
|
if (RARE(!isFun(f))) { decG(x); if (isMd(f)) thrM("Calling a modifier"); return inc(f); }
|
||||||
if (isPervasiveDyExt(f)) {
|
if (isPervasiveDyExt(f)) {
|
||||||
if (xr==1) return m_unit(fold_c1(d, x));
|
if (xr==1) return m_unit(fold_c1(d, x));
|
||||||
if (len==IA(x)) {
|
usz xia = IA(x);
|
||||||
|
if (len==xia) {
|
||||||
B r = m_vec1(fold_c1(d, C1(shape, x)));
|
B r = m_vec1(fold_c1(d, C1(shape, x)));
|
||||||
ur rr = xr - 1;
|
ur rr = xr - 1;
|
||||||
if (rr > 1) {
|
if (rr > 1) {
|
||||||
@ -420,6 +483,9 @@ B insert_c1(Md1D* d, B x) { B f = d->f;
|
|||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
if (len>2 && xia<6*(u64)len) {
|
||||||
|
return insert_scal(f, c2fn(f), x, 0, m_f64(0), xia, xr-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (RTID(f) != RTID_NONE) {
|
if (RTID(f) != RTID_NONE) {
|
||||||
u8 rtid = RTID(f);
|
u8 rtid = RTID(f);
|
||||||
@ -448,26 +514,34 @@ B insert_c2(Md1D* d, B w, B x) { B f = d->f;
|
|||||||
usz len = *SH(x);
|
usz len = *SH(x);
|
||||||
if (len==0) { decG(x); return w; }
|
if (len==0) { decG(x); return w; }
|
||||||
if (RARE(!isFun(f))) { dec(w); decG(x); if (isMd(f)) thrM("Calling a modifier"); return inc(f); }
|
if (RARE(!isFun(f))) { dec(w); decG(x); if (isMd(f)) thrM("Calling a modifier"); return inc(f); }
|
||||||
if (isPervasiveDyExt(f) && len==IA(x)) {
|
if (isPervasiveDyExt(f)) {
|
||||||
// 1-element arrays are always conformable
|
usz xia = IA(x);
|
||||||
// final rank is higher of w, cell rank of x
|
|
||||||
ur rr = xr - 1;
|
ur rr = xr - 1;
|
||||||
if (isArr(w)) {
|
if (len==xia) {
|
||||||
if (IA(w) != 1) goto skip;
|
// 1-element arrays are always conformable
|
||||||
ur wr = RNK(w); if (wr>rr) rr = wr;
|
// final rank is higher of w, cell rank of x
|
||||||
w = TO_GET(w, 0);
|
if (isArr(w)) {
|
||||||
}
|
if (IA(w) != 1) goto skip;
|
||||||
if (xr > 1) x = C1(shape, x);
|
ur wr = RNK(w); if (wr>rr) rr = wr;
|
||||||
B r = m_unit(fold_c2(d, w, x));
|
w = TO_GET(w, 0);
|
||||||
if (rr > 0) {
|
|
||||||
if (rr == 1) arr_shVec(a(r));
|
|
||||||
else {
|
|
||||||
ShArr* rsh = m_shArr(rr);
|
|
||||||
PLAINLOOP for (ur i=0; i<rr; i++) rsh->a[i] = 1;
|
|
||||||
arr_shReplace(a(r), rr, rsh);
|
|
||||||
}
|
}
|
||||||
|
if (xr > 1) x = C1(shape, x);
|
||||||
|
B r = m_unit(fold_c2(d, w, x));
|
||||||
|
if (rr > 0) {
|
||||||
|
if (rr == 1) arr_shVec(a(r));
|
||||||
|
else {
|
||||||
|
ShArr* rsh = m_shArr(rr);
|
||||||
|
PLAINLOOP for (ur i=0; i<rr; i++) rsh->a[i] = 1;
|
||||||
|
arr_shReplace(a(r), rr, rsh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
if (len>2 && xia<6*(u64)len && !(isArr(w) && RNK(w)>rr)) {
|
||||||
|
FC2 fc2 = c2fn(f);
|
||||||
|
w = fc2(f, C2(select, m_f64(-1), incG(x)), w);
|
||||||
|
return insert_scal(f, fc2, x, 1, w, xia, rr);
|
||||||
}
|
}
|
||||||
return r;
|
|
||||||
skip:;
|
skip:;
|
||||||
}
|
}
|
||||||
if (RTID(f) != RTID_NONE) {
|
if (RTID(f) != RTID_NONE) {
|
||||||
|
|||||||
@ -30,6 +30,10 @@
|
|||||||
%USE fill ⋄ Fill ⊢¨"" %EACH_FILLS %% ' '
|
%USE fill ⋄ Fill ⊢¨"" %EACH_FILLS %% ' '
|
||||||
%USE fill ⋄ Fill ⊢∘⊢¨"" %EACH_FILLS %% ' '
|
%USE fill ⋄ Fill ⊢∘⊢¨"" %EACH_FILLS %% ' '
|
||||||
|
|
||||||
|
{3↑ -˝𝕩‿2⥊<<'a'}¨ 5‿6 %!HEAPVERIFY %% <¨¨ ⟨"aa ", 3⥊0⟩
|
||||||
|
{3↑ (2⥊2)-˝𝕩‿2⥊<<'x'}¨ 5‿6 %!HEAPVERIFY %% <¨¨ ⟨"vv ", 2‿2‿0⟩
|
||||||
|
{3↑ "ee"-˝𝕩‿2⥊<<'a'}¨ 5‿6 %!HEAPVERIFY %% <¨¨ ⟨¯4‿¯4‿0, "ee "⟩
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
# ⟨↑‿3⥊↕10 ⋄ ↑‿3⥊<¨↕10 ⋄ ↑‿3⥊<˘↕10⟩
|
# ⟨↑‿3⥊↕10 ⋄ ↑‿3⥊<¨↕10 ⋄ ↑‿3⥊<˘↕10⟩
|
||||||
# 5‿¯5↑⌜⟨↕2 ⋄ "ab" ⋄ <¨↕2 ⋄ <˘↕2⟩
|
# 5‿¯5↑⌜⟨↕2 ⋄ "ab" ⋄ <¨↕2 ⋄ <˘↕2⟩
|
||||||
|
|||||||
@ -515,6 +515,13 @@ a←↕2 ⋄ ! "e" ≡ (↕10){b←a‿a‿a‿a‿a‿a‿a‿a‿a‿a ⋄
|
|||||||
# ˝
|
# ˝
|
||||||
!"𝔽˝𝕩: 𝕩 must have rank at least 1" % ⊢˝0
|
!"𝔽˝𝕩: 𝕩 must have rank at least 1" % ⊢˝0
|
||||||
!"𝔽˝𝕩: Identity not found" % •internal.Keep˝⟨⟩
|
!"𝔽˝𝕩: Identity not found" % •internal.Keep˝⟨⟩
|
||||||
|
(↕4)+˝↕7 %% 21‿22‿23‿24
|
||||||
|
(2‿2⥊↕4)+˝7‿2‿2⥊↕28 %% 2‿2⥊84‿92‿100‿108
|
||||||
|
(2‿2⥊↕4)+˝2‿2⥊↕28 %% 2‿2⥊2‿3‿6‿7
|
||||||
|
+˝ ↕10‿4 %% 45 ⋈¨ 10×↕4
|
||||||
|
( ↕4) +˝ ↕10‿4 %% (↕4) + 45 ⋈¨ 10×↕4
|
||||||
|
(<¨ ↕4) +˝ ↕10‿4 %% (↕4) + 45 ⋈¨ 10×↕4
|
||||||
|
(0‿5⊸+¨↕4) +˝ ↕10‿4 %% ((↕4) + 45) ⋈¨ 5 + 11×↕4
|
||||||
|
|
||||||
# ⌜
|
# ⌜
|
||||||
!"𝕨𝔽⌜𝕩: Result rank too large (200≡=𝕨, 200≡=𝕩)" % +⌜˜(200⥊1)⥊1
|
!"𝕨𝔽⌜𝕩: Result rank too large (200≡=𝕨, 200≡=𝕩)" % +⌜˜(200⥊1)⥊1
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user