more complete DirectArr thing, use for 𝔽⌾(f64arr⊸⊏)
This commit is contained in:
parent
eca886ed4d
commit
7dc5aa9090
@ -125,51 +125,6 @@ FORCE_INLINE void cf_call(CFRes f, void* r, ux rs, void* x, ux xs) {
|
||||
f.fn(r, rs, x, xs, f.data);
|
||||
}
|
||||
|
||||
extern INIT_GLOBAL u8 reuseElType[t_COUNT];
|
||||
typedef struct { B obj; void* data; } DirectArr;
|
||||
static NOINLINE DirectArr toFillArr(B x, B fill) {
|
||||
usz ia = IA(x);
|
||||
Arr* r = arr_shCopy(m_fillarrp(ia), x);
|
||||
fillarr_setFill(r, fill);
|
||||
B* rp = fillarrv_ptr(r);
|
||||
COPY_TO(rp, el_B, 0, x, 0, ia);
|
||||
NOGC_E;
|
||||
decG(x);
|
||||
return (DirectArr){taga(r), rp};
|
||||
}
|
||||
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);
|
||||
}
|
||||
static 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
|
||||
assert(isArr(x));
|
||||
if (reusable(x) && re==reuseElType[TY(x)]) {
|
||||
x = REUSE(x);
|
||||
return (DirectArr){x, reusableArr_ptr(a(x), re)};
|
||||
}
|
||||
|
||||
Arr* tyarr;
|
||||
switch (re) { default: UD;
|
||||
case el_bit: tyarr = cpyBitArr(x); goto tyarr;
|
||||
case el_i8: tyarr = cpyI8Arr(x); goto tyarr;
|
||||
case el_i16: tyarr = cpyI16Arr(x); goto tyarr;
|
||||
case el_i32: tyarr = cpyI32Arr(x); goto tyarr;
|
||||
case el_f64: tyarr = cpyF64Arr(x); goto tyarr;
|
||||
case el_c8: tyarr = cpyC8Arr(x); goto tyarr;
|
||||
case el_c16: tyarr = cpyC16Arr(x); goto tyarr;
|
||||
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);
|
||||
}
|
||||
|
||||
tyarr:
|
||||
return (DirectArr){taga(tyarr), tyarrv_ptr((TyArr*) tyarr)};
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern GLOBAL B rt_select;
|
||||
@ -513,40 +468,33 @@ B select_replace(u32 chr, B w, B x, B rep, usz wia, usz cam, usz csz) { // consu
|
||||
u8 we = TI(w,elType); assert(elNum(we) || wia==0);
|
||||
u8 xe = TI(x,elType);
|
||||
u8 re = el_or(xe, TI(rep,elType));
|
||||
Arr* ra; B rb;
|
||||
// w = taga(cpyF64Arr(w)); we = el_f64; // test the float path
|
||||
DIRECTARR_COPY(r, re, x);
|
||||
B rb = r.obj;
|
||||
|
||||
if (we==el_f64) {
|
||||
f64* wp = f64any_ptr(w);
|
||||
SPARSE_INIT((i64)wp[i])
|
||||
|
||||
MAKE_MUT(r, cam*csz);
|
||||
mut_init_copy(r, x, re);
|
||||
NOGC_E;
|
||||
MUTG_INIT(r);
|
||||
if (csz==1) {
|
||||
SGet(rep)
|
||||
for (usz i = 0; i < wia; i++) {
|
||||
READ_W(cw, i);
|
||||
B cn = Get(rep, i);
|
||||
EQ1(!compatible(mut_getU(r, cw), cn));
|
||||
mut_rm(r, cw);
|
||||
mut_setG(r, cw, cn);
|
||||
EQ1(!compatible(DIRECTARR_GETU(r, cw), cn));
|
||||
DIRECTARR_REPLACE(r, cw, cn);
|
||||
}
|
||||
} else {
|
||||
SGetU(rep)
|
||||
for (usz i = 0; i < wia; i++) {
|
||||
READ_W(cw, i);
|
||||
EQ(for (usz j = 0; j < csz; j++), !compatible(mut_getU(r, cw*csz + j), GetU(rep, i*csz + j)));
|
||||
for (usz j = 0; j < csz; j++) mut_rm(r, cw*csz + j);
|
||||
mut_copyG(r, cw*csz, rep, i*csz, csz);
|
||||
EQ(for (usz j = 0; j < csz; j++), !compatible(DIRECTARR_GETU(r, cw*csz + j), GetU(rep, i*csz + j)));
|
||||
DIRECTARR_REPLACE_RANGE(r, cw*csz, rep, i*csz, csz);
|
||||
}
|
||||
}
|
||||
ra = mut_fp(r);
|
||||
goto dec_ret_ra;
|
||||
goto dec_ret_rb;
|
||||
}
|
||||
assert(elInt(we) || wia==0);
|
||||
|
||||
DirectArr r = toEltypeArr(x, re); rb = r.obj;
|
||||
w = toI32Any(w);
|
||||
i32* wp = i32any_ptr(w);
|
||||
SPARSE_INIT(wp[i])
|
||||
@ -638,8 +586,6 @@ B select_replace(u32 chr, B w, B x, B rep, usz wia, usz cam, usz csz) { // consu
|
||||
|
||||
|
||||
|
||||
dec_ret_ra:;
|
||||
rb = taga(ra);
|
||||
dec_ret_rb:;
|
||||
decG(w); decG(rep);
|
||||
FREE_CHECK;
|
||||
|
||||
@ -1089,7 +1089,7 @@ 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;
|
||||
if (xe==el_B) goto notConstEach; // TODO not
|
||||
|
||||
Md1D* od = c(Md1D,o);
|
||||
if (PRTID(od->m1) != n_each) goto notConstEach;
|
||||
|
||||
@ -800,12 +800,79 @@ NOINLINE void apd_widen(ApdMut* m, B x, ApdFn* const* fns) {
|
||||
|
||||
|
||||
|
||||
static NOINLINE DirectArr toFillArr(B x, B fill) {
|
||||
usz ia = IA(x);
|
||||
Arr* r = arr_shCopy(m_fillarrp(ia), x);
|
||||
fillarr_setFill(r, fill);
|
||||
B* rp = fillarrv_ptr(r);
|
||||
COPY_TO(rp, el_B, 0, x, 0, ia);
|
||||
NOGC_E;
|
||||
decG(x);
|
||||
return (DirectArr){taga(r), rp};
|
||||
}
|
||||
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
|
||||
assert(isArr(x));
|
||||
if (reusable(x) && re==reuseElType[TY(x)]) {
|
||||
x = REUSE(x);
|
||||
return (DirectArr){x, reusableArr_ptr(a(x), re)};
|
||||
}
|
||||
|
||||
Arr* tyarr;
|
||||
switch (re) { default: UD;
|
||||
case el_bit: tyarr = cpyBitArr(x); goto tyarr;
|
||||
case el_i8: tyarr = cpyI8Arr(x); goto tyarr;
|
||||
case el_i16: tyarr = cpyI16Arr(x); goto tyarr;
|
||||
case el_i32: tyarr = cpyI32Arr(x); goto tyarr;
|
||||
case el_f64: tyarr = cpyF64Arr(x); goto tyarr;
|
||||
case el_c8: tyarr = cpyC8Arr(x); goto tyarr;
|
||||
case el_c16: tyarr = cpyC16Arr(x); goto tyarr;
|
||||
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);
|
||||
}
|
||||
|
||||
tyarr:
|
||||
return (DirectArr){taga(tyarr), tyarrv_ptr((TyArr*) tyarr)};
|
||||
}
|
||||
|
||||
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); }
|
||||
B directGetU_i16(void* data, ux i) { return m_f64(((i16*)data)[i]); } void directSet_i16(void* data, ux i, B v) { ((i16*)data)[i] = o2iG(v); }
|
||||
B directGetU_i32(void* data, ux i) { return m_f64(((i32*)data)[i]); } void directSet_i32(void* data, ux i, B v) { ((i32*)data)[i] = o2iG(v); }
|
||||
B directGetU_f64(void* data, ux i) { return m_f64(((f64*)data)[i]); } void directSet_f64(void* data, ux i, B v) { ((f64*)data)[i] = o2fG(v); }
|
||||
B directGetU_c8 (void* data, ux i) { return m_c32((( u8*)data)[i]); } void directSet_c8 (void* data, ux i, B v) { (( u8*)data)[i] = o2cG(v); }
|
||||
B directGetU_c16(void* data, ux i) { return m_c32(((u16*)data)[i]); } void directSet_c16(void* data, ux i, B v) { ((u16*)data)[i] = o2cG(v); }
|
||||
B directGetU_c32(void* data, ux i) { return m_c32(((u32*)data)[i]); } void directSet_c32(void* data, ux i, B v) { ((u32*)data)[i] = o2cG(v); }
|
||||
B directGetU_B (void* data, ux i) { return ((B*)data)[i]; } void directSet_B (void* data, ux i, B v) { B* p = i+(B*)data; dec(*p); *p = v; }
|
||||
|
||||
void directSetRange_bit(void* data, ux rs, B x, ux xs, ux l) { COPY_TO(data, el_bit, rs, x, xs, l); }
|
||||
void directSetRange_i8 (void* data, ux rs, B x, ux xs, ux l) { COPY_TO(data, el_i8 , rs, x, xs, l); }
|
||||
void directSetRange_i16(void* data, ux rs, B x, ux xs, ux l) { COPY_TO(data, el_i16, rs, x, xs, l); }
|
||||
void directSetRange_i32(void* data, ux rs, B x, ux xs, ux l) { COPY_TO(data, el_i32, rs, x, xs, l); }
|
||||
void directSetRange_f64(void* data, ux rs, B x, ux xs, ux l) { COPY_TO(data, el_f64, rs, x, xs, l); }
|
||||
void directSetRange_c8 (void* data, ux rs, B x, ux xs, ux l) { COPY_TO(data, el_c8 , rs, x, xs, l); }
|
||||
void directSetRange_c16(void* data, ux rs, B x, ux xs, ux l) { COPY_TO(data, el_c16, rs, x, xs, l); }
|
||||
void directSetRange_c32(void* data, ux rs, B x, ux xs, ux l) { COPY_TO(data, el_c32, rs, x, xs, l); }
|
||||
void directSetRange_B (void* data, ux rs, B x, ux xs, ux l) {
|
||||
for (ux i = 0; i < l; i++) dec(((B*)data)[rs+i]);
|
||||
COPY_TO(data, el_B, rs, x, xs, l);
|
||||
}
|
||||
|
||||
INIT_GLOBAL M_CopyF copyFns[el_MAX];
|
||||
INIT_GLOBAL M_FillF fillFns[el_MAX];
|
||||
INIT_GLOBAL MutFns mutFns[el_MAX+1];
|
||||
INIT_GLOBAL u8 el_orArr[el_MAX*16 + el_MAX+1];
|
||||
INIT_GLOBAL DirectGet directGetU[el_MAX];
|
||||
INIT_GLOBAL DirectSet directSet[el_MAX];
|
||||
INIT_GLOBAL DirectSetRange directSetRange[el_MAX];
|
||||
void mutF_init(void) {
|
||||
for (u8 i = 0; i <= el_MAX; i++) {
|
||||
for (u8 j = 0; j <= el_MAX; j++) {
|
||||
@ -826,15 +893,26 @@ void mutF_init(void) {
|
||||
for (ux i = 0; i < t_COUNT; i++) reuseElType[i] = el_MAX;
|
||||
|
||||
mutFns[el_bit].elType = el_bit; mutFns[el_bit].valType = t_bitarr; reuseElType[t_bitarr] = el_bit;
|
||||
mutFns[el_i8 ].elType = el_i8 ; mutFns[el_i8 ].valType = t_i8arr; reuseElType[t_i8arr] = el_i8;
|
||||
mutFns[el_i8 ].elType = el_i8 ; mutFns[el_i8 ].valType = t_i8arr; reuseElType[t_i8arr ] = el_i8;
|
||||
mutFns[el_i16].elType = el_i16; mutFns[el_i16].valType = t_i16arr; reuseElType[t_i16arr] = el_i16;
|
||||
mutFns[el_i32].elType = el_i32; mutFns[el_i32].valType = t_i32arr; reuseElType[t_i32arr] = el_i32;
|
||||
mutFns[el_c8 ].elType = el_c8 ; mutFns[el_c8 ].valType = t_c8arr; reuseElType[t_c8arr] = el_c8;
|
||||
mutFns[el_c8 ].elType = el_c8 ; mutFns[el_c8 ].valType = t_c8arr; reuseElType[t_c8arr ] = el_c8;
|
||||
mutFns[el_c16].elType = el_c16; mutFns[el_c16].valType = t_c16arr; reuseElType[t_c16arr] = el_c16;
|
||||
mutFns[el_c32].elType = el_c32; mutFns[el_c32].valType = t_c32arr; reuseElType[t_c32arr] = el_c32;
|
||||
mutFns[el_f64].elType = el_f64; mutFns[el_f64].valType = t_f64arr; reuseElType[t_f64arr] = el_f64;
|
||||
mutFns[el_B ].elType = el_B ; mutFns[el_B ].valType = t_harr; reuseElType[t_harr] = el_B;
|
||||
mutFns[el_B ].elType = el_B ; mutFns[el_B ].valType = t_harr; reuseElType[t_harr ] = el_B;
|
||||
/* and fillarr also to complete being able to reuse any target */ reuseElType[t_fillarr]= el_B;
|
||||
|
||||
directGetU[el_bit] = directGetU_bit; directSet[el_bit] = directSet_bit; directSetRange[el_bit] = directSetRange_bit;
|
||||
directGetU[el_i8 ] = directGetU_i8; directSet[el_i8 ] = directSet_i8; directSetRange[el_i8 ] = directSetRange_i8;
|
||||
directGetU[el_i16] = directGetU_i16; directSet[el_i16] = directSet_i16; directSetRange[el_i16] = directSetRange_i16;
|
||||
directGetU[el_i32] = directGetU_i32; directSet[el_i32] = directSet_i32; directSetRange[el_i32] = directSetRange_i32;
|
||||
directGetU[el_c8 ] = directGetU_c8; directSet[el_c8 ] = directSet_c8; directSetRange[el_c8 ] = directSetRange_c8;
|
||||
directGetU[el_c16] = directGetU_c16; directSet[el_c16] = directSet_c16; directSetRange[el_c16] = directSetRange_c16;
|
||||
directGetU[el_c32] = directGetU_c32; directSet[el_c32] = directSet_c32; directSetRange[el_c32] = directSetRange_c32;
|
||||
directGetU[el_f64] = directGetU_f64; directSet[el_f64] = directSet_f64; directSetRange[el_f64] = directSetRange_f64;
|
||||
directGetU[el_B ] = directGetU_B; directSet[el_B ] = directSet_B; directSetRange[el_B ] = directSetRange_B;
|
||||
|
||||
mutFns[el_MAX].elType = el_MAX; mutFns[el_MAX].valType = t_COUNT;
|
||||
for (u8 i = 0; i < el_MAX; i++) copyFns[i] = mutFns[i].m_copyG;
|
||||
for (u8 i = 0; i < el_MAX; i++) fillFns[i] = mutFns[i].m_fillG;
|
||||
|
||||
@ -281,3 +281,25 @@ ApdFn apd_tot_init, apd_sh_init, apd_reshape;
|
||||
#define APDD(M, A) ({ B av_ = (A); M.apd(&M, av_); dec(av_); }) // consumes A
|
||||
#define APD_SH_GET(M, TY) (M.end(&M, TY))
|
||||
#define APD_TOT_GET(M) (M.obj)
|
||||
|
||||
|
||||
|
||||
typedef struct { B obj; void* data; } DirectArr;
|
||||
typedef B (*DirectGet)(void* data, ux i);
|
||||
typedef void (*DirectSet)(void* data, ux i, B v);
|
||||
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];
|
||||
DirectArr toEltypeArr(B x, u8 re);
|
||||
#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];
|
||||
|
||||
#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)
|
||||
#define DIRECTARR_REPLACE(R, I, V) R##_set(R.data, I, V)
|
||||
#define DIRECTARR_REPLACE_RANGE(R, RS, X, XS, L) R##_setRange(R.data, RS, X, XS, L)
|
||||
|
||||
@ -173,6 +173,8 @@ n←500 ⋄ a←↕n ⋄ i←(-n)+↕2×n ⋄ r←⌽(2×n)⥊a ⋄ ! (⌽a) ≡
|
||||
10⊸+⌾(⟨1,0‿1⟩⊸/)↕2‿2 %% 2‿2⥊⟨0‿0,10‿11,1‿0,11‿11⟩
|
||||
!"𝔽⌾(a⊸/): Incompatible result elements" % 1‿2⌾(2‿0⊸/)↕2
|
||||
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"⟩
|
||||
!"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