├── install ├── bin └── README ├── src ├── Makefile ├── lua │ ├── src │ │ ├── complex.c │ │ ├── conf.h │ │ ├── ndarray.h │ │ ├── init.c │ │ ├── luand.h │ │ ├── dtype.c │ │ ├── luand.c │ │ └── ndarray.c │ └── include │ │ ├── lualib.h │ │ ├── lauxlib.h │ │ └── lua.h ├── init.lua ├── core │ ├── arraydims.h │ ├── LNHalf.h │ ├── converts.h │ ├── generic │ │ ├── arraymath.h │ │ ├── vector.h │ │ ├── vector.c │ │ └── arraymath.c │ ├── arraycast.h │ ├── LNGenerateInt8Type.h │ ├── LNGenerateInt16Type.h │ ├── LNGenerateInt32Type.h │ ├── LNGenerateInt64Type.h │ ├── LNGenerateUInt8Type.h │ ├── LNGenerateFloat32Type.h │ ├── LNGenerateFloat64Type.h │ ├── LNGenerateUInt16Type.h │ ├── LNGenerateUInt32Type.h │ ├── LNGenerateUInt64Type.h │ ├── LNGenerateComplex64Type.h │ ├── LNGenerateComplex128Type.h │ ├── LNGenerateAllTypes.h │ ├── arrayindex.h │ ├── utils.h │ ├── vector.c │ ├── utils.c │ ├── buffer.h │ ├── vector.h │ ├── arraymath.h │ ├── arrayinis.h │ ├── simd │ │ ├── AVX.h │ │ ├── SSE.h │ │ ├── AVX512.h │ │ ├── AVX.c │ │ ├── AVX512.c │ │ └── SSE.c │ ├── luandarray.h │ ├── error.h │ ├── arrayobj.h │ ├── arraydtype.h │ ├── error.c │ ├── arrayindex.c │ ├── arraytypes.h │ ├── arraycast.c │ ├── converts.c │ ├── arrayobj.c │ ├── buffer.c │ ├── arrayaplly.h │ ├── arrayinis.c │ ├── arraymath.c │ └── arraydtype.c └── luajit │ ├── dtype.lua │ ├── complex.lua │ └── defs.lua ├── Makefile ├── .vscode └── settings.json ├── README.md ├── rockspecs └── luandarray-1.1.0-0.rockspec ├── LICENSE ├── detect_simd.c ├── docs └── dtypes.md ├── ospp.lua └── install.lua /install: -------------------------------------------------------------------------------- 1 | #! /bin/luajit 2 | dofile("install.lua") 3 | -------------------------------------------------------------------------------- /bin/README: -------------------------------------------------------------------------------- 1 | binaries generated by the installed will be shown here. 2 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -shared -msse2 core/*.c core/simd/*.c -o luajit/core.dll -------------------------------------------------------------------------------- /src/lua/src/complex.c: -------------------------------------------------------------------------------- 1 | // #include 2 | 3 | // int ln_complex_init(lua_State *L){ 4 | // return 0; 5 | // } 6 | -------------------------------------------------------------------------------- /src/init.lua: -------------------------------------------------------------------------------- 1 | if jit then 2 | return require "luandarray.luajit.init" 3 | else 4 | error "luandarray does not has support for Lua." 5 | end -------------------------------------------------------------------------------- /src/core/arraydims.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_ARRAYDIMS_H_ 2 | #define LUANDARRAY_SRC_CORE_ARRAYDIMS_H_ 3 | 4 | #include "arrayobj.h" 5 | 6 | Ndarray *LNArray_ExpandDims(const Ndarray *arr, const size_t *dims, size_t ndims); 7 | 8 | #endif -------------------------------------------------------------------------------- /src/core/LNHalf.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_LNHALF_H_ 2 | #define LUANDARRAY_SRC_CORE_LNHALF_H_ 3 | 4 | #include 5 | 6 | typedef int16_t LNHalf_t; 7 | 8 | LNHalf_t LN_float2half(float x); 9 | float LN_half2float(LNHalf_t x); 10 | 11 | #endif -------------------------------------------------------------------------------- /src/lua/src/conf.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_LUA_SRC_CONF_H_ 2 | #define LUANDARRAY_SRC_LUA_SRC_CONF_H_ 3 | 4 | #define LN_NDARRAY_MT "luandarray.ndarray" 5 | #define LN_DTYPE_MT "luandarray.dtype" 6 | #define LN_DEFAULTTYPE_KEY "luandarray.default_type" 7 | 8 | #endif /* LUANDARRAY_SRC_LUA_SRC_CONF_H_ */ -------------------------------------------------------------------------------- /src/core/converts.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_CONVERTS_H_ 2 | #define LUANDARRAY_SRC_CORE_CONVERTS_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "arrayobj.h" 8 | #include "buffer.h" 9 | 10 | char *LNArray_toString_(LNBuffer *b, Ndarray *arr); 11 | char *LNArray_toString(Ndarray *arr, const char *prefix, const char *sufix); 12 | void LNArray_Print(Ndarray *arr, const char *prefix, const char *sufix); 13 | 14 | #define LNArray_SPrint(arr) LNArray_Print(arr, "array(", ")") 15 | 16 | #endif -------------------------------------------------------------------------------- /src/core/generic/arraymath.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #define LN_GENERIC_FILE "generic/arraymath.h" 3 | #else 4 | 5 | #include "../arraytypes.h" 6 | 7 | Ndarray *LNMath_(SumAxis)(Ndarray *arr, long long axis); 8 | Ndarray *LNMath_(MaxAxis)(Ndarray *arr, long long axis); 9 | Ndarray *LNMath_(MinAxis)(Ndarray *arr, long long axis); 10 | 11 | Ndarray *LNMath_(Sum)(Ndarray *arr); 12 | Ndarray *LNMath_(Max)(Ndarray *arr); 13 | Ndarray *LNMath_(Min)(Ndarray *arr); 14 | 15 | #endif /* LUANDARRAY_SRC_CORE_GENERIC_ARRAYMATH_H_ */ -------------------------------------------------------------------------------- /src/lua/src/ndarray.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_LUA_SRC_NDARRAY_H_ 2 | #define LUANDARRAY_SRC_LUA_SRC_NDARRAY_H_ 3 | 4 | #include 5 | #include 6 | 7 | void ln_array_init(lua_State *L); 8 | 9 | int ln_array_zeros(lua_State *L); 10 | int ln_array_ones(lua_State *L); 11 | int ln_array_arange(lua_State *L); 12 | int ln_array_new(lua_State *L); 13 | 14 | int ln_array__gc(lua_State *L); 15 | int ln_array__tostring(lua_State *L); 16 | int ln_array__add(lua_State *L); 17 | 18 | #endif /*LUANDARRAY_SRC_LUA_SRC_NDARRAY_H_*/ 19 | -------------------------------------------------------------------------------- /src/core/arraycast.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_ARRAYCAST_H_ 2 | #define LUANDARRAY_SRC_CORE_ARRAYCAST_H_ 3 | 4 | #include "arrayobj.h" 5 | 6 | typedef enum LNCast_t{ 7 | LNCAST_UNSAFE=0, 8 | LNCAST_SAFE 9 | } LNCast_t; 10 | 11 | void LNArray_CastTo_(Ndarray *out, const Ndarray *arr, const LNTypeDescr *newtype, LNCast_t casttype); 12 | Ndarray *LNArray_CastTo(const Ndarray *arr, const LNTypeDescr *newtype, LNCast_t casttype); 13 | int LNArray_CanCast(const LNTypeDescr *from, const LNTypeDescr *to, LNCast_t casttype); 14 | 15 | #endif -------------------------------------------------------------------------------- /src/core/LNGenerateInt8Type.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #error "define LN_GENERIC_FILE." 3 | #endif 4 | 5 | #include 6 | 7 | #include "arraydtype.h" 8 | 9 | #define real int8_t 10 | #define Real Int8 11 | #define RealDType LNDType_GetFromID(LN_INT8) 12 | #define LN_REAL_IS_INT8 13 | #define LN_REAL_IS_INTEGER 14 | #line 1 LN_GENERIC_FILE 15 | #include LN_GENERIC_FILE 16 | #undef real 17 | #undef Real 18 | #undef RealDType 19 | #undef LN_REAL_IS_INT8 20 | #undef LN_REAL_IS_INTEGER 21 | #ifndef LN_GENERATE_MANY_TYPES 22 | #undef LN_GENERIC_FILE 23 | #endif 24 | -------------------------------------------------------------------------------- /src/core/LNGenerateInt16Type.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #error "define LN_GENERIC_FILE." 3 | #endif 4 | 5 | #include 6 | 7 | #include "arraydtype.h" 8 | 9 | #define real int16_t 10 | #define Real Int16 11 | #define RealDType LNDType_GetFromID(LN_INT16) 12 | #define LN_REAL_IS_INT16 13 | #define LN_REAL_IS_INTEGER 14 | #line 1 LN_GENERIC_FILE 15 | #include LN_GENERIC_FILE 16 | #undef real 17 | #undef Real 18 | #undef RealDType 19 | #undef LN_REAL_IS_INT16 20 | #undef LN_REAL_IS_INTEGER 21 | #ifndef LN_GENERATE_MANY_TYPES 22 | #undef LN_GENERIC_FILE 23 | #endif 24 | -------------------------------------------------------------------------------- /src/core/LNGenerateInt32Type.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #error "define LN_GENERIC_FILE." 3 | #endif 4 | 5 | #include 6 | 7 | #include "arraydtype.h" 8 | 9 | #define real int32_t 10 | #define Real Int32 11 | #define RealDType LNDType_GetFromID(LN_INT32) 12 | #define LN_REAL_IS_INT32 13 | #define LN_REAL_IS_INTEGER 14 | #line 1 LN_GENERIC_FILE 15 | #include LN_GENERIC_FILE 16 | #undef real 17 | #undef Real 18 | #undef RealDType 19 | #undef LN_REAL_IS_INT32 20 | #undef LN_REAL_IS_INTEGER 21 | #ifndef LN_GENERATE_MANY_TYPES 22 | #undef LN_GENERIC_FILE 23 | #endif 24 | -------------------------------------------------------------------------------- /src/core/LNGenerateInt64Type.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #error "define LN_GENERIC_FILE." 3 | #endif 4 | 5 | #include 6 | 7 | #include "arraydtype.h" 8 | 9 | #define real int64_t 10 | #define Real Int64 11 | #define RealDType LNDType_GetFromID(LN_INT64) 12 | #define LN_REAL_IS_INT64 13 | #define LN_REAL_IS_INTEGER 14 | #line 1 LN_GENERIC_FILE 15 | #include LN_GENERIC_FILE 16 | #undef real 17 | #undef Real 18 | #undef RealDType 19 | #undef LN_REAL_IS_INT64 20 | #undef LN_REAL_IS_INTEGER 21 | #ifndef LN_GENERATE_MANY_TYPES 22 | #undef LN_GENERIC_FILE 23 | #endif 24 | -------------------------------------------------------------------------------- /src/core/LNGenerateUInt8Type.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #error "define LN_GENERIC_FILE." 3 | #endif 4 | 5 | #include 6 | 7 | #include "arraydtype.h" 8 | 9 | #define real uint8_t 10 | #define Real UInt8 11 | #define RealDType LNDType_GetFromID(LN_UINT8) 12 | #define LN_REAL_IS_UINT8 13 | #define LN_REAL_IS_INTEGER 14 | #line 1 LN_GENERIC_FILE 15 | #include LN_GENERIC_FILE 16 | #undef real 17 | #undef Real 18 | #undef RealDType 19 | #undef LN_REAL_IS_UINT8 20 | #undef LN_REAL_IS_INTEGER 21 | #ifndef LN_GENERATE_MANY_TYPES 22 | #undef LN_GENERIC_FILE 23 | #endif 24 | -------------------------------------------------------------------------------- /src/core/LNGenerateFloat32Type.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #error "define LN_GENERIC_FILE." 3 | #endif 4 | 5 | #include 6 | 7 | #include "arraydtype.h" 8 | 9 | #define real float32_t 10 | #define Real Float32 11 | #define RealDType LNDType_GetFromID(LN_FLOAT32) 12 | #define LN_REAL_IS_FLOAT32 13 | #define LN_REAL_IS_FLOAT 14 | #line 1 LN_GENERIC_FILE 15 | #include LN_GENERIC_FILE 16 | #undef real 17 | #undef Real 18 | #undef RealDType 19 | #undef LN_REAL_IS_FLOAT32 20 | #undef LN_REAL_IS_FLOAT 21 | #ifndef LN_GENERATE_MANY_TYPES 22 | #undef LN_GENERIC_FILE 23 | #endif 24 | -------------------------------------------------------------------------------- /src/core/LNGenerateFloat64Type.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #error "define LN_GENERIC_FILE." 3 | #endif 4 | 5 | #include 6 | 7 | #include "arraydtype.h" 8 | 9 | #define real float64_t 10 | #define Real Float64 11 | #define RealDType LNDType_GetFromID(LN_FLOAT64) 12 | #define LN_REAL_IS_FLOAT64 13 | #define LN_REAL_IS_FLOAT 14 | #line 1 LN_GENERIC_FILE 15 | #include LN_GENERIC_FILE 16 | #undef real 17 | #undef Real 18 | #undef RealDType 19 | #undef LN_REAL_IS_FLOAT64 20 | #undef LN_REAL_IS_FLOAT 21 | #ifndef LN_GENERATE_MANY_TYPES 22 | #undef LN_GENERIC_FILE 23 | #endif 24 | -------------------------------------------------------------------------------- /src/core/LNGenerateUInt16Type.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #error "define LN_GENERIC_FILE." 3 | #endif 4 | 5 | #include 6 | 7 | #include "arraydtype.h" 8 | 9 | #define real uint16_t 10 | #define Real UInt16 11 | #define RealDType LNDType_GetFromID(LN_UINT16) 12 | #define LN_REAL_IS_UINT16 13 | #define LN_REAL_IS_INTEGER 14 | #line 1 LN_GENERIC_FILE 15 | #include LN_GENERIC_FILE 16 | #undef real 17 | #undef Real 18 | #undef RealDType 19 | #undef LN_REAL_IS_UINT16 20 | #undef LN_REAL_IS_INTEGER 21 | #ifndef LN_GENERATE_MANY_TYPES 22 | #undef LN_GENERIC_FILE 23 | #endif 24 | -------------------------------------------------------------------------------- /src/core/LNGenerateUInt32Type.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #error "define LN_GENERIC_FILE." 3 | #endif 4 | 5 | #include 6 | 7 | #include "arraydtype.h" 8 | 9 | #define real uint32_t 10 | #define Real UInt32 11 | #define RealDType LNDType_GetFromID(LN_UINT32) 12 | #define LN_REAL_IS_UINT32 13 | #define LN_REAL_IS_INTEGER 14 | #line 1 LN_GENERIC_FILE 15 | #include LN_GENERIC_FILE 16 | #undef real 17 | #undef Real 18 | #undef RealDType 19 | #undef LN_REAL_IS_UINT32 20 | #undef LN_REAL_IS_INTEGER 21 | #ifndef LN_GENERATE_MANY_TYPES 22 | #undef LN_GENERIC_FILE 23 | #endif 24 | -------------------------------------------------------------------------------- /src/core/LNGenerateUInt64Type.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #error "define LN_GENERIC_FILE." 3 | #endif 4 | 5 | #include 6 | 7 | #include "arraydtype.h" 8 | 9 | #define real uint64_t 10 | #define Real UInt64 11 | #define RealDType LNDType_GetFromID(LN_UINT64) 12 | #define LN_REAL_IS_UINT64 13 | #define LN_REAL_IS_INTEGER 14 | #line 1 LN_GENERIC_FILE 15 | #include LN_GENERIC_FILE 16 | #undef real 17 | #undef Real 18 | #undef RealDType 19 | #undef LN_REAL_IS_UINT64 20 | #undef LN_REAL_IS_INTEGER 21 | #ifndef LN_GENERATE_MANY_TYPES 22 | #undef LN_GENERIC_FILE 23 | #endif 24 | -------------------------------------------------------------------------------- /src/core/LNGenerateComplex64Type.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #error "define LN_GENERIC_FILE." 3 | #endif 4 | 5 | #include 6 | 7 | #include "arraydtype.h" 8 | 9 | #define real complex64_t 10 | #define Real Complex64 11 | #define RealDType LNDType_GetFromID(LN_COMPLEX64) 12 | #define LN_REAL_IS_COMPLEX64 13 | #define LN_REAL_IS_COMPLEX 14 | #line 1 LN_GENERIC_FILE 15 | #include LN_GENERIC_FILE 16 | #undef real 17 | #undef Real 18 | #undef RealDType 19 | #undef LN_REAL_IS_COMPLEX64 20 | #undef LN_REAL_IS_COMPLEX 21 | #ifndef LN_GENERATE_MANY_TYPES 22 | #undef LN_GENERIC_FILE 23 | #endif 24 | -------------------------------------------------------------------------------- /src/core/LNGenerateComplex128Type.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #error "define LN_GENERIC_FILE." 3 | #endif 4 | 5 | #include 6 | 7 | #include "arraydtype.h" 8 | 9 | #define real complex128_t 10 | #define Real Complex128 11 | #define RealDType LNDType_GetFromID(LN_COMPLEX128) 12 | #define LN_REAL_IS_COMPLEX128 13 | #define LN_REAL_IS_COMPLEX 14 | #line 1 LN_GENERIC_FILE 15 | #include LN_GENERIC_FILE 16 | #undef real 17 | #undef Real 18 | #undef RealDType 19 | #undef LN_REAL_IS_COMPLEX128 20 | #undef LN_REAL_IS_COMPLEX 21 | #ifndef LN_GENERATE_MANY_TYPES 22 | #undef LN_GENERIC_FILE 23 | #endif 24 | -------------------------------------------------------------------------------- /src/core/LNGenerateAllTypes.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #error "LN_GENERIC_FILE not defined" 3 | #endif 4 | 5 | #define LN_GENERATE_MANY_TYPES 6 | 7 | #include "LNGenerateInt8Type.h" 8 | #include "LNGenerateInt16Type.h" 9 | #include "LNGenerateInt32Type.h" 10 | #include "LNGenerateInt64Type.h" 11 | 12 | #include "LNGenerateUInt8Type.h" 13 | #include "LNGenerateUInt16Type.h" 14 | #include "LNGenerateUInt32Type.h" 15 | #include "LNGenerateUInt64Type.h" 16 | 17 | #include "LNGenerateFloat32Type.h" 18 | #include "LNGenerateFloat64Type.h" 19 | 20 | #include "LNGenerateComplex64Type.h" 21 | #include "LNGenerateComplex128Type.h" 22 | 23 | #undef LN_GENERIC_FILE 24 | #undef LN_GENERATE_MANY_TYPES 25 | -------------------------------------------------------------------------------- /src/core/generic/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #define LN_GENERIC_FILE "generic/vector.h" 3 | #else 4 | 5 | real *LNVector_(Fill)(real *v, real fill_value, size_t n); 6 | real *LNVector_(Add)(real *z, const real *a, const real *b, size_t n); 7 | real *LNVector_(Sub)(real *z, const real *a, const real *b, size_t n); 8 | real *LNVector_(Mul)(real *z, const real *a, const real *b, size_t n); 9 | real *LNVector_(Div)(real *z, const real *a, const real *b, size_t n); 10 | #if defined(LN_REAL_IS_INTEGER) 11 | real *LNVector_(Range)(real *z, long long start, long long stop, long long step); 12 | #else 13 | real *LNVector_(Range)(real *z, double start, double stop, double step); 14 | #endif 15 | 16 | #endif -------------------------------------------------------------------------------- /src/core/arrayindex.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_ARRAYINDEX_H_ 2 | #define LUANDARRAY_SRC_CORE_ARRAYINDEX_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "arrayobj.h" 8 | 9 | int LNGetIndexStart(); 10 | void LNIndexStartZero(bool_t s); 11 | 12 | Ndarray *LNArray_Index(Ndarray *arr, long long idx); 13 | Ndarray *LNArray_Index_(Ndarray *out, Ndarray *arr, long long idx); 14 | 15 | // Ndarray *LNArray_MultiIndex_(Ndarray *out, Ndarray *arr, size_t *idxs, size_t nidxs); 16 | Ndarray *LNArray_MultiIndex(Ndarray *arr, long long *idxs, size_t nidxs); 17 | 18 | void* LNArray_MultiIndexItem(Ndarray *arr, long long *idxs); 19 | 20 | void LNArray_MapDim(Ndarray *arr, long long dim); 21 | 22 | #endif -------------------------------------------------------------------------------- /src/core/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_UTILS_H_ 2 | #define LUANDARRAY_SRC_CORE_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | #define LN_CONCAT2(a,b) LN_CONCAT2_EXPAND(a,b) 8 | #define LN_CONCAT2_EXPAND(a,b) a##b 9 | 10 | #define LN_CONCAT3(a,b,c) LN_CONCAT3_EXPAND(a,b,c) 11 | #define LN_CONCAT3_EXPAND(a,b,c) a##b##c 12 | 13 | #define LN_CONCAT4(a,b,c,d) LN_CONCAT4_EXPAND(a,b,c,d) 14 | #define LN_CONCAT4_EXPAND(a,b,c,d) a##b##c##d 15 | 16 | #define LN_MAX(x,y) ((x)>(y)) ? (x) : (y) 17 | #define LN_MIN(x,y) ((x)<(y)) ? (x) : (y) 18 | 19 | void *LNMem_alloc(size_t bytes); 20 | void *LNMem_calloc(size_t sz, size_t q); 21 | void *LNMem_realloc(void *ptr, size_t newsize); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/core/vector.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | #include "vector.h" 3 | 4 | #define LNVector_(name) LN_CONCAT4(LN, Real, Vector_, name) 5 | 6 | #include "generic/vector.c" 7 | #include "LNGenerateInt8Type.h" 8 | 9 | #include "generic/vector.c" 10 | #include "LNGenerateInt16Type.h" 11 | 12 | #include "generic/vector.c" 13 | #include "LNGenerateInt32Type.h" 14 | 15 | #include "generic/vector.c" 16 | #include "LNGenerateInt64Type.h" 17 | 18 | #include "generic/vector.c" 19 | #include "LNGenerateFloat32Type.h" 20 | 21 | #include "generic/vector.c" 22 | #include "LNGenerateFloat64Type.h" 23 | 24 | #include "generic/vector.c" 25 | #include "LNGenerateComplex64Type.h" 26 | 27 | #include "generic/vector.c" 28 | #include "LNGenerateComplex128Type.h" 29 | 30 | #undef LNVector_ 31 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(OS), Windows_NT) 2 | COPYCMD := copy 3 | else 4 | COPYCMD := cp 5 | endif 6 | 7 | ifeq ($(LIB_EXTENSION), dll) 8 | EXEC_EXT := exe 9 | else 10 | EXEC_EXT := out 11 | endif 12 | 13 | CODE := 'local res = string.gsub(string.gsub(string.lower(_VERSION), "[ .]", ""), "lua", "") print(res)' 14 | LUA_VERSION = $(shell $(LUA) -e $(CODE)) 15 | LUA_LIB = -llua$(LUA_VERSION) 16 | 17 | ARCH := $(shell $(CC) detect_simd.c -o detect_simd.$(EXEC_EXT)) 18 | ARCH := -m$(shell ./detect_simd) 19 | 20 | ifeq (ARCH, -m) 21 | ARCH := 22 | endif 23 | 24 | all: 25 | $(CC) $(CFLAGS) $(ARCH) -march=native -shared -I$(LUA_INCDIR) -L$(LUA_LIBDIR) multiarray/*.c multiarray/simd/*.c -o core.$(LIB_EXTENSION) $(LUA_LIB) 26 | 27 | install: 28 | $(COPYCMD) core.$(LIB_EXTENSION) "$(ENV_INST_PREFIX)" 29 | -------------------------------------------------------------------------------- /src/core/utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "error.h" 4 | #include "utils.h" 5 | 6 | void *LNMem_alloc(size_t bytes){ 7 | void *block = malloc(bytes); 8 | if(!block){ 9 | LNError_setFString("attemp to allocate %zu bytes", bytes); 10 | } 11 | return block; 12 | } 13 | 14 | void *LNMem_calloc(size_t sz, size_t len){ 15 | void *block = calloc(sz, len); 16 | if(!block){ 17 | LNError_setFString("attemp to allocate %zu bytes", sz * len); 18 | } 19 | return block; 20 | } 21 | 22 | void *LNMem_realloc(void *ptr, size_t newsize){ 23 | if(!ptr) 24 | return LNMem_alloc(newsize); 25 | 26 | void *res = realloc(ptr, newsize); 27 | if(!res) 28 | LNError_setFString("attemp to allocate %zu bytes", newsize); 29 | 30 | return res; 31 | } -------------------------------------------------------------------------------- /src/core/buffer.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LUANDARRAY_CORE_SRC_BUFFER_H_ 3 | #define LUANDARRAY_CORE_SRC_BUFFER_H_ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include"utils.h" 10 | #include"arraydtype.h" 11 | 12 | typedef struct LNBuffer{ 13 | char *buff; 14 | size_t n; 15 | } LNBuffer; 16 | 17 | #define LNBuff_ADDR(b) ((b)->buff) 18 | #define LNBuff_LEN(b) ((b)->n) 19 | 20 | void LNBuff_Init(LNBuffer *b); 21 | void LNBuff_addchar(LNBuffer *b, char chr); 22 | void LNBuff_addlstring(LNBuffer *b, const char *str, size_t l); 23 | void LNBuff_addstring(LNBuffer *b, const char *str); 24 | void LNBuff_addfstring(LNBuffer *b, const char *fmt, ...); 25 | void LNBuff_addtype(LNBuffer *b, const void *data, const LNTypeDescr *dtype); 26 | 27 | #define LNBuff_alloc() (LNBuffer*)LNMem_alloc(sizeof(LNBuffer)) 28 | 29 | #endif -------------------------------------------------------------------------------- /src/core/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_MULTIARRAY_VECTOR_H_ 2 | #define LUANDARRAY_MULTIARRAY_VECTOR_H_ 3 | 4 | #include "utils.h" 5 | 6 | #define LNVector_(name) LN_CONCAT4(LN, Real, Vector_, name) 7 | 8 | #include "generic/vector.h" 9 | #include "LNGenerateInt8Type.h" 10 | 11 | #include "generic/vector.h" 12 | #include "LNGenerateInt16Type.h" 13 | 14 | #include "generic/vector.h" 15 | #include "LNGenerateInt32Type.h" 16 | 17 | #include "generic/vector.h" 18 | #include "LNGenerateInt64Type.h" 19 | 20 | #include "generic/vector.h" 21 | #include "LNGenerateFloat32Type.h" 22 | 23 | #include "generic/vector.h" 24 | #include "LNGenerateFloat64Type.h" 25 | 26 | #include "generic/vector.h" 27 | #include "LNGenerateComplex64Type.h" 28 | 29 | #include "generic/vector.h" 30 | #include "LNGenerateComplex128Type.h" 31 | 32 | #undef LNVector_ 33 | 34 | #endif -------------------------------------------------------------------------------- /src/core/arraymath.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_ARRAYMATH_H_ 2 | #define LUANDARRAY_SRC_CORE_ARRAYMATH_H_ 3 | 4 | #include 5 | #include 6 | 7 | // #include"utils.h" 8 | #include"arrayobj.h" 9 | 10 | 11 | #define LNMath_(name) LN_CONCAT4(LN, Real, Array_, name) 12 | #define LNRealDType LN_CONCAT2(LN, Real) 13 | 14 | #include "generic/arraymath.h" 15 | #include "LNGenerateAllTypes.h" 16 | 17 | #undef LNMath_ 18 | #undef LNRealDType 19 | 20 | void LNArray_BroadcastTo(Ndarray *out, Ndarray*arr, size_t *to, size_t nd); 21 | 22 | Ndarray*LNArray_Add(Ndarray*arr1, Ndarray*arr2); 23 | 24 | Ndarray*LNArray_MaxAxis(Ndarray*arr, long long axis); 25 | Ndarray*LNArray_Max(Ndarray*arr); 26 | 27 | Ndarray*LNArray_MinAxis(Ndarray*arr, long long axis); 28 | Ndarray*LNArray_Min(Ndarray*arr); 29 | 30 | Ndarray*LNArray_SumAxis(Ndarray*arr, long long axis); 31 | Ndarray*LNArray_Sum(Ndarray*arr); 32 | 33 | #undef LNMath_ 34 | #undef LNRealDType 35 | 36 | #endif -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "immintrin.h": "c", 4 | "emmintrin.h": "c", 5 | "array": "c", 6 | "functional": "c", 7 | "tuple": "c", 8 | "type_traits": "c", 9 | "utility": "c", 10 | "utils.h": "c", 11 | "cmath": "c", 12 | "random": "cpp", 13 | "sse.h": "c", 14 | "arraymath.h": "c", 15 | "stdnoreturn.h": "c", 16 | "luandarray.h": "c", 17 | "lngenerateint32type.h": "c", 18 | "lngenerateint8type.h": "c", 19 | "vector.h": "c", 20 | "complex": "c", 21 | "inttypes.h": "c", 22 | "buffer.h": "c", 23 | "arrayaplly.h": "c", 24 | "arrayobj.h": "c", 25 | "lngeneratealltypes.h": "c", 26 | "lngeneratecomplex128type.h": "c", 27 | "lngeneratecomplex64type.h": "c", 28 | "arraytypes.h": "c" 29 | }, 30 | "C_Cpp.errorSquiggles": "disabled", 31 | "Lua.runtime.version": "LuaJIT", 32 | } -------------------------------------------------------------------------------- /src/core/arrayinis.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_ARRAYINIS_H_ 2 | #define LUANDARRAY_SRC_CORE_ARRAYINIS_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "arraydtype.h" 8 | #include "arrayobj.h" 9 | 10 | Ndarray *LNArray_Empty_(Ndarray *out, const size_t *dims, size_t ndim, const LNTypeDescr); 11 | Ndarray *LNArray_Empty(const size_t *dims, size_t ndim, const LNTypeDescr *dtype); 12 | 13 | Ndarray *LNArray_Zeros_(Ndarray *out, const size_t *dims, size_t ndim, const LNTypeDescr *dtype); 14 | Ndarray *LNArray_Zeros(const size_t *dims, size_t ndim, const LNTypeDescr *dtype); 15 | 16 | Ndarray *LNArray_Ones_(Ndarray *out, const size_t *dims, size_t ndim, const LNTypeDescr *dtype); 17 | Ndarray *LNArray_Ones(const size_t *dims, size_t ndim, const LNTypeDescr *dtype); 18 | 19 | Ndarray *LNArray_Range_(Ndarray *out, double start, double stop, double step, const LNTypeDescr *dtype); 20 | Ndarray *LNArray_Range(double start, double stop, double step, const LNTypeDescr *dtype); 21 | 22 | #endif -------------------------------------------------------------------------------- /src/core/simd/AVX.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_SIMD_AVX_H_ 2 | #define LUANDARRAY_SRC_CORE_SIMD_AVX_H_ 3 | #ifdef __AVX__ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | float *LNFloat32Vector_Fill_AVX(float *z, float fill_value, size_t n); 10 | float *LNFloat32Vector_Add_AVX(float *z, const float *a, const float *b, size_t n); 11 | float *LNFloat32Vector_Sub_AVX(float *z, const float *a, const float *b, size_t n); 12 | float *LNFloat32Vector_Mul_AVX(float *z, const float *a, const float *b, size_t n); 13 | float *LNFloat32Vector_Div_AVX(float *z, const float *a, const float *b, size_t n); 14 | 15 | double *LNFloat64Vector_Fill_AVX(double *z, double fill_value, size_t n); 16 | double *LNFloat64Vector_Add_AVX(double *z, const double *a, const double *b, size_t n); 17 | double *LNFloat64Vector_Sub_AVX(double *z, const double *a, const double *b, size_t n); 18 | double *LNFloat64Vector_Mul_AVX(double *z, const double *a, const double *b, size_t n); 19 | double *LNFloat64Vector_Div_AVX(double *z, const double *a, const double *b, size_t n); 20 | 21 | #endif 22 | #endif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LuaNdarray 2 | 3 | LuaNdarray is a high-performance linear algebra library for Lua, implemented in C for maximum performance. 4 | 5 | ## Data Types 6 | 7 | LuaNdarray currently primarily supports `double` data types. While we plan to expand support for various data types in future releases, please be aware that as of now, LuaNdarray does not have full support for different data types. 8 | 9 | We are actively working on improving and expanding the capabilities of LuaNdarray, and your feedback and contributions are highly appreciated. 10 | 11 | 12 | ## Installation 13 | 14 | To install LuaNdarray just use the command: 15 | ``` 16 | luarocks install luandarray 17 | ``` 18 | easy, right? 19 | 20 | ## LuaNdarray Overview 21 | 22 | ### Creating a Ndarray 23 | 24 | You can create a Ndarray with the function `ln.array`, passing as argument a table 25 | ```lua 26 | local ln = require "luandarray" 27 | 28 | local arr_1D = ln.array({1,2,3}) 29 | local arr_2D = ln.array({{1,2,3}, {4,5,6}}) 30 | local arr_3D = ln.array({{{1,2,3}, {4,5,6}}, {{7,8,9}, {10,11,12}}}) 31 | -- ... 32 | 33 | You can see more about LuaNdarray in the folder `docs` 34 | -------------------------------------------------------------------------------- /src/core/simd/SSE.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_SIMD_SSE_H_ 2 | #define LUANDARRAY_SRC_CORE_SIMD_SSE_H_ 3 | #ifdef __SSE__ 4 | #include 5 | #include 6 | #include 7 | 8 | float *LNFloat32Vector_Fill_SSE(float *z, float fill_value, size_t n); 9 | float *LNFloat32Vector_Add_SSE(float *z, const float *a, const float *b, size_t n); 10 | float *LNFloat32Vector_Sub_SSE(float *z, const float *a, const float *b, size_t n); 11 | float *LNFloat32Vector_Mul_SSE(float *z, const float *a, const float *b, size_t n); 12 | float *LNFloat32Vector_Div_SSE(float *z, const float *a, const float *b, size_t n); 13 | 14 | #ifdef __SSE2__ 15 | double *LNFloat64Vector_Fill_SSE(double *z, double fill_value, size_t n); 16 | double *LNFloat64Vector_Add_SSE(double *z, const double *a, const double *b, size_t n); 17 | double *LNFloat64Vector_Sub_SSE(double *z, const double *a, const double *b, size_t n); 18 | double *LNFloat64Vector_Mul_SSE(double *z, const double *a, const double *b, size_t n); 19 | double *LNFloat64Vector_Div_SSE(double *z, const double *a, const double *b, size_t n); 20 | #endif 21 | 22 | #endif 23 | 24 | #endif /* LUANDARRAY_SRC_CORE_SIMD_SSE_H_ */ -------------------------------------------------------------------------------- /src/core/simd/AVX512.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_SIMD_AVX512_H_ 2 | #define LUANDARRAY_SRC_CORE_SIMD_AVX512_H_ 3 | 4 | #ifdef __AVX512F__ 5 | #include 6 | #include 7 | #include 8 | 9 | float *LNFloat32Vector_Fill_AVX512(float *z, float fill_value, size_t n); 10 | float *LNFloat32Vector_Add_AVX512(float *z, const float *a, const float *b, size_t n); 11 | float *LNFloat32Vector_Sub_AVX512(float *z, const float *a, const float *b, size_t n); 12 | float *LNFloat32Vector_Mul_AVX512(float *z, const float *a, const float *b, size_t n); 13 | float *LNFloat32Vector_Div_AVX512(float *z, const float *a, const float *b, size_t n); 14 | 15 | double *LNFloat64Vector_Fill_AVX512(double *z, double fill_value, size_t n); 16 | double *LNFloat64Vector_Add_AVX512(double *z, const double *a, const double *b, size_t n); 17 | double *LNFloat64Vector_Sub_AVX512(double *z, const double *a, const double *b, size_t n); 18 | double *LNFloat64Vector_Mul_AVX512(double *z, const double *a, const double *b, size_t n); 19 | double *LNFloat64Vector_Div_AVX512(double *z, const double *a, const double *b, size_t n); 20 | 21 | #endif 22 | #endif /* LUANDARRAY_SRC_CORE_SIMD_AVX512_H_ */ -------------------------------------------------------------------------------- /src/lua/include/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | /* Key to file-handle type */ 15 | #define LUA_FILEHANDLE "FILE*" 16 | 17 | 18 | #define LUA_COLIBNAME "coroutine" 19 | LUALIB_API int (luaopen_base) (lua_State *L); 20 | 21 | #define LUA_TABLIBNAME "table" 22 | LUALIB_API int (luaopen_table) (lua_State *L); 23 | 24 | #define LUA_IOLIBNAME "io" 25 | LUALIB_API int (luaopen_io) (lua_State *L); 26 | 27 | #define LUA_OSLIBNAME "os" 28 | LUALIB_API int (luaopen_os) (lua_State *L); 29 | 30 | #define LUA_STRLIBNAME "string" 31 | LUALIB_API int (luaopen_string) (lua_State *L); 32 | 33 | #define LUA_MATHLIBNAME "math" 34 | LUALIB_API int (luaopen_math) (lua_State *L); 35 | 36 | #define LUA_DBLIBNAME "debug" 37 | LUALIB_API int (luaopen_debug) (lua_State *L); 38 | 39 | #define LUA_LOADLIBNAME "package" 40 | LUALIB_API int (luaopen_package) (lua_State *L); 41 | 42 | 43 | /* open all previous libraries */ 44 | LUALIB_API void (luaL_openlibs) (lua_State *L); 45 | 46 | 47 | 48 | #ifndef lua_assert 49 | #define lua_assert(x) ((void)0) 50 | #endif 51 | 52 | 53 | #endif -------------------------------------------------------------------------------- /src/core/luandarray.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_H_ 2 | #define LUANDARRAY_H_ 3 | 4 | #define require_luandarray()\ 5 | do{\ 6 | LNDType_Init();\ 7 | LNError_Init();\ 8 | if(LNError_Ocurred()){\ 9 | fprintf(stderr, "Fatal Error on initialize LuaNdarray. "\ 10 | "Last error message: %s", LNError_Get());\ 11 | return 1;\ 12 | }\ 13 | }while(0)\ 14 | 15 | #define LN_Finalize()\ 16 | do{\ 17 | LNDType_Free((LNTypeDescr*)LNInt8);\ 18 | LNDType_Free((LNTypeDescr*)LNInt16);\ 19 | LNDType_Free((LNTypeDescr*)LNInt32);\ 20 | LNDType_Free((LNTypeDescr*)LNInt64);\ 21 | \ 22 | LNDType_Free((LNTypeDescr*)LNUInt8);\ 23 | LNDType_Free((LNTypeDescr*)LNUInt16);\ 24 | LNDType_Free((LNTypeDescr*)LNUInt32);\ 25 | LNDType_Free((LNTypeDescr*)LNUInt64);\ 26 | \ 27 | LNDType_Free((LNTypeDescr*)LNFloat32);\ 28 | LNDType_Free((LNTypeDescr*)LNFloat64);\ 29 | }while(0) 30 | 31 | #include "error.h" 32 | #include "buffer.h" 33 | #include "utils.h" 34 | #include "arrayobj.h" 35 | #include "arrayindex.h" 36 | #include "arraydims.h" 37 | #include "converts.h" 38 | #include "arraydtype.h" 39 | #include "arrayinis.h" 40 | #include "arraycast.h" 41 | #include "arraymath.h" 42 | 43 | #endif -------------------------------------------------------------------------------- /src/core/error.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_ERROR_H_ 2 | #define LUANDARRAY_SRC_CORE_ERROR_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #if defined(LUA) 9 | #include 10 | #include 11 | #endif 12 | 13 | typedef struct LNError_t{ 14 | char *errmsg; 15 | char err; 16 | #if defined(LUA) 17 | lua_State *L; 18 | #endif 19 | } LNError_t; 20 | 21 | #define LNError_Check()\ 22 | do {\ 23 | if(LNError_Ocurred()){\ 24 | LNError_Show();\ 25 | exit(1);\ 26 | }\ 27 | } while (0)\ 28 | 29 | #define LNError_CheckNULL()\ 30 | do{\ 31 | if(LNError_Ocurred()){\ 32 | return NULL;\ 33 | }\ 34 | } while(0) 35 | 36 | void LNError_Init(); 37 | 38 | 39 | void LNError_setString(const char *err); 40 | void LNError_setFString(const char *fmt, ...); 41 | 42 | #if defined(LUA) 43 | void LNError_setState(lua_State *L); 44 | #endif 45 | 46 | #if defined(LUA) 47 | void LNError_Run(); 48 | #endif 49 | 50 | char LNError_Ocurred(); 51 | char *LNError_Get(); 52 | 53 | void LNError_Show(); 54 | void LNError_Remove(); 55 | 56 | #define LNError_Raise()\ 57 | do{\ 58 | fprintf(stderr, "LuaNdarray error ocurred:\n\t%s:%d: %s", __FILE__, __LINE__, LNError_Get());\ 59 | exit(1);\ 60 | }while(0) 61 | 62 | #endif -------------------------------------------------------------------------------- /rockspecs/luandarray-1.1.0-0.rockspec: -------------------------------------------------------------------------------- 1 | ---@diagnostic disable: lowercase-global 2 | package = "LuaNdarray" 3 | version = "1.1.0-0" 4 | 5 | source = { 6 | url = "git+https://github.com/ErickProgramer/LuaNdarray.git", 7 | tag = "v1.1.0" 8 | } 9 | 10 | description = { 11 | summary = "Ndarray manipulation quickly and optimally", 12 | detailed = [[ 13 | LuaNdarray is a library for manipulating Ndarray 14 | offering several valuable functions for manipulating Ndarray 15 | for now we do not have support for dtypes but over time this will be added! 16 | ]], 17 | 18 | homepage = "https://github.com/ErickProgramer/LuaNdarray", 19 | 20 | license = "BSD 3-clause" 21 | } 22 | 23 | dependencies = { 24 | "lua >= 5.1" 25 | } 26 | 27 | build = { 28 | type = "make", 29 | 30 | variables = { 31 | LIB_EXTENSION = "$(LIB_EXTENSION)", 32 | }, 33 | 34 | build_variables = { 35 | CFLAGS = "$(CFLAGS)", 36 | LIBFLAG = "$(LIBFLAG)", 37 | LUA_LIBDIR = "$(LUA_LIBDIR)", 38 | LUA_BINDIR = "$(LUA_BINDIR)", 39 | LUA_INCDIR = "$(LUA_INCDIR)", 40 | LUA = "$(LUA)", 41 | LDFLAGS = "$(LIBFLAG)", 42 | }, 43 | 44 | install_variables = { 45 | ENV_INST_PREFIX = "$(PREFIX)", 46 | ENV_INST_BINDIR = "$(BINDIR)", 47 | ENV_INST_LIBDIR = "$(LIBDIR)", 48 | ENV_INST_LUADIR = "$(LUADIR)", 49 | ENV_INST_CONFDIR = "$(CONFDIR)", 50 | }, 51 | } -------------------------------------------------------------------------------- /src/core/arrayobj.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_ARRAYOBJ_H_ 2 | #define LUANDARRAY_SRC_CORE_ARRAYOBJ_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "utils.h" 8 | #include "arraytypes.h" 9 | 10 | #define LNArray_STEP(arr) ((arr)->step) 11 | #define LNArray_DIMENSIONS(arr) ((arr)->dimensions) 12 | #define LNArray_DIMS(arr) ((arr)->dimensions) 13 | #define LNArray_NDIM(arr) ((arr)->nd) 14 | #define LNArray_SIZE(arr) ((arr)->size) 15 | #define LNArray_LEN(arr) ((arr)->dimensions[0]) 16 | 17 | #define LNArray_TYPE(arr) ((arr)->dtype) 18 | 19 | #define LNArray_ITEMSIZE(arr) (LNArray_TYPE(arr)->itemsize) 20 | #define LNArray_ALIGNMENT(arr) (LNArray_TYPE(arr)->alignment) 21 | 22 | void LNArray_Init(Ndarray *arr); 23 | 24 | void LNArray_Debug(const Ndarray *arr); 25 | 26 | Ndarray *LNArray_New(void *data, size_t *dims, long long *strides, size_t nd, const LNTypeDescr *dtype); 27 | Ndarray *LNArray_NewScalar(const void *scalar, const LNTypeDescr *dtype); 28 | Ndarray *LNArray_New1D(void *data, size_t ax0, const LNTypeDescr *dtype); 29 | Ndarray *LNArray_New2D(void *data, size_t ax0, size_t ax1, const LNTypeDescr *dtype); 30 | Ndarray *LNArray_Copy(const Ndarray *arr); 31 | int LNArray_IsContiguous(const Ndarray *arr); 32 | 33 | void LNArray_Free(Ndarray *arr); 34 | 35 | #define LNArray_Alloc() ((Ndarray*)LNMem_alloc(sizeof(Ndarray))) 36 | #define LNArray_NewMatrix LNArray_New2D 37 | 38 | #define LNArray_IsScalar(arr) ((arr)->nd == 0 && (arr)->size == 1) 39 | #define LNArray_IsEmpty(arr) ((arr)->size == 0) 40 | 41 | #endif /* LUANDARRAY_SRC_CORE_ARRAYOBJ_H_ */ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2023, ErickProgramer 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /src/luajit/dtype.lua: -------------------------------------------------------------------------------- 1 | local setmetatable, getmetatable = setmetatable, getmetatable 2 | local type = type 3 | local pcall = pcall 4 | 5 | local ffi=require"ffi" 6 | 7 | local function try_paths(...) 8 | local paths = {...} 9 | 10 | for i, path in ipairs(paths) do 11 | local ok, r = pcall(ffi.load, path) 12 | if ok then 13 | return r 14 | end 15 | end 16 | 17 | return nil 18 | end 19 | 20 | local lnc = try_paths("luandarray/luajit/bin/core.so", 21 | "luandarray/luajit/bin/core.dll", 22 | "luandarray/luajit/bin/core") 23 | 24 | local dtype_meta={} 25 | dtype_meta.__name = "dtype" 26 | dtype_meta.__index=dtype_meta 27 | 28 | ---@return ln.dtype 29 | local function newDType(struct, constructor) 30 | local self=setmetatable({},dtype_meta) 31 | getmetatable(self).__call = constructor 32 | 33 | self.dtype=struct 34 | self.name="" 35 | self.alignment=self.dtype.alignment 36 | self.itemsize=self.dtype.itemsize 37 | 38 | local i=0 39 | while self.dtype.name[i]~=0 do 40 | self.name=self.name..string.char(self.dtype.name[i]) 41 | i=i+1 42 | end 43 | return self 44 | end 45 | 46 | function dtype_meta:__tostring() 47 | return string.format('dtype("%s")', self.name) 48 | end 49 | 50 | function dtype_meta:__gc() 51 | lnc.LNDType_Free(self.dtype) 52 | self=nil 53 | end 54 | 55 | function dtype_meta.is(v) 56 | return type(v) == "table" and (v.__name=="dtype" and tostring(ffi.typeof(v.dtype)) == "ctype") 57 | end 58 | 59 | return {newDType=newDType, dtype_meta=dtype_meta} -------------------------------------------------------------------------------- /src/core/arraydtype.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_ARRAYDTYPE_H_ 2 | #define LUANDARRAY_SRC_CORE_ARRAYDTYPE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "arraytypes.h" 10 | 11 | 12 | void LNDType_Init(); 13 | 14 | LNTypeDescr *LNDType_New(LNDTypes id, CastFunc castfunc, LNAxisOperator max_axis_func, LNAxisOperator min_axis_func, LNAxisOperator sum_axis_func, LNMapOperator max_func, LNMapOperator min_func, LNMapOperator sum_func, char *name, char *fmt, size_t alignment, size_t itemsize); 15 | LNTypeDescr *LNDType_NewFromID(LNDTypes id); 16 | const LNTypeDescr *LNDType_GetFromID(LNDTypes id); 17 | LNTypeDescr *LNDType_Copy(LNTypeDescr *dst, const LNTypeDescr *src); 18 | bool_t LNDType_CastIsSafe(const LNTypeDescr *orig_type, const LNTypeDescr *new_type); 19 | const LNTypeDescr *LNDType_setdefault(const LNTypeDescr *type); 20 | const LNTypeDescr *LNDType_getdefault(); 21 | 22 | void LNDType_Print(const LNTypeDescr *dtype); 23 | const LNTypeDescr *LNDType_Promote(const LNTypeDescr *t1, const LNTypeDescr *t2); 24 | 25 | void LNDType_Free(LNTypeDescr *dtype); 26 | 27 | #define LNDType_IsInt(id) ((id) >= LN_INT8 && (id) <= LN_INT64) 28 | #define LNDType_IsUInt(id) ((id) >= LN_UINT8 && (id) <= LN_UINT64) 29 | #define LNDType_IsFloat(id) ((id) >= LN_FLOAT32 && (id) <= LN_FLOAT64) 30 | #define LNDType_IsComplex(id) ((id) >= LN_COMPLEX64 && (id) <= LN_COMPLEX128) 31 | #define LNDType_IsSuperior(dtype1,dtype2) ((dtype1)->id > (dtype1)->id) 32 | 33 | #define LNDType_GetInt(id1,id2) LNDType_IsInt(id1) ? (id1) : (id2) 34 | 35 | #define LNDTYPE_FLOAT32_FMT "%.14g" 36 | #define LNDTYPE_FLOAT64_FMT "%.14g" 37 | 38 | #undef CAN_CAST_TYPE 39 | 40 | #endif -------------------------------------------------------------------------------- /src/core/error.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "error.h" 7 | 8 | static LNError_t LNExc_Error; 9 | 10 | void LNError_Init(){ 11 | #ifdef LUA 12 | LNExc_Error.L = NULL; 13 | #endif 14 | LNExc_Error.errmsg = NULL; 15 | LNExc_Error.err = 0; 16 | } 17 | 18 | #if defined(LUA) 19 | void LNError_setState(lua_State *L){ 20 | LNExc_Error.L = L; 21 | } 22 | #endif 23 | 24 | void LNError_setString(const char *errmsg){ 25 | LNError_Remove(); 26 | 27 | size_t len=strlen(errmsg); 28 | LNExc_Error.errmsg = malloc(len+1); 29 | strncpy(LNExc_Error.errmsg, errmsg, len); 30 | LNExc_Error.errmsg[len]='\0'; 31 | LNExc_Error.err = 1; 32 | } 33 | 34 | void LNError_setFString(const char *fmt, ...){ 35 | va_list args; 36 | va_start(args, fmt); 37 | int n = vsnprintf(NULL, 0, fmt, args); 38 | if(n<0)n=0; 39 | va_end(args); 40 | 41 | va_start(args, fmt); 42 | char *err = malloc(n+1); 43 | if(!err) 44 | err="Fatal Error: error on allocate the message error"; 45 | vsnprintf(err, n+1, fmt, args); 46 | va_end(args); 47 | 48 | LNError_Remove(); 49 | LNExc_Error.errmsg = err; 50 | LNExc_Error.err = 1; 51 | } 52 | 53 | char LNError_Ocurred(){ 54 | return LNExc_Error.err; 55 | } 56 | 57 | char *LNError_Get(){ 58 | return LNExc_Error.errmsg; 59 | } 60 | 61 | void LNError_Show(){ 62 | printf("%s\n", LNExc_Error.errmsg); 63 | } 64 | 65 | #if defined(LUA) 66 | void LNError_Run(){ 67 | luaL_error(LNExc_Error.L, LNError_Get()) 68 | } 69 | #endif 70 | 71 | void LNError_Run(){ 72 | #ifdef LUA 73 | luaL_error(LNExc_Error.L, LNExc_Error.errmsg); 74 | #endif 75 | } 76 | 77 | void LNError_Remove(){ 78 | if(LNExc_Error.errmsg) 79 | free((char*)LNExc_Error.errmsg); 80 | LNExc_Error.err = 0; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /src/lua/src/init.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include"luand.h" 8 | #include "ndarray.h" 9 | #include "conf.h" 10 | 11 | void ln_debug_stack(lua_State *L){ 12 | int i; 13 | for(i = 1; i <= lua_gettop(L); i++){ 14 | printf("%s\t%s\n", lua_tostring(L, i), luaL_typename(L, i)); 15 | } 16 | } 17 | 18 | void ln_dtype_init(lua_State *L); 19 | void ln_ndarray_init(lua_State *L); 20 | 21 | 22 | static int ln_type(lua_State *L){ 23 | if(luaND_isdtype(L, 1)){ 24 | lua_pushstring(L, "dtype"); 25 | } else if(luaND_isndarray(L, 2)){ 26 | lua_pushstring(L, "ndarray"); 27 | } else{ 28 | lua_pushstring(L, luaL_typename(L, 1)); 29 | } 30 | return 1; 31 | } 32 | 33 | 34 | int ln_setdefaulttype(lua_State *L){ 35 | if(lua_gettop(L) != 1){ 36 | luaL_error(L, "wrong number of arguments to 'setdefaulttype'"); 37 | } 38 | 39 | const LNTypeDescr *dtype = luaND_checkdtype(L, 1); 40 | LNDType_setdefault(dtype); 41 | return 1; 42 | } 43 | 44 | int ln_getdefaulttype(lua_State *L){ 45 | luaND_pushdtypep(L, LNDType_getdefault()); 46 | return 1; 47 | } 48 | 49 | static const luaL_Reg ln[] = { 50 | {"arange", ln_array_arange}, 51 | {"ndarray", ln_array_new}, 52 | {"ones", ln_array_ones}, 53 | {"zeros", ln_array_zeros}, 54 | {"type", ln_type}, 55 | {"setdefaulttype", ln_setdefaulttype}, 56 | {"getdefaulttype", ln_getdefaulttype}, 57 | {NULL, NULL} 58 | }; 59 | 60 | int luaopen_luandarray(lua_State *L){ 61 | // loading LuaNdarray 62 | require_luandarray(); 63 | 64 | luaND_newlibtable(L, ln); 65 | 66 | // Initializing dtypes 67 | ln_dtype_init(L); 68 | 69 | // initializing the Ndarray object 70 | ln_array_init(L); 71 | 72 | 73 | luaND_setfuncs(L, ln, 0); 74 | 75 | return 1; 76 | } 77 | -------------------------------------------------------------------------------- /src/core/arrayindex.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "arrayindex.h" 6 | #include "error.h" 7 | #include "arrayobj.h" 8 | #include "arrayaplly.h" 9 | 10 | static int INDEX_BASE; 11 | 12 | int LNGetIndexStart(){ 13 | return INDEX_BASE; 14 | } 15 | 16 | void LNIndexStartZero(bool_t s){ 17 | INDEX_BASE = s == 0; 18 | } 19 | 20 | Ndarray *LNArray_Index_(Ndarray *out, Ndarray *arr, long long idx){ 21 | if(idx < 0){ 22 | idx=arr->dimensions[0]+idx; 23 | } 24 | 25 | if(arr->nd == 0){ 26 | LNError_setString("attemp to index a 0-dimensional array"); 27 | return NULL; 28 | } else if(idx >= LNArray_LEN(arr)){ 29 | LNError_setFString("index %lld is out of bounds for axis 0 with size %zu", idx, arr->dimensions[0]); 30 | return NULL; 31 | } 32 | 33 | 34 | out->dtype = arr->dtype; 35 | out->size = arr->size / arr->dimensions[0]; 36 | out->nd = arr->nd-1; 37 | out->dimensions = arr->dimensions + 1; 38 | out->strides = arr->strides+1; 39 | out->data = arr->data+(idx*arr->strides[0]); 40 | 41 | return out; 42 | } 43 | 44 | Ndarray *LNArray_Index(Ndarray *arr, long long idx){ 45 | Ndarray *res = LNArray_Alloc(); 46 | if(!res) 47 | return NULL; 48 | return LNArray_Index_(res, arr, idx); 49 | } 50 | 51 | Ndarray *LNArray_MultiIndex(Ndarray *arr, long long *idxs, size_t nidxs){ 52 | size_t i; 53 | for(i = 0; i < nidxs; i++){ 54 | arr = LNArray_Index(arr, idxs[i]); 55 | if(!arr) 56 | return NULL; 57 | } 58 | return arr; 59 | } 60 | 61 | void *LNArray_MultiIndexItem(Ndarray *arr, long long *idxs){ 62 | size_t i; 63 | long long pos=idxs[0]*arr->strides[0]; 64 | 65 | for(i = 1; i < arr->nd; i++) 66 | pos+=idxs[i]*arr->strides[i]; 67 | 68 | return (void*)(arr->data + pos); 69 | } 70 | 71 | void LNArray_MapDim(Ndarray *arr, long long dim){ 72 | long long i; 73 | LN_ARRAY_APPLY_D(arr, dim, 74 | printf("{"); 75 | for(i = 0; i < __axis_size; i++){ 76 | printf("%d, ", ((char*)item)[i]); 77 | } 78 | printf("}\n"); 79 | ); 80 | } 81 | -------------------------------------------------------------------------------- /src/lua/src/luand.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_LUA_LUAND_H_ 2 | #define LUANDARRAY_SRC_LUA_LUAND_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | void *luaND_alloc(lua_State *L, size_t bytes); 12 | void *luaND_realloc(lua_State *L, void *ptr, size_t _size); 13 | 14 | Ndarray *luaND_newndarray(lua_State *L); 15 | 16 | 17 | void luaND_pushndarray(lua_State *L, Ndarray *arr); 18 | void luaND_pushdtypep(lua_State *L, const LNTypeDescr *dtype); 19 | void luaND_pushdtype(lua_State *L, LNDTypes dtype); 20 | 21 | void luaND_pushfunsp(lua_State *L, const luaL_Reg *funs, int to); 22 | 23 | #define luaND_pushfuns(L, funs) (lua_newtable(), luaND_pushfunsp(L, -1)) 24 | 25 | int luaND_isndarray(lua_State *L, int arg); 26 | int luaND_isdtype(lua_State *L, int arg); 27 | int luaND_type(lua_State *L, int arg); 28 | 29 | Ndarray *luaND_optndarray(lua_State *L, int arg, Ndarray *d); 30 | 31 | #define luaND_checkndarray(L, arg) (*(Ndarray**)luaL_checkudata((L), (arg), LN_NDARRAY_MT)) 32 | #define luaND_checkdtype(L, arg) (*(const LNTypeDescr**)luaL_checkudata((L), (arg), LN_DTYPE_MT)) 33 | 34 | 35 | #define luaND_optdtype(L, arg, dtype) (lua_isnoneornil((L), (arg)) ? (dtype) : luaND_checkdtype(L, arg)) 36 | #define luaND_optndarray(L, arg, arr) (lua_isnoneornil((L), (arg)) ? (arr) : luaND_checkndarray(L, arg)) 37 | 38 | int luaND_newmetatable(lua_State *L, const char *name); 39 | 40 | int luaND_testudata(lua_State *L, int arg, const char *uname); 41 | void *luaND_checkudata(lua_State *L, int arg, const char *ud); 42 | 43 | int luaND_argcheck(lua_State *L, int cond, int arg, const char *fmt, ...); 44 | 45 | void luaND_setfuncs(lua_State *L, const luaL_Reg *l, int nup); 46 | 47 | #define luaND_newndarray(L) ((Ndarray*)lua_newuserdata(L, sizeof(Ndarray))) 48 | 49 | #define luaND_newlib(L, l) (luaND_newlibtable(L,l), luaND_setfuncs(L,l,0)) 50 | #define luaND_newlibtable(L,l) \ 51 | lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) 52 | 53 | #if LUA_VERSION_NUM == 501 54 | #define luaND_len(L, obj) lua_objlen(L, obj) 55 | #else 56 | #define luaND_len(L, obj) luaL_len(L, obj) 57 | #endif 58 | 59 | #define luaND_opttable(L, arg, extramsg) (luaL_argcheck(L, lua_istable(L, arg) || lua_isnoneornil(L, arg), numarg, extramsg)) 60 | 61 | #define LUAND_TNDARRAY 9 62 | 63 | #endif /* LUANDARRAY_SRC_LUA_LUAND_H_ */ 64 | -------------------------------------------------------------------------------- /src/lua/src/dtype.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "luand.h" 9 | #include "conf.h" 10 | 11 | int ln_debug_stack(lua_State *L); 12 | 13 | // __tostring meta method 14 | static int ln_dtype__tostring(lua_State *L){ 15 | const LNTypeDescr *dtype = luaND_checkdtype(L, 1); 16 | lua_pushfstring(L, "dtype(\"%s\")", dtype->name); 17 | return 1; 18 | } 19 | 20 | static int ln_dtype__index(lua_State *L){ 21 | const LNTypeDescr *dtype = luaND_checkdtype(L, 1); 22 | 23 | lua_pushstring(L, "alignment"); 24 | if(lua_rawequal(L, -1, -2)){ 25 | lua_pushinteger(L, (lua_Integer)dtype->alignment); 26 | return 1; 27 | } 28 | lua_pop(L, 1); 29 | 30 | lua_pushstring(L, "itemsize"); 31 | if(lua_rawequal(L, -1, -2)){ 32 | lua_pushinteger(L, (lua_Integer)dtype->itemsize); 33 | return 1; 34 | } 35 | lua_pop(L, 1); 36 | 37 | lua_pushstring(L, "name"); 38 | if(lua_rawequal(L, -1, -2)){ 39 | lua_pushstring(L, dtype->name); 40 | return 1; 41 | } 42 | lua_pop(L, 1); 43 | 44 | lua_pushnil(L); 45 | return 1; 46 | } 47 | 48 | static int ln_dtype__eq(lua_State *L){ 49 | if(luaND_isdtype(L, 1) && luaND_isdtype(L, 2)){ 50 | const LNTypeDescr *dtype1 = luaND_checkdtype(L, 1); 51 | const LNTypeDescr *dtype2 = luaND_checkdtype(L, 2); 52 | lua_pushboolean(L, dtype1 != NULL && dtype1->id == dtype2->id); 53 | } else { 54 | lua_pushboolean(L, 0); 55 | } 56 | } 57 | 58 | static const luaL_Reg dtype_meta[] = { 59 | {"__tostring", ln_dtype__tostring}, 60 | {"__index", ln_dtype__index}, 61 | // {"__eq", ln_dtype__eq}, 62 | {NULL, NULL} 63 | }; 64 | 65 | void ln_makemetatable(lua_State *L){ 66 | luaL_newmetatable(L, LN_DTYPE_MT); 67 | lua_pushboolean(L, 1); 68 | lua_setfield(L, -2, "__metatable"); 69 | luaND_setfuncs(L, dtype_meta, 0); 70 | lua_pop(L, 1); 71 | } 72 | 73 | static void ln_setdtype(lua_State *L, LNDTypes id){ 74 | const LNTypeDescr *dtype = LNDType_GetFromID(id); 75 | lua_pushstring(L, dtype->name); 76 | luaND_pushdtypep(L, dtype); 77 | lua_settable(L, -3); 78 | } 79 | 80 | static void ln_setdtypes(lua_State *L){ 81 | int i; 82 | for(i = 0; i < LN_NUMTYPES; i++){ 83 | ln_setdtype(L, i); 84 | } 85 | } 86 | 87 | void ln_dtype_init(lua_State *L){ 88 | ln_makemetatable(L); 89 | ln_setdtypes(L); 90 | } -------------------------------------------------------------------------------- /src/core/arraytypes.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_ARRAYTYPES_H_ 2 | #define LUANDARRAY_SRC_CORE_ARRAYTYPES_H_ 3 | 4 | #include 5 | #include 6 | 7 | typedef float float32_t; 8 | typedef double float64_t; 9 | 10 | typedef struct complex128_t complex128_t; 11 | typedef struct complex64_t complex64_t; 12 | 13 | typedef enum LNDTypes LNDTypes; 14 | 15 | typedef struct Ndarray_fields Ndarray; 16 | typedef struct LNTypeDescr LNTypeDescr; 17 | 18 | struct complex128_t{ 19 | float64_t realp; 20 | float64_t imagp; 21 | }; 22 | 23 | struct complex64_t{ 24 | float32_t realp; 25 | float32_t imagp; 26 | }; 27 | 28 | #define ln_c64real(v) (*(complex64_t*)(v)).realp 29 | #define ln_c64imag(v) (*(complex64_t*)(v)).imagp 30 | 31 | #define ln_c128real(v) (*(complex128_t*)(v)).realp 32 | #define ln_c128imag(v) (*(complex128_t*)(v)).imagp 33 | 34 | typedef unsigned char bool_t; 35 | 36 | #ifndef true 37 | #define true 1 38 | #endif 39 | 40 | #ifndef false 41 | #define false 0 42 | #endif 43 | 44 | 45 | enum LNDTypes{ 46 | LN_CHAR=0, 47 | LN_BOOL, 48 | 49 | LN_INT8, 50 | LN_INT16, 51 | LN_INT32, 52 | LN_INT64, 53 | 54 | LN_UINT8, 55 | LN_UINT16, 56 | LN_UINT32, 57 | LN_UINT64, 58 | 59 | LN_FLOAT32, 60 | LN_FLOAT64, 61 | 62 | LN_COMPLEX64, 63 | LN_COMPLEX128, 64 | 65 | LN_NUMTYPES 66 | }; 67 | 68 | // typedef void (*CastFunc)(void *dst, const void *src, LNDTypes newdtype, size_t n); 69 | typedef void (*CastFunc)(Ndarray *dst, const Ndarray *src, LNDTypes newtype); 70 | 71 | typedef void (*LNFillFunc)(void *vec, const void *v, size_t n); 72 | 73 | typedef Ndarray *(*LNAxisOperator)(Ndarray *arr, long long axis); 74 | typedef Ndarray *(*LNMapOperator)(Ndarray *arr); 75 | 76 | struct LNTypeDescr{ 77 | LNDTypes id; 78 | size_t alignment; 79 | size_t itemsize; 80 | 81 | char *name; 82 | char *fmt; 83 | 84 | CastFunc castfunc; 85 | LNAxisOperator max_axis_func; 86 | LNAxisOperator min_axis_func; 87 | LNAxisOperator sum_axis_func; 88 | 89 | LNMapOperator max_func; 90 | LNMapOperator min_func; 91 | LNMapOperator sum_func; 92 | }; 93 | 94 | /* ndarray struct */ 95 | struct Ndarray_fields{ 96 | /* data of the ndarray */ 97 | char *data; 98 | 99 | /* dimensions of the array */ 100 | size_t *dimensions; 101 | 102 | long long *strides; 103 | 104 | /* number of dimensions */ 105 | size_t nd; 106 | 107 | /* size of `data` (multiplication of the dimensions) */ 108 | size_t size; 109 | 110 | const LNTypeDescr *dtype; 111 | }; 112 | 113 | 114 | 115 | #endif -------------------------------------------------------------------------------- /src/luajit/complex.lua: -------------------------------------------------------------------------------- 1 | -- LuaJIT -- 2 | -- LuaNdarray Complex Numbers library -- 3 | 4 | local setmetatable = setmetatable 5 | local type = type 6 | local math = math 7 | 8 | local function re(x) 9 | if type(x)=="number" then 10 | return x 11 | end 12 | return x.real 13 | end 14 | 15 | local function im(x) 16 | if type(x)=="number" then 17 | return 0 18 | end 19 | return x.imag 20 | end 21 | 22 | local complex={} 23 | complex.__index=complex 24 | complex.__name="complex" 25 | 26 | local function Complex(real, imag) 27 | local self=setmetatable({},complex) 28 | self.real = real 29 | self.imag = imag 30 | return self 31 | end 32 | 33 | local function rect(r,phi) 34 | return Complex(r*math.cos(phi),r*math.sin(phi)) 35 | end 36 | 37 | function complex:__add(other) 38 | return Complex(re(self)+re(other), im(self)+im(other)) 39 | end 40 | 41 | function complex:__sub(other) 42 | return Complex(re(self)-re(other), im(self)-im(other)) 43 | end 44 | 45 | function complex:__mul(other) 46 | local r1,i1, r2,i2 = re(self),im(self), re(other),im(other) 47 | return Complex(r1*r2-i1*i2,r1*i2+r2*i1) 48 | end 49 | 50 | function complex:__div(other) 51 | local r1,i1, r2,i2=re(self),im(self), re(other),im(other) 52 | local rsq=r2^2+i2^2 53 | return Complex((r1*r2+i1*i2)/rsq,(r2*i1-r1*i2)/rsq) 54 | end 55 | 56 | function complex:__pow(other) 57 | local r1,i1, r2,i2=re(self),im(self), re(other),im(other) 58 | local rsq=r1^2+i1^2 59 | if rsq==0 then 60 | if r2==0 and i2==0 then 61 | return 1 62 | end 63 | return 0 64 | end 65 | local phi=math.atan2(i1,r1) 66 | return rect(rsq^(r2/2)*math.exp(-i2*phi),i2*math.log(rsq)/2+r2*phi) 67 | end 68 | 69 | function complex:__unm() 70 | return Complex(-re(self), -im(self)) 71 | end 72 | 73 | function complex:__tostring() 74 | local r,i=re(self),im(self) 75 | if i==0 then 76 | return tostring(r) 77 | elseif r==0 then 78 | if i==1 then 79 | return "i" 80 | elseif i==-1 then 81 | return "-i" 82 | end 83 | return i.."i" 84 | elseif i<0 then 85 | if i==-1 then 86 | return r.."-i" 87 | end 88 | return r..i.."i" 89 | else 90 | if i==1 then 91 | return r.."+i" 92 | end 93 | return r.."+"..i.."i" 94 | end 95 | end 96 | 97 | function complex:is() 98 | return (type(self)=="table" and self.__name=="complex") 99 | end 100 | 101 | -- global Complex to create Complex numbers... 102 | I = Complex(0,1) 103 | 104 | complex.new=Complex 105 | 106 | return complex -------------------------------------------------------------------------------- /detect_simd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifdef _MSC_VER 5 | #include 6 | #endif 7 | 8 | #ifdef __GNUC__ 9 | 10 | void __cpuid(int* cpuinfo, int info) 11 | { 12 | __asm__ __volatile__( 13 | "xchg %%ebx, %%edi;" 14 | "cpuid;" 15 | "xchg %%ebx, %%edi;" 16 | :"=a" (cpuinfo[0]), "=D" (cpuinfo[1]), "=c" (cpuinfo[2]), "=d" (cpuinfo[3]) 17 | :"0" (info) 18 | ); 19 | } 20 | 21 | unsigned long long _xgetbv(unsigned int index) 22 | { 23 | unsigned int eax, edx; 24 | __asm__ __volatile__( 25 | "xgetbv;" 26 | : "=a" (eax), "=d"(edx) 27 | : "c" (index) 28 | ); 29 | return ((unsigned long long)edx << 32) | eax; 30 | } 31 | 32 | #endif 33 | 34 | int main(){ 35 | bool sseSupportted = false; 36 | bool sse2Supportted = false; 37 | bool sse3Supportted = false; 38 | bool ssse3Supportted = false; 39 | bool sse4_1Supportted = false; 40 | bool sse4_2Supportted = false; 41 | bool sse4aSupportted = false; 42 | bool sse5Supportted = false; 43 | bool avxSupportted = false; 44 | bool avx2Supportted = false; 45 | bool avx512Supportted = false; 46 | 47 | int cpuinfo[4]; 48 | __cpuid(cpuinfo, 1); 49 | 50 | // Check SSE, SSE2, SSE3, SSSE3, SSE4.1, and SSE4.2 support 51 | sseSupportted = cpuinfo[3] & (1 << 25) || false; 52 | sse2Supportted = cpuinfo[3] & (1 << 26) || false; 53 | sse3Supportted = cpuinfo[2] & (1 << 0) || false; 54 | ssse3Supportted = cpuinfo[2] & (1 << 9) || false; 55 | sse4_1Supportted = cpuinfo[2] & (1 << 19) || false; 56 | sse4_2Supportted = cpuinfo[2] & (1 << 20) || false; 57 | 58 | // Check AVX support 59 | avxSupportted = cpuinfo[2] & (1 << 28) || false; 60 | bool osxsaveSupported = cpuinfo[2] & (1 << 27) || false; 61 | if (osxsaveSupported && avxSupportted) 62 | { 63 | // _XCR_XFEATURE_ENABLED_MASK = 0 64 | unsigned long long xcrFeatureMask = _xgetbv(0); 65 | avxSupportted = (xcrFeatureMask & 0x6) == 0x6; 66 | } 67 | 68 | // Check AVX2 support 69 | __cpuid(cpuinfo, 7); 70 | avx2Supportted = cpuinfo[1] & (1 << 5) || false; 71 | 72 | // Check AVX-512 support 73 | __cpuid(cpuinfo, 0); 74 | int numExtendedIds = cpuinfo[0]; 75 | if (numExtendedIds >= 0xD) 76 | { 77 | __cpuid(cpuinfo, 0xD); 78 | avx512Supportted = cpuinfo[1] & (1 << 16) || false; 79 | } 80 | 81 | if(avx512Supportted){ 82 | printf("avx512f"); 83 | } else if(avxSupportted){ 84 | printf("avx"); 85 | } else if(sse4_2Supportted){ 86 | printf("sse4.2"); 87 | } else if(sse4_1Supportted){ 88 | printf("sse4.1"); 89 | } else if(sse3Supportted){ 90 | printf("sse3"); 91 | } else if(sse2Supportted){ 92 | printf("sse2"); 93 | } else if(sseSupportted){ 94 | printf("sse"); 95 | } 96 | 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /src/core/arraycast.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "arrayobj.h" 6 | #include "arraydtype.h" 7 | #include "error.h" 8 | #include "arraycast.h" 9 | #include "arrayaplly.h" 10 | 11 | void LNArray_CastTo_(Ndarray *out, const Ndarray *arr, const LNTypeDescr *newtype, LNCast_t casttype){ 12 | if(!LNArray_CanCast(arr->dtype, newtype, casttype)){ 13 | char rule_repr[7]; 14 | switch (casttype){ 15 | case LNCAST_SAFE: 16 | strncpy(rule_repr, "safe", 7); 17 | break; 18 | case LNCAST_UNSAFE: 19 | strncpy(rule_repr, "unsafe", 7); 20 | break; 21 | } 22 | 23 | LNError_setFString("cannot cast array data from dtype(\"%s\") to dtype(\"%s\") according to the rule %s", 24 | arr->dtype->name, newtype->name, rule_repr); 25 | return; 26 | } 27 | out->nd = arr->nd; 28 | out->dtype = newtype; 29 | 30 | out->strides = LNMem_alloc(sizeof(long long)*out->nd); 31 | if(!out->strides) 32 | return; 33 | 34 | out->dimensions = LNMem_alloc(sizeof(size_t)*out->nd); 35 | if(!out->dimensions) 36 | return; 37 | 38 | 39 | out->size = 1; 40 | size_t i; 41 | for(i = arr->nd; i > 0; i--){ 42 | out->strides[i-1] = out->size * LNArray_ALIGNMENT(out); 43 | out->dimensions[i-1] = arr->dimensions[i-1]; 44 | out->size *= out->dimensions[i-1]; 45 | } 46 | 47 | out->data = LNMem_alloc(LNArray_ALIGNMENT(out)*out->size); 48 | if(!out->data) 49 | return; 50 | 51 | arr->dtype->castfunc(out, arr, newtype->id); 52 | } 53 | 54 | Ndarray *LNArray_CastTo(const Ndarray *arr, const LNTypeDescr *newtype, LNCast_t casttype){ 55 | Ndarray *out = LNArray_Alloc(); 56 | if(!out) 57 | return NULL; 58 | 59 | LNArray_CastTo_(out, arr, newtype, casttype); 60 | if(LNError_Ocurred()){ 61 | LNArray_Free(out); 62 | return NULL; 63 | } 64 | 65 | return out; 66 | } 67 | 68 | int LNArray_CanCast(const LNTypeDescr *from, const LNTypeDescr *to, LNCast_t casttype){ 69 | switch (casttype){ 70 | case LNCAST_UNSAFE: 71 | return true; 72 | 73 | case LNCAST_SAFE: 74 | if(to->itemsize < from->itemsize) 75 | return false; 76 | if(LNDType_IsFloat(from->id) && (LNDType_IsInt(to->id) || LNDType_IsUInt(to->id))) 77 | return false; 78 | if(LNDType_IsInt(from->id) && LNDType_IsUInt(to->id)) 79 | return false; 80 | if((LNDType_IsUInt(from->id) && LNDType_IsInt(to->id)) && to->itemsize < from->itemsize) 81 | return false; 82 | if((LNDType_IsComplex(from->id) && to->itemsize < from->itemsize)) 83 | return false; 84 | return true; 85 | 86 | default: 87 | return -1; 88 | } 89 | } -------------------------------------------------------------------------------- /src/core/converts.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "error.h" 5 | #include "arrayobj.h" 6 | #include "buffer.h" 7 | #include "arrayindex.h" 8 | 9 | static void LNArray_RecursiveToString(LNBuffer *b, Ndarray *arr, size_t indent_level){ 10 | Ndarray *aux = LNArray_Alloc(); 11 | if(!aux) 12 | return; 13 | LNBuff_addchar(b, '{'); 14 | if(LNError_Ocurred()){ 15 | return; 16 | } 17 | 18 | size_t i, j; 19 | for(i = 0; i < LNArray_LEN(arr); i++){ 20 | LNArray_Index_(aux, arr, i); 21 | if(LNError_Ocurred()){ 22 | return; 23 | } 24 | if(LNArray_IsScalar(aux)){ 25 | LNBuff_addtype(b, aux->data, aux->dtype); 26 | if(LNError_Ocurred()){ 27 | return; 28 | } 29 | if(i < LNArray_LEN(arr)-1){ 30 | LNBuff_addchar(b, '\t'); 31 | if(LNError_Ocurred()){ 32 | return; 33 | } 34 | } 35 | } else{ 36 | if(i > 0){ 37 | for(j = 0; j < indent_level; j++){ 38 | LNBuff_addchar(b, ' '); 39 | if(LNError_Ocurred()){ 40 | return; 41 | } 42 | } 43 | } 44 | LNArray_RecursiveToString(b, aux, indent_level+1); 45 | if(i < LNArray_LEN(arr)-1){ 46 | for(j = 0; j < LNArray_NDIM(aux); j++){ 47 | LNBuff_addchar(b, '\n'); 48 | if(LNError_Ocurred()){ 49 | return; 50 | } 51 | } 52 | } 53 | } 54 | } 55 | free(aux); 56 | LNBuff_addchar(b, '}'); 57 | if(LNError_Ocurred()){ 58 | return; 59 | } 60 | } 61 | 62 | char *LNArray_toString_(LNBuffer *b, Ndarray *arr, const char *prefix, const char *sufix){ 63 | if(!b){ 64 | b = LNBuff_alloc(); 65 | if(!b){ 66 | return NULL; 67 | } 68 | LNBuff_Init(b); 69 | } 70 | 71 | LNBuff_addstring(b, prefix); 72 | if(LNArray_IsScalar(arr)){ 73 | LNBuff_addtype(b, arr->data, arr->dtype); 74 | } else if(LNArray_IsEmpty(arr)){ 75 | LNBuff_addstring(b, "{}, shape={"); 76 | size_t i; 77 | for(i = 0; i < arr->nd; i++){ 78 | LNBuff_addfstring(b, "%zu", LNArray_DIMS(arr)[i]); 79 | if(i < arr->nd-1){ 80 | LNBuff_addstring(b, ", "); 81 | } 82 | } 83 | LNBuff_addchar(b, '}'); 84 | } else { 85 | LNArray_RecursiveToString(b, arr, strlen(prefix)+1); 86 | } 87 | LNBuff_addfstring(b, ", dtype=%s", arr->dtype->name); 88 | LNBuff_addstring(b, sufix); 89 | 90 | return LNBuff_ADDR(b); 91 | } 92 | 93 | char *LNArray_toString(Ndarray *arr, const char *prefix, const char *sufix){ 94 | LNBuffer b; 95 | LNBuff_Init(&b); 96 | LNArray_toString_(&b, arr, prefix, sufix); 97 | return LNBuff_ADDR(&b); 98 | } 99 | 100 | void LNArray_Print(Ndarray *arr, const char *prefix, const char *sufix){ 101 | printf("%s", LNArray_toString(arr, prefix, sufix)); 102 | } 103 | -------------------------------------------------------------------------------- /src/lua/src/luand.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include "luand.h" 6 | #include "conf.h" 7 | 8 | void ln_debug_stack(lua_State *L); 9 | 10 | void *luaND_alloc(lua_State *L, size_t bytes){ 11 | void *block = LNMem_alloc(bytes); 12 | if(!block){ 13 | luaL_error(L, LNError_Get()); 14 | return NULL; 15 | } 16 | return block; 17 | } 18 | 19 | void *luaND_realloc(lua_State *L, void *ptr, size_t bytes){ 20 | void *r = LNMem_realloc(ptr, bytes); 21 | if(!r){ 22 | luaL_error(L, LNError_Get()); 23 | return NULL; 24 | } 25 | } 26 | 27 | 28 | void luaND_pushndarray(lua_State *L, Ndarray *arr){ 29 | Ndarray **res = (Ndarray**)lua_newuserdata(L, sizeof(Ndarray*)); 30 | *res = arr; 31 | luaL_getmetatable(L, LN_NDARRAY_MT); 32 | lua_setmetatable(L, -2); 33 | } 34 | 35 | void luaND_pushdtypep(lua_State *L, const LNTypeDescr *dtype){ 36 | LNTypeDescr **ud = (LNTypeDescr**)lua_newuserdata(L, sizeof(LNTypeDescr*)); 37 | *ud = (LNTypeDescr*)dtype; 38 | 39 | luaL_getmetatable(L, LN_DTYPE_MT); 40 | lua_setmetatable(L, -2); 41 | } 42 | 43 | void luaND_pushdtype(lua_State *L, LNDTypes dtype){ 44 | luaND_pushdtypep(L, LNDType_GetFromID(dtype)); 45 | } 46 | 47 | // a copy of the function luaL_setfuncs 48 | void luaND_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { 49 | luaL_checkstack(L, nup, "too many upvalues"); 50 | for (; l->name != NULL; l++) { /* fill the table with given functions */ 51 | if (l->func == NULL) /* placeholder? */ 52 | lua_pushboolean(L, 0); 53 | else { 54 | int i; 55 | for (i = 0; i < nup; i++) /* copy upvalues to the top */ 56 | lua_pushvalue(L, -nup); 57 | lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ 58 | } 59 | lua_setfield(L, -(nup + 2), l->name); 60 | } 61 | lua_pop(L, nup); /* remove upvalues */ 62 | } 63 | 64 | int luaND_isndarray(lua_State *L, int arg){ 65 | if(lua_isuserdata(L, arg)){ 66 | lua_getmetatable(L, arg); 67 | luaL_getmetafield(L, -1, "__name"); 68 | lua_pushstring(L, LN_NDARRAY_MT); 69 | int is = lua_rawequal(L, -2, -1); 70 | lua_pop(L, 1); 71 | return is; 72 | } 73 | return 0; 74 | } 75 | 76 | int luaND_isdtype(lua_State *L, int arg){ 77 | if(lua_isuserdata(L, arg)){ 78 | luaL_getmetafield(L, arg, "__name"); 79 | lua_pushstring(L, LN_DTYPE_MT); 80 | return lua_rawequal(L, -2, -1); 81 | } 82 | return 0; 83 | } 84 | 85 | 86 | int luaND_type(lua_State *L, int arg){ 87 | if(luaND_isndarray(L, arg)){ 88 | return LUAND_TNDARRAY; 89 | } 90 | 91 | return lua_type(L, arg); 92 | } 93 | 94 | int luaND_newmetatable(lua_State *L, const char *name){ 95 | luaL_getmetatable(L, name); 96 | if(!lua_isnil(L, -1)){ 97 | lua_pop(L, 1); 98 | return 0; 99 | } 100 | 101 | lua_newtable(L); 102 | lua_pushstring(L, "__name"); 103 | lua_pushstring(L, name); 104 | lua_settable(L, -3); 105 | 106 | lua_setfield(L, LUA_REGISTRYINDEX, name); 107 | 108 | // lua_pop(L, 2); 109 | 110 | return 1; 111 | } 112 | 113 | int luaND_testudata(lua_State *L, int arg, const char *uname){ 114 | if(lua_isuserdata(L, arg) && lua_getmetatable(L, arg)){ 115 | luaL_getmetatable(L, uname); 116 | int eq = lua_rawequal(L, -1, -2); 117 | lua_pop(L, 2); 118 | return eq; 119 | } 120 | return 0; 121 | } 122 | 123 | void *luaND_checkudata(lua_State *L, int arg, const char *ud){ 124 | luaND_argcheck(L, luaND_testudata(L, arg, ud), arg, "%s expected", ud); 125 | return lua_touserdata(L, arg); 126 | } 127 | 128 | // LuaNdarray's argcheck function 129 | int luaND_argcheck(lua_State *L, int cond, int arg, const char *fmt, ...){ 130 | if(!cond){ 131 | va_list ap; 132 | va_start(ap, fmt); 133 | lua_pushvfstring(L, fmt, ap); 134 | 135 | luaL_argerror(L, arg, lua_tostring(L, -1)); 136 | lua_pop(L, 1); 137 | return 0; 138 | } 139 | return 1; 140 | } 141 | -------------------------------------------------------------------------------- /src/core/simd/AVX.c: -------------------------------------------------------------------------------- 1 | #ifdef __AVX__ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "AVX.h" 8 | 9 | float *LNFloat32Vector_Fill_AVX(float *z, float fill_value, size_t n){ 10 | __m256 v = _mm256_set1_ps(fill_value); 11 | 12 | size_t i; 13 | for(i = 0; i < ((n)-(n%8)); i+=8){ 14 | _mm256_storeu_ps(z + i, v); 15 | } 16 | 17 | for(; i < n; i++){ 18 | z[i] = fill_value; 19 | } 20 | 21 | return z; 22 | } 23 | 24 | float *LNFloat32Vector_Add_AVX(float *z, const float *a, const float *b, size_t n){ 25 | size_t i; 26 | 27 | for(i = 0; i < ((n)-(n%8)); i+=8){ 28 | __m256 _a = _mm256_loadu_ps(a + i); 29 | __m256 _b = _mm256_loadu_ps(b + i); 30 | __m256 _z = _mm256_add_ps(_a, _b); 31 | _mm256_storeu_ps(z + i, _z); 32 | } 33 | 34 | for(; i < n; i++){ 35 | z[i] = a[i] + b[i]; 36 | } 37 | } 38 | 39 | float *LNFloat32Vector_Sub_AVX(float *z, const float *a, const float *b, size_t n){ 40 | size_t i; 41 | 42 | for(i = 0; i < ((n)-(n%8)); i+=8){ 43 | __m256 _a = _mm256_loadu_ps(a + i); 44 | __m256 _b = _mm256_loadu_ps(b + i); 45 | __m256 _z = _mm256_sub_ps(_a, _b); 46 | _mm256_storeu_ps(z + i, _z); 47 | } 48 | 49 | for(; i < n; i++){ 50 | z[i] = a[i] - b[i]; 51 | } 52 | } 53 | 54 | float *LNFloat32Vector_Mul_AVX(float *z, const float *a, const float *b, size_t n){ 55 | size_t i; 56 | 57 | for(i = 0; i < ((n)-(n%8)); i+=8){ 58 | __m256 _a = _mm256_loadu_ps(a + i); 59 | __m256 _b = _mm256_loadu_ps(b + i); 60 | __m256 _z = _mm256_mul_ps(_a, _b); 61 | _mm256_storeu_ps(z + i, _z); 62 | } 63 | 64 | for(; i < n; i++){ 65 | z[i] = a[i] * b[i]; 66 | } 67 | } 68 | 69 | float *LNFloat32Vector_Div_AVX(float *z, const float *a, const float *b, size_t n){ 70 | size_t i; 71 | 72 | for(i = 0; i < ((n)-(n%8)); i+=8){ 73 | __m256 _a = _mm256_loadu_ps(a + i); 74 | __m256 _b = _mm256_loadu_ps(b + i); 75 | __m256 _z = _mm256_add_ps(_a, _b); 76 | _mm256_storeu_ps(z + i, _z); 77 | } 78 | 79 | for(; i < n; i++){ 80 | z[i] = a[i] + b[i]; 81 | } 82 | } 83 | 84 | 85 | double *LNFloat64Vector_Fill_AVX(double *z, double fill_value, size_t n){ 86 | __m256d v = _mm256_set1_pd(fill_value); 87 | 88 | size_t i; 89 | for(i = 0; i < ((n)-(n%8)); i+=8){ 90 | _mm256_storeu_pd(z + i, v); 91 | } 92 | 93 | for(; i < n; i++){ 94 | z[i] = fill_value; 95 | } 96 | 97 | return z; 98 | } 99 | 100 | double *LNFloat64Vector_Add_AVX(double *z, const double *a, const double *b, size_t n){ 101 | size_t i; 102 | 103 | for(i = 0; i < ((n)-(n%4)); i+=4){ 104 | __m256d _a = _mm256_loadu_pd(a + i); 105 | __m256d _b = _mm256_loadu_pd(b + i); 106 | __m256d _z = _mm256_add_pd(_a, _b); 107 | _mm256_storeu_pd(z + i, _z); 108 | } 109 | 110 | for(; i < n; i++){ 111 | z[i] = a[i] + b[i]; 112 | } 113 | } 114 | 115 | double *LNFloat64Vector_Sub_AVX(double *z, const double *a, const double *b, size_t n){ 116 | size_t i; 117 | 118 | for(i = 0; i < ((n)-(n%4)); i+=4){ 119 | __m256d _a = _mm256_loadu_pd(a + i); 120 | __m256d _b = _mm256_loadu_pd(b + i); 121 | __m256d _z = _mm256_sub_pd(_a, _b); 122 | _mm256_storeu_pd(z + i, _z); 123 | } 124 | 125 | for(; i < n; i++){ 126 | z[i] = a[i] - b[i]; 127 | } 128 | } 129 | 130 | double *LNFloat64Vector_Mul_AVX(double *z, const double *a, const double *b, size_t n){ 131 | size_t i; 132 | 133 | for(i = 0; i < ((n)-(n%4)); i+=4){ 134 | __m256d _a = _mm256_loadu_pd(a + i); 135 | __m256d _b = _mm256_loadu_pd(b + i); 136 | __m256d _z = _mm256_mul_pd(_a, _b); 137 | _mm256_storeu_pd(z + i, _z); 138 | } 139 | 140 | for(; i < n; i++){ 141 | z[i] = a[i] * b[i]; 142 | } 143 | } 144 | 145 | double *LNFloat64Vector_Div_AVX(double *z, const double *a, const double *b, size_t n){ 146 | size_t i; 147 | 148 | for(i = 0; i < ((n)-(n%4)); i+=4){ 149 | __m256d _a = _mm256_loadu_pd(a + i); 150 | __m256d _b = _mm256_loadu_pd(b + i); 151 | __m256d _z = _mm256_div_pd(_a, _b); 152 | _mm256_storeu_pd(z + i, _z); 153 | } 154 | 155 | for(; i < n; i++){ 156 | z[i] = a[i] / b[i]; 157 | } 158 | } 159 | 160 | #endif -------------------------------------------------------------------------------- /src/core/simd/AVX512.c: -------------------------------------------------------------------------------- 1 | #ifdef __AVX512F__ 2 | 3 | #include 4 | #include 5 | #include 6 | #include "AVX512.h" 7 | 8 | float *LNFloat32Vector_Fill_AVX512(float *z, float fill_value, size_t n){ 9 | __m512 v = _mm512_set1_ps(fill_value); 10 | 11 | size_t i; 12 | for(i = 0; i < ((n)-(n%16)); i+=16){ 13 | _mm512_storeu_ps(z + i, v); 14 | } 15 | 16 | for(; i < n; i++){ 17 | z[i] = fill_value; 18 | } 19 | 20 | return z; 21 | } 22 | 23 | float *LNFloat32Vector_Add_AVX512(float *z, const float *a, const float *b, size_t n){ 24 | size_t i; 25 | for(i = 0; i < ((n)-(n%16)); i+=16){ 26 | __m512 _a = _mm512_loadu_ps(a + i); 27 | __m512 _b = _mm512_loadu_ps(b + i); 28 | __m512 _z = _mm512_add_ps(_a, _b); 29 | _mm512_storeu_ps(z + i, _z); 30 | } 31 | 32 | for(; i < n; i++){ 33 | z[i] = a[i] + b[i]; 34 | } 35 | 36 | return z; 37 | } 38 | 39 | float *LNFloat32Vector_Sub_AVX512(float *z, const float *a, const float *b, size_t n){ 40 | size_t i; 41 | for(i = 0; i < ((n)-(n%16)); i+=16){ 42 | __m512 _a = _mm512_loadu_ps(a + i); 43 | __m512 _b = _mm512_loadu_ps(b + i); 44 | __m512 _z = _mm512_sub_ps(_a, _b); 45 | _mm512_storeu_ps(z + i, _z); 46 | } 47 | 48 | for(; i < n; i++){ 49 | z[i] = a[i] - b[i]; 50 | } 51 | 52 | return z; 53 | } 54 | 55 | float *LNFloat32Vector_Mul_AVX512(float *z, const float *a, const float *b, size_t n){ 56 | size_t i; 57 | for(i = 0; i < ((n)-(n%16)); i+=16){ 58 | __m512 _a = _mm512_loadu_ps(a + i); 59 | __m512 _b = _mm512_loadu_ps(b + i); 60 | __m512 _z = _mm512_mul_ps(_a, _b); 61 | _mm512_storeu_ps(z + i, _z); 62 | } 63 | 64 | for(; i < n; i++){ 65 | z[i] = a[i] * b[i]; 66 | } 67 | 68 | return z; 69 | } 70 | 71 | float *LNFloat32Vector_Div_AVX512(float *z, const float *a, const float *b, size_t n){ 72 | size_t i; 73 | for(i = 0; i < ((n)-(n%16)); i+=16){ 74 | __m512 _a = _mm512_loadu_ps(a + i); 75 | __m512 _b = _mm512_loadu_ps(b + i); 76 | __m512 _z = _mm512_div_ps(_a, _b); 77 | _mm512_storeu_ps(z + i, _z); 78 | } 79 | 80 | for(; i < n; i++){ 81 | z[i] = a[i] / b[i]; 82 | } 83 | 84 | return z; 85 | } 86 | 87 | 88 | double *LNFloat64Vector_Fill_AVX512(double *z, double fill_value, size_t n){ 89 | __m512d v = _mm512_set1_pd(fill_value); 90 | 91 | size_t i; 92 | for(i = 0; i < ((n)-(n%8)); i+=8){ 93 | _mm512_storeu_pd(z + i, v); 94 | } 95 | 96 | for(; i < n; i++){ 97 | z[i] = fill_value; 98 | } 99 | 100 | return z; 101 | } 102 | 103 | double *LNFloat64Vector_Add_AVX512(double *z, const double *a, const double *b, size_t n){ 104 | size_t i; 105 | for(i = 0; i < ((n)-(n%8)); i+=8){ 106 | __m512d _a = _mm512_loadu_pd(a + i); 107 | __m512d _b = _mm512_loadu_pd(b + i); 108 | __m512d _z = _mm512_add_pd(_a, _b); 109 | _mm512_storeu_pd(z + i, _z); 110 | } 111 | 112 | for(; i < n; i++){ 113 | z[i] = a[i] + b[i]; 114 | } 115 | 116 | return z; 117 | } 118 | 119 | double *LNFloat64Vector_Sub_AVX512(double *z, const double *a, const double *b, size_t n){ 120 | size_t i; 121 | for(i = 0; i < ((n)-(n%8)); i+=8){ 122 | __m512d _a = _mm512_loadu_pd(a + i); 123 | __m512d _b = _mm512_loadu_pd(b + i); 124 | __m512d _z = _mm512_sub_pd(_a, _b); 125 | _mm512_storeu_pd(z + i, _z); 126 | } 127 | 128 | for(; i < n; i++){ 129 | z[i] = a[i] - b[i]; 130 | } 131 | 132 | return z; 133 | } 134 | 135 | double *LNFloat64Vector_Mul_AVX512(double *z, const double *a, const double *b, size_t n){ 136 | size_t i; 137 | for(i = 0; i < ((n)-(n%8)); i+=8){ 138 | __m512d _a = _mm512_loadu_pd(a + i); 139 | __m512d _b = _mm512_loadu_pd(b + i); 140 | __m512d _z = _mm512_mul_pd(_a, _b); 141 | _mm512_storeu_pd(z + i, _z); 142 | } 143 | 144 | for(; i < n; i++){ 145 | z[i] = a[i] * b[i]; 146 | } 147 | 148 | return z; 149 | } 150 | 151 | double *LNFloat64Vector_Div_AVX512(double *z, const double *a, const double *b, size_t n){ 152 | size_t i; 153 | for(i = 0; i < ((n)-(n%8)); i+=8){ 154 | __m512d _a = _mm512_loadu_pd(a + i); 155 | __m512d _b = _mm512_loadu_pd(b + i); 156 | __m512d _z = _mm512_div_pd(_a, _b); 157 | _mm512_storeu_pd(z + i, _z); 158 | } 159 | 160 | for(; i < n; i++){ 161 | z[i] = a[i] / b[i]; 162 | } 163 | 164 | return z; 165 | } 166 | 167 | #endif -------------------------------------------------------------------------------- /src/luajit/defs.lua: -------------------------------------------------------------------------------- 1 | -- LuaNdarray C-API functions definitions -- 2 | 3 | local ffi = require "ffi" 4 | 5 | ffi.cdef[[ 6 | 7 | typedef float float32_t; 8 | typedef double float64_t; 9 | 10 | typedef struct complex128_t complex128_t; 11 | typedef struct complex64_t complex64_t; 12 | 13 | typedef enum LNDTypes LNDTypes; 14 | 15 | typedef struct Ndarray_fields Ndarray; 16 | typedef struct LNTypeDescr LNTypeDescr; 17 | 18 | struct complex128_t{ 19 | float64_t realp; 20 | float64_t imagp; 21 | }; 22 | 23 | struct complex64_t{ 24 | float32_t realp; 25 | float32_t imagp; 26 | }; 27 | 28 | typedef unsigned char bool_t; 29 | 30 | enum LNDTypes{ 31 | LN_CHAR=0, 32 | LN_BOOL, 33 | 34 | LN_INT8, 35 | LN_INT16, 36 | LN_INT32, 37 | LN_INT64, 38 | 39 | LN_UINT8, 40 | LN_UINT16, 41 | LN_UINT32, 42 | LN_UINT64, 43 | 44 | LN_FLOAT32, 45 | LN_FLOAT64, 46 | 47 | LN_COMPLEX64, 48 | LN_COMPLEX128, 49 | 50 | LN_NUMTYPES 51 | }; 52 | 53 | // typedef void (*CastFunc)(void *dst, const void *src, LNDTypes newdtype, size_t n); 54 | typedef void (*CastFunc)(Ndarray *dst, const Ndarray *src, LNDTypes newtype); 55 | 56 | typedef void (*LNFillFunc)(void *vec, const void *v, size_t n); 57 | 58 | typedef Ndarray *(*LNAxisOperator)(Ndarray *arr, long long axis); 59 | typedef Ndarray *(*LNMapOperator)(Ndarray *arr); 60 | 61 | struct LNTypeDescr{ 62 | LNDTypes id; 63 | size_t alignment; 64 | size_t itemsize; 65 | 66 | char *name; 67 | char *fmt; 68 | 69 | CastFunc castfunc; 70 | LNAxisOperator max_axis_func; 71 | LNAxisOperator min_axis_func; 72 | LNAxisOperator sum_axis_func; 73 | 74 | LNMapOperator max_func; 75 | LNMapOperator min_func; 76 | LNMapOperator sum_func; 77 | }; 78 | 79 | /* ndarray struct */ 80 | struct Ndarray_fields{ 81 | /* data of the ndarray */ 82 | char *data; 83 | 84 | /* dimensions of the array */ 85 | size_t *dimensions; 86 | 87 | long long *strides; 88 | 89 | /* number of dimensions */ 90 | size_t nd; 91 | 92 | /* size of `data` (multiplication of the dimensions) */ 93 | size_t size; 94 | 95 | const LNTypeDescr *dtype; 96 | }; 97 | 98 | typedef enum LNCast_t{ 99 | LNCAST_UNSAFE=0, 100 | LNCAST_SAFE 101 | } LNCast_t; 102 | 103 | // types 104 | const LNTypeDescr *LNInt8; 105 | const LNTypeDescr *LNInt16; 106 | const LNTypeDescr *LNInt32; 107 | const LNTypeDescr *LNInt64; 108 | 109 | const LNTypeDescr *LNUInt8; 110 | const LNTypeDescr *LNUInt16; 111 | const LNTypeDescr *LNUInt32; 112 | const LNTypeDescr *LNUInt64; 113 | 114 | const LNTypeDescr *LNFloat32; 115 | const LNTypeDescr *LNFloat64; 116 | 117 | const LNTypeDescr *LNComplex64; 118 | const LNTypeDescr *LNComplex128; 119 | 120 | const LNTypeDescr *LNChar; 121 | const LNTypeDescr *LNBool; 122 | 123 | typedef struct LNError_t LNError_t; 124 | 125 | LNError_t LNExc_Error; 126 | 127 | int LNError_Ocurred(); 128 | char *LNError_Get(); 129 | 130 | void *LNMem_alloc(size_t bytes); 131 | 132 | void LNDType_Init(); 133 | const LNTypeDescr *LNDType_GetFromID(LNDTypes id); 134 | void LNDType_Free(LNTypeDescr *dtype); 135 | 136 | const LNTypeDescr *LNDType_Promote(const LNTypeDescr *t1, const LNTypeDescr *t2); 137 | 138 | Ndarray *LNArray_New(void *data, size_t *dims, long long *strides, size_t nd, const LNTypeDescr *dtype); 139 | Ndarray *LNArray_Zeros(size_t *dims, size_t nd, const LNTypeDescr *dtype); 140 | Ndarray *LNArray_Ones(size_t *dims, size_t nd, const LNTypeDescr *dtype); 141 | 142 | Ndarray *LNArray_Index(Ndarray *arr, long long idx); 143 | void LNArray_Free(Ndarray *arr); 144 | 145 | char *LNArray_toString(Ndarray *arr, const char *prefix, const char *sufix); 146 | 147 | void LNArray_BroadcastTo(Ndarray *out, Ndarray *arr, size_t *to, size_t nd); 148 | Ndarray *LNArray_Add(Ndarray *arr1, Ndarray *arr2); 149 | Ndarray *LNArray_CastTo(Ndarray *arr, const LNTypeDescr *newtype, LNCast_t casttype); 150 | int LNArray_CanCast(const LNTypeDescr *from, const LNTypeDescr *to, LNCast_t casttype); 151 | 152 | Ndarray *LNArray_Max(Ndarray *arr); 153 | Ndarray *LNArray_MaxAxis(Ndarray *arr, long long axis); 154 | 155 | Ndarray *LNArray_Empty(const size_t *dims, size_t ndim, const LNTypeDescr *dtype); 156 | void LNArray_MapDim(Ndarray *arr, long long dim); 157 | ]] 158 | 159 | ---@class ln.dtype* 160 | ---@field id ffi.cdata* 161 | ---@field name ffi.cdata* 162 | ---@field alignment ffi.cdata* 163 | ---@field itemsize ffi.cdata* 164 | 165 | ---@class ln.dtype 166 | ---@overload fun(data: any): ln.Ndarray 167 | ---@operator call(ln.dtype): ln.dtype 168 | ---@field name string 169 | ---@field alignment integer 170 | ---@field itemsize integer 171 | ---@field dtype ln.dtype* 172 | -------------------------------------------------------------------------------- /src/core/simd/SSE.c: -------------------------------------------------------------------------------- 1 | #ifdef __SSE__ 2 | 3 | #include 4 | #include 5 | #include 6 | #include "SSE.h" 7 | 8 | #if defined(__SSE4_2__) 9 | #include // SSE4.2 10 | #elif defined(__SSE4_1__) 11 | #include // SSE4.1 12 | #elif defined(__SSE3__) 13 | #include // SSE3 14 | #elif defined(__SSE2__) 15 | #include // SSE2 16 | #elif defined(__SSE__) 17 | #include // SSE 18 | #endif 19 | 20 | float *LNFloat32Vector_Fill_SSE(float *z, float fill_value, size_t n){ 21 | __m128 v = _mm_set1_ps(fill_value); 22 | 23 | size_t i; 24 | for(i = 0; i < ((n)-(n%4)); i+=4){ 25 | _mm_storeu_ps(z + i, v); 26 | } 27 | 28 | for(; i < n; i++){ 29 | z[i] = fill_value; 30 | } 31 | 32 | return z; 33 | } 34 | 35 | float *LNFloat32Vector_Add_SSE(float *z, const float *a, const float *b, size_t n){ 36 | size_t i; 37 | 38 | for(i = 0; i < ((n)-(n%4)); i+=4){ 39 | __m128 _a = _mm_loadu_ps(a + i); 40 | __m128 _b = _mm_loadu_ps(b + i); 41 | __m128 _z = _mm_add_ps(_a, _b); 42 | _mm_storeu_ps(z + i, _z); 43 | } 44 | 45 | for(; i < n; i++){ 46 | z[i] = a[i] + b[i]; 47 | } 48 | 49 | return z; 50 | } 51 | 52 | float *LNFloat32Vector_Sub_SSE(float *z, const float *a, const float *b, size_t n){ 53 | size_t i; 54 | 55 | for(i = 0; i < ((n)-(n%4)); i+=4){ 56 | __m128 _a = _mm_loadu_ps(a + i); 57 | __m128 _b = _mm_loadu_ps(b + i); 58 | __m128 _z = _mm_sub_ps(_a, _b); 59 | _mm_storeu_ps(z + i, _z); 60 | } 61 | 62 | for(; i < n; i++){ 63 | z[i] = a[i] - b[i]; 64 | } 65 | 66 | return z; 67 | } 68 | 69 | float *LNFloat32Vector_Div_SSE(float *z, const float *a, const float *b, size_t n){ 70 | size_t i; 71 | 72 | for(i = 0; i < ((n)-(n%4)); i+=4){ 73 | __m128 _a = _mm_loadu_ps(a + i); 74 | __m128 _b = _mm_loadu_ps(b + i); 75 | __m128 _z = _mm_div_ps(_a, _b); 76 | _mm_storeu_ps(z + i, _z); 77 | } 78 | 79 | for(; i < n; i++){ 80 | z[i] = a[i] / b[i]; 81 | } 82 | 83 | return z; 84 | } 85 | 86 | float *LNFloat32Vector_Mul_SSE(float *z, const float *a, const float *b, size_t n){ 87 | size_t i; 88 | 89 | for(i = 0; i < ((n)-(n%4)); i+=4){ 90 | __m128 _a = _mm_loadu_ps(a + i); 91 | __m128 _b = _mm_loadu_ps(b + i); 92 | __m128 _z = _mm_mul_ps(_a, _b); 93 | _mm_storeu_ps(z + i, _z); 94 | } 95 | 96 | for(; i < n; i++){ 97 | z[i] = a[i] * b[i]; 98 | } 99 | 100 | return z; 101 | } 102 | 103 | #ifdef __SSE2__ 104 | 105 | double *LNFloat64Vector_Fill_SSE(double *z, double fill_value, size_t n){ 106 | __m128d v = _mm_set1_pd(fill_value); 107 | 108 | size_t i; 109 | for(i = 0; i < ((n)-(n%2)); i+=2){ 110 | _mm_storeu_pd(z + i, v); 111 | } 112 | 113 | for(i=0; i < n; i++){ 114 | z[i] = fill_value; 115 | } 116 | 117 | return z; 118 | } 119 | 120 | double *LNFloat64Vector_Add_SSE(double *z, const double *a, const double *b, size_t n){ 121 | size_t i; 122 | 123 | for(i = 0; i < ((n)-(n%2)); i+=2){ 124 | __m128d _a = _mm_loadu_pd(a + i); 125 | __m128d _b = _mm_loadu_pd(b + i); 126 | __m128d _z = _mm_add_pd(_a, _b); 127 | _mm_storeu_pd(z + i, _z); 128 | } 129 | 130 | for(; i < n; i++){ 131 | z[i] = a[i] + b[i]; 132 | } 133 | 134 | return z; 135 | } 136 | 137 | double *LNFloat64Vector_Sub_SSE(double *z, const double *a, const double *b, size_t n){ 138 | size_t i; 139 | 140 | for(i = 0; i < ((n)-(n%2)); i+=2){ 141 | __m128d _a = _mm_loadu_pd(a + i); 142 | __m128d _b = _mm_loadu_pd(b + i); 143 | __m128d _z = _mm_sub_pd(_a, _b); 144 | _mm_storeu_pd(z + i, _z); 145 | } 146 | 147 | for(; i < n; i++){ 148 | z[i] = a[i] - b[i]; 149 | } 150 | 151 | return z; 152 | } 153 | 154 | double *LNFloat64Vector_Div_SSE(double *z, const double *a, const double *b, size_t n){ 155 | size_t i; 156 | 157 | for(i = 0; i < ((n)-(n%2)); i+=2){ 158 | __m128d _a = _mm_loadu_pd(a + i); 159 | __m128d _b = _mm_loadu_pd(b + i); 160 | __m128d _z = _mm_div_pd(_a, _b); 161 | _mm_storeu_pd(z + i, _z); 162 | } 163 | 164 | for(; i < n; i++){ 165 | z[i] = a[i] / b[i]; 166 | } 167 | 168 | return z; 169 | } 170 | 171 | double *LNFloat64Vector_Mul_SSE(double *z, const double *a, const double *b, size_t n){ 172 | size_t i; 173 | 174 | for(i = 0; i < ((n)-(n%4)); i+=4){ 175 | __m128d _a = _mm_loadu_pd(a + i); 176 | __m128d _b = _mm_loadu_pd(b + i); 177 | __m128d _z = _mm_mul_pd(_a, _b); 178 | _mm_storeu_pd(z + i, _z); 179 | } 180 | 181 | for(; i < n; i++){ 182 | z[i] = a[i] * b[i]; 183 | } 184 | 185 | return z; 186 | } 187 | 188 | #endif 189 | 190 | #endif 191 | -------------------------------------------------------------------------------- /docs/dtypes.md: -------------------------------------------------------------------------------- 1 | # dtypes 2 | 3 | ## what are? 4 | dtypes are specific data types such as int8, int16 etc. With them we can create integers for example of any size up to 64 bits for example an 8 bit integer would take up less memory than an integer 5 | 16, 32, 64 bits. But it would have less precision than these, an int8 varies from `-128` to `127` while an int64 varies from `-9,223,372,036,854,775,808` to `9,223,372,036,854,775,807` actually much more than an int8. On the other hand it takes up more memory than an int8. Use dtypes wisely! 6 | 7 | - `int8`: signed integer of 8 bits 8 | - `int16`: signed integer of 16 bits 9 | - `int32`: signed integer of 32 bits 10 | - `int64`: signed integer of 64 bits 11 | - `uint8`: signed integer of 8 bits 12 | - `uint16`: unsigned integer of 16 bits 13 | - `uint32`: unsigned integer of 32 bits 14 | - `uint64`: unsigned integer of 64 bits 15 | - `float32`: float of 32 bits 16 | - `float64`: float of 32 bits 17 | - `complex64`: complex number of 64 bits 18 | - `complex128`: complex number of 128 bits 19 | - `char`: single character (8 bits) 20 | - `bool`: 1 (`true`) or 0 (`false`) (8 bits) 21 | - `byte`: alias for `int8` 22 | 23 | wow, really a lot! 24 | 25 | # signed integers 26 | LuaNdarray, as we saw, has integers from 8 bits to 64 bits, now we will see an example of how to create arrays of this type: 27 | 28 | ```lua 29 | > ln = require "luandarray" 30 | > ln.int8({1,2}) -- Note that we can also create arrays of different types by calling the types as functions 31 | array({1 2}, dtype=int8) 32 | > ln.array(200, ln.int8) 33 | array(-56, dtype=int8) 34 | ``` 35 | The rule is the same for all other integers. 36 | 37 | # unsigned integers 38 | unsigned integers work like conventional integers, but they cannot be negative, so they support positive numbers much larger than signed integers, for example an 8-bit integer as we saw, goes from `-127` to `128`, and an unsigned integer 8-bit signal goes from `0` to `255`. They can be useful when we want large positive integers and don't need negative numbers. e.g.: 39 | ```lua 40 | > ln = require "luandarray" 41 | > ln.uint8({-5,-100}) -- Note that we can also create arrays of different types by calling the types as functions 42 | array({251 246}, dtype=uint8) 43 | > ln.array(200, ln.uint8) 44 | array(200, dtype=uint8) 45 | ``` 46 | see that this time, the number 200 worked correctly, but when we used -5 and -100 the results were unpredictable. 47 | 48 | # floats 49 | floating point numbers are like Lua numbers, which may or may not have numbers after the comma, LuaNdarray has 2 types of floating numbers: float32 and float64, with float64 having twice the precision but at the same time being twice as heavy, e.g.: 50 | ```lua 51 | > ln = require "luandarray" 52 | > ln.float32({10.6055543, -10.09392}) -- Note that we can also create arrays of different types by calling the types as functions 53 | array({10.605554580688 -10.093919754028}, dtype=float32) 54 | > ln.array({10.6055543, -10.09392}, ln.float64) 55 | array({10.6055543 -10.09392}, dtype=float64) 56 | ``` 57 | note that in float32 there was a precision problem, while in float64 the result was more accurate. 58 | 59 | # complex 60 | Complex numbers are numbers that have a real and imaginary part, in LuaNdarray there are 2 types of complex numbers: complex64 where the real and imaginary part are 32-bit floats and complex128 where the real and imaginary part are 64-bit floats. E.g.: 61 | 62 | ```lua 63 | > ln = require "luandarray" 64 | > ln.array({10+4*I, 1*I, I, -I, -100.54+1.54*I, 10}, ln.complex64) 65 | array({10+4i i i -i -100.5+1.54i 10}, dtype=complex64) 66 | > ln.array({10+4*I, 1*I, I, -I, -100.54+1.54*I, 10}, ln.complex128) 67 | array({10+4i i i -i -100.5+1.54i 10}, dtype=complex128) 68 | ``` 69 | 70 | Note: `I` is a global LuaNdarray variable that is represented by a complex number with the real part being 0 and the imaginary part being 1. 71 | 72 | # others 73 | Now let's talk about LuaNdarray's boolean and char types, booleans can represent `true` or `false` but LuaNdarray does not store them as 1 bit in memory, instead booleans occupy 8 bits (1 byte) in memory just like int8 . And the char type, which also occupies 8 bits but is treated as a character instead of a number. There is also the byte type, which is just a different name for `int8`. 74 | 75 | ```lua 76 | > ln = require "luandarray" 77 | > ln.array({'a', 'b', 'c'}, ln.char) -- or ln.char({'a', 'b', 'c'}) 78 | array({'a' 'b' 'c'}, dtype=char) 79 | > ln.array({1, 0, true, false}, ln.bool) -- or ln.bool({1, 0, true, false}) 80 | array({true false true false}, dtype=bool) 81 | > ln.array({1, 43, 127, -128}, ln.byte) -- or ln.byte({1, 43, 127, -128}) 82 | array({1 43 127 -128}, dtype=int8) 83 | ``` 84 | 85 | # IMPORTANT! 86 | for 64-bit integers, there may be a precision problem when converting the Lua number to an int64 or uint64, this is because int64/uint64 support integers larger than Lua itself, a solution is to avoid passing too large numbers when create an array with `ln.array` or any other constructor. 87 | -------------------------------------------------------------------------------- /src/core/arrayobj.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "arraytypes.h" 7 | #include "error.h" 8 | #include "arrayobj.h" 9 | #include "vector.h" 10 | #include "arrayindex.h" 11 | #include "buffer.h" 12 | 13 | void LNArray_Init(Ndarray *arr){ 14 | arr->data=NULL; 15 | arr->dimensions=NULL; 16 | arr->strides=NULL; 17 | arr->dtype=NULL; 18 | 19 | arr->nd=0; 20 | arr->size=0; 21 | } 22 | 23 | void LNArray_Debug(const Ndarray *arr){ 24 | size_t i; 25 | 26 | printf("*********************\n"); 27 | printf("dimensions={"); 28 | for(i=0;ind;i++){ 29 | printf("%zu\t",arr->dimensions[i]); 30 | } 31 | printf("}\n"); 32 | printf("strides={"); 33 | for(i=0;ind;i++){ 34 | printf("%lld\t",arr->strides[i]); 35 | } 36 | printf("}\n"); 37 | printf("size=%zu\n",arr->size); 38 | printf("dtype=%s\n",LNArray_TYPE(arr)->name); 39 | 40 | LNBuffer repr; 41 | LNBuff_Init(&repr); 42 | for(i=0;isize;i++){ 43 | LNBuff_addtype(&repr,arr->data+(i*arr->dtype->alignment),arr->dtype); 44 | LNBuff_addchar(&repr,','); 45 | } 46 | printf("arr->data={%s}\n",LNBuff_ADDR(&repr)); 47 | 48 | printf("*********************\n"); 49 | } 50 | 51 | Ndarray *LNArray_New(void *data, size_t *dims, long long *strides, size_t nd, const LNTypeDescr *dtype){ 52 | Ndarray *arr = LNArray_Alloc(); 53 | if(!arr) 54 | return NULL; 55 | 56 | arr->strides = strides; 57 | 58 | arr->dtype = dtype; 59 | 60 | arr->data = data; 61 | 62 | arr->dimensions = dims; 63 | arr->nd = nd; 64 | 65 | size_t i; 66 | arr->size = 1; 67 | if(!strides){ 68 | arr->strides=LNMem_alloc(sizeof(long long)*nd); 69 | if(!arr->strides) 70 | return NULL; 71 | for(i = arr->nd; i > 0; i--){ 72 | arr->strides[i-1] = arr->size*dtype->alignment; 73 | arr->size *= arr->dimensions[i-1]; 74 | } 75 | }else{ 76 | arr->strides = strides; 77 | } 78 | 79 | return arr; 80 | } 81 | 82 | 83 | 84 | Ndarray *LNArray_Copy(const Ndarray *arr){ 85 | Ndarray *copy = LNArray_Alloc(); 86 | if(!copy){ 87 | return NULL; 88 | } 89 | 90 | copy->dtype = arr->dtype; 91 | copy->nd = arr->nd; 92 | copy->dimensions = arr->dimensions; 93 | copy->size = arr->size; 94 | 95 | copy->strides = LNMem_alloc(sizeof(size_t)*copy->nd); 96 | if(!copy->strides) 97 | return NULL; 98 | 99 | copy->data = LNMem_alloc(copy->dtype->alignment * copy->size); 100 | if(!copy->data) 101 | return NULL; 102 | 103 | if(LNArray_IsContiguous(arr) || arr->size==1){ 104 | memcpy(copy->data, arr->data, arr->dtype->alignment * arr->size); 105 | } else{ 106 | long i; 107 | for(i=0;isize;i+=arr->strides[arr->nd-1]){ 108 | memcpy(copy->data+i, arr->data+i, LNArray_ALIGNMENT(arr)); 109 | } 110 | } 111 | 112 | return copy; 113 | } 114 | 115 | Ndarray *LNArray_NewScalar(const void *data, const LNTypeDescr *dtype){ 116 | Ndarray *arr = LNArray_Alloc(); 117 | if(!arr) 118 | return NULL; 119 | LNArray_Init(arr); 120 | 121 | arr->data = LNMem_alloc(dtype->alignment); 122 | if(!arr->data) 123 | return NULL; 124 | 125 | arr->size=1; 126 | arr->dtype=dtype; 127 | 128 | memcpy(arr->data, data, arr->dtype->alignment); 129 | 130 | return arr; 131 | } 132 | 133 | Ndarray *LNArray_New1D(void *data, size_t ax0, const LNTypeDescr *dtype){ 134 | Ndarray *arr = LNArray_Alloc(); 135 | if(!arr) 136 | return NULL; 137 | 138 | arr->dtype = dtype; 139 | arr->size = ax0; 140 | arr->nd = 1; 141 | 142 | arr->dimensions = LNMem_alloc(sizeof(size_t)); 143 | if(!arr->dimensions) 144 | return NULL; 145 | 146 | arr->strides = LNMem_alloc(sizeof(long long)); 147 | if(!arr->strides) 148 | return NULL; 149 | 150 | *arr->dimensions = ax0; 151 | *arr->strides = LNArray_ALIGNMENT(arr); 152 | 153 | arr->data = data; 154 | 155 | return arr; 156 | } 157 | 158 | Ndarray *LNArray_New2D(void *data, size_t ax0, size_t ax1, const LNTypeDescr *dtype){ 159 | Ndarray *arr = LNArray_Alloc(); 160 | if(!arr) 161 | return NULL; 162 | 163 | arr->dimensions = LNMem_alloc(sizeof(size_t)*2); 164 | if(!arr->dimensions) 165 | return NULL; 166 | 167 | arr->strides = LNMem_alloc(sizeof(long long)*2); 168 | if(!arr->strides) 169 | return NULL; 170 | 171 | arr->dimensions[0] = ax0; 172 | arr->dimensions[1] = ax1; 173 | 174 | arr->strides[1] = dtype->alignment; 175 | arr->strides[0] = arr->dimensions[0]*dtype->alignment; 176 | 177 | arr->dtype = dtype; 178 | arr->size = ax0*ax1; 179 | arr->nd = 2; 180 | 181 | arr->data = data; 182 | 183 | return arr; 184 | } 185 | 186 | int LNArray_IsContiguous(const Ndarray *arr){ 187 | size_t i; 188 | size_t size=1; 189 | long long curstride; 190 | for(i=arr->nd; i>0; i--){ 191 | curstride=size*LNArray_ALIGNMENT(arr); 192 | if(arr->strides[i-1] != curstride) 193 | return false; 194 | size*=arr->dimensions[i-1]; 195 | } 196 | return true; 197 | } 198 | 199 | void LNArray_Free(Ndarray *arr){ 200 | if(arr){ 201 | if(arr->data) 202 | free(arr->data); 203 | if(arr->dimensions) 204 | free(arr->dimensions); 205 | if(arr->strides) 206 | free(arr->strides); 207 | free(arr); 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /ospp.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | -- MIT License 4 | -- 5 | -- Copyright (c) 2023 LuaUtils 6 | -- 7 | -- Permission is hereby granted, free of charge, to any person obtaining a copy 8 | -- of this software and associated documentation files (the "Software"), to deal 9 | -- in the Software without restriction, including without limitation the rights 10 | -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | -- copies of the Software, and to permit persons to whom the Software is 12 | -- furnished to do so, subject to the following conditions: 13 | -- 14 | -- The above copyright notice and this permission notice shall be included in all 15 | -- copies or substantial portions of the Software. 16 | -- 17 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | -- SOFTWARE. 24 | 25 | -- O.S library expansion 26 | 27 | local os = require("os") 28 | local io = require("io") 29 | 30 | ---@class ospplib: oslib 31 | local ospp = {} 32 | setmetatable(ospp, {__index = os}) 33 | 34 | ---@return "win"|"unix" 35 | function ospp.get() 36 | return package.config:sub(1,1) == "\\" and "win" or "unix" 37 | end 38 | 39 | ---@type "nul"|"/dev/null" 40 | ospp.devnull = (ospp.get() == "win") and "nul" or "/dev/null" 41 | 42 | local join_paths, adjust_path 43 | 44 | if ospp.get() == "win" then 45 | function join_paths(...) 46 | return table.concat({...}, "\\"):gsub("/", "\\"):gsub("\\+", "\\") 47 | end 48 | 49 | function adjust_path(path) 50 | path = path:gsub("/", "\\") 51 | return path 52 | end 53 | else 54 | function join_paths(...) 55 | return table.concat({...}, "/"):gsub("\\", "/"):gsub("/+", "/") 56 | end 57 | 58 | function adjust_path(path) 59 | path = path:gsub("\\", "/") 60 | return path 61 | end 62 | end 63 | 64 | do 65 | local get_path_cmd = ospp.get() == "win" and "cd" or "pwd" 66 | 67 | ---@return string | nil 68 | function ospp.curdir() 69 | local cmd = io.popen(get_path_cmd) 70 | if not cmd then 71 | return nil 72 | end 73 | 74 | local path = cmd:read() 75 | cmd:close() 76 | 77 | return path 78 | end 79 | end 80 | 81 | do 82 | local copy_cmd = ospp.get() == "win" and "copy" or "cp -r" 83 | function ospp.copy(src, dst) 84 | src = adjust_path(src) 85 | dst = adjust_path(dst) 86 | 87 | io.popen(copy_cmd .. ' "' .. src .. '" "' .. dst .. '"') 88 | end 89 | end 90 | 91 | do 92 | local disk = ospp.get() == "win" and "C:\\" or "/" 93 | function ospp.move(path, to) 94 | local new_path 95 | if path:sub(1, #disk) == disk then 96 | new_path = adjust_path(to) 97 | else 98 | new_path = join_paths(to, path) 99 | end 100 | 101 | os.rename(path, adjust_path(new_path)) 102 | 103 | return new_path 104 | end 105 | end 106 | 107 | function ospp.mkdir(dirname) 108 | os.execute('mkdir "' .. dirname .. '"') 109 | end 110 | 111 | if ospp.get() == "win" then 112 | function ospp.exists(path) 113 | path = path:gsub("/", "\\"):gsub("\\+", "\\") 114 | return io.popen('if exist "'..path..'" (echo ok)'):read() == "ok" 115 | end 116 | 117 | function ospp.listdir(dirpath) 118 | if dirpath == nil then dirpath = "." end 119 | dirpath = dirpath:gsub("/", "\\"):gsub("\\+", "\\") 120 | 121 | if not ospp.exists(dirpath) then 122 | return nil 123 | end 124 | 125 | local files = {} 126 | for file in io.popen('dir "' .. dirpath .. '" /b /a'):lines() do 127 | table.insert(files, file) 128 | end 129 | 130 | return files 131 | end 132 | 133 | function ospp.setenv(name, value) 134 | io.popen('setx ' .. name .. ' "' .. value .. '"'):close() 135 | end 136 | 137 | function ospp.rmdir(path) 138 | path = path:gsub("/", "\\"):gsub("\\+", "\\") 139 | if not ospp.exists(path) then 140 | return false 141 | end 142 | io.popen('rmdir /s /q "'..path..'"') 143 | return true 144 | end 145 | else -- unix 146 | function ospp.exists(path) 147 | path = path:gsub("\\", "/"):gsub("/+", "/") 148 | return io.popen('[ -e "' .. path .. '" ] && echo ok'):read() == "ok" 149 | end 150 | 151 | function ospp.listdir(dirpath) 152 | if dirpath == nil then dirpath = "." end 153 | dirpath = dirpath:gsub("\\", "/"):gsub("/+", "/") 154 | 155 | if not ospp.exists(dirpath) then 156 | return nil 157 | end 158 | 159 | local p = io.popen('ls -A1 "'..dirpath..'"') 160 | local files = {} 161 | 162 | -- Read the output line by line 163 | for file in p:lines() do 164 | table.insert(files, file) 165 | end 166 | 167 | p:close() 168 | return files 169 | end 170 | 171 | function ospp.setenv(name, value) 172 | io.popen('export ' .. name .. '="' .. value .. '"') 173 | end 174 | 175 | function ospp.rmdir(path) 176 | path = path:gsub("\\", "/"):gsub("/+", "/") 177 | if not ospp.exists(path) then 178 | return false 179 | end 180 | io.popen('rm -rf "' .. path .. '"') 181 | return true 182 | end 183 | end 184 | 185 | function ospp.isfile(path) 186 | local f = io.open(path, "r") 187 | 188 | return f and (io.type(f) == "file" or io.type(f) == "closed file") 189 | end 190 | 191 | return ospp 192 | 193 | -------------------------------------------------------------------------------- /src/core/buffer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "error.h" 8 | #include "buffer.h" 9 | 10 | void LNBuff_Init(LNBuffer *b){ 11 | b->buff = NULL; 12 | b->n = 0; 13 | } 14 | 15 | void LNBuff_addchar(LNBuffer *b, char chr){ 16 | b->buff = LNMem_realloc(b->buff, b->n+2); 17 | if(LNError_Ocurred()){ 18 | return; 19 | } 20 | b->buff[b->n] = chr; 21 | b->buff[b->n+1] = '\0'; 22 | b->n++; 23 | } 24 | 25 | void LNBuff_addlstring(LNBuffer *b, const char *str, size_t l){ 26 | b->buff = LNMem_realloc(b->buff, b->n + l + 1); 27 | memcpy(b->buff + b->n, str, l); 28 | b->n += l; 29 | b->buff[b->n] = '\0'; 30 | // b->buff = LNMem_realloc(b->buff, b->n + l + 1); 31 | // if(LNError_Ocurred()) 32 | // return; 33 | // memcpy(b->buff + b->n, str, l); 34 | // b->buff[b->n + l] = '\0'; 35 | 36 | // b->n += l; 37 | } 38 | 39 | void LNBuff_addstring(LNBuffer *b, const char *str){ 40 | return LNBuff_addlstring(b, str, strlen(str)); 41 | } 42 | 43 | void LNBuff_addfstring(LNBuffer *b, const char *fmt, ...){ 44 | va_list args; 45 | va_start(args, fmt); 46 | int n = vsnprintf(NULL, 0, fmt, args); 47 | va_end(args); 48 | va_start(args, fmt); 49 | char *res = malloc(n+1); 50 | vsnprintf(res, n+1, fmt, args); 51 | LNBuff_addlstring(b, res, n); 52 | va_end(args); 53 | } 54 | 55 | void LNBuff_addtype(LNBuffer *b, const void *data, const LNTypeDescr *type){ 56 | switch (type->id){ 57 | case LN_INT8: 58 | LNBuff_addfstring(b, "%" PRId8, *(const int8_t*)data); 59 | break; 60 | case LN_INT16: 61 | LNBuff_addfstring(b, "%" PRId16, *(const int16_t*)data); 62 | break; 63 | case LN_INT32: 64 | LNBuff_addfstring(b, "%" PRId32, *(const int32_t*)data); 65 | break; 66 | case LN_INT64: 67 | LNBuff_addfstring(b, "%" PRId64, *(const int64_t*)data); 68 | break; 69 | 70 | case LN_UINT8: 71 | LNBuff_addfstring(b, "%" PRIu8, *(const uint8_t*)data); 72 | break; 73 | case LN_UINT16: 74 | LNBuff_addfstring(b, "%" PRIu16, *(const uint16_t*)data); 75 | break; 76 | case LN_UINT32: 77 | LNBuff_addfstring(b, "%" PRIu32, *(const uint32_t*)data); 78 | break; 79 | case LN_UINT64: 80 | LNBuff_addfstring(b, "%" PRIu64, *(const uint64_t*)data); 81 | break; 82 | 83 | case LN_FLOAT32: 84 | LNBuff_addfstring(b, LNDTYPE_FLOAT32_FMT, *(const float32_t*)data); 85 | break; 86 | case LN_FLOAT64: 87 | LNBuff_addfstring(b, LNDTYPE_FLOAT64_FMT, *(const float64_t*)data); 88 | break; 89 | 90 | /* 91 | local r,i=re(c),im(c) 92 | if i==0 then 93 | return tostring(r) 94 | elseif r==0 then 95 | if i==1 then 96 | return "i" 97 | elseif i==-1 then 98 | return "-i" 99 | end 100 | return i.."i" 101 | elseif i<0 then 102 | if i==-1 then 103 | return r.."-i" 104 | end 105 | return r..i.."i" 106 | else 107 | if i==1 then 108 | return r.."+i" 109 | end 110 | return r.."+"..i.."i" 111 | end 112 | */ 113 | case LN_COMPLEX64:{ 114 | float32_t r =((const complex64_t*)data)->realp, i=((const complex64_t*)data)->imagp; 115 | if(i==0){ 116 | LNBuff_addfstring(b, "%.4g", r); 117 | }else if(r==0){ 118 | if(i==1){ 119 | LNBuff_addchar(b, 'i'); 120 | } else if(i==-1){ 121 | LNBuff_addstring(b, "-i"); 122 | } else{ 123 | LNBuff_addfstring(b, "%.4gi", i); 124 | } 125 | } else if(i<0){ 126 | if(i==-1){ 127 | LNBuff_addfstring(b, "%.4g-i",r); 128 | } else{ 129 | LNBuff_addfstring(b, "%.4g%.4gi",r,i); 130 | } 131 | } else{ 132 | if(i==1){ 133 | LNBuff_addfstring(b, "%.4g+i", r); 134 | } else{ 135 | LNBuff_addfstring(b, "%.4g+%.4gi",r,i); 136 | } 137 | } 138 | break; 139 | } 140 | case LN_COMPLEX128:{ 141 | float64_t r = ((const complex128_t*)data)->realp, i=((const complex128_t*)data)->imagp; 142 | if(i==0){ 143 | LNBuff_addfstring(b, "%.4g", r); 144 | }else if(r==0){ 145 | if(i==1){ 146 | LNBuff_addchar(b, 'i'); 147 | } else if(i==-1){ 148 | LNBuff_addstring(b, "-i"); 149 | } else{ 150 | LNBuff_addfstring(b, "%.4gi", i); 151 | } 152 | } else if(i<0){ 153 | if(i==-1){ 154 | LNBuff_addfstring(b, "%.4g-i",r); 155 | } else{ 156 | LNBuff_addfstring(b, "%.4g%.4gi",r,i); 157 | } 158 | } else{ 159 | if(i==1){ 160 | LNBuff_addfstring(b, "%.4g+i", r); 161 | } else{ 162 | LNBuff_addfstring(b, "%.4g+%.4gi",r,i); 163 | } 164 | } 165 | break; 166 | } 167 | 168 | case LN_CHAR: 169 | switch(*(const char*)data){ 170 | case '\n': 171 | LNBuff_addstring(b, "'\\n'"); 172 | break; 173 | case '\t': 174 | LNBuff_addstring(b, "'\\t'"); 175 | break; 176 | case '\0': 177 | LNBuff_addstring(b, "''"); 178 | break; 179 | default: 180 | LNBuff_addfstring(b, "'%c'", *(const char*)data); 181 | break; 182 | } 183 | break; 184 | case LN_BOOL: 185 | LNBuff_addstring(b, *((const bool_t*)data) ? "true" : "false"); 186 | break; 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /src/core/arrayaplly.h: -------------------------------------------------------------------------------- 1 | #ifndef LUANDARRAY_SRC_CORE_ARRAYAPLLY_H_ 2 | #define LUANDARRAY_SRC_CORE_ARRAYAPLLY_H_ 3 | 4 | #define LN_VECTOR_APPLY_CONTIG(VEC, DIMS, STRIDES, NDIM, CODE)\ 5 | do{\ 6 | long long __i,__j;\ 7 | long long *INDEX_SEQ=(long long*)LNMem_alloc((NDIM)*sizeof(long long));\ 8 | for(__i=0; __i < (NDIM); __i++)\ 9 | INDEX_SEQ[__i]=0;\ 10 | \ 11 | while(1){\ 12 | void *item = (void*)(VEC);\ 13 | for(__i=0; __i<(NDIM); __i++){\ 14 | item = (void*)((char*)item + (INDEX_SEQ[__i]*((STRIDES)[__i])));\ 15 | }\ 16 | CODE\ 17 | int finish=true;\ 18 | for(__i=0; __i < (NDIM); __i++){\ 19 | if(((DIMS)[__i])-1!=INDEX_SEQ[__i]){\ 20 | finish=false;\ 21 | break;\ 22 | }\ 23 | }\ 24 | if(finish)\ 25 | break;\ 26 | INDEX_SEQ[(NDIM)-1]++;\ 27 | for(__i=(NDIM)-1; __i>0; __i--){\ 28 | if(INDEX_SEQ[__i]>=((DIMS)[__i])){\ 29 | for(__j=__i; __j >= 0; __j--){\ 30 | INDEX_SEQ[__j]++;\ 31 | }\ 32 | INDEX_SEQ[__i] = 0;\ 33 | }\ 34 | }\ 35 | }\ 36 | }while(0) 37 | 38 | 39 | #define LN_VECTOR_APPLY_D(VEC, STRIDES, DIMS, DIM, NDIM, CODE)\ 40 | do{\ 41 | long __i, __j;\ 42 | size_t __axis_size = 1;\ 43 | size_t __axis_n = 1;\ 44 | for(__i = 0; __i < (DIM)+1; __i++)\ 45 | __axis_n *= (DIMS)[__i];\ 46 | for(__i = (DIM)+1; __i < (NDIM); __i++)\ 47 | __axis_size *= (DIMS)[__i];\ 48 | void *item = ((void*)VEC);\ 49 | for(__i = 0; __i < __axis_n; __i++){\ 50 | CODE\ 51 | item = (void*)((char*)item + (STRIDES)[DIM]);\ 52 | }\ 53 | }while(0) 54 | 55 | // do{\ 56 | // long long __i,__j;\ 57 | // long long *INDEX_SEQ=(long long*)LNMem_alloc(((DIM)+1)*sizeof(long long));\ 58 | // for(__i=0; __i < (DIM); __i++){\ 59 | // INDEX_SEQ[__i]=0;\ 60 | // }\ 61 | // size_t __axis_size = 1;\ 62 | // for(__i=(DIM)+1; __i < (NDIM); __i++){\ 63 | // __axis_size *= (DIMS)[__i];\ 64 | // }\ 65 | // \ 66 | // while(1){\ 67 | // void *item = (void*)(VEC);\ 68 | // for(__i=0; __i<(DIM); __i++){\ 69 | // item = (void*)((char*)item + (INDEX_SEQ[__i]*((STRIDES)[__i])));\ 70 | // }\ 71 | // CODE\ 72 | // int finish=true;\ 73 | // for(__i=0; __i < (DIM)+1; __i++){\ 74 | // if(((DIMS)[__i])-1!=INDEX_SEQ[__i]){\ 75 | // finish=false;\ 76 | // break;\ 77 | // }\ 78 | // }\ 79 | // if(finish)\ 80 | // break;\ 81 | // INDEX_SEQ[(DIM)]++;\ 82 | // for(__i=(DIM); __i>0; __i--){\ 83 | // if(INDEX_SEQ[__i]>((DIMS)[__i])){\ 84 | // for(__j=__i; __j >= 0; __j--){\ 85 | // INDEX_SEQ[__j]++;\ 86 | // }\ 87 | // INDEX_SEQ[__i] = 0;\ 88 | // }\ 89 | // }\ 90 | // }\ 91 | // }while(0) 92 | 93 | #define LN_ARRAY_APPLY_CONTIG(ARRAY, CODE)\ 94 | LN_VECTOR_APPLY_CONTIG((ARRAY)->data, (ARRAY)->dimensions, (ARRAY)->strides, (ARRAY)->nd, CODE)\ 95 | 96 | #define LN_ARRAY_APPLY_D(ARRAY, DIM, CODE)\ 97 | LN_VECTOR_APPLY_D((ARRAY)->data, (ARRAY)->strides, (ARRAY)->dimensions, DIM, (ARRAY)->nd, CODE)\ 98 | 99 | #define LN_VECTOR_APPLY2_CONTIG(VEC1, VEC2, DIMS1, DIMS2, STRIDES1, STRIDES2, NDIM, CODE)\ 100 | long long __i,__j;\ 101 | long long *INDEX_SEQ=(long long*)LNMem_alloc((NDIM)*sizeof(long long));\ 102 | for(__i=0; __i < (NDIM); __i++)\ 103 | INDEX_SEQ[__i]=0;\ 104 | \ 105 | while(1){\ 106 | void *item1 = VEC1;\ 107 | void *item2 = VEC2;\ 108 | for(__i=0; __i < (NDIM); __i++){\ 109 | item1 = (char*)item1 + INDEX_SEQ[__i]*(STRIDES1)[__i];\ 110 | item2 = (char*)item2 + INDEX_SEQ[__i]*(STRIDES2)[__i];\ 111 | }\ 112 | CODE\ 113 | int finish=true;\ 114 | for(__i=0; __i < (NDIM); __i++){\ 115 | if((DIMS1)[__i]!=INDEX_SEQ[__i]){\ 116 | finish=false;\ 117 | break;\ 118 | }\ 119 | }\ 120 | if(finish)\ 121 | break;\ 122 | INDEX_SEQ[(NDIM)]++;\ 123 | for(__i=(NDIM); __i>0; __i--){\ 124 | if(INDEX_SEQ[__i]>=(DIMS1)[__i]){\ 125 | for(__j=__i; __j > 0; __j++)\ 126 | INDEX_SEQ[__j]++;\ 127 | INDEX_SEQ[__i] = 0;\ 128 | }\ 129 | }\ 130 | }\ 131 | 132 | #define LN_ARRAY_APPLY2_CONTIG(ARRAY1, ARRAY2, CODE)\ 133 | LN_VECTOR_APPLY2_CONTIG((ARRAY1)->data, (ARRAY2)->data, (ARRAY1)->dimensions, (ARRAY2)->dimensions, (ARRAY1)->strides, (ARRAY2)->strides, (ARRAY1)->nd, CODE) 134 | 135 | #define LN_ARRAY_APPLY2_D(ARRAY1, ARRAY2, DIM, CODE)\ 136 | long long i,j;\ 137 | long *INDEX_SEQ=(long long*)LNMem_alloc(ARRAY->nd*sizeof(size_t));\ 138 | for(i=0; i < DIM; i++)\ 139 | INDEX_SEQ[i]=0;\ 140 | \ 141 | size_t AXIS_LEN=1;\ 142 | for(i=DIM; i < ARRAY1->nd; i+=){\ 143 | AXIS_LEN *= ARRAY1->dimensions[i];\ 144 | }\ 145 | while(1){\ 146 | void *item1 = LNArray_MultiIndex(ARRAY1, INDEX_SEQ, DIM);\ 147 | void *item2 = LNArray_MultiIndex(ARRAY2, INDEX_SEQ, DIM);\ 148 | CODE\ 149 | int finish=true;\ 150 | for(i=dim; i < ARRAY->nd; i++){\ 151 | if(ARRAY->dimensions!=INDEX_SEQ[i-dim]){\ 152 | finish=false;\ 153 | break;\ 154 | }\ 155 | }\ 156 | if(finish)\ 157 | break;\ 158 | INDEX_SEQ[ARRAY1->nd]++;\ 159 | for(i=ARRAY->nd-1; i>0; i--){\ 160 | if(INDEX_SEQ[i]>=ARRAY1->dimensions[i]){\ 161 | for(j=i; j > 0; j++)\ 162 | INDEX_SEQ[j]++;\ 163 | INDEX_SEQ[i] = 0;\ 164 | }\ 165 | }\ 166 | }\ 167 | 168 | #endif -------------------------------------------------------------------------------- /src/lua/include/lauxlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Auxiliary functions for building Lua libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lauxlib_h 9 | #define lauxlib_h 10 | 11 | 12 | #include 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | 18 | #if defined(LUA_COMPAT_GETN) 19 | LUALIB_API int (luaL_getn) (lua_State *L, int t); 20 | LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); 21 | #else 22 | #define luaL_getn(L,i) ((int)lua_objlen(L, i)) 23 | #define luaL_setn(L,i,j) ((void)0) /* no op! */ 24 | #endif 25 | 26 | #if defined(LUA_COMPAT_OPENLIB) 27 | #define luaI_openlib luaL_openlib 28 | #endif 29 | 30 | 31 | /* extra error code for `luaL_load' */ 32 | #define LUA_ERRFILE (LUA_ERRERR+1) 33 | 34 | 35 | typedef struct luaL_Reg { 36 | const char *name; 37 | lua_CFunction func; 38 | } luaL_Reg; 39 | 40 | 41 | 42 | LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, 43 | const luaL_Reg *l, int nup); 44 | LUALIB_API void (luaL_register) (lua_State *L, const char *libname, 45 | const luaL_Reg *l); 46 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); 47 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 48 | LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); 49 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); 50 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, 51 | size_t *l); 52 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, 53 | const char *def, size_t *l); 54 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); 55 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); 56 | 57 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); 58 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, 59 | lua_Integer def); 60 | 61 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); 62 | LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); 63 | LUALIB_API void (luaL_checkany) (lua_State *L, int narg); 64 | 65 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); 66 | LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); 67 | 68 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); 69 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); 70 | 71 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, 72 | const char *const lst[]); 73 | 74 | LUALIB_API int (luaL_ref) (lua_State *L, int t); 75 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 76 | 77 | LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); 78 | LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, 79 | const char *name); 80 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 81 | 82 | LUALIB_API lua_State *(luaL_newstate) (void); 83 | 84 | 85 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, 86 | const char *r); 87 | 88 | LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, 89 | const char *fname, int szhint); 90 | 91 | 92 | 93 | 94 | /* 95 | ** =============================================================== 96 | ** some useful macros 97 | ** =============================================================== 98 | */ 99 | 100 | #define luaL_argcheck(L, cond,numarg,extramsg) \ 101 | ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) 102 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 103 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) 104 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) 105 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) 106 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) 107 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) 108 | 109 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) 110 | 111 | #define luaL_dofile(L, fn) \ 112 | (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) 113 | 114 | #define luaL_dostring(L, s) \ 115 | (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) 116 | 117 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) 118 | 119 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) 120 | 121 | /* 122 | ** {====================================================== 123 | ** Generic Buffer manipulation 124 | ** ======================================================= 125 | */ 126 | 127 | 128 | 129 | typedef struct luaL_Buffer { 130 | char *p; /* current position in buffer */ 131 | int lvl; /* number of strings in the stack (level) */ 132 | lua_State *L; 133 | char buffer[LUAL_BUFFERSIZE]; 134 | } luaL_Buffer; 135 | 136 | #define luaL_addchar(B,c) \ 137 | ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ 138 | (*(B)->p++ = (char)(c))) 139 | 140 | /* compatibility only */ 141 | #define luaL_putchar(B,c) luaL_addchar(B,c) 142 | 143 | #define luaL_addsize(B,n) ((B)->p += (n)) 144 | 145 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); 146 | LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); 147 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); 148 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); 149 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); 150 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); 151 | 152 | 153 | /* }====================================================== */ 154 | 155 | 156 | /* compatibility with ref system */ 157 | 158 | /* pre-defined references */ 159 | #define LUA_NOREF (-2) 160 | #define LUA_REFNIL (-1) 161 | 162 | #define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ 163 | (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) 164 | 165 | #define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) 166 | 167 | #define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) 168 | 169 | 170 | #define luaL_reg luaL_Reg 171 | 172 | #endif -------------------------------------------------------------------------------- /src/core/generic/vector.c: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #define LN_GENERIC_FILE "generic/vector.c" 3 | #else 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #define LN_DEFAULT_VECTOR_OP(op)\ 10 | for(i = 0; i < n; i++){\ 11 | z[i] = a[i] op b[i];\ 12 | } 13 | 14 | #if defined(LN_REAL_IS_COMPLEX) 15 | 16 | real *LNVector_(Fill)(real *v, real fill_value, size_t n){ 17 | size_t i; 18 | for(i=0;i 2 | #include 3 | #include 4 | #include 5 | 6 | #include "arraydtype.h" 7 | #include "error.h" 8 | #include "arrayobj.h" 9 | #include "arrayinis.h" 10 | #include "vector.h" 11 | 12 | Ndarray *LNArray_Empty(const size_t *dims, size_t ndim, const LNTypeDescr *dtype){ 13 | Ndarray *arr = LNArray_Alloc(); 14 | if(!arr) 15 | return NULL; 16 | 17 | arr->dimensions = LNMem_alloc(sizeof(size_t)*ndim); 18 | if(!arr->dimensions)return NULL; 19 | 20 | arr->strides = LNMem_alloc(sizeof(long long)*ndim); 21 | if(!arr->strides) 22 | return NULL; 23 | 24 | arr->dtype = dtype; 25 | arr->nd = ndim; 26 | 27 | size_t i; 28 | arr->size = 1; 29 | for(i = arr->nd; i > 0; i--){ 30 | arr->dimensions[i-1] = dims[i-1]; 31 | arr->strides[i-1] = arr->size*dtype->alignment; 32 | arr->size *= arr->dimensions[i-1]; 33 | } 34 | 35 | arr->data = LNMem_alloc(arr->dtype->alignment * arr->size); 36 | if(!arr->data) 37 | return NULL; 38 | 39 | return arr; 40 | } 41 | 42 | Ndarray *LNArray_Zeros(const size_t *dims, size_t ndim, const LNTypeDescr *dtype){ 43 | Ndarray *arr = LNArray_Alloc(); 44 | if(!arr) 45 | return NULL; 46 | 47 | arr->dimensions = LNMem_alloc(sizeof(size_t)*ndim); 48 | if(!arr->dimensions)return NULL; 49 | 50 | arr->strides = LNMem_alloc(sizeof(long long)*ndim); 51 | if(!arr->strides) 52 | return NULL; 53 | 54 | arr->dtype = dtype; 55 | arr->nd = ndim; 56 | 57 | size_t i; 58 | arr->size = 1; 59 | for(i = arr->nd; i > 0; i--){ 60 | arr->dimensions[i-1] = dims[i-1]; 61 | arr->strides[i-1] = arr->size*dtype->alignment; 62 | arr->size *= arr->dimensions[i-1]; 63 | } 64 | 65 | arr->data = LNMem_calloc(arr->dtype->alignment, arr->size); 66 | if(!arr->data) 67 | return NULL; 68 | 69 | return arr; 70 | } 71 | 72 | Ndarray *LNArray_Ones_(Ndarray *out, const size_t *dims, size_t ndim, const LNTypeDescr *dtype){ 73 | out->dimensions = LNMem_alloc(sizeof(size_t)*ndim); 74 | if(!out->dimensions)return NULL; 75 | 76 | out->strides = LNMem_alloc(sizeof(long long)*ndim); 77 | if(!out->strides) 78 | return NULL; 79 | 80 | out->dtype = dtype; 81 | out->nd = ndim; 82 | 83 | size_t i; 84 | out->size = 1; 85 | for(i = out->nd; i > 0; i--){ 86 | out->dimensions[i-1] = dims[i-1]; 87 | out->strides[i-1] = out->size*dtype->alignment; 88 | out->size *= out->dimensions[i-1]; 89 | } 90 | 91 | out->data = LNMem_alloc(out->dtype->alignment*out->size); 92 | if(!out->data) 93 | return NULL; 94 | 95 | switch(LNArray_TYPE(out)->id){ 96 | case LN_BOOL: 97 | case LN_CHAR: 98 | case LN_UINT8: 99 | case LN_INT8: 100 | LNInt8Vector_Fill((int8_t*)out->data, 1, out->size); 101 | break; 102 | 103 | case LN_UINT16: 104 | case LN_INT16: 105 | LNInt16Vector_Fill((int16_t*)out->data, 1, out->size); 106 | break; 107 | 108 | case LN_UINT32: 109 | case LN_INT32: 110 | LNInt32Vector_Fill((int32_t*)out->data, 1, out->size); 111 | break; 112 | 113 | case LN_UINT64: 114 | case LN_INT64: 115 | LNInt64Vector_Fill((int64_t*)out->data, 1, out->size); 116 | break; 117 | 118 | case LN_FLOAT32: 119 | LNFloat32Vector_Fill((float32_t*)out->data, 1.0f, out->size); 120 | break; 121 | 122 | case LN_FLOAT64: 123 | LNFloat64Vector_Fill((float64_t*)out->data, 1.0f, out->size); 124 | break; 125 | 126 | case LN_COMPLEX64: 127 | LNComplex64Vector_Fill((complex64_t*)out->data, (complex64_t){1.0f,0.0f}, out->size); 128 | break; 129 | case LN_COMPLEX128: 130 | LNComplex128Vector_Fill((complex128_t*)out->data, (complex128_t){1.0f,0.0f}, out->size); 131 | break; 132 | } 133 | 134 | return out; 135 | } 136 | 137 | Ndarray *LNArray_Ones(const size_t *dims, size_t ndim, const LNTypeDescr *dtype){ 138 | Ndarray *out = LNArray_Alloc(); 139 | if(!out) 140 | return NULL; 141 | 142 | return LNArray_Ones_(out, dims, ndim, dtype); 143 | } 144 | 145 | Ndarray *LNArray_Range_(Ndarray *out, double start, double stop, double step, const LNTypeDescr *dtype){ 146 | if(LNDType_IsInt(dtype->id) || LNDType_IsUInt(dtype->id)){ 147 | start = (long long)start; 148 | stop = (long long)stop; 149 | step = (long long)step; 150 | } 151 | 152 | // Empty Ndarray. 153 | if(start > stop){ 154 | out->dimensions = NULL; 155 | out->strides = NULL; 156 | out->data = NULL; 157 | out->size = 0; 158 | out->nd = 0; 159 | out->dtype = dtype; 160 | return out; 161 | } 162 | 163 | out->dimensions = LNMem_alloc(sizeof(size_t)); 164 | if(!out->dimensions) 165 | return NULL; 166 | 167 | out->strides = LNMem_alloc(sizeof(long long)); 168 | if(!out->strides) 169 | return NULL; 170 | 171 | out->size = (size_t)ceil((stop-start)/step); 172 | 173 | out->data = LNMem_alloc(dtype->alignment*out->size); 174 | if(!out->data) 175 | return NULL; 176 | 177 | out->nd = 1; 178 | out->dimensions[0] = out->size; 179 | out->strides[0] = dtype->alignment; 180 | out->dtype = dtype; 181 | 182 | size_t p; 183 | switch(dtype->id){ 184 | case LN_BOOL: 185 | case LN_CHAR: 186 | case LN_UINT8: 187 | case LN_INT8: 188 | LNInt8Vector_Range((int8_t*)out->data, start, stop, step); 189 | break; 190 | 191 | case LN_UINT16: 192 | case LN_INT16: 193 | LNInt16Vector_Range((int16_t*)out->data, start, stop, step); 194 | break; 195 | 196 | case LN_UINT32: 197 | case LN_INT32: 198 | LNInt32Vector_Range((int32_t*)out->data, start, stop, step); 199 | break; 200 | 201 | case LN_UINT64: 202 | case LN_INT64: 203 | LNInt64Vector_Range((int64_t*)out->data, start, stop, step); 204 | break; 205 | 206 | case LN_FLOAT32: 207 | LNFloat32Vector_Range((float32_t*)out->data, start, stop, step); 208 | break; 209 | 210 | case LN_FLOAT64: 211 | LNFloat64Vector_Range((float64_t*)out->data, start, stop, step); 212 | break; 213 | 214 | case LN_COMPLEX64: 215 | LNComplex64Vector_Range((complex64_t*)out->data, start, stop, step); 216 | break; 217 | 218 | case LN_COMPLEX128: 219 | LNComplex128Vector_Range((complex128_t*)out->data, start, stop, step); 220 | break; 221 | } 222 | 223 | return out; 224 | } 225 | 226 | Ndarray *LNArray_Range(double start, double stop, double step, const LNTypeDescr *dtype){ 227 | Ndarray *arr = LNArray_Alloc(); 228 | if(!arr) 229 | return NULL; 230 | return LNArray_Range_(arr, start, stop, step, dtype); 231 | } 232 | 233 | #undef CASE 234 | -------------------------------------------------------------------------------- /src/core/generic/arraymath.c: -------------------------------------------------------------------------------- 1 | #ifndef LN_GENERIC_FILE 2 | #define LN_GENERIC_FILE "generic/arraymath.c" 3 | #else 4 | 5 | #include "../arrayobj.h" 6 | #include "../arraydtype.h" 7 | #include "../arrayaplly.h" 8 | #include "../utils.h" 9 | 10 | Ndarray *LNMath_(SumAxis)(Ndarray *arr, long long axis){ 11 | Ndarray *res = LNArray_Alloc(); 12 | if(!res) 13 | return NULL; 14 | 15 | res->nd = arr->nd - 1; 16 | res->size = arr->size / arr->dimensions[axis]; 17 | 18 | res->dimensions = LNMem_alloc(sizeof(size_t)*res->nd); 19 | if(!res->dimensions) 20 | return NULL; 21 | 22 | res->strides = LNMem_alloc(sizeof(long long)*res->nd); 23 | if(!res->strides) 24 | return NULL; 25 | 26 | res->data = LNMem_alloc(sizeof(real) * res->size); 27 | if(!res->data) 28 | return NULL; 29 | 30 | res->dtype = RealDType; 31 | 32 | memcpy(res->dimensions, arr->dimensions, sizeof(size_t) * axis); 33 | memcpy(res->dimensions+axis, arr->dimensions+axis, sizeof(size_t) * (arr->nd-axis)); 34 | 35 | long long i, j; 36 | size_t axis_size=1; 37 | for(i=axis; i < arr->nd; i++){ 38 | axis_size *= arr->dimensions[i]; 39 | } 40 | 41 | size_t curpos=0; 42 | for(i=0; i < arr->dimensions[axis]; i++){ 43 | real *axis_data = (real*)(arr->data + (i * arr->strides[axis])); 44 | 45 | LN_VECTOR_APPLY_CONTIG(axis_data, arr->dimensions+axis, arr->strides+axis, res->nd, 46 | #if defined(LN_REAL_IS_COMPLEX) 47 | ((real*)res->data)[curpos].realp += (*(real*)item).realp; 48 | ((real*)res->data)[curpos].imagp += (*(real*)item).imagp; 49 | #else 50 | ((real*)res->data)[curpos] += *(real*)item; 51 | #endif 52 | ); 53 | 54 | curpos++; 55 | } 56 | 57 | return res; 58 | } 59 | 60 | Ndarray *LNMath_(MaxAxis)(Ndarray *arr, long long axis){ 61 | Ndarray *res = LNArray_Alloc(); 62 | if(!res) 63 | return NULL; 64 | 65 | res->nd = arr->nd - 1; 66 | res->size = arr->size / arr->dimensions[axis]; 67 | 68 | res->dimensions = LNMem_alloc(sizeof(size_t)*res->nd); 69 | if(!res->dimensions) 70 | return NULL; 71 | 72 | res->strides = LNMem_alloc(sizeof(long long)*res->nd); 73 | if(!res->strides) 74 | return NULL; 75 | 76 | res->data = LNMem_alloc(sizeof(real) * res->size); 77 | if(!res->data) 78 | return NULL; 79 | 80 | res->dtype = RealDType; 81 | 82 | memcpy(res->dimensions, arr->dimensions, sizeof(size_t) * axis); 83 | memcpy(res->dimensions+axis, arr->dimensions+axis, sizeof(size_t) * (arr->nd-axis)); 84 | 85 | long long i, j; 86 | size_t axis_size=1; 87 | for(i=axis; i < arr->nd; i++){ 88 | axis_size *= arr->dimensions[i]; 89 | } 90 | 91 | size_t curpos=0; 92 | for(i=0; i < arr->dimensions[axis]; i++){ 93 | real *axis_data = (real*)(arr->data + (i * arr->strides[axis])); 94 | real max_v = *axis_data; 95 | 96 | LN_VECTOR_APPLY_CONTIG(axis_data, arr->dimensions+axis, arr->strides+axis, res->nd, 97 | #if defined(LN_REAL_IS_COMPLEX) 98 | if(((*(real*)item).realp > max_v.realp) && ((*(real*)item).imagp > max_v.imagp)){ 99 | max_v = *(real*)item; 100 | } 101 | #else 102 | if(*(real*)item > max_v){ 103 | max_v = *(real*)item; 104 | } 105 | #endif 106 | ); 107 | 108 | curpos++; 109 | } 110 | 111 | return res; 112 | } 113 | 114 | Ndarray *LNMath_(MinAxis)(Ndarray *arr, long long axis){ 115 | Ndarray *res = LNArray_Alloc(); 116 | if(!res) 117 | return NULL; 118 | 119 | res->nd = arr->nd - 1; 120 | res->size = arr->size / arr->dimensions[axis]; 121 | 122 | res->dimensions = LNMem_alloc(sizeof(size_t)*res->nd); 123 | if(!res->dimensions) 124 | return NULL; 125 | 126 | res->strides = LNMem_alloc(sizeof(long long)*res->nd); 127 | if(!res->strides) 128 | return NULL; 129 | 130 | res->data = LNMem_alloc(sizeof(real) * res->size); 131 | if(!res->data) 132 | return NULL; 133 | 134 | res->dtype = RealDType; 135 | 136 | memcpy(res->dimensions, arr->dimensions, sizeof(size_t) * axis); 137 | memcpy(res->dimensions+axis, arr->dimensions+axis, sizeof(size_t) * (arr->nd-axis)); 138 | 139 | long long i, j; 140 | size_t axis_size=1; 141 | for(i=axis; i < arr->nd; i++){ 142 | axis_size *= arr->dimensions[i]; 143 | } 144 | 145 | // LN_ARRAY_APPLY_D(arr, axis, 146 | 147 | // ) 148 | // size_t curpos=0; 149 | // for(i=0; i < arr->dimensions[axis]; i++){ 150 | // real *axis_data = (real*)(arr->data + (i * arr->strides[axis])); 151 | // real min_v = *axis_data; 152 | 153 | // LN_VECTOR_APPLY_D(axis_data) 154 | // // LN_VECTOR_APPLY_CONTIG(axis_data, arr->dimensions+axis, arr->strides+axis, res->nd, 155 | // // #if defined(LN_REAL_IS_COMPLEX) 156 | // // if(((*(real*)item).realp < min_v.realp) && ((*(real*)item).imagp < min_v.imagp)){ 157 | // // min_v = *(real*)item; 158 | // // } 159 | // // #else 160 | // // if(*(real*)item < min_v){ 161 | // // min_v = *(real*)item; 162 | // // } 163 | // // #endif 164 | // // ) 165 | 166 | // curpos++; 167 | // } 168 | 169 | return res; 170 | } 171 | 172 | Ndarray *LNMath_(Max)(Ndarray *arr){ 173 | Ndarray *res = LNArray_Alloc(); 174 | if(!res) 175 | return NULL; 176 | 177 | res->data = LNMem_alloc(sizeof(real)); 178 | if(!res->data) 179 | return NULL; 180 | 181 | *(real*)res->data = *(real*)arr->data; 182 | 183 | res->nd = 0; 184 | res->size = 1; 185 | res->strides = NULL; 186 | res->dimensions = NULL; 187 | res->dtype = RealDType; 188 | 189 | LN_ARRAY_APPLY_CONTIG(arr, 190 | #if defined(LN_REAL_IS_COMPLEX) 191 | if((*(real*)item).realp > (*(real*)res->data).realp && (*(real*)item).imagp > (*(real*)res->data).imagp){ 192 | *(real*)res->data = *(real*)item; 193 | } 194 | #else 195 | if(*(real*)item > *(real*)res->data){ 196 | *(real*)res->data = *(real*)item; 197 | } 198 | #endif 199 | ); 200 | 201 | return res; 202 | } 203 | 204 | Ndarray *LNMath_(Min)(Ndarray *arr){ 205 | Ndarray *res = LNArray_Alloc(); 206 | if(!res) 207 | return NULL; 208 | 209 | res->data = LNMem_alloc(sizeof(real)); 210 | if(!res->data) 211 | return NULL; 212 | 213 | *(real*)res->data = *(real*)arr->data; 214 | 215 | res->nd = 0; 216 | res->size = 1; 217 | res->strides = NULL; 218 | res->dimensions = NULL; 219 | res->dtype = RealDType; 220 | 221 | real max_v = *(real*)arr->data; 222 | LN_ARRAY_APPLY_CONTIG(arr, 223 | #if defined(LN_REAL_IS_COMPLEX) 224 | if((*(real*)item).realp < (*(real*)res->data).realp && (*(real*)item).imagp < (*(real*)res->data).imagp){ 225 | *(real*)res->data = *(real*)item; 226 | } 227 | #else 228 | if(*(real*)item < *(real*)res->data){ 229 | *(real*)res->data = *(real*)item; 230 | } 231 | #endif 232 | ); 233 | 234 | return res; 235 | } 236 | 237 | Ndarray *LNMath_(Sum)(Ndarray *arr){ 238 | Ndarray *res = LNArray_Alloc(); 239 | if(!res) 240 | return NULL; 241 | 242 | res->data = LNMem_alloc(sizeof(real)); 243 | if(!res->data) 244 | return NULL; 245 | 246 | res->nd = 0; 247 | res->size = 1; 248 | res->strides = NULL; 249 | res->dimensions = NULL; 250 | res->dtype = RealDType; 251 | 252 | #if defined(LN_REAL_IS_COMPLEX) 253 | *(real*)res->data = (real){.realp=0, .imagp=0}; 254 | #else 255 | *(real*)res->data = 0; 256 | #endif 257 | LN_ARRAY_APPLY_CONTIG(arr, 258 | #if defined(LN_REAL_IS_COMPLEX) 259 | (*(real*)res->data).realp += (*(real*)item).realp; 260 | (*(real*)res->data).imagp += (*(real*)item).imagp; 261 | #else 262 | *(real*)res->data += *(real*)item; 263 | #endif 264 | ); 265 | 266 | return res; 267 | } 268 | 269 | #endif -------------------------------------------------------------------------------- /src/lua/src/ndarray.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include "luand.h" 8 | #include "conf.h" 9 | #include "ndarray.h" 10 | 11 | static const luaL_Reg metatable[] = { 12 | {"__tostring", ln_array__tostring}, 13 | {"__gc", ln_array__gc}, 14 | //{"__add", ln_array__add}, 15 | {NULL, NULL} 16 | }; 17 | 18 | void ln_array_init(lua_State *L){ 19 | luaL_newmetatable(L, LN_NDARRAY_MT);; 20 | luaND_setfuncs(L, metatable, 0); 21 | lua_pop(L, 1); 22 | } 23 | 24 | 25 | /* auxiliar functions */ 26 | size_t *ln_table2dims(lua_State *L, int idx, size_t l){ 27 | size_t *vec = (size_t*)luaND_alloc(L, sizeof(size_t) * l); 28 | lua_pushvalue(L, idx); 29 | 30 | size_t i; 31 | for(i = 0; i < l; i++){ 32 | lua_pushinteger(L, (lua_Integer)i + 1); 33 | lua_gettable(L, -2); 34 | 35 | lua_Integer num = lua_tonumber(L, -1); 36 | if(num < 0){ 37 | luaL_error(L, "negatives index are not allowed"); 38 | return NULL; 39 | } 40 | 41 | vec[i] = (size_t)num; 42 | lua_pop(L, 1); 43 | } 44 | 45 | return vec; 46 | } 47 | 48 | #define ln_tonumber(L, idx) (lua_isboolean((L), (idx)) ? lua_toboolean((L), (idx)) : lua_tonumber((L), (idx))) 49 | 50 | #define CASE(id, t)\ 51 | case id:\ 52 | for(i = 0; i < n; i++){\ 53 | lua_rawgeti(L, idx, i+1);\ 54 | ((t*)vec)[i] = (t)ln_tonumber(L, -1);\ 55 | lua_pop(L, 1);\ 56 | }\ 57 | break\ 58 | 59 | // transforms a lua table into a C array based on the `dtype` 60 | void *ln_table2vector(lua_State *L, int idx, const LNTypeDescr *dtype){ 61 | size_t i, n; 62 | n = luaND_len(L, idx); 63 | 64 | void *vec = luaND_alloc(L, dtype->alignment * n); 65 | switch(dtype->id){ 66 | case LN_UINT8: 67 | CASE(LN_INT8, int8_t); 68 | 69 | case LN_UINT16: 70 | CASE(LN_INT16, int16_t); 71 | 72 | case LN_UINT32: 73 | CASE(LN_INT32, int32_t); 74 | 75 | case LN_UINT64: 76 | CASE(LN_INT64, int64_t); 77 | 78 | CASE(LN_FLOAT32, float); 79 | CASE(LN_FLOAT64, double); 80 | } 81 | 82 | return vec; 83 | } 84 | /********************************* */ 85 | 86 | int ln_array_zeros(lua_State *L){ 87 | size_t ndim = luaND_len(L, 1); 88 | size_t *dims = ln_table2dims(L, 1, ndim); 89 | const LNTypeDescr *dtype = luaND_optdtype(L, 2, LNDType_GetFromID(LN_FLOAT64)); 90 | 91 | Ndarray *arr = LNArray_Zeros(dims, ndim, dtype); 92 | if(LNError_Ocurred()){ 93 | luaL_error(L, LNError_Get()); 94 | return 0; 95 | } 96 | 97 | luaND_pushndarray(L, arr); 98 | return 1; 99 | } 100 | 101 | int ln_array_ones(lua_State *L){ 102 | size_t ndim = luaND_len(L, 1); 103 | size_t *dims = ln_table2dims(L, 1, ndim); 104 | 105 | const LNTypeDescr *dtype = luaND_optdtype(L, 2, LNDType_GetFromID(LN_FLOAT64)); 106 | 107 | Ndarray *arr = LNArray_Ones(dims, ndim, dtype); 108 | if(LNError_Ocurred()){ 109 | luaL_error(L, LNError_Get()); 110 | return 0; 111 | } 112 | 113 | luaND_pushndarray(L, arr); 114 | 115 | return 1; 116 | } 117 | 118 | int ln_array_empty(lua_State *L){ 119 | size_t ndim = luaND_len(L, 1); 120 | size_t *dims = ln_table2dims(L, 1, ndim); 121 | const LNTypeDescr *dtype = luaND_optdtype(L, 2, LNDType_GetFromID(LN_FLOAT64)); 122 | 123 | Ndarray *arr = LNArray_Empty(dims, ndim, dtype); 124 | if(LNError_Ocurred()){ 125 | luaL_error(L, LNError_Get()); 126 | return 0; 127 | } 128 | 129 | luaND_pushndarray(L, arr); 130 | return 1; 131 | } 132 | 133 | int ln_array_arange(lua_State *L){ 134 | lua_Number start, stop, step; 135 | const LNTypeDescr *dtype; 136 | switch(lua_gettop(L)){ 137 | case 2: 138 | start = 1; 139 | stop = luaL_checknumber(L, 1); 140 | step = 1; 141 | dtype = luaND_optdtype(L, 2, LNDType_GetFromID(LN_FLOAT64)); 142 | 143 | break; 144 | 145 | case 3: 146 | start = luaL_checknumber(L, 1); 147 | stop = luaL_checknumber(L, 2); 148 | step = 1; 149 | dtype = luaND_optdtype(L, 3, LNDType_GetFromID(LN_FLOAT64)); 150 | break; 151 | 152 | case 4: 153 | start = luaL_checknumber(L, 1); 154 | stop = luaL_checknumber(L, 2); 155 | step = luaL_checknumber(L, 3); 156 | dtype = luaND_optdtype(L, 4, LNDType_GetFromID(LN_FLOAT64)); 157 | break; 158 | 159 | default: 160 | luaL_error(L, "wrong number of arguments to 'arange'"); 161 | break; 162 | } 163 | Ndarray *res = LNArray_Range(start, stop, step, dtype); 164 | luaND_pushndarray(L, res); 165 | 166 | return 1; 167 | } 168 | 169 | static void collectInfo(lua_State *L, Ndarray *out){ 170 | while(1){ 171 | out->nd++; 172 | out->dimensions = luaND_realloc(L, out->dimensions, sizeof(size_t)*out->nd); 173 | out->dimensions[out->nd-1] = luaND_len(L, -1); 174 | 175 | lua_rawgeti(L, -1, 1); 176 | if(!lua_istable(L, -1)){ 177 | break; 178 | } 179 | } 180 | lua_pop(L, out->nd-1); 181 | 182 | out->strides = luaND_alloc(L, sizeof(long long) * out->nd); 183 | 184 | size_t i; 185 | out->size = 1; 186 | for(i=0; i < out->nd; i++){ 187 | out->strides[out->nd - i - 1] = sizeof(LNArray_ALIGNMENT(out))*out->size; 188 | out->size *= out->dimensions[i]; 189 | } 190 | 191 | out->data = luaND_alloc(L, LNArray_ALIGNMENT(out)*out->size); 192 | 193 | size_t *INDEX = luaND_alloc(L, sizeof(size_t)*out->nd); 194 | for(i=0; ind; i++){ 195 | INDEX[i] = 0; 196 | } 197 | } 198 | 199 | static int ln_array_int32build(lua_State *L){ 200 | Ndarray *arr = LNArray_Alloc(); 201 | LNArray_Init(arr); 202 | arr->dtype = LNDType_GetFromID(LN_INT32); 203 | collectInfo(L, arr); 204 | 205 | size_t i, p = 0; 206 | size_t *INDEX = luaND_alloc(L, sizeof(size_t)*arr->nd); 207 | while(1){ 208 | for(i=0; i < arr->nd; i++){ 209 | lua_rawgeti(L, -1, INDEX[i]+1); 210 | } 211 | p++; 212 | 213 | arr->data[p] = luaL_checknumber(L, -1); 214 | 215 | if(p == arr->size){ 216 | break; 217 | } 218 | 219 | INDEX[arr->nd-1]++; 220 | } 221 | 222 | luaND_pushndarray(L, arr); 223 | return 1; 224 | } 225 | 226 | // function ln.ndarray(data, shape, strides, dtype) 227 | 228 | static const LNTypeDescr *ln_aux_getdtype(lua_State *L, int obj){ 229 | int tp = lua_type(L, obj); 230 | 231 | if(tp == LUA_TNUMBER){ 232 | luaND_pushdtype(L, LN_INT64); 233 | } 234 | } 235 | 236 | int ln_array_new(lua_State *L){ 237 | int top = lua_gettop(L); 238 | 239 | if(top == 2){ /* flags? */ 240 | lua_getfield(L, 2, "shape"); 241 | lua_getfield(L, 2, "strides"); 242 | lua_getfield(L, 2, "dtype"); 243 | lua_remove(L, 2); 244 | } else if(top != 4){ 245 | luaL_error(L, "wrong number of arguments to 'ndarray'"); 246 | return 0; 247 | } 248 | 249 | size_t *shape = NULL; 250 | size_t nd = 0; 251 | size_t size = 1; 252 | const LNTypeDescr *dtype = luaND_checkdtype(L, 4); 253 | 254 | switch(luaND_type(L, 2)){ 255 | case LUA_TTABLE: 256 | nd = luaND_len(L, 2); 257 | shape = ln_table2dims(L, 2, nd); 258 | 259 | /* is not needed to calculate the size if strides are nil */ 260 | if(!lua_isnil(L, 3)){ 261 | size_t i; 262 | for(i=0; i < nd; i++){ 263 | size *= shape[i]; 264 | } 265 | } 266 | break; 267 | } 268 | 269 | long long *strides = luaND_alloc(L, sizeof(long long)*nd); 270 | if(lua_isnil(L, 3)){ /* strides */ 271 | size_t i; 272 | size = 1; 273 | for(i = nd; i > 0; i--){ 274 | strides[i-1] = size*dtype->alignment; 275 | size *= shape[i-1]; 276 | } 277 | } else { 278 | size_t i; 279 | for(i=0; i < nd; i++){ 280 | lua_rawgeti(L, 3, i+1); 281 | if(!lua_isnumber(L, -1)){ 282 | free(strides); 283 | free(shape); 284 | luaL_error(L, "%s cannot be interpreted as an integer", luaL_typename(L, -1)); 285 | return 0; 286 | } 287 | 288 | strides[i] = lua_tonumber(L, -1); 289 | 290 | lua_pop(L, 1); 291 | } 292 | } 293 | 294 | 295 | size_t i; 296 | Ndarray *res = (Ndarray*)luaND_alloc(L, sizeof(Ndarray)); 297 | 298 | res->data = ln_table2vector(L, 1, dtype); 299 | res->size = size; 300 | res->nd = nd; 301 | res->dimensions = shape; 302 | res->strides = strides; 303 | res->dtype = dtype; 304 | 305 | luaND_pushndarray(L, res); 306 | 307 | return 1; 308 | } 309 | 310 | //int ln_array(lua_State *L){ 311 | // const LNTypeDescr *dtype = luaND_checkdtype(L, 2); 312 | // 313 | // size_t ndim = 0, i; 314 | // size_t *shape = malloc(0); 315 | // 316 | // lua_pushvalue(L, 1); 317 | // while (lua_type(L, -1) == LUA_TTABLE){ 318 | // ndim += 1; 319 | // 320 | // 321 | // if(lua_type(L, -1) == LUA_TTABLE){ 322 | // size_t len = lua_objlen(L, -1); 323 | // lua_rawgeti(L, 1); 324 | // size_t exp_len = lua_objlen(L, 1); 325 | // 326 | // for(i=2; i <= len; i++){ 327 | // lua_rawgeti(L, i); 328 | // if(mustbe_table && lua_type(L, -1) != LUA_TTABLE){ 329 | // 330 | // } 331 | // 332 | // size_t sub_len = lua_objlen(L, -1); 333 | // if(sub_len != exp_len){ 334 | // 335 | // } 336 | // lua_pop(L, 1); 337 | // } 338 | // } 339 | // 340 | // if(!realloc(shape, sizeof(size_t)*ndim)){ 341 | // luaL_error(L, "was not possible to allocate the shape vector") 342 | // return 0; 343 | // } 344 | // 345 | // shape[ndim-1] = len; 346 | // } 347 | // lua_pop(L, ndim); 348 | // 349 | //} 350 | 351 | // __tostring meta method 352 | int ln_array__tostring(lua_State *L){ 353 | Ndarray *arr = luaND_checkndarray(L, 1); 354 | 355 | char *repr = LNArray_toString(arr, "array(", ")"); 356 | if(LNError_Ocurred()){ 357 | luaL_error(L, LNError_Get()); 358 | return 0; 359 | } 360 | 361 | lua_pushstring(L, repr); 362 | return 1; 363 | } 364 | 365 | int ln_array__gc(lua_State *L){ 366 | Ndarray *arr = luaND_checkndarray(L, 1); 367 | LNArray_Free(arr); 368 | return 0; 369 | } 370 | 371 | -------------------------------------------------------------------------------- /src/core/arraymath.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include"arrayobj.h" 5 | #include"arraydtype.h" 6 | #include"arraymath.h" 7 | #include"arrayindex.h" 8 | #include"arrayaplly.h" 9 | #include"arraycast.h" 10 | #include"error.h" 11 | #include"vector.h" 12 | #include"buffer.h" 13 | 14 | #define LNMath_(name) LN_CONCAT4(LN, Real, Array_, name) 15 | #define LNRealDType LN_CONCAT2(LN, Real) 16 | 17 | #include "generic/arraymath.c" 18 | #include "LNGenerateAllTypes.h" 19 | 20 | #undef LNMath_ 21 | #undef LNRealDType 22 | 23 | #define TEST printf("TEST on %d\n", __LINE__) 24 | 25 | void LNArray_BroadcastTo(Ndarray *out, Ndarray *arr, size_t *to, size_t nd){ 26 | size_t i, j; 27 | 28 | 29 | size_t new_ndim = LN_MAX(arr->nd, nd); 30 | 31 | size_t *arrdims_expanded = LNMem_alloc(sizeof(size_t) * new_ndim); 32 | if(!arrdims_expanded) 33 | return; 34 | 35 | size_t *to_expanded = LNMem_alloc(sizeof(size_t) * new_ndim); 36 | if(!to_expanded) 37 | return; 38 | 39 | for(i = 0; i < new_ndim; i++){ 40 | arrdims_expanded[i] = 1; 41 | to_expanded[i] = 1; 42 | } 43 | 44 | memcpy(arrdims_expanded + (new_ndim - arr->nd), arr->dimensions, sizeof(size_t)*arr->nd); 45 | memcpy(to_expanded + (new_ndim - nd), to, sizeof(size_t)*nd); 46 | 47 | for(i = new_ndim; i > 0; i++){ 48 | if(!((arrdims_expanded[i-1] == to_expanded[i-1]) || (arrdims_expanded[i-1] == 1))){ 49 | LNBuffer errmsg; 50 | LNBuff_Init(&errmsg); 51 | 52 | LNBuff_addchar(&errmsg, '{'); 53 | for(j = 0; j < arr->nd; j++) 54 | LNBuff_addfstring(&errmsg, "%zu,", arr->dimensions[j]); 55 | LNBuff_addstring(&errmsg, "} "); 56 | 57 | LNBuff_addchar(&errmsg, '{'); 58 | for(j = 0; j < nd; j++) 59 | LNBuff_addfstring(&errmsg, "%zu,", to[j]); 60 | LNBuff_addchar(&errmsg, '}'); 61 | LNBuff_addfstring(&errmsg, " shapes at dim %zu does not match", i-1); 62 | 63 | LNError_setString(LNBuff_ADDR(&errmsg)); 64 | return; 65 | } 66 | } 67 | 68 | out->dtype = arr->dtype; 69 | out->nd = new_ndim; 70 | out->dimensions = LNMem_alloc(sizeof(size_t) * out->nd); 71 | if(!out->dimensions) 72 | return; 73 | 74 | out->strides = LNMem_alloc(sizeof(long long) * out->nd); 75 | if(!out->strides) 76 | return; 77 | 78 | 79 | size_t new_size = 1; 80 | out->size = 1; 81 | for(i = out->nd; i > 0; i--){ 82 | out->dimensions[i-1] = arrdims_expanded[i-1]; 83 | out->strides[i-1] = out->size * LNArray_ALIGNMENT(out); 84 | out->size *= out->dimensions[i-1]; 85 | new_size *= to_expanded[i-1]; 86 | } 87 | 88 | out->data = LNMem_alloc(LNArray_ALIGNMENT(out) * new_size); 89 | if(!out->data) 90 | return; 91 | memcpy(out->data, arr->data, LNArray_ALIGNMENT(arr) * arr->size); 92 | 93 | size_t expanded_size; 94 | char *expanded = LNMem_alloc(LNArray_ALIGNMENT(out) * new_size); 95 | 96 | if(!LNArray_IsContiguous(arr)){ 97 | 98 | } 99 | 100 | i = new_ndim; 101 | while(i > 0){ 102 | i--; 103 | 104 | size_t diff = to_expanded[i] - arrdims_expanded[i] + 1; 105 | expanded_size = 0; 106 | LN_ARRAY_APPLY_D(out, i, 107 | for(j = 0; j < diff; j++){ 108 | memcpy(expanded + expanded_size, item, LNArray_ALIGNMENT(out)*__axis_size); 109 | expanded_size += __axis_size; 110 | } 111 | ); 112 | 113 | out->size /= out->dimensions[i]; 114 | out->dimensions[i] = to_expanded[i]; 115 | out->size *= out->dimensions[i]; 116 | 117 | memcpy(out->data, expanded, LNArray_ALIGNMENT(out)*expanded_size); 118 | } 119 | 120 | free(to_expanded); 121 | free(arrdims_expanded); 122 | free(expanded); 123 | // printf("ok\n"); 124 | // // iterators 125 | // size_t i, j; 126 | 127 | // size_t new_ndim = LN_MAX(arr->nd, nd); 128 | 129 | // size_t *dims1_expanded = LNMem_alloc(sizeof(size_t)*new_ndim); 130 | // if(!dims1_expanded) 131 | // return; 132 | 133 | // size_t *to_expanded = LNMem_alloc(sizeof(size_t)*new_ndim); 134 | // if(!dims2_expanded) 135 | // return; 136 | 137 | // size_t diff; 138 | 139 | // if(arr->nd > nd){ 140 | // diff=arr->nd-nd; 141 | 142 | // if(arr->dimensions) 143 | // memcpy(dims1_expanded, arr->dimensions, sizeof(size_t)*arr->nd); 144 | // else{ 145 | // for(i=0;ind; 155 | 156 | // memcpy(to_expanded, to, sizeof(size_t)*nd); 157 | // for(i=0; i < diff; i++){ 158 | // dims1_expanded[i]=1; 159 | // } 160 | // if(arr->dimensions) 161 | // memcpy(dims1_expanded+diff, arr->dimensions, sizeof(size_t)*new_ndim); 162 | // else{ 163 | // for(i=diff;i0;i--){ 172 | // if(!((to_expanded[i-1] == dims1_expanded[i-1]) || dims1_expanded[i-1] == 1)){ 173 | // TEST; 174 | // LNError_setFString("Error on axis %zu: size (%zu) must be the same as (%zu) or the old size must be 1", i-1, dims2_expanded[i-1], dims1_expanded[i-1]); 175 | // free(new_strides); 176 | // free(dims1_expanded); 177 | // free(dims2_expanded); 178 | // LNArray_Free(out); 179 | // return; 180 | // } 181 | 182 | // new_strides[i-1] = new_size*LNArray_ALIGNMENT(arr); 183 | // new_size *= dims2_expanded[i-1]; 184 | // } 185 | // TEST; 186 | 187 | // out->dtype = arr->dtype; 188 | // out->nd = new_ndim; 189 | 190 | // out->dimensions = LNMem_alloc(sizeof(size_t) * new_ndim); 191 | // if(!out->dimensions) 192 | // return; 193 | 194 | // out->strides = LNMem_alloc(sizeof(long long) * new_ndim); 195 | // if(!out->strides) 196 | // return; 197 | 198 | // out->size = 1; 199 | // for(i = new_ndim; i > 0; i--){ 200 | // out->strides[i-1] = out->size * LNArray_ALIGNMENT(arr); 201 | // out->dimensions[i-1] = dims1_expanded[i-1]; 202 | // out->size *= dims2_expanded[i-1]; 203 | // } 204 | 205 | // out->data = LNMem_alloc(LNArray_ALIGNMENT(arr)*new_size); 206 | // if(!out->data) 207 | // return; 208 | // memcpy(out->data, arr->data, LNArray_ALIGNMENT(arr)*arr->size); 209 | 210 | // char *expanded = LNMem_alloc(LNArray_ALIGNMENT(arr)*out->size); 211 | // if(!expanded) 212 | // return; 213 | 214 | // size_t expanded_size = 0; 215 | 216 | // i = new_ndim; 217 | // while(i > 0){ 218 | // i--; 219 | 220 | // diff = dims2_expanded[i] - dims1_expanded[i] + 1; 221 | // LN_ARRAY_APPLY_D(out, i, 222 | // for(j = 0; j < diff; j++){ 223 | // memcpy(expanded + expanded_size, item, __axis_size * LNArray_ALIGNMENT(arr)); 224 | // expanded_size += __axis_size; 225 | // } 226 | // ); 227 | 228 | // memcpy(out->data, expanded, out->size * LNArray_ALIGNMENT(arr)); 229 | // out->dimensions[i] = dims2_expanded[i]; 230 | 231 | // expanded_size = 0; 232 | // } 233 | // } 234 | 235 | // #define CASE(id, real, Real, op)\ 236 | // case id:{\ 237 | // if(LNArray_IsContiguous(arr1_solved) && LNArray_IsContiguous(arr2_solved)){\ 238 | // LN##Real##Vector_Add((real*)res->data, (real*)arr1->data, (real*)arr2->data, res->size);\ 239 | // } else {\ 240 | // size_t pos=0;\ 241 | // LN_ARRAY_APPLY2_CONTIG(arr1,arr2,\ 242 | // ((real*)res->data)[pos] = *(real*)item1 op *(real*)item2;\ 243 | // pos++;\ 244 | // )\ 245 | // }\ 246 | // \ 247 | // break;\ 248 | // } 249 | 250 | // Ndarray *LNArray_Add(Ndarray *arr1, Ndarray *arr2){ 251 | // Ndarray *res = LNArray_Alloc(); 252 | // if(!res) 253 | // return NULL; 254 | 255 | // Ndarray *arr1_solved; 256 | // Ndarray *arr2_solved; 257 | 258 | // const LNTypeDescr *new_type=LNDType_Promote(arr1->dtype, arr2->dtype); 259 | // if(LNArray_TYPE(arr1)->id==LNArray_TYPE(arr2)->id){ 260 | // arr1_solved = arr1; 261 | // arr2_solved = arr2; 262 | // } else{ 263 | // arr1_solved = LNArray_CastTo(arr1, new_type, LNCAST_SAFE); 264 | // arr2_solved = LNArray_CastTo(arr2, new_type, LNCAST_SAFE); 265 | // if(LNError_Ocurred()){ 266 | // return NULL; 267 | // } 268 | // } 269 | 270 | // res->size = arr1->size; 271 | // res->nd = arr1->nd; 272 | // res->dimensions=arr1->dimensions; 273 | // res->strides=arr1->strides; 274 | // res->dtype=arr1->dtype; 275 | 276 | // res->data = LNMem_alloc(arr1->dtype->itemsize * res->size); 277 | // if(!res->data) 278 | // return NULL; 279 | 280 | // switch (arr1->dtype->id){ 281 | // case LN_CHAR: 282 | // case LN_BOOL: 283 | // case LN_UINT8: 284 | // CASE(LN_INT8, int8_t, Int8, +); 285 | 286 | // case LN_UINT16: 287 | // CASE(LN_INT16, int16_t, Int16, +); 288 | 289 | // case LN_UINT32: 290 | // CASE(LN_INT32, int32_t, Int32, +); 291 | 292 | // case LN_UINT64: 293 | // CASE(LN_INT64, int64_t, Int64, +); 294 | 295 | // CASE(LN_FLOAT32, float32_t, Float32, +); 296 | 297 | // CASE(LN_FLOAT64, float64_t, Float64, +); 298 | 299 | // case LN_COMPLEX64: 300 | // if(LNArray_IsContiguous(arr1) && LNArray_IsContiguous(arr2)){ 301 | // LNComplex64Vector_Add((complex64_t*)res->data, (complex64_t*)arr1->data, (complex64_t*)arr2->data, res->size); 302 | // } else{ 303 | // float32_t r1, i1, r2, i2; 304 | // size_t pos=0; 305 | // LN_ARRAY_APPLY2_CONTIG(arr1,arr2, 306 | // r1=((complex64_t*)item1)->realp; 307 | // i1=((complex64_t*)item1)->imagp; 308 | 309 | // r2=((complex64_t*)item2)->realp; 310 | // i2=((complex64_t*)item2)->imagp; 311 | 312 | // ((complex64_t*)res->data)[pos].realp = r1+r2; 313 | // ((complex64_t*)res->data)[pos].imagp = i1+i2; 314 | // pos++; 315 | // ) 316 | // } 317 | // break; 318 | 319 | // case LN_COMPLEX128: 320 | // if(LNArray_IsContiguous(arr1) && LNArray_IsContiguous(arr2)){ 321 | // LNComplex128Vector_Add((complex128_t*)res->data, (complex128_t*)arr1->data, (complex128_t*)arr2->data, res->size); 322 | // } else{ 323 | // float64_t r1, i1, r2, i2; 324 | // size_t pos=0; 325 | // LN_ARRAY_APPLY2_CONTIG(arr1,arr2, 326 | // r1=((complex128_t*)item1)->realp; 327 | // i1=((complex128_t*)item1)->imagp; 328 | 329 | // r2=((complex128_t*)item2)->realp; 330 | // i2=((complex128_t*)item2)->imagp; 331 | // ((complex128_t*)res->data)[pos].realp = r1+r2; 332 | // ((complex128_t*)res->data)[pos].imagp = i1+i2; 333 | // pos++; 334 | // ) 335 | // } 336 | // break; 337 | 338 | // } 339 | 340 | // return res; 341 | } 342 | 343 | 344 | Ndarray *LNArray_MaxAxis(Ndarray *arr, long long axis){ 345 | return arr->dtype->max_axis_func(arr, axis); 346 | } 347 | 348 | Ndarray *LNArray_Max(Ndarray *arr){ 349 | return arr->dtype->max_func(arr); 350 | } 351 | 352 | Ndarray *LNArray_MinAxis(Ndarray *arr, long long axis){ 353 | return arr->dtype->max_axis_func(arr, axis); 354 | } 355 | 356 | Ndarray *LNArray_Min(Ndarray *arr){ 357 | return arr->dtype->min_func(arr); 358 | } 359 | 360 | Ndarray *LNArray_SumAxis(Ndarray *arr, long long axis){ 361 | return arr->dtype->sum_axis_func(arr, axis); 362 | } 363 | 364 | Ndarray *LNArray_Sum(Ndarray *arr){ 365 | return arr->dtype->sum_func(arr); 366 | } 367 | -------------------------------------------------------------------------------- /src/lua/include/lua.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lua.h,v 1.218.1.7 2012/01/13 20:36:20 roberto Exp $ 3 | ** Lua - An Extensible Extension Language 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) 5 | ** See Copyright Notice at the end of this file 6 | */ 7 | 8 | 9 | #ifndef lua_h 10 | #define lua_h 11 | 12 | #include 13 | #include 14 | 15 | 16 | #include "luaconf.h" 17 | 18 | 19 | #define LUA_VERSION "Lua 5.1" 20 | #define LUA_RELEASE "Lua 5.1.5" 21 | #define LUA_VERSION_NUM 501 22 | #define LUA_COPYRIGHT "Copyright (C) 1994-2012 Lua.org, PUC-Rio" 23 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" 24 | 25 | 26 | /* mark for precompiled code (`Lua') */ 27 | #define LUA_SIGNATURE "\033Lua" 28 | 29 | /* option for multiple returns in `lua_pcall' and `lua_call' */ 30 | #define LUA_MULTRET (-1) 31 | 32 | 33 | /* 34 | ** pseudo-indices 35 | */ 36 | #define LUA_REGISTRYINDEX (-10000) 37 | #define LUA_ENVIRONINDEX (-10001) 38 | #define LUA_GLOBALSINDEX (-10002) 39 | #define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) 40 | 41 | 42 | /* thread status; 0 is OK */ 43 | #define LUA_YIELD 1 44 | #define LUA_ERRRUN 2 45 | #define LUA_ERRSYNTAX 3 46 | #define LUA_ERRMEM 4 47 | #define LUA_ERRERR 5 48 | 49 | 50 | typedef struct lua_State lua_State; 51 | 52 | typedef int (*lua_CFunction) (lua_State *L); 53 | 54 | 55 | /* 56 | ** functions that read/write blocks when loading/dumping Lua chunks 57 | */ 58 | typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); 59 | 60 | typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); 61 | 62 | 63 | /* 64 | ** prototype for memory-allocation functions 65 | */ 66 | typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); 67 | 68 | 69 | /* 70 | ** basic types 71 | */ 72 | #define LUA_TNONE (-1) 73 | 74 | #define LUA_TNIL 0 75 | #define LUA_TBOOLEAN 1 76 | #define LUA_TLIGHTUSERDATA 2 77 | #define LUA_TNUMBER 3 78 | #define LUA_TSTRING 4 79 | #define LUA_TTABLE 5 80 | #define LUA_TFUNCTION 6 81 | #define LUA_TUSERDATA 7 82 | #define LUA_TTHREAD 8 83 | 84 | 85 | 86 | /* minimum Lua stack available to a C function */ 87 | #define LUA_MINSTACK 20 88 | 89 | 90 | /* 91 | ** generic extra include file 92 | */ 93 | #if defined(LUA_USER_H) 94 | #include LUA_USER_H 95 | #endif 96 | 97 | 98 | /* type of numbers in Lua */ 99 | typedef LUA_NUMBER lua_Number; 100 | 101 | 102 | /* type for integer functions */ 103 | typedef LUA_INTEGER lua_Integer; 104 | 105 | 106 | 107 | /* 108 | ** state manipulation 109 | */ 110 | LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); 111 | LUA_API void (lua_close) (lua_State *L); 112 | LUA_API lua_State *(lua_newthread) (lua_State *L); 113 | 114 | LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); 115 | 116 | 117 | /* 118 | ** basic stack manipulation 119 | */ 120 | LUA_API int (lua_gettop) (lua_State *L); 121 | LUA_API void (lua_settop) (lua_State *L, int idx); 122 | LUA_API void (lua_pushvalue) (lua_State *L, int idx); 123 | LUA_API void (lua_remove) (lua_State *L, int idx); 124 | LUA_API void (lua_insert) (lua_State *L, int idx); 125 | LUA_API void (lua_replace) (lua_State *L, int idx); 126 | LUA_API int (lua_checkstack) (lua_State *L, int sz); 127 | 128 | LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); 129 | 130 | 131 | /* 132 | ** access functions (stack -> C) 133 | */ 134 | 135 | LUA_API int (lua_isnumber) (lua_State *L, int idx); 136 | LUA_API int (lua_isstring) (lua_State *L, int idx); 137 | LUA_API int (lua_iscfunction) (lua_State *L, int idx); 138 | LUA_API int (lua_isuserdata) (lua_State *L, int idx); 139 | LUA_API int (lua_type) (lua_State *L, int idx); 140 | LUA_API const char *(lua_typename) (lua_State *L, int tp); 141 | 142 | LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); 143 | LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); 144 | LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); 145 | 146 | LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); 147 | LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); 148 | LUA_API int (lua_toboolean) (lua_State *L, int idx); 149 | LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); 150 | LUA_API size_t (lua_objlen) (lua_State *L, int idx); 151 | LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); 152 | LUA_API void *(lua_touserdata) (lua_State *L, int idx); 153 | LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); 154 | LUA_API const void *(lua_topointer) (lua_State *L, int idx); 155 | 156 | 157 | /* 158 | ** push functions (C -> stack) 159 | */ 160 | LUA_API void (lua_pushnil) (lua_State *L); 161 | LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); 162 | LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); 163 | LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); 164 | LUA_API void (lua_pushstring) (lua_State *L, const char *s); 165 | LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, 166 | va_list argp); 167 | LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); 168 | LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); 169 | LUA_API void (lua_pushboolean) (lua_State *L, int b); 170 | LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); 171 | LUA_API int (lua_pushthread) (lua_State *L); 172 | 173 | 174 | /* 175 | ** get functions (Lua -> stack) 176 | */ 177 | LUA_API void (lua_gettable) (lua_State *L, int idx); 178 | LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); 179 | LUA_API void (lua_rawget) (lua_State *L, int idx); 180 | LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); 181 | LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); 182 | LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); 183 | LUA_API int (lua_getmetatable) (lua_State *L, int objindex); 184 | LUA_API void (lua_getfenv) (lua_State *L, int idx); 185 | 186 | 187 | /* 188 | ** set functions (stack -> Lua) 189 | */ 190 | LUA_API void (lua_settable) (lua_State *L, int idx); 191 | LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); 192 | LUA_API void (lua_rawset) (lua_State *L, int idx); 193 | LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); 194 | LUA_API int (lua_setmetatable) (lua_State *L, int objindex); 195 | LUA_API int (lua_setfenv) (lua_State *L, int idx); 196 | 197 | 198 | /* 199 | ** `load' and `call' functions (load and run Lua code) 200 | */ 201 | LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); 202 | LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); 203 | LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); 204 | LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, 205 | const char *chunkname); 206 | 207 | LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); 208 | 209 | 210 | /* 211 | ** coroutine functions 212 | */ 213 | LUA_API int (lua_yield) (lua_State *L, int nresults); 214 | LUA_API int (lua_resume) (lua_State *L, int narg); 215 | LUA_API int (lua_status) (lua_State *L); 216 | 217 | /* 218 | ** garbage-collection function and options 219 | */ 220 | 221 | #define LUA_GCSTOP 0 222 | #define LUA_GCRESTART 1 223 | #define LUA_GCCOLLECT 2 224 | #define LUA_GCCOUNT 3 225 | #define LUA_GCCOUNTB 4 226 | #define LUA_GCSTEP 5 227 | #define LUA_GCSETPAUSE 6 228 | #define LUA_GCSETSTEPMUL 7 229 | 230 | LUA_API int (lua_gc) (lua_State *L, int what, int data); 231 | 232 | 233 | /* 234 | ** miscellaneous functions 235 | */ 236 | 237 | LUA_API int (lua_error) (lua_State *L); 238 | 239 | LUA_API int (lua_next) (lua_State *L, int idx); 240 | 241 | LUA_API void (lua_concat) (lua_State *L, int n); 242 | 243 | LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); 244 | LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); 245 | 246 | 247 | 248 | /* 249 | ** =============================================================== 250 | ** some useful macros 251 | ** =============================================================== 252 | */ 253 | 254 | #define lua_pop(L,n) lua_settop(L, -(n)-1) 255 | 256 | #define lua_newtable(L) lua_createtable(L, 0, 0) 257 | 258 | #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) 259 | 260 | #define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) 261 | 262 | #define lua_strlen(L,i) lua_objlen(L, (i)) 263 | 264 | #define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) 265 | #define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) 266 | #define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) 267 | #define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) 268 | #define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) 269 | #define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) 270 | #define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) 271 | #define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) 272 | 273 | #define lua_pushliteral(L, s) \ 274 | lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) 275 | 276 | #define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) 277 | #define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) 278 | 279 | #define lua_tostring(L,i) lua_tolstring(L, (i), NULL) 280 | 281 | 282 | 283 | /* 284 | ** compatibility macros and functions 285 | */ 286 | 287 | #define lua_open() luaL_newstate() 288 | 289 | #define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) 290 | 291 | #define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) 292 | 293 | #define lua_Chunkreader lua_Reader 294 | #define lua_Chunkwriter lua_Writer 295 | 296 | 297 | /* hack */ 298 | LUA_API void lua_setlevel (lua_State *from, lua_State *to); 299 | 300 | 301 | /* 302 | ** {====================================================================== 303 | ** Debug API 304 | ** ======================================================================= 305 | */ 306 | 307 | 308 | /* 309 | ** Event codes 310 | */ 311 | #define LUA_HOOKCALL 0 312 | #define LUA_HOOKRET 1 313 | #define LUA_HOOKLINE 2 314 | #define LUA_HOOKCOUNT 3 315 | #define LUA_HOOKTAILRET 4 316 | 317 | 318 | /* 319 | ** Event masks 320 | */ 321 | #define LUA_MASKCALL (1 << LUA_HOOKCALL) 322 | #define LUA_MASKRET (1 << LUA_HOOKRET) 323 | #define LUA_MASKLINE (1 << LUA_HOOKLINE) 324 | #define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) 325 | 326 | typedef struct lua_Debug lua_Debug; /* activation record */ 327 | 328 | 329 | /* Functions to be called by the debuger in specific events */ 330 | typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); 331 | 332 | 333 | LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); 334 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); 335 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); 336 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); 337 | LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); 338 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); 339 | 340 | LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); 341 | LUA_API lua_Hook lua_gethook (lua_State *L); 342 | LUA_API int lua_gethookmask (lua_State *L); 343 | LUA_API int lua_gethookcount (lua_State *L); 344 | 345 | 346 | struct lua_Debug { 347 | int event; 348 | const char *name; /* (n) */ 349 | const char *namewhat; /* (n) `global', `local', `field', `method' */ 350 | const char *what; /* (S) `Lua', `C', `main', `tail' */ 351 | const char *source; /* (S) */ 352 | int currentline; /* (l) */ 353 | int nups; /* (u) number of upvalues */ 354 | int linedefined; /* (S) */ 355 | int lastlinedefined; /* (S) */ 356 | char short_src[LUA_IDSIZE]; /* (S) */ 357 | /* private part */ 358 | int i_ci; /* active function */ 359 | }; 360 | 361 | /* }====================================================================== */ 362 | 363 | 364 | /****************************************************************************** 365 | * Copyright (C) 1994-2012 Lua.org, PUC-Rio. All rights reserved. 366 | * 367 | * Permission is hereby granted, free of charge, to any person obtaining 368 | * a copy of this software and associated documentation files (the 369 | * "Software"), to deal in the Software without restriction, including 370 | * without limitation the rights to use, copy, modify, merge, publish, 371 | * distribute, sublicense, and/or sell copies of the Software, and to 372 | * permit persons to whom the Software is furnished to do so, subject to 373 | * the following conditions: 374 | * 375 | * The above copyright notice and this permission notice shall be 376 | * included in all copies or substantial portions of the Software. 377 | * 378 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 379 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 380 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 381 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 382 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 383 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 384 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 385 | ******************************************************************************/ 386 | 387 | 388 | #endif -------------------------------------------------------------------------------- /install.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path .. ";?.lua" 2 | 3 | -- This table stores colors used by luandarray installer 4 | local colors = { 5 | red = "\27[31m", 6 | red_bold = "\27[31;1m", 7 | 8 | green = "\27[32m", 9 | green_bold = "\27[32;1m", 10 | 11 | yellow = "\27[33m", 12 | yellow_bold = "\27[33;1m", 13 | 14 | blue = "\27[34m", 15 | blue_bold = "\27[34;1m", 16 | 17 | pink = "\27[35m", 18 | pink_bold = "\27[35;1m", 19 | 20 | bold = "\27[;1m", 21 | 22 | none = "\27[0m" 23 | } 24 | 25 | -- LuaNdarray's write function 26 | local function lnwrite(txt) 27 | txt = tostring(txt) 28 | local i = 0 29 | while i < #txt do 30 | i=i + 1 31 | 32 | if txt:sub(i,i+1) == "\\<" then 33 | io.write("<") 34 | i=i + 1 35 | elseif txt:sub(i,i) == "<" then 36 | local color = txt:sub(i, -1):match("[<]([%w_]+)[>]") 37 | io.write(colors[color] or error("color '" .. color .."' does not exist")) 38 | i=i + #color + 1 39 | else 40 | io.write(txt:sub(i,i)) 41 | end 42 | end 43 | end 44 | 45 | function print(...) 46 | local args = {...} 47 | 48 | for i, a in ipairs(args) do 49 | lnwrite(a) 50 | if i < #args then 51 | io.write("\t") 52 | end 53 | end 54 | io.write("\n") 55 | end 56 | 57 | function NOTICE(msg) 58 | print("[NOTICE] " .. msg) 59 | return 0 60 | end 61 | 62 | function SUCCESS(msg) 63 | print("[SUCCESS] " .. msg) 64 | end 65 | 66 | function ERROR(msg) 67 | print("[ERROR] " .. msg) 68 | return 1 69 | end 70 | 71 | function WARNING(msg) 72 | print("[WARNING] " .. msg) 73 | end 74 | 75 | local os = require "ospp" 76 | 77 | local lfs_support, lfs = pcall(require, "lfs") 78 | if not lfs_support then 79 | WARNING("LuaFileSystem not detected, backing to os++") 80 | end 81 | 82 | -- Some useful classes 83 | local CCmeta = { 84 | __tostring = function (self) 85 | return string.format('CC("%s")', self.name) 86 | end 87 | } 88 | CCmeta.__index = CCmeta 89 | 90 | local function newCC(name) 91 | local self = setmetatable({}, CCmeta) 92 | self.name = name 93 | return self 94 | end 95 | 96 | function CCmeta:generateObj(source, dst, flags) 97 | if dst == nil then 98 | dst = source:sub(1, -3) .. ".o" 99 | end 100 | if flags == nil then 101 | flags = "" 102 | end 103 | 104 | os.execute(self.name .. " " .. flags .. " -c " .. source .. " -o " .. dst) 105 | return os.exists(dst), dst -- Compiled successfully? 106 | end 107 | 108 | function CCmeta:link(flags, outname, o_files) 109 | os.execute(self.name .. " " .. flags .. " -o " .. outname .. " " .. table.concat(o_files, " ")) 110 | return os.exists(outname) 111 | end 112 | 113 | -- Returns true if the compiler is supported 114 | function CCmeta:supported() 115 | return os.execute(self.name .. " -v > " .. os.devnull .. " 2>&1") ~= nil 116 | end 117 | 118 | -- for detect ospp.lua 119 | package.path = package.path .. ";?.lua" 120 | 121 | local function adjust_path(path) 122 | if package.config:sub(1,1) == "/" then 123 | return path:gsub("/", "\\"):gsub("\\+", "\\") 124 | end 125 | return path:gsub("\\", "/"):gsub("/+", "/") 126 | end 127 | 128 | local function SUCCESSFULLY() 129 | SUCCESS("luandarray installed successfully") 130 | os.exit(0) 131 | end 132 | 133 | local function INSTALL_ERROR() 134 | SUCCESS("luandarray installed successfully") 135 | os.exit(0) 136 | end 137 | 138 | local function compiler_exists(cc) 139 | return os.execute(cc.." -v > " .. os.devnull .. " 2>&1") ~= nil 140 | end 141 | 142 | local function cacheExists() 143 | return io.open(".cache", "r") ~= nil 144 | end 145 | 146 | local function createCache(cc, simd) 147 | local f = io.open(".cache", "w") 148 | if f then 149 | f:write("CC:"..cc .. "\nsimd:"..simd) 150 | f:close() 151 | end 152 | end 153 | 154 | local function getCacheInfos() 155 | local cache_file = io.lines(".cache") 156 | 157 | local infos = {} 158 | 159 | for line in cache_file do 160 | local conf_name, conf_value = line:match("(%w+)%:(.+)") 161 | if not conf_name then break end 162 | infos[conf_name] = conf_value 163 | end 164 | 165 | return infos 166 | end 167 | 168 | local function detect_cc() 169 | 170 | for i, cc in ipairs({"gcc", "mingw64-gcc", "mingw32-gcc", "clang"}) do 171 | if newCC(cc):supported() then 172 | return cc 173 | end 174 | end 175 | 176 | -- No compiler detected 177 | return nil 178 | end 179 | 180 | local function get_OS() 181 | if jit then 182 | return jit.os 183 | end 184 | local success, name = pcall(io.popen, "uname -s") 185 | 186 | if success and name then return name:read() end 187 | 188 | local nt = os.getenv("Windows_NT") 189 | if nt then 190 | return nt:lower():match("windows") ~= nil and "windows" or "unknows" 191 | end 192 | 193 | return "unknown" 194 | end 195 | 196 | -- detects simd architecture 197 | local function detect_simd(cc) 198 | os.execute(cc .. " detect_simd.c -o detect_simd") 199 | 200 | local simd = io.popen((os.get() == "unix" and "./" or "") .. "detect_simd" .. (os.get() == "win" and ".exe" or ""), "r"):read("*a") 201 | return simd 202 | end 203 | 204 | -- Initialize LuaNdarray's folder 205 | local function init() 206 | if lfs_support then 207 | if not lfs.attributes("luandarray") then 208 | lfs.mkdir("luandarray") 209 | end 210 | 211 | if not lfs.attributes("luandarray/luajit") then 212 | os.mkdir("luandarray/luajit") 213 | end 214 | 215 | if not lfs.attributes("luandarray/luajit/bin") then 216 | lfs.mkdir("luandarray/luajit/bin") 217 | end 218 | 219 | return 220 | end 221 | if not os.exists("luandarray") then 222 | os.mkdir("luandarray") 223 | end 224 | 225 | if not os.exists("luandarray/luajit") then 226 | os.mkdir("luandarray/luajit") 227 | end 228 | 229 | if not os.exists("luandarray/luajit/bin") then 230 | os.mkdir("luandarray/luajit/bin") 231 | end 232 | end 233 | 234 | local generateObjFiles 235 | if lfs_support then 236 | function generateObjFiles(cc, flags, dir) 237 | local obj_files = {} for file in lfs.dir(dir) do 238 | if file:sub(-2, -1) == ".c" then 239 | local success, out = cc:generateObj(dir .. "/" .. file, nil, flags) 240 | if not success then 241 | ERROR("error on generate object file " .. out .. "") 242 | os.exit(1) 243 | end 244 | 245 | NOTICE("compiling " .. dir .. "/" .. file.."") 246 | table.insert(obj_files, out) 247 | end 248 | end 249 | 250 | return obj_files 251 | end 252 | else 253 | function generateObjFiles(cc, flags, dir) 254 | local files = os.listdir(dir) 255 | local obj_files = {} 256 | for i, file in ipairs(files) do 257 | -- only .c files will be compiled 258 | if file:sub(-2, -1) == ".c" then 259 | local success, out = cc:generateObj(dir .. "/" .. file, nil, flags) 260 | table.insert(obj_files, out) 261 | if not success then 262 | ERROR("error on generate object file " .. out .. "") 263 | os.exit(1) 264 | end 265 | NOTICE("compiling " .. dir .. "/" .. file.."") 266 | end 267 | end 268 | return obj_files 269 | end 270 | end 271 | 272 | -- Returns the full path where Lua interpreter is. 273 | local function getLuaInterpreterFolder() 274 | local i_min = 0 275 | while arg[ i_min] do 276 | i_min = i_min - 1 277 | end 278 | 279 | local path = arg[i_min+1] 280 | local sep = package.config:sub(1,1) 281 | for i=#path, 1, -1 do 282 | if path:sub(i,i) == sep then 283 | path = path:sub(1, i-1) 284 | break 285 | end 286 | end 287 | 288 | return path 289 | end 290 | 291 | local function luaLibPathExistsIn(dir, version) 292 | version = version or _VERSION:match("[%d%.]+") 293 | local version_num = version:gsub("%.", "") 294 | local ext = os.get() == "win" and "dll" or "so" 295 | 296 | 297 | local finder 298 | 299 | if jit and os.get() == "unix" then 300 | function finder(name) 301 | return name:match("libluajit%-" .. version:gsub("%.", "%.") .. ".so%.%d+") 302 | end 303 | else 304 | if os.get() == "win" then 305 | function finder(name) 306 | return name == "lua" .. version .. ".dll" or 307 | name == "lua" .. version_num .. ".dll" 308 | end 309 | else 310 | function finder(name) 311 | return name:match("liblua" .. version:gsub("%.", "%%.") .. "%.so%.%d+") or 312 | name:match("liblua" .. version_num .. "%.so%.%d+") or 313 | name == "liblua.so" 314 | end 315 | end 316 | end 317 | 318 | if lfs_support then 319 | for file in lfs.dir(dir) do 320 | if finder(file) then 321 | return file 322 | end 323 | end 324 | else 325 | for _, file in ipairs(os.listdir(dir)) do 326 | if finder(file) then 327 | return file 328 | end 329 | end 330 | end 331 | 332 | return nil -- not found 333 | end 334 | 335 | local lualib_search_in = os.get() == "win" and {getLuaInterpreterFolder(), "C:\\lua"} or { 336 | "/usr/lib/x86_64-linux-gnu", "/usr/local/lib", "/usr/lib32", "/usr/lib64","/usr/share", 337 | "/lib/x86_64-linux-gnu" 338 | } 339 | local function getLuaLibPath() 340 | local sep = package.config:sub(1,1) 341 | for i, folder in ipairs(lualib_search_in) do 342 | if lfs_support and lfs.attributes(folder) or os.exists(folder) then 343 | local name = luaLibPathExistsIn(folder) 344 | if name then 345 | return name, (folder .. sep .. name):gsub(sep.."+", sep) 346 | end 347 | end 348 | end 349 | 350 | return nil 351 | end 352 | 353 | local function removeObjFiles(dir) 354 | local files = os.listdir(dir) 355 | if not files then return nil end 356 | 357 | for i, file in ipairs(files) do 358 | if file:sub(-2, -1) == ".o" then 359 | os.remove(dir.."/"..file) 360 | end 361 | end 362 | 363 | return true 364 | end 365 | 366 | local function lnRemoveObjFiles() 367 | removeObjFiles("src/core") 368 | removeObjFiles("src/lua/src") 369 | removeObjFiles("src/core/generic") 370 | removeObjFiles("src/core/simd") 371 | end 372 | 373 | local function getFlags() 374 | local flags = {} 375 | for _, argv in ipairs(arg) do 376 | local name, value = argv:match("(%w+)%=(%S+)") 377 | if name and value then 378 | flags[name] = value 379 | end 380 | end 381 | return flags 382 | end 383 | 384 | -- Compiles LuaNdarray's source code 385 | local function compile(cc, simd, lualib) 386 | assert(lualib, "lualib is required") 387 | lualib = lualib:gsub("%.so.+", ""):gsub("lib", ""):gsub("%.dll", "") 388 | -- stores every file 389 | local files = os.listdir("src/core") 390 | if not files then 391 | ERROR "error on compile LuaNdarray (core folder was not found)" 392 | os.exit(1) 393 | end 394 | 395 | local fpic = (os.get() == "unix" and "-fPIC" or "") .. " -m" .. simd 396 | 397 | local all_files = {} 398 | for i, fs in ipairs({ 399 | generateObjFiles(cc, fpic, "src/core"), 400 | generateObjFiles(cc, fpic .. " -Isrc/core -Isrc/lua/include", "src/lua/src"), 401 | generateObjFiles(cc, fpic, "src/core/generic"), 402 | generateObjFiles(cc, fpic, "src/core/simd") 403 | }) do 404 | for _, f in ipairs(fs) do 405 | table.insert(all_files, f) 406 | end 407 | end 408 | 409 | NOTICE("linking LuaNdarray...") 410 | local flags = ("-fPIC -shared ") 411 | for i, dir in ipairs(lualib_search_in) do 412 | flags=flags .. "-L" .. dir .. " " 413 | end 414 | flags=flags .. "-l"..lualib.."" 415 | 416 | local dst = os.get() == "win" and "bin\\luandarray.dll" or "bin/luandarray.so" 417 | if not cc:link(flags, dst, all_files) then 418 | ERROR("Error on link LuaNdarray") 419 | os.exit(1) 420 | end 421 | end 422 | 423 | local function push_lua_files() 424 | local files = os.listdir("src/luajit") 425 | if not files then 426 | ERROR("luajit files not found") 427 | os.exit(1) 428 | end 429 | 430 | for i, file in ipairs(files) do 431 | os.copy("src/luajit/"..file, "luandarray/luajit/"..file) 432 | end 433 | end 434 | 435 | local function main(arg) 436 | NOTICE("OS detected: " .. get_OS() .. "") 437 | NOTICE("Initalizing luandarray folder...") 438 | init() 439 | 440 | local flags = getFlags() 441 | 442 | if not flags.lualib then 443 | NOTICE("searching Lua library...") 444 | flags.lualib = getLuaLibPath() 445 | if flags.lualib then 446 | NOTICE("Lua Library detected in " .. flags.lualib .."") 447 | else 448 | ERROR("Lua library was not found. Please specify the Lua path by adding the flag: --lualib=\\") 449 | return 1 450 | end 451 | else 452 | NOTICE("Lua library in use: " .. flags.lualib) 453 | end 454 | 455 | local CC, simd 456 | 457 | if flags.cc then 458 | if not compiler_exists(flags.cc) then 459 | ERROR("C Compiler '" .. flags.cc.."' not found") 460 | return 1 461 | else 462 | NOTICE("using C compiler '" .. flags.cc .. "'") 463 | CC = newCC(flags.cc) 464 | end 465 | end 466 | 467 | if flags.simd then 468 | NOTICE("using SIMD architecture '" .. flags.simd .. "'") 469 | simd = flags.simd 470 | end 471 | 472 | if cacheExists() then 473 | local infos = getCacheInfos() 474 | if not CC then 475 | CC = newCC(infos.CC) 476 | NOTICE("C compiler: " .. CC.name .." (from cache)") 477 | end 478 | if not simd then 479 | simd = infos.simd 480 | NOTICE("simd: "..simd.." (from cache)") 481 | end 482 | else 483 | CC = detect_cc() 484 | if not CC then 485 | ERROR("No C Compiler detected") 486 | return 1 487 | end 488 | NOTICE("C Compiler detected: " .. CC .."") 489 | 490 | simd = detect_simd(CC) 491 | NOTICE("SIMD architecture detect: " .. simd .. "") 492 | 493 | createCache(CC, simd) 494 | CC = newCC(CC) 495 | end 496 | 497 | NOTICE("compiling LuaNdarray...") 498 | compile(CC, simd, flags.lualib) 499 | 500 | NOTICE("copying lua files...") 501 | push_lua_files() 502 | 503 | NOTICE("removing object files...") 504 | lnRemoveObjFiles() 505 | 506 | return 0 507 | end 508 | 509 | local status = main(arg) 510 | if status == 1 then 511 | INSTALL_ERROR() 512 | else 513 | SUCCESSFULLY() 514 | end 515 | -------------------------------------------------------------------------------- /src/core/arraydtype.c: -------------------------------------------------------------------------------- 1 | #include"error.h" 2 | #include"utils.h" 3 | #include"arraydtype.h" 4 | #include"buffer.h" 5 | #include"arrayaplly.h" 6 | 7 | #include "arraymath.h" 8 | 9 | #include 10 | 11 | #define CASTCASE(id, oldtype, real)\ 12 | case id:{\ 13 | LN_ARRAY_APPLY_CONTIG(src,\ 14 | ((real*)((dst)->data))[i] = (real)(*(oldtype*)item);\ 15 | i++;\ 16 | );\ 17 | break;\ 18 | } 19 | 20 | #define LN_GENERATE_CAST_FUNC(tpy)\ 21 | static void ln_cast_##tpy##_to(Ndarray *dst, const Ndarray *src, LNDTypes newtype){\ 22 | size_t i = 0;\ 23 | const tpy *src_cast = (const tpy*)src;\ 24 | switch (newtype){\ 25 | CASTCASE(LN_INT8, tpy, int8_t)\ 26 | CASTCASE(LN_INT16, tpy, int16_t)\ 27 | CASTCASE(LN_INT32, tpy, int32_t)\ 28 | CASTCASE(LN_INT64, tpy, int64_t)\ 29 | \ 30 | CASTCASE(LN_UINT8, tpy, uint8_t)\ 31 | CASTCASE(LN_UINT16, tpy, uint16_t)\ 32 | CASTCASE(LN_UINT32, tpy, uint32_t)\ 33 | CASTCASE(LN_UINT64, tpy, uint64_t)\ 34 | \ 35 | CASTCASE(LN_FLOAT32, tpy, float32_t);\ 36 | CASTCASE(LN_FLOAT64, tpy, float64_t);\ 37 | \ 38 | case LN_COMPLEX64:\ 39 | LN_ARRAY_APPLY_CONTIG(src,\ 40 | ((complex64_t*)dst)[i].realp = (float32_t)(*(tpy*)item);\ 41 | ((complex64_t*)dst)[i].imagp = 0;\ 42 | i++;\ 43 | );\ 44 | break;\ 45 | case LN_COMPLEX128:\ 46 | LN_ARRAY_APPLY_CONTIG(src,\ 47 | ((complex128_t*)dst)[i].realp = (float64_t)(*(tpy*)item);\ 48 | ((complex128_t*)dst)[i].imagp = 0;\ 49 | i++;\ 50 | );\ 51 | break;\ 52 | }\ 53 | } 54 | 55 | #define CASE(id, complex_type, newtype)\ 56 | case id:{\ 57 | LN_ARRAY_APPLY_CONTIG(src,\ 58 | ((newtype*)dst)[i] = (newtype)(*(complex_type*)item).realp;\ 59 | i++;\ 60 | );\ 61 | break;\ 62 | }\ 63 | 64 | #define LN_GENERATE_COMPLEX_CAST_FUNC(complex_type, parts_type)\ 65 | static void ln_cast_##complex_type##_to(Ndarray *dst, const Ndarray *src, LNDTypes newtype){\ 66 | complex_type *src_cast=(complex_type*)src;\ 67 | size_t i = 0;\ 68 | switch(newtype){\ 69 | CASE(LN_INT8, complex_type, int8_t);\ 70 | CASE(LN_INT16, complex_type, int16_t);\ 71 | CASE(LN_INT32, complex_type, int32_t);\ 72 | CASE(LN_INT64, complex_type, int64_t);\ 73 | \ 74 | CASE(LN_UINT8, complex_type, uint8_t);\ 75 | CASE(LN_UINT16, complex_type, uint16_t);\ 76 | CASE(LN_UINT32, complex_type, uint32_t);\ 77 | CASE(LN_UINT64, complex_type, uint64_t);\ 78 | \ 79 | CASE(LN_FLOAT32, complex_type, float32_t);\ 80 | CASE(LN_FLOAT64, complex_type, float64_t);\ 81 | \ 82 | CASE(LN_BOOL, complex_type, bool_t);\ 83 | CASE(LN_CHAR, complex_type, char);\ 84 | \ 85 | case LN_COMPLEX64:\ 86 | LN_ARRAY_APPLY_CONTIG(src,\ 87 | ((complex64_t*)dst)[i].realp=(float32_t)((*(complex_type*)item).realp);\ 88 | ((complex64_t*)dst)[i].imagp=(float32_t)((*(complex_type*)item).imagp);\ 89 | i++;\ 90 | );\ 91 | break;\ 92 | case LN_COMPLEX128:\ 93 | LN_ARRAY_APPLY_CONTIG(src,\ 94 | ((complex128_t*)dst)[i].realp=(float64_t)(*(complex_type*)item).realp;\ 95 | ((complex128_t*)dst)[i].imagp=(float64_t)(*(complex_type*)item).imagp;\ 96 | i++;\ 97 | );\ 98 | break;\ 99 | }\ 100 | } 101 | 102 | #define LN_INTEGER_TO_COMPLEX\ 103 | (dst+i)->real=src_cast[i];\ 104 | (dst+i)->imag=0;\ 105 | 106 | LN_GENERATE_CAST_FUNC(int8_t) 107 | LN_GENERATE_CAST_FUNC(int16_t) 108 | LN_GENERATE_CAST_FUNC(int32_t) 109 | LN_GENERATE_CAST_FUNC(int64_t) 110 | 111 | LN_GENERATE_CAST_FUNC(uint8_t) 112 | 113 | LN_GENERATE_CAST_FUNC(uint16_t) 114 | 115 | LN_GENERATE_CAST_FUNC(uint32_t) 116 | LN_GENERATE_CAST_FUNC(uint64_t) 117 | 118 | LN_GENERATE_CAST_FUNC(float32_t) 119 | LN_GENERATE_CAST_FUNC(float64_t) 120 | 121 | LN_GENERATE_CAST_FUNC(char) 122 | LN_GENERATE_CAST_FUNC(bool_t) 123 | 124 | LN_GENERATE_COMPLEX_CAST_FUNC(complex64_t, float32_t) 125 | LN_GENERATE_COMPLEX_CAST_FUNC(complex128_t, float64_t) 126 | 127 | LNTypeDescr *LNDType_New(LNDTypes id, 128 | CastFunc castfunc, 129 | LNAxisOperator max_axis_func, LNAxisOperator min_axis_func, LNAxisOperator sum_axis_func, 130 | LNMapOperator max_func, LNMapOperator min_func, LNMapOperator sum_func, 131 | char *name, char *fmt, size_t alignment, size_t itemsize){ 132 | LNTypeDescr *dtype = LNMem_alloc(sizeof(LNTypeDescr)); 133 | if(!dtype) 134 | return NULL; 135 | 136 | dtype->max_axis_func = max_axis_func; 137 | dtype->min_axis_func = min_axis_func; 138 | dtype->sum_axis_func = sum_axis_func; 139 | 140 | dtype->max_func = max_func; 141 | dtype->min_func = min_func; 142 | dtype->sum_func = sum_func; 143 | 144 | dtype->castfunc = castfunc; 145 | 146 | dtype->id = id; 147 | 148 | dtype->name = name; 149 | dtype->fmt = fmt; 150 | dtype->alignment = alignment; 151 | dtype->itemsize = itemsize; 152 | 153 | return dtype; 154 | } 155 | 156 | static const LNTypeDescr *LNInt8; 157 | static const LNTypeDescr *LNInt16; 158 | static const LNTypeDescr *LNInt32; 159 | static const LNTypeDescr *LNInt64; 160 | 161 | static const LNTypeDescr *LNUInt8; 162 | static const LNTypeDescr *LNUInt16; 163 | static const LNTypeDescr *LNUInt32; 164 | static const LNTypeDescr *LNUInt64; 165 | 166 | static const LNTypeDescr *LNFloat32; 167 | static const LNTypeDescr *LNFloat64; 168 | 169 | static const LNTypeDescr *LNComplex64; 170 | static const LNTypeDescr *LNComplex128; 171 | 172 | static const LNTypeDescr *LNChar; 173 | static const LNTypeDescr *LNBool; 174 | 175 | static const LNTypeDescr *LNDefault; 176 | 177 | void LNDType_Init(){ 178 | LNInt8 = LNDType_NewFromID(LN_INT8); 179 | LNInt16 = LNDType_NewFromID(LN_INT16); 180 | LNInt32 = LNDType_NewFromID(LN_INT32); 181 | LNInt64 = LNDType_NewFromID(LN_INT64); 182 | 183 | LNUInt8 = LNDType_NewFromID(LN_UINT8); 184 | LNUInt16 = LNDType_NewFromID(LN_UINT16); 185 | LNUInt32 = LNDType_NewFromID(LN_UINT32); 186 | LNUInt64 = LNDType_NewFromID(LN_UINT64); 187 | 188 | LNFloat32 = LNDType_NewFromID(LN_FLOAT32); 189 | LNFloat64 = LNDType_NewFromID(LN_FLOAT64); 190 | 191 | LNComplex64 = LNDType_NewFromID(LN_COMPLEX64); 192 | LNComplex128 = LNDType_NewFromID(LN_COMPLEX128); 193 | 194 | LNChar = LNDType_NewFromID(LN_CHAR); 195 | LNBool = LNDType_NewFromID(LN_BOOL); 196 | 197 | LNDefault = LNFloat64; 198 | } 199 | 200 | const LNTypeDescr *LNDType_setdefault(const LNTypeDescr *type){ 201 | LNDefault = type; 202 | return LNDefault; 203 | } 204 | 205 | const LNTypeDescr *LNDType_getdefault(){ 206 | return LNDefault; 207 | } 208 | 209 | #define LN_NEW_DTYPE_CREATOR(id, real, Real, repr)\ 210 | LNTypeDescr *LNDType_New##Real(){\ 211 | return LNDType_New(id,\ 212 | ln_cast_##real##_to,\ 213 | LN##Real##Array_MaxAxis, LN##Real##Array_MinAxis, LN##Real##Array_SumAxis,\ 214 | LN##Real##Array_Max, LN##Real##Array_Min, LN##Real##Array_Sum,\ 215 | #repr,\ 216 | NULL, sizeof(real), sizeof(real));\ 217 | } 218 | 219 | 220 | LN_NEW_DTYPE_CREATOR(LN_INT8, int8_t, Int8, int8) 221 | LN_NEW_DTYPE_CREATOR(LN_INT16, int16_t, Int16, int16) 222 | LN_NEW_DTYPE_CREATOR(LN_INT32, int32_t, Int32, int32) 223 | LN_NEW_DTYPE_CREATOR(LN_INT64, int64_t, Int64, int64) 224 | 225 | LN_NEW_DTYPE_CREATOR(LN_UINT8, uint8_t, UInt8, uint8) 226 | LN_NEW_DTYPE_CREATOR(LN_UINT16, uint16_t, UInt16, uint16) 227 | LN_NEW_DTYPE_CREATOR(LN_UINT32, uint32_t, UInt32, uint32) 228 | LN_NEW_DTYPE_CREATOR(LN_UINT64, uint64_t, UInt64, uint64) 229 | 230 | LN_NEW_DTYPE_CREATOR(LN_FLOAT32, float32_t, Float32, float32) 231 | LN_NEW_DTYPE_CREATOR(LN_FLOAT64, float64_t, Float64, float64) 232 | 233 | LN_NEW_DTYPE_CREATOR(LN_COMPLEX64, complex64_t, Complex64, complex64) 234 | LN_NEW_DTYPE_CREATOR(LN_COMPLEX128, complex128_t, Complex128, complex128) 235 | 236 | LNTypeDescr *LNDType_NewBool(){ 237 | return LNDType_New(LN_BOOL, 238 | ln_cast_bool_t_to, 239 | LNInt8Array_MaxAxis, LNInt8Array_MinAxis, 240 | LNInt8Array_SumAxis, 241 | LNInt8Array_Max, 242 | LNInt8Array_Min, 243 | LNInt8Array_Sum, 244 | "bool", 245 | NULL, 246 | sizeof(bool_t), sizeof(bool_t)); 247 | } 248 | 249 | LNTypeDescr *LNDType_NewChar(){ 250 | return LNDType_New(LN_CHAR, 251 | ln_cast_char_to, 252 | LNInt8Array_MaxAxis, LNInt8Array_MinAxis, 253 | LNInt8Array_SumAxis, 254 | LNInt8Array_Max, 255 | LNInt8Array_Min, 256 | LNInt8Array_Sum, 257 | "char", 258 | NULL, 259 | sizeof(bool_t), sizeof(bool_t)); 260 | } 261 | 262 | // LN_NEW_DTYPE_CREATOR(LN_BOOL, bool_t, Bool, bool); 263 | // LN_NEW_DTYPE_CREATOR(LN_CHAR, char, Char, char); 264 | 265 | #undef LN_NEW_DTYPE_CREATOR 266 | 267 | LNTypeDescr *LNDType_NewFromID(LNDTypes id){ 268 | switch (id){ 269 | case LN_INT8: 270 | return LNDType_NewInt8(); 271 | case LN_INT16: 272 | return LNDType_NewInt16(); 273 | case LN_INT32: 274 | return LNDType_NewInt32(); 275 | case LN_INT64: 276 | return LNDType_NewInt64(); 277 | case LN_UINT8: 278 | return LNDType_NewUInt8(); 279 | case LN_UINT16: 280 | return LNDType_NewUInt16(); 281 | case LN_UINT32: 282 | return LNDType_NewUInt32(); 283 | case LN_UINT64: 284 | return LNDType_NewUInt64(); 285 | case LN_FLOAT32: 286 | return LNDType_NewFloat32(); 287 | case LN_FLOAT64: 288 | return LNDType_NewFloat64(); 289 | case LN_COMPLEX64: 290 | return LNDType_NewComplex64(); 291 | case LN_COMPLEX128: 292 | return LNDType_NewComplex128(); 293 | case LN_CHAR: 294 | return LNDType_NewChar(); 295 | case LN_BOOL: 296 | return LNDType_NewBool(); 297 | 298 | default: 299 | LNError_setFString("type %d do not exist", id); 300 | return NULL; 301 | } 302 | } 303 | 304 | const LNTypeDescr *LNDType_GetFromID(LNDTypes id){ 305 | switch(id){ 306 | case LN_INT8: 307 | return LNInt8; 308 | case LN_INT16: 309 | return LNInt16; 310 | case LN_INT32: 311 | return LNInt32; 312 | case LN_INT64: 313 | return LNInt64; 314 | case LN_UINT8: 315 | return LNUInt8; 316 | case LN_UINT16: 317 | return LNUInt16; 318 | case LN_UINT32: 319 | return LNUInt32; 320 | case LN_UINT64: 321 | return LNUInt64; 322 | case LN_FLOAT32: 323 | return LNFloat32; 324 | case LN_FLOAT64: 325 | return LNFloat64; 326 | case LN_COMPLEX64: 327 | return LNComplex64; 328 | case LN_COMPLEX128: 329 | return LNComplex128; 330 | case LN_CHAR: 331 | return LNChar; 332 | case LN_BOOL: 333 | return LNBool; 334 | default: 335 | LNError_setFString("type %d does not exist", id); 336 | return NULL; 337 | } 338 | } 339 | 340 | LNTypeDescr *LNDType_Copy(LNTypeDescr *dst, const LNTypeDescr *src){ 341 | dst->id = src->id; 342 | dst->name = src->name; 343 | dst->fmt = src->fmt; 344 | dst->alignment = src->alignment; 345 | dst->itemsize = src->itemsize; 346 | return dst; 347 | } 348 | 349 | const LNTypeDescr *LNDType_Promote(const LNTypeDescr *t1, const LNTypeDescr *t2){ 350 | if(t1->id==t2->id) 351 | return t1; 352 | if(LNDType_IsSuperior(t1,t2)){ 353 | if(t1->itemsize==t2->itemsize) 354 | return LNDType_GetFromID(t1->id+1); 355 | return t1; 356 | } 357 | 358 | if(t1->itemsize==t2->itemsize) 359 | return LNDType_GetFromID(t2->id+1); 360 | return t2; 361 | 362 | // if(t1->itemsize == t2->itemsize){ 363 | 364 | // if(LNDType_IsComplex(t1->id) || LNDType_IsComplex(t2->id)){ 365 | // return LNComplex128; 366 | // } 367 | 368 | // if(LNDType_IsFloat(t1->id) || LNDType_IsFloat(t2->id)){ 369 | // return LNFloat64; 370 | // } 371 | 372 | // if(LNDType_IsInt(t1->id) || LNDType_IsInt(t2->id)){ 373 | // return LNInt64; 374 | // } 375 | 376 | // if(LNDType_IsUInt(t1->id) || LNDType_IsUInt(t2->id)){ 377 | // return LNUInt64; 378 | // } 379 | 380 | // // if(LNDType_IsUInt(t1->id) && LNDType_IsInt(t2->id)){ 381 | // // if(t2->id==LN_INT64) 382 | // // return LNDType_GetFromID(LN_FLOAT64); 383 | // // return LNDType_GetFromID(t2->id+1); 384 | // // }else if(LNDType_IsInt(t1->id) && LNDType_IsUInt(t2->id)){ 385 | // // if(t1->id==LN_INT64) 386 | // // return LNDType_GetFromID(LN_FLOAT64); 387 | // // return LNDType_GetFromID(t1->id+1); 388 | // // } 389 | // return t1; 390 | // } 391 | 392 | // if(t1->itemsize > t2->itemsize){ 393 | // if(LNDType_IsUInt(t1->id) && LNDType_IsInt(t2->id)){ 394 | // if(t1->id == LN_UINT64){ 395 | // return LNFloat64; 396 | // } 397 | // return LNDType_GetFromdID(t1->id-LN_INT32); 398 | // } 399 | // return t1; 400 | // } 401 | 402 | // if(LNDType_IsUInt(t2->id) && LNDType_IsInt(t1->id)){ 403 | // if(t2->id == LN_UINT64){ 404 | // return LNFloat64; 405 | // } 406 | // return LNDType_GetFromdID(t2->id-LN_INT32); 407 | // } 408 | 409 | return t2; 410 | // LNDTypes newtype; 411 | // if(t1->id==t2->id){ 412 | // newtype=t1->id; 413 | // return LNDType_NewFromID(newtype); 414 | // } 415 | 416 | // if(t1->itemsize == t2->itemsize){ 417 | // if(LNDType_IsInt(t1->id) && LNDType_IsUInt(t2->id)){ 418 | // if(t1->id == LN_INT64) 419 | // newtype = LN_FLOAT64; 420 | // else 421 | // newtype = t1->id+1; 422 | // } else if(LNDType_IsInt(t2->id) && LNDType_IsUInt(t1->id)){ 423 | // if(t2->id == LN_INT64) 424 | // newtype = LN_FLOAT64; 425 | // else 426 | // newtype = t2->id+1; 427 | // } else{ 428 | // newtype = LN_FLOAT64; 429 | // } 430 | // } else{ 431 | // newtype = t1->itemsize > t2->itemsize ? t1->id : t2->id; 432 | // } 433 | 434 | // return LNDType_NewFromID(newtype); 435 | } 436 | 437 | bool_t LNDType_CastIsSafe(const LNTypeDescr *orig_type, const LNTypeDescr *new_type){ 438 | return orig_type->itemsize >= new_type->itemsize; 439 | } 440 | 441 | void LNDType_Print(const LNTypeDescr *dtype){ 442 | printf("dtype(\"%s\", id=%d, fmt=%%%s, alignment=%zu, itemsize=%zu)\n", 443 | dtype->name, dtype->id, dtype->fmt, dtype->alignment, dtype->itemsize); 444 | } 445 | 446 | void LNDType_Free(LNTypeDescr *dtype){ 447 | if(dtype){ 448 | free(dtype->name); 449 | free(dtype->castfunc); 450 | free(dtype); 451 | } 452 | } 453 | --------------------------------------------------------------------------------