fix 0‿1⊸⊏˘3‿1⥊2; accept any non-empty array x in select_rows_typed→select_rows_direct

This commit is contained in:
dzaima 2024-07-29 00:18:48 +03:00
parent 3a722b552f
commit 52f36c61c0
4 changed files with 35 additions and 25 deletions

View File

@ -26,7 +26,7 @@ B try_interleave_cells(B w, B x, ur xr, ur xk, usz* xsh); // from transpose.c
// from select.c:
B select_rows_B(B x, ux csz, ux cam, B inds);
B select_rows_typed(B x, ux csz, ux cam, void* inds, ux indn, u8 ie);
B select_rows_direct(B x, ux csz, ux cam, void* inds, ux indn, u8 ie);
// X - variable name; XSH - its shape; K - number of leading axes that get iterated over; SLN - number of slices that will be made; DX - additional refcount count to add to x
#define S_KSLICES(X, XSH, K, SLN, DX)\
@ -507,7 +507,7 @@ B for_cells_c1(B f, u32 xr, u32 cr, u32 k, B x, u32 chr) { // F⎉cr x; array x,
u8 xe = TI(x,elType);
if (cr==1 && csz<=64 && xe!=el_bit && xe!=el_B && csz < (128*8 >> arrTypeBitsLog(TY(x)))) {
incG(x); // TODO proper shape moving
Arr* r = customizeShape(select_rows_typed(x, csz, cam, reverse_inds_64+64-csz, csz, el_i8));
Arr* r = customizeShape(select_rows_direct(x, csz, cam, reverse_inds_64+64-csz, csz, el_i8));
arr_shCopy(r, x);
decG(x);
return taga(r);

View File

@ -55,7 +55,7 @@
// Direct call to select function per cell
// COULD have a more direct call that avoids overflow checking & wrapping
// COULD generate full list of indices via arith
// 1-element cells: use (≠inds)/⥊x after checking ∧´0=inds
// 1-element cells: use (≠inds)/⥊x after checking ∧´inds∊0‿¯1
// Used for ⌽⎉1
// SHOULD use for atom⊸⊏⎉k, /⎉k, ⌽⎉k, ↑⎉k, ⍉⎉k, probably more
@ -579,7 +579,7 @@ B select_cells_base(B inds, B x0, ux csz, ux cam);
#endif
#define INDS_BUF_MAX 64 // only need 32 bytes for AVX2 & 16 for NEON, but have more for past-the-end pointers and writes
B select_rows_typed(B x, ux csz, ux cam, void* inds, ux indn, u8 ie) { // ⥊ (indn↑inds As ie)⊸⊏˘ cam‿csz⥊z; xe cannot be el_bit or el_B, unless csz==1; ie must be ≤el_i8 if csz≤128
B select_rows_direct(B x, ux csz, ux cam, void* inds, ux indn, u8 ie) { // ⥊ (indn↑inds As ie)⊸⊏˘ cam‿csz⥊x
assert(csz!=0 && cam!=0);
assert(csz*cam == IA(x));
assert(ie<=el_i32);
@ -588,21 +588,22 @@ B select_rows_typed(B x, ux csz, ux cam, void* inds, ux indn, u8 ie) { // ⥊ (i
bool generic_allowed = true; // whether required interpretation of x hasn't changed from its real one
if (csz==1) { // TODO maybe move to select_rows_B and require csz>=2 here?
i64 bounds[2];
if (!getRange_fns[ie](inds, bounds, indn) || bounds[0]<-1 || bounds[1]>0) goto generic;
if (!getRange_fns[ie](inds, bounds, indn) || bounds[0]<-1 || bounds[1]>0) goto generic_any;
return C2(slash, m_f64(indn), taga(arr_shVec(customizeShape(x))));
}
u8 xe = TI(x,elType);
assert(xe!=el_bit && xe!=el_B);
assert(csz>=2);
B r;
u8 xe = TI(x,elType);
u8 lb = arrTypeWidthLog(TY(x));
u8* xp = tyany_ptr(x);
if (xe==el_bit || xe==el_B) goto generic_any;
B r;
ux ria = indn * cam;
bool fast; (void) fast;
ux xbump = csz<<lb;
ux rbump = indn<<lb;
ux ria = indn * cam;
u8* xp = tyany_ptr(x);
bool fast; (void) fast;
i64 bounds[2];
if (ie==el_bit) {
@ -628,15 +629,16 @@ B select_rows_typed(B x, ux csz, ux cam, void* inds, ux indn, u8 ie) { // ⥊ (i
}
}
#if SINGELI
assert(INDS_BUF_MAX_COPY == INDS_BUF_MAX);
{
fast = ie==el_i8;
if (!getRange_fns[ie](inds, bounds, indn)) goto generic;
if (bounds[1] >= (i64)csz) goto generic;
if (!getRange_fns[ie](inds, bounds, indn)) goto generic_int;
if (bounds[1] >= (i64)csz) goto generic_int;
if (bounds[0] < 0) {
if (bounds[0] < -(i64)csz) goto generic;
if (bounds[0] < -(i64)csz) goto generic_int;
if (csz < 128 && indn < INDS_BUF_MAX) {
assert(ie == el_i8);
si_wrap_inds[0](inds, inds_buf, indn, csz);
@ -738,11 +740,18 @@ B select_rows_typed(B x, ux csz, ux cam, void* inds, ux indn, u8 ie) { // ⥊ (i
}
#endif
generic:;
assert(generic_allowed);
generic_any:;
if (ie==el_bit) {
u64* rp;
B indo = m_bitarrv(&rp, indn);
memcpy(rp, inds, (indn+7)>>3);
assert(generic_allowed);
return select_cells_base(indo, x, csz, cam);
}
generic_int:;
assert(ie!=el_bit && generic_allowed);
B indo = taga(arr_shVec(m_tyslice(inds, a(emptyIVec()), ie, indn)));
r = select_cells_base(indo, x, csz, cam);
return r;
return select_cells_base(indo, x, csz, cam);
decG_ret:;
decG(x);
@ -766,12 +775,9 @@ B select_rows_B(B x, ux csz, ux cam, B inds) { // consumes inds,x; ⥊ inds⊸
}
void* ip = tyany_ptr(inds);
u8 xe = TI(x,elType);
if ((xe!=el_bit && xe!=el_B) || csz==1) {
B r = select_rows_typed(x, csz, cam, (u8*)ip, in, ie);
decG(inds);
return r;
}
B r = select_rows_direct(x, csz, cam, (u8*)ip, in, ie);
decG(inds);
return r;
generic:;
return select_cells_base(inds, x, csz, cam);

View File

@ -31,7 +31,8 @@ u8 const arrTypeWidthLog[] = {
[t_i8arr ]=0, [t_i8slice ]=0, [t_c8arr ]=0, [t_c8slice ]=0,
[t_i16arr]=1, [t_i16slice]=1, [t_c16arr]=1, [t_c16slice]=1,
[t_i32arr]=2, [t_i32slice]=2, [t_c32arr]=2, [t_c32slice]=2,
[t_f64arr]=3, [t_f64slice]=3
[t_f64arr]=3, [t_f64slice]=3,
[t_harr ]=3, [t_hslice ]=3, [t_fillarr]=3,[t_fillslice]=3
};
u8 const arrTypeBitsLog[] = {
[t_bitarr]=0,

View File

@ -90,6 +90,9 @@
1201¯12 23424 %% 2544567891011012345678910111617181920212223121314151617181920212223
!"⊏: Indexing out-of-bounds (1∊𝕨, 1≡≠𝕩)" % %USE evar 0¯11¯1 {𝕨˘𝕩}_evar ˘5
!"⊏: Indexing out-of-bounds (¯2∊𝕨, 1≡≠𝕩)" % %USE evar 0¯1¯2¯1 {𝕨˘𝕩}_evar ˘5
!"⊏: Indexing out-of-bounds (¯129∊𝕨, 128≡≠𝕩)" % %USE evar 10¯129 {𝕨˘𝕩}_evar 101281
!"⊏: Indexing out-of-bounds (128∊𝕨, 128≡≠𝕩)" % %USE evar 10128 {𝕨˘𝕩}_evar 101281
!"⊏: Indexing out-of-bounds (1∊𝕨, 1≡≠𝕩)" % %USE evar 1001 {𝕨˘𝕩}_evar 1011
(
%USE IS_HEAPVERIFY