Handle all constant Replicate in Singeli
This commit is contained in:
parent
15c405e7bf
commit
7069a60453
@ -717,24 +717,14 @@ B slash_c2(B t, B w, B x) {
|
|||||||
else { BOOL_REP_OVER(wv, xlen) }
|
else { BOOL_REP_OVER(wv, xlen) }
|
||||||
goto decX_ret;
|
goto decX_ret;
|
||||||
} else {
|
} else {
|
||||||
#if SINGELI
|
|
||||||
static const u8 factors[] = {4, 3, 5, 1, 6, 1, 7, 5, 4, 1, 6, 1, 5, 7, 2, 1, 6, 5, 2, 3, 7, 1, 6, 1, 4};
|
|
||||||
u8 fa;
|
|
||||||
if (xlen>=12 && wv>=8 && wv<32 && (fa=factors[wv-8])>1) {
|
|
||||||
return slash_c2(m_f64(0), m_f64(fa), slash_c2(m_f64(0), m_f64(wv/fa), x));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
u8 xk = xl-3;
|
u8 xk = xl-3;
|
||||||
void* rv = m_tyarrv(&r, 1<<xk, s, xt);
|
void* rv = m_tyarrv(&r, 1<<xk, s, xt);
|
||||||
void* xv = tyany_ptr(x);
|
void* xv = tyany_ptr(x);
|
||||||
#if SINGELI
|
#if SINGELI
|
||||||
if (wv<=7) {
|
#define CASE(L,T) case L: rep_##T(wv, xv, rv, xlen); break;
|
||||||
#define CASE(L,T) case L: rep_##T(wv, xv, rv, xlen); break;
|
#else
|
||||||
switch (xk) { default: UD; CASE(0,u8) CASE(1,u16) CASE(2,u32) CASE(3,u64) }
|
|
||||||
#undef CASE
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
#define CASE(L,T) case L: { REP_BY_SCAN(T, wv) break; }
|
#define CASE(L,T) case L: { REP_BY_SCAN(T, wv) break; }
|
||||||
|
#endif
|
||||||
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) }
|
||||||
#undef CASE
|
#undef CASE
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,14 +85,8 @@ def get_rep_iter{V==[4]u64, wv} = {
|
|||||||
def sh = each{base4, get_shufs{step, wv}}
|
def sh = each{base4, get_shufs{step, wv}}
|
||||||
{x, gen} => each{{s}=>gen{shuf{V, x, s}}, sh}
|
{x, gen} => each{{s}=>gen{shuf{V, x, s}}, sh}
|
||||||
}
|
}
|
||||||
|
def rep_const_shuffle{V, step, wv, xv:*V, rv:*V, n:u64} = {
|
||||||
rep_const{T, wv}(x:*void, r:*void, n:u64) : void = {
|
|
||||||
def step = 256/width{T}
|
|
||||||
def V = [step]T
|
|
||||||
xv := *V~~x
|
|
||||||
rv := *V~~r
|
|
||||||
def onreps = get_rep_iter{V, wv}
|
def onreps = get_rep_iter{V, wv}
|
||||||
|
|
||||||
nv := n / step
|
nv := n / step
|
||||||
j:u64 = 0
|
j:u64 = 0
|
||||||
def write{v} = { store{rv, j, v}; ++j }
|
def write{v} = { store{rv, j, v}; ++j }
|
||||||
@ -112,12 +106,63 @@ rep_const{T, wv}(x:*void, r:*void, n:u64) : void = {
|
|||||||
if (q) maskstoreF{rv, maskOf{V, q}, e, s}
|
if (q) maskstoreF{rv, maskOf{V, q}, e, s}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rep_const_broadcast{T, V}(wv:u64, x:*T, r:*T, n:u64) : void = {
|
||||||
|
kv := cdiv{wv, vcount{V}}
|
||||||
|
@for (x over n) {
|
||||||
|
v := broadcast{V, x}
|
||||||
|
@for (j to kv) store{*V~~r, j, v}
|
||||||
|
r += wv
|
||||||
|
store{*V~~r, -1, v}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rep_const_broadcast{T, V, kv}(wv:u64, x:*T, r:*T, n:u64) : void = {
|
||||||
|
@for (x over n) {
|
||||||
|
v := broadcast{V, x}
|
||||||
|
@unroll (j to kv) store{*V~~r, j, v}
|
||||||
|
r += wv
|
||||||
|
store{*V~~r, -1, v}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rep_const_broadcast{T, V, kv==0}(wv:u64, x:*T, r:*T, n:u64) : void = {
|
||||||
|
@for (x over n-1) {
|
||||||
|
store{*V~~r, 0, broadcast{V, x}}
|
||||||
|
r += wv
|
||||||
|
}
|
||||||
|
maskstoreF{*V~~r, maskOf{V, wv}, 0, broadcast{V, load{x,n-1}}}
|
||||||
|
}
|
||||||
|
|
||||||
|
rep_const{T, wv}(x:*void, r:*void, n:u64) : void = {
|
||||||
|
def step = 256/width{T}
|
||||||
|
def V = [step]T
|
||||||
|
if ((step>=16 and wv==17) or wv <= max{step/2, 6}) {
|
||||||
|
rep_const_shuffle{V, step, wv, *V~~x, *V~~r, n}
|
||||||
|
} else {
|
||||||
|
def kv = (wv - wv%step) / step
|
||||||
|
rep_const_broadcast{T, V, kv}(wv, *T~~x, *T~~r, n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# 1+˝∨`⌾⌽(2+↕6)(0=|⌜)8+↕25
|
||||||
|
def makefact{divisor, range} = {
|
||||||
|
def t = table{{a,b}=>0==b%a, divisor, range}
|
||||||
|
fold{+, 1, reverse{scan{|, reverse{t}}}}
|
||||||
|
}
|
||||||
|
factors:*u8 = makefact{2+iota{6}, 8+iota{25+32}}
|
||||||
rep_const{T}(wv:i32, x:*void, r:*void, n:u64) : void = {
|
rep_const{T}(wv:i32, x:*void, r:*void, n:u64) : void = {
|
||||||
assert{wv>=2}
|
assert{wv>=2}
|
||||||
@unroll (k from 2 to 8) {
|
if (wv*width{T} > 8*256 or wv > 64) return{rep_const_broadcast{T,[256/width{T}]T}(wv,x,r,n)}
|
||||||
if (wv==k) return{rep_const{T, k}(x, r, n)}
|
def pr = tup{2,3,4,5,6,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61}
|
||||||
|
def try{k} = { if (wv==k) return{rep_const{T, k}(x, r, n)} }
|
||||||
|
each{try, pr}
|
||||||
|
k := u32~~wv
|
||||||
|
fa := promote{u32, load{factors,k-8}}
|
||||||
|
if (fa > 1) {
|
||||||
|
fi := promote{u64, k / fa}
|
||||||
|
def t = *T~~r + (promote{u64,k}-fi)*n
|
||||||
|
rep_const{T}(fi,x,t,n)
|
||||||
|
rep_const{T}(fa,t,r,fi*n)
|
||||||
}
|
}
|
||||||
def rc = rep_const{T}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
'rep_u8' = rep_const{i8 }; 'rep_u16' = rep_const{i16}
|
'rep_u8' = rep_const{i8 }; 'rep_u16' = rep_const{i16}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user