move arr⌾(m⊸/)𝕩 over to new DirectArr thing
This commit is contained in:
parent
3abd77fed8
commit
454d1b072d
@ -1036,34 +1036,29 @@ B slash_im(B t, B x) {
|
||||
extern INIT_GLOBAL BlendArrScalarFn* blendArrScalarFns;
|
||||
#endif
|
||||
|
||||
typedef struct { B b; void* data; } AnyArr;
|
||||
AnyArr cpyElTypeArr(u8 re, B x) { // consumes x; returns new array with the given element type, with data & shape from x
|
||||
Arr* a;
|
||||
switch (re) { default: UD;
|
||||
case el_bit: a = cpyBitArr(x); goto tyarr;
|
||||
case el_i8: a = cpyI8Arr(x); goto tyarr;
|
||||
case el_i16: a = cpyI16Arr(x); goto tyarr;
|
||||
case el_i32: a = cpyI32Arr(x); goto tyarr;
|
||||
case el_f64: a = cpyF64Arr(x); goto tyarr;
|
||||
case el_c8: a = cpyC8Arr(x); goto tyarr;
|
||||
case el_c16: a = cpyC16Arr(x); goto tyarr;
|
||||
case el_c32: a = cpyC32Arr(x); goto tyarr;
|
||||
case el_B:
|
||||
a = cpyHArr(x);
|
||||
return (AnyArr){taga(a), harrv_ptr(a)};
|
||||
}
|
||||
tyarr:
|
||||
return (AnyArr){taga(a), tyarrv_ptr((TyArr*)a)};
|
||||
|
||||
#define BY_MASK(F, ELTS, C) ({ \
|
||||
u64 c = (C); \
|
||||
B* elts_ = (ELTS); \
|
||||
while (c) { \
|
||||
F(elts_[CTZ(c)]); \
|
||||
c&=c-1; \
|
||||
} \
|
||||
})
|
||||
|
||||
static void decByMask(u64* mask, B* elts, ux ia, bool inv) {
|
||||
u64 xor = inv? U64_MAX : 0;
|
||||
ux e = ia>>6;
|
||||
for (ux i=0; i<e; i++) BY_MASK(dec, elts + i*64, xor^mask[i]);
|
||||
if (ia&63) BY_MASK(dec, elts + e*64, (xor^mask[e]) & ((1ULL<<(ia&63)) - 1));
|
||||
}
|
||||
AnyArr m_anyarrc(u8 re, B x) { // consumes x; returns new array with given element type; may start NOGC
|
||||
if (re==el_B) {
|
||||
HArr_p r = m_harrUc(x);
|
||||
return (AnyArr) {r.b, r.a};
|
||||
}
|
||||
B r;
|
||||
void* rp = m_tyarrlbc(&r, elwBitLog(re), x, el2t(re));
|
||||
return (AnyArr) {r, rp};
|
||||
static void incByMask(u64* mask, B* elts, ux ia, bool inv) {
|
||||
u64 xor = inv? U64_MAX : 0;
|
||||
ux e = ia>>6;
|
||||
for (ux i=0; i<e; i++) BY_MASK(inc, elts + i*64, xor^mask[i]);
|
||||
if (ia&63) BY_MASK(inc, elts + e*64, (xor^mask[e]) & ((1ULL<<(ia&63)) - 1));
|
||||
}
|
||||
#undef BY_MASK
|
||||
|
||||
B ne_c2(B,B,B);
|
||||
B slash_ucw(B t, B o, B w, B x) {
|
||||
@ -1089,7 +1084,6 @@ B slash_ucw(B t, B o, B w, B x) {
|
||||
#if SINGELI_SIMD
|
||||
if (isFun(o) && TY(o)==t_md1D) {
|
||||
u8 xe = TI(x,elType);
|
||||
if (xe==el_B) goto notConstEach; // TODO not
|
||||
|
||||
Md1D* od = c(Md1D,o);
|
||||
if (PRTID(od->m1) != n_each) goto notConstEach;
|
||||
@ -1104,26 +1098,37 @@ B slash_ucw(B t, B o, B w, B x) {
|
||||
}
|
||||
|
||||
u8 ce = selfElType(c);
|
||||
u8 re = el_or(ce,xe); // can be el_B
|
||||
u8 re = el_or(ce,xe);
|
||||
|
||||
B r;
|
||||
u64 sum = U64_MAX;
|
||||
if (isVal(c)) {
|
||||
u64 sum = usum(w);
|
||||
sum = bit_sum(bitany_ptr(w), ia);
|
||||
if (sum==0) decG(c); // TODO could return x; fills?
|
||||
else incByG(c, sum-1);
|
||||
}
|
||||
|
||||
void* rp;
|
||||
DirectArr r;
|
||||
void* xp;
|
||||
if (re != xe) {
|
||||
AnyArr a = cpyElTypeArr(re, x);
|
||||
x = r = incG(a.b);
|
||||
xp = rp = a.data;
|
||||
assert(xe != el_B);
|
||||
r = toEltypeArr(x, re);
|
||||
x = incG(r.obj);
|
||||
xp = r.data;
|
||||
} else {
|
||||
AnyArr a = m_anyarrc(re, x);
|
||||
r = a.b;
|
||||
rp = a.data;
|
||||
xp = tyany_ptr(x);
|
||||
if (xe==el_B) {
|
||||
r = potentiallyReuse(x);
|
||||
if (r.obj.u == x.u) {
|
||||
xp = r.data;
|
||||
decByMask(bitany_ptr(w), xp, ia, 0);
|
||||
} else {
|
||||
TO_BPTR(x);
|
||||
xp = arr_bptrG(x);
|
||||
incByMask(bitany_ptr(w), xp, ia, 1);
|
||||
}
|
||||
} else {
|
||||
r = potentiallyReuse(x);
|
||||
xp = tyany_ptr(x);
|
||||
}
|
||||
}
|
||||
|
||||
u64 cv;
|
||||
@ -1134,10 +1139,10 @@ B slash_ucw(B t, B o, B w, B x) {
|
||||
cv = re==el_f64? r_f64u(o2fG(c)) : r_Bu(c);
|
||||
}
|
||||
|
||||
blendArrScalarFns[elwBitLog(re)](rp, xp, cv, bitany_ptr(w), IA(x));
|
||||
blendArrScalarFns[elwBitLog(re)](r.data, xp, cv, bitany_ptr(w), ia);
|
||||
NOGC_E;
|
||||
decG(w); decG(x);
|
||||
return r;
|
||||
return r.obj;
|
||||
}
|
||||
#endif
|
||||
goto notConstEach; notConstEach:;
|
||||
|
||||
@ -799,7 +799,7 @@ static NOINLINE DirectArr toFillArr(B x, B fill) {
|
||||
static void* reusableArr_ptr(Arr* t, u8 el) {
|
||||
return el==el_B? (void*)(PTY(t)==t_fillarr? fillarrv_ptr(t) : harrv_ptr(t)) : tyarrv_ptr((TyArr*)t);
|
||||
}
|
||||
DirectArr toEltypeArr(B x, u8 re) { // consumes x; returns an array with eltype==re, with same shape/elements/fill as x, and its data pointer
|
||||
DirectArr toEltypeArr(B x, u8 re) {
|
||||
assert(isArr(x));
|
||||
if (reusable(x) && re==reuseElType[TY(x)]) {
|
||||
x = REUSE(x);
|
||||
@ -818,16 +818,38 @@ DirectArr toEltypeArr(B x, u8 re) { // consumes x; returns an array with eltype=
|
||||
case el_c32: tyarr = cpyC32Arr(x); goto tyarr;
|
||||
case el_B:;
|
||||
B fill = getFillR(x);
|
||||
if (noFill(fill)) {
|
||||
Arr* r = cpyHArr(x);
|
||||
return (DirectArr){taga(r), harrv_ptr(r)};
|
||||
}
|
||||
return toFillArr(x, fill);
|
||||
if (!noFill(fill)) return toFillArr(x, fill);
|
||||
|
||||
Arr* r = cpyHArr(x);
|
||||
return (DirectArr){taga(r), harrv_ptr(r)};
|
||||
}
|
||||
|
||||
tyarr:
|
||||
return (DirectArr){taga(tyarr), tyarrv_ptr((TyArr*) tyarr)};
|
||||
}
|
||||
static NOINLINE DirectArr m_fillarrAs(B x, B fill) {
|
||||
Arr* r = arr_shCopy(m_fillarrp(IA(x)), x);
|
||||
fillarr_setFill(r, fill);
|
||||
return (DirectArr){taga(r), fillarrv_ptr(r)};
|
||||
}
|
||||
DirectArr potentiallyReuse(B x) {
|
||||
assert(isArr(x));
|
||||
u8 xe = TI(x,elType);
|
||||
if (reusable(x) && xe == reuseElType[TY(x)]) {
|
||||
x = REUSE(x);
|
||||
return (DirectArr){incG(x), reusableArr_ptr(a(x), xe)};
|
||||
}
|
||||
if (xe==el_B) {
|
||||
B fill = getFillR(x);
|
||||
if (!noFill(fill)) return m_fillarrAs(x, fill);
|
||||
|
||||
HArr_p r = m_harrUc(x);
|
||||
return (DirectArr) {r.b, r.a};
|
||||
}
|
||||
B r;
|
||||
void* rp = m_tyarrlbc(&r, elwBitLog(xe), x, el2t(xe));
|
||||
return (DirectArr) {r, rp};
|
||||
}
|
||||
|
||||
B directGetU_bit(void* data, ux i) { return m_f64(bitp_get(data,i));} void directSet_bit(void* data, ux i, B v) { bitp_set(data, i, o2bG(v)); }
|
||||
B directGetU_i8 (void* data, ux i) { return m_f64((( i8*)data)[i]); } void directSet_i8 (void* data, ux i, B v) { (( i8*)data)[i] = o2iG(v); }
|
||||
|
||||
@ -287,13 +287,23 @@ typedef void (*DirectSetRange)(void* data, ux rs, B x, ux xs, ux l);
|
||||
extern INIT_GLOBAL DirectGet directGetU[el_MAX];
|
||||
extern INIT_GLOBAL DirectSet directSet[el_MAX];
|
||||
extern INIT_GLOBAL DirectSetRange directSetRange[el_MAX];
|
||||
|
||||
// consumes x; returns an array with eltype==re, with same shape/elements/fill as x, and its data pointer
|
||||
DirectArr toEltypeArr(B x, u8 re);
|
||||
|
||||
// doesn't consume; returns array with same shape & fill as x, returning x itself if possible (iif so, x.u==obj.u).
|
||||
// If reused, the object is untouched besides having its refcount incremented and flags cleared.
|
||||
// As such, if an el_B array is reused, all elements effectively have 1 more refcount than they should as x's elements never get freed
|
||||
// Otherwise, functionality is the same as if a regular new array was made
|
||||
// May start NOGC
|
||||
DirectArr potentiallyReuse(B x);
|
||||
|
||||
#define DIRECTARR_COPY(R, RE, X) \
|
||||
u8 R##_elt = RE; \
|
||||
DirectArr R = toEltypeArr(X, R##_elt); \
|
||||
DirectGet R##_getU = directGetU[R##_elt]; \
|
||||
DirectSet R##_set = directSet[R##_elt]; \
|
||||
DirectSetRange R##_setRange = directSetRange[R##_elt];
|
||||
u8 R##_elt = RE; \
|
||||
MAYBE_UNUSED DirectArr R = toEltypeArr(X, R##_elt); \
|
||||
MAYBE_UNUSED DirectGet R##_getU = directGetU[R##_elt]; \
|
||||
MAYBE_UNUSED DirectSet R##_set = directSet[R##_elt]; \
|
||||
MAYBE_UNUSED DirectSetRange R##_setRange = directSetRange[R##_elt];
|
||||
|
||||
#define DIRECTARR_RM(R, I) if (R##_elt == el_B) dec(((B*)R.data)[I]);
|
||||
#define DIRECTARR_GETU(R, I) R##_getU(R.data, I)
|
||||
|
||||
@ -175,6 +175,7 @@ n←500 ⋄ a←↕n ⋄ i←(-n)+↕2×n ⋄ r←⌽(2×n)⥊a ⋄ ! (⌽a) ≡
|
||||
1⊸+⌾((↕10)⊸/) ↕10 %% ×⊸+ ↕10
|
||||
%USE eqvar ⋄ <‿≥‿> {𝕨⌾(1‿0‿0‿1‿1⊸/) 𝕩}_eqvar +‿-‿×‿÷‿⋆ %% <‿-‿×‿≥‿>
|
||||
%USE eqvar ⋄ ["wx"‿"WX","yz"‿"YZ"] {𝕨⌾(1‿0‿0‿1⊸/) 𝕩}_eqvar (<"aA")+↕4‿2 %% 4‿2⥊⟨"wx","WX","bA","bB","cA","cB","yz","YZ"⟩
|
||||
{m←𝕩•rand.Range 2 ⋄ ! (m{𝕨?"huh";⥊'a'+𝕩}¨↕𝕩) ≡ "huh"¨⌾(m⊸/) 'a'+↕⋈𝕩}¨ ↕100
|
||||
!"Integer out of range: 3.68934881474191e19" % 1¨⌾(a⊸/) a←100⥊2⋆65
|
||||
!"Expected non-negative integer, got ¯10" % %USE evar ⋄ 1¨⌾(a⊸/)_evar a←¯10⌾(50⊸⊑) 100⥊10
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user