fix 𝕨∾𝕩 reuse logic

This commit is contained in:
dzaima 2023-05-22 10:54:20 +03:00
parent 20a946d085
commit 3872f5a625
3 changed files with 15 additions and 13 deletions

View File

@ -923,27 +923,26 @@ B join_c2(B t, B w, B x) {
}
if (c-wr > 1 || c-xr > 1) thrF("∾: Argument ranks must differ by 1 or less (%i≡=𝕨, %i≡=𝕩)", wr, xr);
bool reusedW;
B r = arr_join_inline(w, x, false, &reusedW);
bool usedW;
usz wia0 = IA(w);
B r = arr_join_inline(w, x, false, &usedW);
if (c==1) {
if (RNK(r)==0) SRNK(r,1);
} else {
assert(c>1);
ur rnk0 = RNK(r);
ShArr* sh0 = shObj(r);
usz wia;
usz* wsh;
if (wr==1 && reusedW) {
wia = IA(w)-IA(x);
wsh = &wia;
if (wr==1 && usedW) {
wsh = &wia0;
} else {
wsh = SH(w); // when wr>1, shape object won't be disturbed by arr_join_inline
}
usz* xsh = SH(x);
SRNK(r, 0); // otherwise shape allocation failing may break things
SRNK(r, 0); // otherwise shape allocation failing may break things; leaves shape owned only here
usz* rsh = arr_shAlloc(a(r), c);
#if PRINT_JOIN_REUSE
printf(reusedW? "reuse:1;" : "reuse:0;");
printf(usedW? "reuse:1;" : "reuse:0;");
#endif
for (i32 i = 1; i < c; i++) {
usz s = xsh[i+xr-c];
@ -961,7 +960,7 @@ B join_c2(B t, B w, B x) {
}
decG(x);
if (!reusedW) decG(w);
if (!usedW) decG(w);
return qWithFill(r, f);
}

View File

@ -156,9 +156,11 @@ typedef struct { B w2; void* rp; } JoinFillslice;
JoinFillslice fillslice_getJoin(B w, usz ria); // either returns NULL in rp, or consumes w
// consume==true: consumes w,x and expects both args to be vectors
// consume==false: doesn't consume x, and decrements refcount of w iif *reusedW (won't free because the result will be w); result has arbitrary but valid shape
// consume==false: doesn't consume x, and
// *usedW==true: consumes w, returns w or its backing array; if RNK(w)>1, result has the same shape as w, i.e. not updated
// *usedW==false: doesn't consume w; result has vector shape
// returns possibly incorrect fills if arguments aren't equal class typed arrays
FORCE_INLINE B arr_join_inline(B w, B x, bool consume, bool* reusedW) {
FORCE_INLINE B arr_join_inline(B w, B x, bool consume, bool* usedW) {
assert(isArr(w) && isArr(x));
usz wia = IA(w);
usz xia = IA(x);
@ -193,13 +195,13 @@ FORCE_INLINE B arr_join_inline(B w, B x, bool consume, bool* reusedW) {
mut_copyG(r, 0, w, 0, wia);
mut_copyG(r, wia, x, 0, xia);
if (consume) { decG(x); decG(w); }
*reusedW = false;
*usedW = false;
return mut_fv(r);
yes:
COPY_TO(rp, we, wia, x, 0, xia);
if (consume) decG(x);
*reusedW = true;
*usedW = true;
a(w)->ia = ria;
return FL_KEEP(w,fl_squoze); // keeping fl_squoze as appending items can't make the largest item smaller
}

View File

@ -181,6 +181,7 @@ w←1‿1⥊1 ⋄ x←2⥊1 ⋄ w‿x <¨↩ ⋄ {! (∾⟨•Repr𝕩,": Expe
# ≍𝕩
!"≍: Result rank too large (255≡=𝕩)" % 256 1
%USE tvar 1234564 {c𝕊e: {!¨ _tvar´ 𝕩}¨ 4c, c ({𝕩<e}¨) 0c, 1c, c} 1, 'a', 12
# « & »
!"shift: Lengths not matchable (⟨2⟩ ≡ ≢𝕨, 3‿3 ≡ ≢𝕩)" % 12»33