Singeli const¨⌾(m⊸/)b
This commit is contained in:
parent
02573fa4eb
commit
41785cb4bf
@ -932,6 +932,40 @@ B slash_im(B t, B x) {
|
|||||||
decG(x); return r;
|
decG(x); return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SINGELI_SIMD
|
||||||
|
typedef void (*BlendArrScalarFn)(void* r, void* zero, u64 one, void* mask, u64 n);
|
||||||
|
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)};
|
||||||
|
}
|
||||||
|
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};
|
||||||
|
}
|
||||||
|
|
||||||
B slash_ucw(B t, B o, B w, B x) {
|
B slash_ucw(B t, B o, B w, B x) {
|
||||||
if (isAtm(w) || isAtm(x) || RNK(w)!=1 || RNK(x)!=1 || IA(w)!=IA(x)) {
|
if (isAtm(w) || isAtm(x) || RNK(w)!=1 || RNK(x)!=1 || IA(w)!=IA(x)) {
|
||||||
base:
|
base:
|
||||||
@ -939,10 +973,63 @@ B slash_ucw(B t, B o, B w, B x) {
|
|||||||
}
|
}
|
||||||
usz ia = IA(x);
|
usz ia = IA(x);
|
||||||
SGetU(w)
|
SGetU(w)
|
||||||
if (TY(w) != t_bitarr) {
|
if (TI(w,elType) != el_bit) {
|
||||||
w = num_squeezeChk(w);
|
w = num_squeezeChk(w);
|
||||||
if (!elInt(TI(w,elType))) goto base;
|
if (!elInt(TI(w,elType))) goto base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (c ; C˙)¨⌾(w⊸/) x
|
||||||
|
#if SINGELI_SIMD
|
||||||
|
if (isFun(o) && TY(o)==t_md1D) {
|
||||||
|
if (TI(w,elType) != el_bit) goto notConstEach; // TODO could do w↩w≠0 after range checking
|
||||||
|
u8 xe = TI(x,elType);
|
||||||
|
if (xe==el_B) goto notConstEach;
|
||||||
|
|
||||||
|
Md1D* od = c(Md1D,o);
|
||||||
|
if (od->m1->flags-1 != n_each) goto notConstEach;
|
||||||
|
B f = od->f;
|
||||||
|
B c;
|
||||||
|
if (!toConstant(f, &c)) goto notConstEach;
|
||||||
|
|
||||||
|
u8 ce = selfElType(c);
|
||||||
|
u8 re = el_or(ce,xe); // can be el_B
|
||||||
|
|
||||||
|
B r;
|
||||||
|
if (isVal(c)) {
|
||||||
|
u64 sum = usum(w);
|
||||||
|
if (sum==0) decG(c); // TODO could return x; fills?
|
||||||
|
else incByG(c, sum-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* rp;
|
||||||
|
void* xp;
|
||||||
|
if (re != xe) {
|
||||||
|
AnyArr a = cpyElTypeArr(re, x);
|
||||||
|
x = r = incG(a.b);
|
||||||
|
xp = rp = a.data;
|
||||||
|
} else {
|
||||||
|
AnyArr a = m_anyarrc(re, x);
|
||||||
|
r = a.b;
|
||||||
|
rp = a.data;
|
||||||
|
xp = tyany_ptr(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 cv;
|
||||||
|
if (elInt(re)) cv = o2iG(c);
|
||||||
|
else if (elChr(re)) cv = o2cG(c);
|
||||||
|
else {
|
||||||
|
assert(re==el_B || re==el_f64);
|
||||||
|
cv = re==el_f64? r_f64u(o2fG(c)) : r_Bu(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
blendArrScalarFns[elwBitLog(re)](rp, xp, cv, bitany_ptr(w), IA(x));
|
||||||
|
NOGC_E;
|
||||||
|
decG(w); decG(x);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
notConstEach:;
|
||||||
|
|
||||||
B arg = C2(slash, incG(w), incG(x));
|
B arg = C2(slash, incG(w), incG(x));
|
||||||
usz argIA = IA(arg);
|
usz argIA = IA(arg);
|
||||||
B rep = c1(o, arg);
|
B rep = c1(o, arg);
|
||||||
@ -950,7 +1037,7 @@ B slash_ucw(B t, B o, B w, B x) {
|
|||||||
u8 re = el_or(TI(x,elType), TI(rep,elType));
|
u8 re = el_or(TI(x,elType), TI(rep,elType));
|
||||||
MAKE_MUT_INIT(r, ia, re? re : 1);
|
MAKE_MUT_INIT(r, ia, re? re : 1);
|
||||||
usz repI = 0;
|
usz repI = 0;
|
||||||
bool wb = TY(w) == t_bitarr;
|
bool wb = TI(w,elType) == el_bit;
|
||||||
if (wb && re!=el_B) {
|
if (wb && re!=el_B) {
|
||||||
u64* d = bitany_ptr(w);
|
u64* d = bitany_ptr(w);
|
||||||
void* rp = r->a;
|
void* rp = r->a;
|
||||||
@ -973,7 +1060,7 @@ B slash_ucw(B t, B o, B w, B x) {
|
|||||||
((T*)rp)[i] = *(v? np+repI : xp+i); \
|
((T*)rp)[i] = *(v? np+repI : xp+i); \
|
||||||
repI+= v; \
|
repI+= v; \
|
||||||
} \
|
} \
|
||||||
goto dec_ret; \
|
goto mut_dec_ret; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
bit_u8: IMPL(u8);
|
bit_u8: IMPL(u8);
|
||||||
@ -1000,7 +1087,7 @@ B slash_ucw(B t, B o, B w, B x) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dec_ret:;
|
mut_dec_ret:;
|
||||||
decG(w); decG(rep);
|
decG(w); decG(rep);
|
||||||
B rb = mut_fcd(r, x);
|
B rb = mut_fcd(r, x);
|
||||||
return re==0? taga(cpyBitArr(rb)) : rb;
|
return re==0? taga(cpyBitArr(rb)) : rb;
|
||||||
|
|||||||
@ -301,6 +301,8 @@ static NOINLINE B or_SA(B t, B w, B x) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void (*const orAAu_bit_bit_bit)(void*,void*,void*,u64); // used in bits.c
|
||||||
|
|
||||||
#define SINGELI_FILE arTables
|
#define SINGELI_FILE arTables
|
||||||
#include "../../utils/includeSingeli.h"
|
#include "../../utils/includeSingeli.h"
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,21 @@ def table{w} = each{bitsel_i{w, .}, tup{u8, u16, u32, u64}}
|
|||||||
|
|
||||||
exportT{'simd_bitsel', table{arch_defvw}}
|
exportT{'simd_bitsel', table{arch_defvw}}
|
||||||
|
|
||||||
|
fn blend_arr_scalar{E}(rp:*void, zero:*void, one0:u64, mask:*void, len:u64) : void = {
|
||||||
|
if (same{E,'!'}) {
|
||||||
|
fatal{'bad blend'}
|
||||||
|
} else if (E==u1) {
|
||||||
|
emit{void, 'blendArrScalarBits', rp, zero, cast_i{E, one0}, mask, len}
|
||||||
|
} else {
|
||||||
|
def bulk = arch_defvw / width{E}
|
||||||
|
def VT = [bulk]E
|
||||||
|
def one = VT**cast_i{E, one0}
|
||||||
|
@maskedLoop{bulk}(r in tup{VT,*E~~rp}, zero in tup{VT,*E~~zero}, mask in tup{'b',VT,mask} over i to len) r = homBlend{zero, one, mask}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exportT{'si_blend_arr_scalar', each{blend_arr_scalar, tup{u1, '!', '!', u8, u16, u32, u64}}}
|
||||||
|
|
||||||
(if (has_sel) {
|
(if (has_sel) {
|
||||||
fn bitwiden_n_8(src:*void, dst:*void, csz:ux, cam:ux) : void = {
|
fn bitwiden_n_8(src:*void, dst:*void, csz:ux, cam:ux) : void = {
|
||||||
assert{cam>0}
|
assert{cam>0}
|
||||||
|
|||||||
@ -4,8 +4,18 @@
|
|||||||
|
|
||||||
|
|
||||||
#if SINGELI_SIMD
|
#if SINGELI_SIMD
|
||||||
|
extern void (*const orAAu_bit_bit_bit)(void*,void*,void*,u64);
|
||||||
|
static void blendArrScalarBits(void* r, void* zero, bool one, void* mask, u64 n) {
|
||||||
|
if (one) orAAu_bit_bit_bit(r, zero, mask, n);
|
||||||
|
else CMP_AA_CALL(CMP_AA_FN(gt, el_bit), r, zero, mask, n);
|
||||||
|
}
|
||||||
|
|
||||||
#define SINGELI_FILE bits
|
#define SINGELI_FILE bits
|
||||||
#include "../utils/includeSingeli.h"
|
#include "../utils/includeSingeli.h"
|
||||||
|
|
||||||
|
typedef void (*BlendArrScalarFn)(void* r, void* zero, u64 one, void* mask, u64 n);
|
||||||
|
INIT_GLOBAL BlendArrScalarFn* blendArrScalarFns = si_blend_arr_scalar;
|
||||||
|
|
||||||
INIT_GLOBAL BitSelFn* bitselFns = simd_bitsel;
|
INIT_GLOBAL BitSelFn* bitselFns = simd_bitsel;
|
||||||
#else
|
#else
|
||||||
#define BITSEL_DEF(E) void bitsel_##E(void* rp, u64* bp, u64 e0i, u64 e1i, u64 ia) { for (usz i=0; i<ia; i++) ((E*)rp)[i] = bitp_get(bp,i)? e1i : e0i; }
|
#define BITSEL_DEF(E) void bitsel_##E(void* rp, u64* bp, u64 e0i, u64 e1i, u64 ia) { for (usz i=0; i<ia; i++) ((E*)rp)[i] = bitp_get(bp,i)? e1i : e0i; }
|
||||||
|
|||||||
@ -109,6 +109,17 @@ n←500 ⋄ a←↕n ⋄ i←(-n)+↕2×n ⋄ r←⌽(2×n)⥊a ⋄ ! (⌽a) ≡
|
|||||||
{!(a×1+9× 0‿1‿2∊𝕩+↕3) ≡ 10⊸×⌾(𝕩⊸↓) a←3‿4‿5⥊↕60}¨ ¯5+↕10
|
{!(a×1+9× 0‿1‿2∊𝕩+↕3) ≡ 10⊸×⌾(𝕩⊸↓) a←3‿4‿5⥊↕60}¨ ¯5+↕10
|
||||||
{!(a×1+9׬0‿1‿2∊𝕩+↕3) ≡ 10⊸×⌾(𝕩⊸↑) a←3‿4‿5⥊↕60}¨ ¯3+↕7
|
{!(a×1+9׬0‿1‿2∊𝕩+↕3) ≡ 10⊸×⌾(𝕩⊸↑) a←3‿4‿5⥊↕60}¨ ¯3+↕7
|
||||||
|
|
||||||
|
%USE eqvar ⋄ 1‿0‿0‿0‿1‿1 { 1¨⌾(𝕨⊸/)𝕩}_eqvar 0‿1‿0‿1‿0‿1 %% 1‿1‿0‿1‿1‿1
|
||||||
|
%USE eqvar ⋄ 1‿0‿0‿0‿1‿1 { 0¨⌾(𝕨⊸/)𝕩}_eqvar 0‿1‿0‿1‿0‿1 %% 0‿1‿0‿1‿0‿0
|
||||||
|
%USE eqvar ⋄ 1‿0‿0‿0‿1‿1 {'!'¨⌾(𝕨⊸/)𝕩}_eqvar 0‿1‿0‿1‿0‿1 %% '!'‿1‿0‿1‿'!'‿'!'
|
||||||
|
%USE eqvar ⋄ 1‿0‿0‿0‿1‿1 { ≥˙¨⌾(𝕨⊸/)𝕩}_eqvar 0‿1‿0‿1‿0‿1 %% ≥‿1‿0‿1‿≥‿≥
|
||||||
|
%USE eqvar ⋄ 1‿0‿0‿0‿1‿1 { 3¨⌾(𝕨⊸/)𝕩}_eqvar "hellow" %% 3‿'e'‿'l'‿'l'‿3‿3
|
||||||
|
%USE eqvar ⋄ 1‿0‿0‿0‿1‿1 { +˙¨⌾(𝕨⊸/)𝕩}_eqvar -‿÷‿×‿=‿<‿> %% +‿÷‿×‿=‿+‿+
|
||||||
|
!"/: Lengths of components of 𝕨 must match 𝕩 (6 ≠ 7)" % 0¨⌾(1‿0‿0‿0‿1‿1⊸/) 0‿1‿0‿1‿0‿1‿0
|
||||||
|
4↑ (⋈⋈3)⌾(0‿1‿0⊸/) ↕⋈3 %% ⟨⋈0,⋈3,⋈2,0⟩
|
||||||
|
4↑ ⊢⌾(0‿1‿0⊸/) ↕⋈3 %% ⟨⋈0,⋈1,⋈2,0⟩
|
||||||
|
4↑ ⊢⌾(0‿0‿0⊸/) ↕⋈3 %% ⟨⋈0,⋈1,⋈2,0⟩
|
||||||
|
|
||||||
# <
|
# <
|
||||||
⊢⌾< 4 %% 4
|
⊢⌾< 4 %% 4
|
||||||
(<5)⌾< 4 %% 5
|
(<5)⌾< 4 %% 5
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user