AI-MXNetCAPI
view release on metacpan or search on metacpan
%module "AI::MXNetCAPI"
%rename("%(strip:[MX])s") "";
%include typemaps.i
%include mxnet_typemaps.i
%inline %{
#include <c_api.h>
// Taken as is from http://cpansearch.perl.org/src/COLEMINOR/Games-EternalLands-Binary-Float16-0.01/Float16.xs
/* This method is faster than the OpenEXR implementation (very often
* used, eg. in Ogre), with the additional benefit of rounding, inspired
* by James Tursa's half-precision code. */
static inline uint16_t _float_to_half(uint32_t x) {
uint16_t bits = (x >> 16) & 0x8000;
uint16_t m = (x >> 12) & 0x07ff;
unsigned int e = (x >> 23) & 0xff;
if (e < 103)
return bits;
if (e > 142) {
bits |= 0x7c00u;
bits |= e == 255 && (x & 0x007fffffu);
return bits;
}
if (e < 113) {
m |= 0x0800u;
bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);
return bits;
}
bits |= ((e - 112) << 10) | (m >> 1);
bits += m & 1;
return bits;
}
static int const shifttable[32] = {
23, 14, 22, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 20, 0,
15, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 17, 0, 18, 19, 0,
};
static uint32_t const shiftmagic = 0x07c4acddu;
/* This algorithm is similar to the OpenEXR implementation, except it
* uses branchless code in the denormal path. This is slower than a
* table version, but will be more friendly to the cache for occasional
* uses. */
static inline uint32_t _half_to_float(uint16_t x) {
uint32_t s = (x & 0x8000u) << 16;
if ((x & 0x7fffu) == 0)
return (uint32_t)x << 16;
uint32_t e = x & 0x7c00u;
uint32_t m = x & 0x03ffu;
if (e == 0) {
uint32_t v = m | (m >> 1);
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
e = shifttable[(v * shiftmagic) >> 27];
return s | (((125 - e) << 23) + (m << e));
}
if (e == 0x7c00u) {
if (m == 0)
return s | 0x7f800000u;
return s | 0x7fc00000u;
}
return s | (((e >> 10) + 112) << 23) | (m << 13);
}
union fbits {
float f;
uint32_t x;
};
static void KVStore_callback(int index, NDArrayHandle recv, NDArrayHandle local, void* callback)
{
{
dSP;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSViv(index)));
XPUSHs(SWIG_NewPointerObj(SWIG_as_voidptr(recv), SWIGTYPE_p_MXNDArray, 0));
XPUSHs(SWIG_NewPointerObj(SWIG_as_voidptr(local), SWIGTYPE_p_MXNDArray, 0));
PUTBACK;
call_sv((SV*)callback, G_DISCARD);
}
}
static void KVStoreServer_callback(int head, const char *body, void* callback)
{
{
dSP;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSViv(head)));
XPUSHs(sv_2mortal(newSVpv(body, 0)));
PUTBACK;
call_sv((SV*)callback, G_DISCARD);
}
}
static void ExecutorMonitor_callback(const char* name, NDArrayHandle handle, void* callback)
{
{
dSP;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSVpv(name, 0)));
XPUSHs(SWIG_NewPointerObj(SWIG_as_voidptr(handle), SWIGTYPE_p_MXNDArray, 0));
PUTBACK;
call_sv((SV*)callback, G_DISCARD);
}
}
%}
%init %{
/* These SWIG_TypeClientData() calls might break in the future, but
* %rename should work on these types before that happens. */
SWIG_TypeClientData(SWIGTYPE_p_MXNDArray, (void *)"NDArrayHandle");
SWIG_TypeClientData(SWIGTYPE_p_MXFunction, (void *)"FunctionHandle");
SWIG_TypeClientData(SWIGTYPE_p_MXAtomicSymbolCreator, (void *)"AtomicSymbolCreator");
SWIG_TypeClientData(SWIGTYPE_p_MXSymbol, (void *)"SymbolHandle");
SWIG_TypeClientData(SWIGTYPE_p_MXExecutor, (void *)"ExecutorHandle");
SWIG_TypeClientData(SWIGTYPE_p_MXDataIterCreator, (void *)"DataIterCreator");
SWIG_TypeClientData(SWIGTYPE_p_MXDataIter, (void *)"DataIterHandle");
SWIG_TypeClientData(SWIGTYPE_p_MXKVStore, (void *)"KVStoreHandle");
SWIG_TypeClientData(SWIGTYPE_p_MXRecordIO, (void *)"RecordIOHandle");
SWIG_TypeClientData(SWIGTYPE_p_MXRtc, (void *)"RtcHandle");
SWIG_TypeClientData(SWIGTYPE_p_MXCachedOp, (void *)"CachedOpHandle");
%}
/*! \brief manually define unsigned int */
typedef unsigned int mx_uint;
/*! \brief manually define float */
typedef float mx_float;
// all the handles are simply void *
// will be casted internally to specific pointers types
// these typedefs are mainly used for readablity reasons
/*! \brief handle to NDArray */
typedef MXNDArray *NDArrayHandle;
/*! \brief handle to a mxnet ndarray function that changes NDArray */
typedef MXFunction *FunctionHandle;
/*! \brief handle to a function that takes param and creates symbol */
typedef MXAtomicSymbolCreator *AtomicSymbolCreator;
/*! \brief handle to a symbol that can be bind as operator */
typedef MXSymbol *SymbolHandle;
/*! \brief handle to a AtomicSymbol */
typedef MXAtomicSymbol *AtomicSymbolHandle;
/*! \brief handle to an Executor */
typedef MXExecutor *ExecutorHandle;
/*! \brief handle a dataiter creator */
typedef MXDataIterCreator *DataIterCreator;
/*! \brief handle to a DataIterator */
typedef MXDataIter *DataIterHandle;
/*! \brief handle to KVStore */
typedef MXKVStore *KVStoreHandle;
/*! \brief handle to RecordIO */
typedef MXRecordIO *RecordIOHandle;
/*! \brief handle to MXRtc*/
typedef MXRtc *RtcHandle;
/*! \brief handle to cached operator */
typedef MXCachedOp *CachedOpHandle;
typedef void (*ExecutorMonitorCallback)(const char*,
NDArrayHandle,
void *);
struct NativeOpInfo {
void (*forward)(int, float**, int*, unsigned**, int*, void*);
void (*backward)(int, float**, int*, unsigned**, int*, void*);
void (*infer_shape)(int, int*, unsigned**, void*);
void (*list_outputs)(char***, void*);
void (*list_arguments)(char***, void*);
// all functions also pass a payload void* pointer
void* p_forward;
void* p_backward;
void* p_infer_shape;
void* p_list_outputs;
void* p_list_arguments;
( run in 0.452 second using v1.01-cache-2.11-cpan-96521ef73a4 )