Move tranpose to its own file
This commit is contained in:
parent
0e2e315e51
commit
ff6361e363
@ -549,7 +549,7 @@ MakeLinkerInv ← { 𝕊 GetArgs‿cache‿name‿srcs:
|
|||||||
cachedBin‿linkerCache ← {
|
cachedBin‿linkerCache ← {
|
||||||
Shorten ← {po.clangd? 𝕩; r ← {𝕩↓˜¯1-⊑'.'⊐˜⌽𝕩}¨ •file.Name¨ 𝕩 ⋄ ! ∧´ ∊r ⋄ r}
|
Shorten ← {po.clangd? 𝕩; r ← {𝕩↓˜¯1-⊑'.'⊐˜⌽𝕩}¨ •file.Name¨ 𝕩 ⋄ ! ∧´ ∊r ⋄ r}
|
||||||
cbqnSrc ← ∾{⌽(⊑𝕩)⊸•file.At¨ 1↓𝕩}¨ ⌽⟨
|
cbqnSrc ← ∾{⌽(⊑𝕩)⊸•file.At¨ 1↓𝕩}¨ ⌽⟨
|
||||||
⟨"src/builtins/", "arithd.c", "arithm.c", "cmp.c", "sfns.c", "squeeze.c", "select.c", "slash.c", "group.c", "sort.c", "search.c", "selfsearch.c", "fold.c", "scan.c", "md1.c", "md2.c", "fns.c", "sysfn.c", "internal.c", "inverse.c"⟩
|
⟨"src/builtins/", "arithd.c", "arithm.c", "cmp.c", "sfns.c", "squeeze.c", "select.c", "slash.c", "group.c", "sort.c", "search.c", "selfsearch.c", "transpose.c", "fold.c", "scan.c", "md1.c", "md2.c", "fns.c", "sysfn.c", "internal.c", "inverse.c"⟩
|
||||||
⟨"src/core/", "tyarr.c", "harr.c", "fillarr.c", "stuff.c", "derv.c", "mm.c", "heap.c"⟩
|
⟨"src/core/", "tyarr.c", "harr.c", "fillarr.c", "stuff.c", "derv.c", "mm.c", "heap.c"⟩
|
||||||
⟨"src/", "load.c", "main.c", "rtwrap.c", "vm.c", "ns.c", "nfns.c", "ffi.c"⟩
|
⟨"src/", "load.c", "main.c", "rtwrap.c", "vm.c", "ns.c", "nfns.c", "ffi.c"⟩
|
||||||
⟨"src/jit/", "nvm.c"⟩
|
⟨"src/jit/", "nvm.c"⟩
|
||||||
@ -562,7 +562,7 @@ cachedBin‿linkerCache ← {
|
|||||||
"xa"‿"src/builtins/arithd.c"‿"dyarith", "xa"‿"src/builtins/cmp.c"‿"cmp", "xa"‿"src/builtins/squeeze.c"‿"squeeze"
|
"xa"‿"src/builtins/arithd.c"‿"dyarith", "xa"‿"src/builtins/cmp.c"‿"cmp", "xa"‿"src/builtins/squeeze.c"‿"squeeze"
|
||||||
"x."‿"src/builtins/select.c"‿"select", "x."‿"src/builtins/fold.c"‿"fold", "x."‿"src/builtins/scan.c"‿"scan"
|
"x."‿"src/builtins/select.c"‿"select", "x."‿"src/builtins/fold.c"‿"fold", "x."‿"src/builtins/scan.c"‿"scan"
|
||||||
"x."‿"src/builtins/scan.c"‿"neq", "x."‿"src/builtins/slash.c"‿"slash", "x."‿"src/builtins/slash.c"‿"constrep"
|
"x."‿"src/builtins/scan.c"‿"neq", "x."‿"src/builtins/slash.c"‿"slash", "x."‿"src/builtins/slash.c"‿"constrep"
|
||||||
"x."‿"src/builtins/sfns.c"‿"transpose"
|
"x."‿"src/builtins/transpose.c"‿"transpose"
|
||||||
⟩
|
⟩
|
||||||
objs ← ⟨⟩
|
objs ← ⟨⟩
|
||||||
|
|
||||||
|
|||||||
2
makefile
2
makefile
@ -283,7 +283,7 @@ ${bd}/%.o: src/jit/%.c
|
|||||||
@echo $< | cut -c 5-
|
@echo $< | cut -c 5-
|
||||||
@$(CC_INC) $@.d -o $@ -c $<
|
@$(CC_INC) $@.d -o $@ -c $<
|
||||||
|
|
||||||
builtins: ${addprefix ${bd}/, arithm.o arithd.o cmp.o sfns.o squeeze.o select.o slash.o group.o sort.o search.o selfsearch.o fold.o scan.o md1.o md2.o fns.o sysfn.o internal.o inverse.o}
|
builtins: ${addprefix ${bd}/, arithm.o arithd.o cmp.o sfns.o squeeze.o select.o slash.o group.o sort.o search.o selfsearch.o tranpose.o fold.o scan.o md1.o md2.o fns.o sysfn.o internal.o inverse.o}
|
||||||
${bd}/%.o: src/builtins/%.c
|
${bd}/%.o: src/builtins/%.c
|
||||||
@echo $< | cut -c 5-
|
@echo $< | cut -c 5-
|
||||||
@$(CC_INC) $@.d -o $@ -c $<
|
@$(CC_INC) $@.d -o $@ -c $<
|
||||||
|
|||||||
@ -1237,160 +1237,6 @@ B reverse_c2(B t, B w, B x) {
|
|||||||
return withFill(mut_fcd(r, x), xf);
|
return withFill(mut_fcd(r, x), xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __BMI2__
|
|
||||||
#include <immintrin.h>
|
|
||||||
#if USE_VALGRIND
|
|
||||||
#define _pdep_u64 vg_pdep_u64
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SINGELI_X86_64
|
|
||||||
static NOINLINE void base_transpose_i16(i16* rp, i16* xp, u64 w, u64 h, u64 xo, u64 ro) { PLAINLOOP for(usz y=0;y<h;y++) NOVECTORIZE for(usz x=0;x<w;x++) rp[x*ro+y] = xp[y*xo+x]; }
|
|
||||||
static NOINLINE void base_transpose_i32(i32* rp, i32* xp, u64 w, u64 h, u64 xo, u64 ro) { PLAINLOOP for(usz y=0;y<h;y++) NOVECTORIZE for(usz x=0;x<w;x++) rp[x*ro+y] = xp[y*xo+x]; }
|
|
||||||
static NOINLINE void base_transpose_i64(i64* rp, i64* xp, u64 w, u64 h, u64 xo, u64 ro) { PLAINLOOP for(usz y=0;y<h;y++) NOVECTORIZE for(usz x=0;x<w;x++) rp[x*ro+y] = xp[y*xo+x]; }
|
|
||||||
#define SINGELI_FILE transpose
|
|
||||||
#include "../utils/includeSingeli.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
extern B rt_transp;
|
|
||||||
B transp_c1(B t, B x) {
|
|
||||||
if (RARE(isAtm(x))) return m_atomUnit(x);
|
|
||||||
ur xr = RNK(x);
|
|
||||||
if (xr<=1) return x;
|
|
||||||
|
|
||||||
usz ia = IA(x);
|
|
||||||
usz* xsh = SH(x);
|
|
||||||
usz h = xsh[0];
|
|
||||||
if (ia==0 || h==1) {
|
|
||||||
no_reorder:;
|
|
||||||
Arr* r = cpyWithShape(x);
|
|
||||||
ShArr* sh = m_shArr(xr);
|
|
||||||
shcpy(sh->a, xsh+1, xr-1);
|
|
||||||
sh->a[xr-1] = h;
|
|
||||||
arr_shReplace(r, xr, sh);
|
|
||||||
return taga(r);
|
|
||||||
}
|
|
||||||
usz w = xsh[1] * shProd(xsh, 2, xr);
|
|
||||||
if (w==1) goto no_reorder;
|
|
||||||
|
|
||||||
Arr* r;
|
|
||||||
usz xi = 0;
|
|
||||||
u8 xe = TI(x,elType);
|
|
||||||
bool toBit = false;
|
|
||||||
if (h==2) {
|
|
||||||
if (xe==el_B) {
|
|
||||||
B* xp = TO_BPTR(x);
|
|
||||||
B* x0 = xp; B* x1 = x0+w;
|
|
||||||
HArr_p rp = m_harrUp(ia);
|
|
||||||
for (usz i=0; i<w; i++) { rp.a[i*2] = inc(x0[i]); rp.a[i*2+1] = inc(x1[i]); }
|
|
||||||
NOGC_E;
|
|
||||||
r = (Arr*) rp.c;
|
|
||||||
} else {
|
|
||||||
#ifndef __BMI2__
|
|
||||||
if (xe==el_bit) { x = taga(cpyI8Arr(x)); xsh=SH(x); xe=el_i8; toBit=true; }
|
|
||||||
void* rp = m_tyarrp(&r,elWidth(xe),ia,el2t(xe));
|
|
||||||
#else
|
|
||||||
void* rp = m_tyarrlbp(&r,elWidthLogBits(xe),ia,el2t(xe));
|
|
||||||
#endif
|
|
||||||
void* xp = tyany_ptr(x);
|
|
||||||
switch(xe) { default: UD;
|
|
||||||
#ifdef __BMI2__
|
|
||||||
case el_bit:;
|
|
||||||
u32* x0 = xp;
|
|
||||||
Arr* x1o = TI(x,slice)(inc(x),w,w);
|
|
||||||
u32* x1 = (u32*) ((TyArr*)x1o)->a;
|
|
||||||
for (usz i=0; i<BIT_N(ia); i++) ((u64*)rp)[i] = _pdep_u64(x0[i], 0x5555555555555555) | _pdep_u64(x1[i], 0xAAAAAAAAAAAAAAAA);
|
|
||||||
mm_free((Value*)x1o);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case el_i8: case el_c8: { u8* x0=xp; u8* x1=x0+w; for (usz i=0; i<w; i++) { ((u8* )rp)[i*2] = x0[i]; ((u8* )rp)[i*2+1] = x1[i]; } } break;
|
|
||||||
case el_i16:case el_c16: { u16* x0=xp; u16* x1=x0+w; for (usz i=0; i<w; i++) { ((u16*)rp)[i*2] = x0[i]; ((u16*)rp)[i*2+1] = x1[i]; } } break;
|
|
||||||
case el_i32:case el_c32: { u32* x0=xp; u32* x1=x0+w; for (usz i=0; i<w; i++) { ((u32*)rp)[i*2] = x0[i]; ((u32*)rp)[i*2+1] = x1[i]; } } break;
|
|
||||||
case el_f64: { u64* x0=xp; u64* x1=x0+w; for (usz i=0; i<w; i++) { ((u64*)rp)[i*2] = x0[i]; ((u64*)rp)[i*2+1] = x1[i]; } } break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (w==2 && xe!=el_B) {
|
|
||||||
#ifndef __BMI2__
|
|
||||||
if (xe==el_bit) { x = taga(cpyI8Arr(x)); xsh=SH(x); xe=el_i8; toBit=true; }
|
|
||||||
#endif
|
|
||||||
void* rp = m_tyarrlbp(&r,elWidthLogBits(xe),ia,el2t(xe));
|
|
||||||
void* xp = tyany_ptr(x);
|
|
||||||
switch(xe) { default: UD;
|
|
||||||
#if __BMI2__
|
|
||||||
case el_bit:;
|
|
||||||
u64* r0 = rp; TALLOC(u64, r1, BIT_N(h));
|
|
||||||
for (usz i=0; i<BIT_N(ia); i++) {
|
|
||||||
u64 v = ((u64*)xp)[i];
|
|
||||||
((u32*)r0)[i] = _pext_u64(v, 0x5555555555555555);
|
|
||||||
((u32*)r1)[i] = _pext_u64(v, 0xAAAAAAAAAAAAAAAA);
|
|
||||||
}
|
|
||||||
bit_cpy(r0, h, r1, 0, h);
|
|
||||||
TFREE(r1);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case el_i8: case el_c8: { u8* r0=rp; u8* r1=r0+h; for (usz i=0; i<h; i++) { r0[i] = ((u8* )xp)[i*2]; r1[i] = ((u8* )xp)[i*2+1]; } } break;
|
|
||||||
case el_i16:case el_c16: { u16* r0=rp; u16* r1=r0+h; for (usz i=0; i<h; i++) { r0[i] = ((u16*)xp)[i*2]; r1[i] = ((u16*)xp)[i*2+1]; } } break;
|
|
||||||
case el_i32:case el_c32: { u32* r0=rp; u32* r1=r0+h; for (usz i=0; i<h; i++) { r0[i] = ((u32*)xp)[i*2]; r1[i] = ((u32*)xp)[i*2+1]; } } break;
|
|
||||||
case el_f64: { f64* r0=rp; f64* r1=r0+h; for (usz i=0; i<h; i++) { r0[i] = ((f64*)xp)[i*2]; r1[i] = ((f64*)xp)[i*2+1]; } } break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch(xe) { default: UD;
|
|
||||||
case el_bit: x = taga(cpyI8Arr(x)); xsh=SH(x); xe=el_i8; toBit=true; // fallthough
|
|
||||||
case el_i8: case el_c8: { u8* xp=tyany_ptr(x); u8* rp = m_tyarrp(&r,1,ia,el2t(xe)); PLAINLOOP for(usz y=0;y<h;y++) NOVECTORIZE for(usz x=0;x<w;x++) rp[x*h+y] = xp[xi++]; break; }
|
|
||||||
case el_i16:case el_c16:
|
|
||||||
#if SINGELI_X86_64
|
|
||||||
if (w>=8 && h>=8) { u16* xp=tyany_ptr(x); u16* rp = m_tyarrp(&r,4,ia,el2t(xe)); simd_transpose_i16(rp, xp, w, h); break; }
|
|
||||||
#endif
|
|
||||||
{ u16* xp=tyany_ptr(x); u16* rp = m_tyarrp(&r,2,ia,el2t(xe)); PLAINLOOP for(usz y=0;y<h;y++) NOVECTORIZE for(usz x=0;x<w;x++) rp[x*h+y] = xp[xi++]; break; }
|
|
||||||
case el_i32:case el_c32:
|
|
||||||
#if SINGELI_X86_64
|
|
||||||
if (w>=8 && h>=8) { u32* xp=tyany_ptr(x); u32* rp = m_tyarrp(&r,4,ia,el2t(xe)); simd_transpose_i32(rp, xp, w, h); break; }
|
|
||||||
#endif
|
|
||||||
{ u32* xp=tyany_ptr(x); u32* rp = m_tyarrp(&r,4,ia,el2t(xe)); PLAINLOOP for(usz y=0;y<h;y++) NOVECTORIZE for(usz x=0;x<w;x++) rp[x*h+y] = xp[xi++]; break; }
|
|
||||||
case el_f64:
|
|
||||||
#if SINGELI_X86_64
|
|
||||||
if (w>=4 && h>=4) { f64* xp=f64any_ptr(x); f64* rp; r=m_f64arrp(&rp,ia); simd_transpose_i64(rp, xp, w, h); break; }
|
|
||||||
#endif
|
|
||||||
{ f64* xp=f64any_ptr(x); f64* rp; r=m_f64arrp(&rp,ia); PLAINLOOP for(usz y=0;y<h;y++) NOVECTORIZE for(usz x=0;x<w;x++) rp[x*h+y] = xp[xi++]; break; }
|
|
||||||
case el_B: { // can't be bothered to implement a bitarr transpose
|
|
||||||
B xf = getFillR(x);
|
|
||||||
B* xp = TO_BPTR(x);
|
|
||||||
|
|
||||||
HArr_p p = m_harrUp(ia);
|
|
||||||
for(usz y=0;y<h;y++) for(usz x=0;x<w;x++) p.a[x*h+y] = inc(xp[xi++]); // TODO inc afterwards, but don't when there's a method of freeing a HArr without freeing its elements
|
|
||||||
NOGC_E;
|
|
||||||
|
|
||||||
usz* rsh = arr_shAlloc((Arr*)p.c, xr);
|
|
||||||
if (xr==2) {
|
|
||||||
rsh[0] = w;
|
|
||||||
rsh[1] = h;
|
|
||||||
} else {
|
|
||||||
shcpy(rsh, xsh+1, xr-1);
|
|
||||||
rsh[xr-1] = h;
|
|
||||||
}
|
|
||||||
decG(x); return qWithFill(p.b, xf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
usz* rsh = arr_shAlloc(r, xr);
|
|
||||||
if (xr==2) {
|
|
||||||
rsh[0] = w;
|
|
||||||
rsh[1] = h;
|
|
||||||
} else {
|
|
||||||
shcpy(rsh, xsh+1, xr-1);
|
|
||||||
rsh[xr-1] = h;
|
|
||||||
}
|
|
||||||
decG(x); return taga(toBit? (Arr*)cpyBitArr(taga(r)) : r);
|
|
||||||
}
|
|
||||||
B transp_c2(B t, B w, B x) { return c2rt(transp, w, x); }
|
|
||||||
|
|
||||||
B transp_im(B t, B x) {
|
|
||||||
if (isAtm(x)) thrM("⍉⁼: 𝕩 must not be an atom");
|
|
||||||
if (RNK(x)<=2) return transp_c1(t, x);
|
|
||||||
return def_fn_im(bi_transp, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
B pick_uc1(B t, B o, B x) { // TODO do in-place like pick_ucw; maybe just call it?
|
B pick_uc1(B t, B o, B x) { // TODO do in-place like pick_ucw; maybe just call it?
|
||||||
if (isAtm(x) || IA(x)==0) return def_fn_uc1(t, o, x);
|
if (isAtm(x) || IA(x)==0) return def_fn_uc1(t, o, x);
|
||||||
@ -1516,7 +1362,6 @@ B shape_uc1(B t, B o, B x) {
|
|||||||
|
|
||||||
B select_ucw(B t, B o, B w, B x);
|
B select_ucw(B t, B o, B w, B x);
|
||||||
|
|
||||||
B transp_uc1(B t, B o, B x) { return transp_im(m_f64(0), c1(o, transp_c1(t, x))); }
|
|
||||||
B reverse_uc1(B t, B o, B x) { return reverse_c1(m_f64(0), c1(o, reverse_c1(t, x))); }
|
B reverse_uc1(B t, B o, B x) { return reverse_c1(m_f64(0), c1(o, reverse_c1(t, x))); }
|
||||||
|
|
||||||
B reverse_ix(B t, B w, B x) {
|
B reverse_ix(B t, B w, B x) {
|
||||||
@ -1547,8 +1392,6 @@ void sfns_init(void) {
|
|||||||
c(BFn,bi_pick)->ucw = pick_ucw;
|
c(BFn,bi_pick)->ucw = pick_ucw;
|
||||||
c(BFn,bi_select)->ucw = select_ucw; // TODO move to new init fn
|
c(BFn,bi_select)->ucw = select_ucw; // TODO move to new init fn
|
||||||
c(BFn,bi_shape)->uc1 = shape_uc1;
|
c(BFn,bi_shape)->uc1 = shape_uc1;
|
||||||
c(BFn,bi_transp)->uc1 = transp_uc1;
|
|
||||||
c(BFn,bi_transp)->im = transp_im;
|
|
||||||
c(BFn,bi_take)->ucw = take_ucw;
|
c(BFn,bi_take)->ucw = take_ucw;
|
||||||
c(BFn,bi_drop)->ucw = drop_ucw;
|
c(BFn,bi_drop)->ucw = drop_ucw;
|
||||||
c(BFn,bi_lt)->im = enclose_im;
|
c(BFn,bi_lt)->im = enclose_im;
|
||||||
|
|||||||
165
src/builtins/transpose.c
Normal file
165
src/builtins/transpose.c
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
#include "../core.h"
|
||||||
|
#include "../utils/each.h"
|
||||||
|
#include "../utils/talloc.h"
|
||||||
|
#include "../builtins.h"
|
||||||
|
|
||||||
|
#ifdef __BMI2__
|
||||||
|
#include <immintrin.h>
|
||||||
|
#if USE_VALGRIND
|
||||||
|
#define _pdep_u64 vg_pdep_u64
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SINGELI_X86_64
|
||||||
|
static NOINLINE void base_transpose_i16(i16* rp, i16* xp, u64 w, u64 h, u64 xo, u64 ro) { PLAINLOOP for(usz y=0;y<h;y++) NOVECTORIZE for(usz x=0;x<w;x++) rp[x*ro+y] = xp[y*xo+x]; }
|
||||||
|
static NOINLINE void base_transpose_i32(i32* rp, i32* xp, u64 w, u64 h, u64 xo, u64 ro) { PLAINLOOP for(usz y=0;y<h;y++) NOVECTORIZE for(usz x=0;x<w;x++) rp[x*ro+y] = xp[y*xo+x]; }
|
||||||
|
static NOINLINE void base_transpose_i64(i64* rp, i64* xp, u64 w, u64 h, u64 xo, u64 ro) { PLAINLOOP for(usz y=0;y<h;y++) NOVECTORIZE for(usz x=0;x<w;x++) rp[x*ro+y] = xp[y*xo+x]; }
|
||||||
|
#define SINGELI_FILE transpose
|
||||||
|
#include "../utils/includeSingeli.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern B rt_transp;
|
||||||
|
B transp_c1(B t, B x) {
|
||||||
|
if (RARE(isAtm(x))) return m_atomUnit(x);
|
||||||
|
ur xr = RNK(x);
|
||||||
|
if (xr<=1) return x;
|
||||||
|
|
||||||
|
usz ia = IA(x);
|
||||||
|
usz* xsh = SH(x);
|
||||||
|
usz h = xsh[0];
|
||||||
|
if (ia==0 || h==1) {
|
||||||
|
no_reorder:;
|
||||||
|
Arr* r = cpyWithShape(x);
|
||||||
|
ShArr* sh = m_shArr(xr);
|
||||||
|
shcpy(sh->a, xsh+1, xr-1);
|
||||||
|
sh->a[xr-1] = h;
|
||||||
|
arr_shReplace(r, xr, sh);
|
||||||
|
return taga(r);
|
||||||
|
}
|
||||||
|
usz w = xsh[1] * shProd(xsh, 2, xr);
|
||||||
|
if (w==1) goto no_reorder;
|
||||||
|
|
||||||
|
Arr* r;
|
||||||
|
usz xi = 0;
|
||||||
|
u8 xe = TI(x,elType);
|
||||||
|
bool toBit = false;
|
||||||
|
if (h==2) {
|
||||||
|
if (xe==el_B) {
|
||||||
|
B* xp = TO_BPTR(x);
|
||||||
|
B* x0 = xp; B* x1 = x0+w;
|
||||||
|
HArr_p rp = m_harrUp(ia);
|
||||||
|
for (usz i=0; i<w; i++) { rp.a[i*2] = inc(x0[i]); rp.a[i*2+1] = inc(x1[i]); }
|
||||||
|
NOGC_E;
|
||||||
|
r = (Arr*) rp.c;
|
||||||
|
} else {
|
||||||
|
#ifndef __BMI2__
|
||||||
|
if (xe==el_bit) { x = taga(cpyI8Arr(x)); xsh=SH(x); xe=el_i8; toBit=true; }
|
||||||
|
void* rp = m_tyarrp(&r,elWidth(xe),ia,el2t(xe));
|
||||||
|
#else
|
||||||
|
void* rp = m_tyarrlbp(&r,elWidthLogBits(xe),ia,el2t(xe));
|
||||||
|
#endif
|
||||||
|
void* xp = tyany_ptr(x);
|
||||||
|
switch(xe) { default: UD;
|
||||||
|
#ifdef __BMI2__
|
||||||
|
case el_bit:;
|
||||||
|
u32* x0 = xp;
|
||||||
|
Arr* x1o = TI(x,slice)(inc(x),w,w);
|
||||||
|
u32* x1 = (u32*) ((TyArr*)x1o)->a;
|
||||||
|
for (usz i=0; i<BIT_N(ia); i++) ((u64*)rp)[i] = _pdep_u64(x0[i], 0x5555555555555555) | _pdep_u64(x1[i], 0xAAAAAAAAAAAAAAAA);
|
||||||
|
mm_free((Value*)x1o);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case el_i8: case el_c8: { u8* x0=xp; u8* x1=x0+w; for (usz i=0; i<w; i++) { ((u8* )rp)[i*2] = x0[i]; ((u8* )rp)[i*2+1] = x1[i]; } } break;
|
||||||
|
case el_i16:case el_c16: { u16* x0=xp; u16* x1=x0+w; for (usz i=0; i<w; i++) { ((u16*)rp)[i*2] = x0[i]; ((u16*)rp)[i*2+1] = x1[i]; } } break;
|
||||||
|
case el_i32:case el_c32: { u32* x0=xp; u32* x1=x0+w; for (usz i=0; i<w; i++) { ((u32*)rp)[i*2] = x0[i]; ((u32*)rp)[i*2+1] = x1[i]; } } break;
|
||||||
|
case el_f64: { u64* x0=xp; u64* x1=x0+w; for (usz i=0; i<w; i++) { ((u64*)rp)[i*2] = x0[i]; ((u64*)rp)[i*2+1] = x1[i]; } } break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (w==2 && xe!=el_B) {
|
||||||
|
#ifndef __BMI2__
|
||||||
|
if (xe==el_bit) { x = taga(cpyI8Arr(x)); xsh=SH(x); xe=el_i8; toBit=true; }
|
||||||
|
#endif
|
||||||
|
void* rp = m_tyarrlbp(&r,elWidthLogBits(xe),ia,el2t(xe));
|
||||||
|
void* xp = tyany_ptr(x);
|
||||||
|
switch(xe) { default: UD;
|
||||||
|
#if __BMI2__
|
||||||
|
case el_bit:;
|
||||||
|
u64* r0 = rp; TALLOC(u64, r1, BIT_N(h));
|
||||||
|
for (usz i=0; i<BIT_N(ia); i++) {
|
||||||
|
u64 v = ((u64*)xp)[i];
|
||||||
|
((u32*)r0)[i] = _pext_u64(v, 0x5555555555555555);
|
||||||
|
((u32*)r1)[i] = _pext_u64(v, 0xAAAAAAAAAAAAAAAA);
|
||||||
|
}
|
||||||
|
bit_cpy(r0, h, r1, 0, h);
|
||||||
|
TFREE(r1);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case el_i8: case el_c8: { u8* r0=rp; u8* r1=r0+h; for (usz i=0; i<h; i++) { r0[i] = ((u8* )xp)[i*2]; r1[i] = ((u8* )xp)[i*2+1]; } } break;
|
||||||
|
case el_i16:case el_c16: { u16* r0=rp; u16* r1=r0+h; for (usz i=0; i<h; i++) { r0[i] = ((u16*)xp)[i*2]; r1[i] = ((u16*)xp)[i*2+1]; } } break;
|
||||||
|
case el_i32:case el_c32: { u32* r0=rp; u32* r1=r0+h; for (usz i=0; i<h; i++) { r0[i] = ((u32*)xp)[i*2]; r1[i] = ((u32*)xp)[i*2+1]; } } break;
|
||||||
|
case el_f64: { f64* r0=rp; f64* r1=r0+h; for (usz i=0; i<h; i++) { r0[i] = ((f64*)xp)[i*2]; r1[i] = ((f64*)xp)[i*2+1]; } } break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch(xe) { default: UD;
|
||||||
|
case el_bit: x = taga(cpyI8Arr(x)); xsh=SH(x); xe=el_i8; toBit=true; // fallthough
|
||||||
|
case el_i8: case el_c8: { u8* xp=tyany_ptr(x); u8* rp = m_tyarrp(&r,1,ia,el2t(xe)); PLAINLOOP for(usz y=0;y<h;y++) NOVECTORIZE for(usz x=0;x<w;x++) rp[x*h+y] = xp[xi++]; break; }
|
||||||
|
case el_i16:case el_c16:
|
||||||
|
#if SINGELI_X86_64
|
||||||
|
if (w>=8 && h>=8) { u16* xp=tyany_ptr(x); u16* rp = m_tyarrp(&r,4,ia,el2t(xe)); simd_transpose_i16(rp, xp, w, h); break; }
|
||||||
|
#endif
|
||||||
|
{ u16* xp=tyany_ptr(x); u16* rp = m_tyarrp(&r,2,ia,el2t(xe)); PLAINLOOP for(usz y=0;y<h;y++) NOVECTORIZE for(usz x=0;x<w;x++) rp[x*h+y] = xp[xi++]; break; }
|
||||||
|
case el_i32:case el_c32:
|
||||||
|
#if SINGELI_X86_64
|
||||||
|
if (w>=8 && h>=8) { u32* xp=tyany_ptr(x); u32* rp = m_tyarrp(&r,4,ia,el2t(xe)); simd_transpose_i32(rp, xp, w, h); break; }
|
||||||
|
#endif
|
||||||
|
{ u32* xp=tyany_ptr(x); u32* rp = m_tyarrp(&r,4,ia,el2t(xe)); PLAINLOOP for(usz y=0;y<h;y++) NOVECTORIZE for(usz x=0;x<w;x++) rp[x*h+y] = xp[xi++]; break; }
|
||||||
|
case el_f64:
|
||||||
|
#if SINGELI_X86_64
|
||||||
|
if (w>=4 && h>=4) { f64* xp=f64any_ptr(x); f64* rp; r=m_f64arrp(&rp,ia); simd_transpose_i64(rp, xp, w, h); break; }
|
||||||
|
#endif
|
||||||
|
{ f64* xp=f64any_ptr(x); f64* rp; r=m_f64arrp(&rp,ia); PLAINLOOP for(usz y=0;y<h;y++) NOVECTORIZE for(usz x=0;x<w;x++) rp[x*h+y] = xp[xi++]; break; }
|
||||||
|
case el_B: { // can't be bothered to implement a bitarr transpose
|
||||||
|
B xf = getFillR(x);
|
||||||
|
B* xp = TO_BPTR(x);
|
||||||
|
|
||||||
|
HArr_p p = m_harrUp(ia);
|
||||||
|
for(usz y=0;y<h;y++) for(usz x=0;x<w;x++) p.a[x*h+y] = inc(xp[xi++]); // TODO inc afterwards, but don't when there's a method of freeing a HArr without freeing its elements
|
||||||
|
NOGC_E;
|
||||||
|
|
||||||
|
usz* rsh = arr_shAlloc((Arr*)p.c, xr);
|
||||||
|
if (xr==2) {
|
||||||
|
rsh[0] = w;
|
||||||
|
rsh[1] = h;
|
||||||
|
} else {
|
||||||
|
shcpy(rsh, xsh+1, xr-1);
|
||||||
|
rsh[xr-1] = h;
|
||||||
|
}
|
||||||
|
decG(x); return qWithFill(p.b, xf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usz* rsh = arr_shAlloc(r, xr);
|
||||||
|
if (xr==2) {
|
||||||
|
rsh[0] = w;
|
||||||
|
rsh[1] = h;
|
||||||
|
} else {
|
||||||
|
shcpy(rsh, xsh+1, xr-1);
|
||||||
|
rsh[xr-1] = h;
|
||||||
|
}
|
||||||
|
decG(x); return taga(toBit? (Arr*)cpyBitArr(taga(r)) : r);
|
||||||
|
}
|
||||||
|
B transp_c2(B t, B w, B x) { return c2rt(transp, w, x); }
|
||||||
|
|
||||||
|
B transp_im(B t, B x) {
|
||||||
|
if (isAtm(x)) thrM("⍉⁼: 𝕩 must not be an atom");
|
||||||
|
if (RNK(x)<=2) return transp_c1(t, x);
|
||||||
|
return def_fn_im(bi_transp, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
B transp_uc1(B t, B o, B x) { return transp_im(m_f64(0), c1(o, transp_c1(t, x))); }
|
||||||
|
|
||||||
|
void transp_init(void) {
|
||||||
|
c(BFn,bi_transp)->uc1 = transp_uc1;
|
||||||
|
c(BFn,bi_transp)->im = transp_im;
|
||||||
|
}
|
||||||
@ -8,7 +8,7 @@
|
|||||||
#define PRECOMPILED_FILE1(X) PRECOMPILED_FILE0(X)
|
#define PRECOMPILED_FILE1(X) PRECOMPILED_FILE0(X)
|
||||||
#define PRECOMPILED_FILE(END) PRECOMPILED_FILE1(../build/BYTECODE_DIR/gen/END)
|
#define PRECOMPILED_FILE(END) PRECOMPILED_FILE1(../build/BYTECODE_DIR/gen/END)
|
||||||
|
|
||||||
#define FOR_INIT(F) F(base) F(harr) F(mutF) F(cmpA) F(fillarr) F(tyarr) F(hash) F(sfns) F(fns) F(arith) F(md1) F(md2) F(derv) F(comp) F(rtWrap) F(ns) F(nfn) F(sysfn) F(inverse) F(slash) F(search) F(load) F(sysfnPost) F(dervPost) F(ryu) F(ffi) F(mmap) F(typesFinished)
|
#define FOR_INIT(F) F(base) F(harr) F(mutF) F(cmpA) F(fillarr) F(tyarr) F(hash) F(sfns) F(fns) F(arith) F(md1) F(md2) F(derv) F(comp) F(rtWrap) F(ns) F(nfn) F(sysfn) F(inverse) F(slash) F(search) F(transp) F(load) F(sysfnPost) F(dervPost) F(ryu) F(ffi) F(mmap) F(typesFinished)
|
||||||
#define F(X) NOINLINE void X##_init(void);
|
#define F(X) NOINLINE void X##_init(void);
|
||||||
FOR_INIT(F)
|
FOR_INIT(F)
|
||||||
#undef F
|
#undef F
|
||||||
|
|||||||
@ -25,6 +25,7 @@
|
|||||||
#include "../builtins/sort.c"
|
#include "../builtins/sort.c"
|
||||||
#include "../builtins/search.c"
|
#include "../builtins/search.c"
|
||||||
#include "../builtins/selfsearch.c"
|
#include "../builtins/selfsearch.c"
|
||||||
|
#include "../builtins/transpose.c"
|
||||||
#include "../builtins/fold.c"
|
#include "../builtins/fold.c"
|
||||||
#include "../builtins/scan.c"
|
#include "../builtins/scan.c"
|
||||||
#include "../builtins/arithm.c"
|
#include "../builtins/arithm.c"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user