Merge scan-based sparse Indices/Replicate code with macros
This commit is contained in:
parent
d647978c8f
commit
7f6cf06eea
@ -448,6 +448,30 @@ static B compress(B w, B x, usz wia, u8 xl, u8 xt) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SCAN_CORE(WV, UPD, SET, SCAN) \
|
||||||
|
usz b = 1<<10; \
|
||||||
|
for (usz k=0, j=0, ij=WV; ; ) { \
|
||||||
|
usz e = b<s-k? k+b : s; \
|
||||||
|
SET; for (usz i=k; i<e; i++) rp[i]=0; \
|
||||||
|
while (ij<e) { j++; UPD; ij+=WV; } \
|
||||||
|
SCAN; \
|
||||||
|
if (e==s) {break;} k=e; \
|
||||||
|
}
|
||||||
|
#define SUM_CORE(T, WV, PREP, INC) \
|
||||||
|
SCAN_CORE(WV, PREP; rp[ij]+=INC, , PLUS_SCAN(T))
|
||||||
|
|
||||||
|
#if SINGELI
|
||||||
|
#define IND_BY_SCAN \
|
||||||
|
SCAN_CORE(xp[j], rp[ij]=j, rp[k]=j, avx2_scan_max32(rp+k,rp+k,e-k))
|
||||||
|
#else
|
||||||
|
#define IND_BY_SCAN usz js=0; SUM_CORE(i32, xp[j], , 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define REP_BY_SCAN(T, WV) \
|
||||||
|
T* xp = xv; T* rp = rv; \
|
||||||
|
T js=xp[0], px=js; \
|
||||||
|
SUM_CORE(T, WV, T sx=px, (px=xp[j])-sx)
|
||||||
|
|
||||||
extern B rt_slash;
|
extern B rt_slash;
|
||||||
B slash_c1(B t, B x) {
|
B slash_c1(B t, B x) {
|
||||||
if (RARE(isAtm(x)) || RARE(RNK(x)!=1)) thrF("/: Argument must have rank 1 (%H ≡ ≢𝕩)", x);
|
if (RARE(isAtm(x)) || RARE(RNK(x)!=1)) thrF("/: Argument must have rank 1 (%H ≡ ≢𝕩)", x);
|
||||||
@ -477,30 +501,7 @@ B slash_c1(B t, B x) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (s/32 <= xia) { // Sparse case: type of x matters
|
if (s/32 <= xia) { // Sparse case: type of x matters
|
||||||
#if SINGELI
|
#define SPARSE_IND(T) T* xp = T##any_ptr(x); IND_BY_SCAN
|
||||||
#define SPARSE_IND(T) \
|
|
||||||
T* xp = T##any_ptr(x); \
|
|
||||||
usz b = 1<<10; \
|
|
||||||
for (usz k=0, j=0, ij=xp[0]; ; ) { \
|
|
||||||
usz e = b<s-k? k+b : s; \
|
|
||||||
for (usz i=k; i<e; i++) rp[i]=0; \
|
|
||||||
rp[k]=j; \
|
|
||||||
while (ij<e) { rp[ij]=++j; ij+=xp[j]; } \
|
|
||||||
avx2_scan_max32(rp+k,rp+k,e-k); \
|
|
||||||
if (e==s) {break;} k=e; \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define SPARSE_IND(T) \
|
|
||||||
T* xp = T##any_ptr(x); \
|
|
||||||
usz b = 1<<10; \
|
|
||||||
for (usz k=0, j=0, js=0, ij=xp[0]; ; ) { \
|
|
||||||
usz e = b<s-k? k+b : s; \
|
|
||||||
for (usz i=k; i<e; i++) rp[i]=0; \
|
|
||||||
while (ij<e) { rp[ij]++; ij+=xp[++j]; } \
|
|
||||||
PLUS_SCAN(i32) \
|
|
||||||
if (e==s) {break;} k=e; \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
i32* rp; r = m_i32arrv(&rp, s);
|
i32* rp; r = m_i32arrv(&rp, s);
|
||||||
if (xe == el_i8 ) { SPARSE_IND(i8 ); }
|
if (xe == el_i8 ) { SPARSE_IND(i8 ); }
|
||||||
else if (xe == el_i16) { SPARSE_IND(i16); }
|
else if (xe == el_i16) { SPARSE_IND(i16); }
|
||||||
@ -643,17 +644,7 @@ B slash_c2(B t, B w, B x) {
|
|||||||
if (rsh) { Arr* ra=a(r); SPRNK(ra,xr); PSH(ra) = rsh; PIA(ra) = s*arr_csz(x); }
|
if (rsh) { Arr* ra=a(r); SPRNK(ra,xr); PSH(ra) = rsh; PIA(ra) = s*arr_csz(x); }
|
||||||
void* xv = tyany_ptr(x);
|
void* xv = tyany_ptr(x);
|
||||||
if (s/64 <= wia) { // Sparse case: use both types
|
if (s/64 <= wia) { // Sparse case: use both types
|
||||||
#define CASE(L,XT) case L: { \
|
#define CASE(L,XT) case L: { REP_BY_SCAN(XT, wp[j]) break; }
|
||||||
XT* xp = xv; XT* rp = rv; \
|
|
||||||
usz b = 1<<10; \
|
|
||||||
XT js=xp[0], px=js; \
|
|
||||||
for (usz k=0, j=0, ij=wp[0]; ; ) { \
|
|
||||||
usz e = b<s-k? k+b : s; \
|
|
||||||
for (usz i=k; i<e; i++) rp[i]=0; \
|
|
||||||
while (ij<e) { j++; XT sx=px; rp[ij]+=(px=xp[j])-sx; ij+=wp[j]; } \
|
|
||||||
PLUS_SCAN(XT) \
|
|
||||||
if (e==s) {break;} k=e; \
|
|
||||||
} break; }
|
|
||||||
#define SPARSE_REP(WT) \
|
#define SPARSE_REP(WT) \
|
||||||
WT* wp = WT##any_ptr(w); \
|
WT* wp = WT##any_ptr(w); \
|
||||||
switch (xk) { default: UD; CASE(0,u8) CASE(1,u16) CASE(2,u32) CASE(3,u64) }
|
switch (xk) { default: UD; CASE(0,u8) CASE(1,u16) CASE(2,u32) CASE(3,u64) }
|
||||||
@ -706,24 +697,9 @@ B slash_c2(B t, B w, B x) {
|
|||||||
Arr* ra=a(r); SPRNK(ra,xr); PSH(ra)=rsh; PIA(ra)=s*arr_csz(x);
|
Arr* ra=a(r); SPRNK(ra,xr); PSH(ra)=rsh; PIA(ra)=s*arr_csz(x);
|
||||||
}
|
}
|
||||||
void* xv = tyany_ptr(x);
|
void* xv = tyany_ptr(x);
|
||||||
#define CONST_REP(T) { \
|
#define CASE(L,T) case L: { REP_BY_SCAN(T, wv) goto decX_ret; }
|
||||||
T* xp = xv; T* rp = rv; \
|
switch (xk) { default: UD; CASE(0,u8) CASE(1,u16) CASE(2,u32) CASE(3,u64) }
|
||||||
usz b = 1<<10; \
|
#undef CASE
|
||||||
T js=xp[0], px=js; \
|
|
||||||
for (usz k=0, j=0, ij=wv; ; ) { \
|
|
||||||
usz e = b<s-k? k+b : s; \
|
|
||||||
for (usz i=k; i<e; i++) rp[i]=0; \
|
|
||||||
while (ij<e) { j++; T sx=px; rp[ij]+=(px=xp[j])-sx; ij+=wv; } \
|
|
||||||
PLUS_SCAN(T) \
|
|
||||||
if (e==s) {break;} k=e; \
|
|
||||||
} goto decX_ret; }
|
|
||||||
switch (xk) { default: UD;
|
|
||||||
case 0: CONST_REP(u8 )
|
|
||||||
case 1: CONST_REP(u16)
|
|
||||||
case 2: CONST_REP(u32)
|
|
||||||
case 3: CONST_REP(u64)
|
|
||||||
}
|
|
||||||
#undef CONST_REP
|
|
||||||
}
|
}
|
||||||
base:
|
base:
|
||||||
return c2(rt_slash, w, x);
|
return c2(rt_slash, w, x);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user