From f5ea456e1876265ccf2bec1bbe631921ff81ee86 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Thu, 19 Nov 2020 16:46:25 -0600 Subject: [PATCH 01/34] Sum example --- numba_dppy/device_init.py | 4 + numba_dppy/dpnp_glue/__init__.py | 0 numba_dppy/dpnp_glue/dpnp_fptr_interface.cpp | 3936 ++++++++++++++++++ numba_dppy/dpnp_glue/dpnpdecl.py | 28 + numba_dppy/dpnp_glue/dpnpimpl.py | 12 + numba_dppy/dpnp_glue/stubs.py | 11 + numba_dppy/dppl_passbuilder.py | 4 + numba_dppy/dppl_passes.py | 91 +- numba_dppy/examples/sum.py | 1 + 9 files changed, 4085 insertions(+), 2 deletions(-) create mode 100644 numba_dppy/dpnp_glue/__init__.py create mode 100644 numba_dppy/dpnp_glue/dpnp_fptr_interface.cpp create mode 100644 numba_dppy/dpnp_glue/dpnpdecl.py create mode 100644 numba_dppy/dpnp_glue/dpnpimpl.py create mode 100644 numba_dppy/dpnp_glue/stubs.py diff --git a/numba_dppy/device_init.py b/numba_dppy/device_init.py index c4506014a8..201ae09650 100644 --- a/numba_dppy/device_init.py +++ b/numba_dppy/device_init.py @@ -18,6 +18,10 @@ CLK_GLOBAL_MEM_FENCE, ) +from .dpnp_glue.stubs import ( + dpnp +) + DEFAULT_LOCAL_SIZE = [] from . import initialize diff --git a/numba_dppy/dpnp_glue/__init__.py b/numba_dppy/dpnp_glue/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/numba_dppy/dpnp_glue/dpnp_fptr_interface.cpp b/numba_dppy/dpnp_glue/dpnp_fptr_interface.cpp new file mode 100644 index 0000000000..b4ab803a03 --- /dev/null +++ b/numba_dppy/dpnp_glue/dpnp_fptr_interface.cpp @@ -0,0 +1,3936 @@ +/* Generated by Cython 0.29.21 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "depends": [ + "/localdisk/work/rhoque/conda_envs/ms141/lib/python3.7/site-packages/dpnp/backend/backend_iface_fptr.hpp" + ], + "include_dirs": [ + "/localdisk/work/rhoque/conda_envs/ms141/lib/python3.7/site-packages/dpnp/backend" + ], + "language": "c++", + "libraries": [ + "dpnp_backend_c" + ], + "library_dirs": [ + "/localdisk/work/rhoque/conda_envs/ms141/lib/python3.7/site-packages/dpnp" + ], + "name": "numba_dppy.dpnp_glue.dpnp_fptr_interface", + "runtime_library_dirs": [ + "/localdisk/work/rhoque/conda_envs/ms141/lib/python3.7/site-packages/dpnp" + ], + "sources": [ + "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx" + ] + }, + "module_name": "numba_dppy.dpnp_glue.dpnp_fptr_interface" +} +END: Cython Metadata */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.6+ or Python 3.3+. +#else +#define CYTHON_ABI "0_29_21" +#define CYTHON_HEX_VERSION 0x001D15F0 +#define CYTHON_FUTURE_DIVISION 1 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #if PY_VERSION_HEX >= 0x02070000 + #define HAVE_LONG_LONG + #endif +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#ifdef PYPY_VERSION + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#elif defined(PYSTON_VERSION) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #elif !defined(CYTHON_USE_PYLONG_INTERNALS) + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) + #endif + #ifndef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #include "longintrepr.h" + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int32 uint32_t; + #endif + #endif +#else + #include +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) && __cplusplus >= 201103L + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #elif __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__ ) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif + +#ifndef __cplusplus + #error "Cython files generated with the C++ option must be compiled with a C++ compiler." +#endif +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #else + #define CYTHON_INLINE inline + #endif +#endif +template +void __Pyx_call_destructor(T& x) { + x.~T(); +} +template +class __Pyx_FakeReference { + public: + __Pyx_FakeReference() : ptr(NULL) { } + __Pyx_FakeReference(const T& ref) : ptr(const_cast(&ref)) { } + T *operator->() { return ptr; } + T *operator&() { return ptr; } + operator T&() { return *ptr; } + template bool operator ==(U other) { return *ptr == other; } + template bool operator !=(U other) { return *ptr != other; } + private: + T *ptr; +}; + +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) + #define Py_OptimizeFlag 0 +#endif +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyClass_Type +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" +#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif + #define __Pyx_DefaultClassType PyType_Type +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #define __Pyx_PyCFunctionFast _PyCFunctionFast + #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords +#endif +#if CYTHON_FAST_PYCCALL +#define __Pyx_PyFastCFunction_Check(func)\ + ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) +#else +#define __Pyx_PyFastCFunction_Check(func) 0 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 + #define PyMem_RawMalloc(n) PyMem_Malloc(n) + #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) + #define PyMem_RawFree(p) PyMem_Free(p) +#endif +#if CYTHON_COMPILING_IN_PYSTON + #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) +#include "pythread.h" +#define Py_tss_NEEDS_INIT 0 +typedef int Py_tss_t; +static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { + *key = PyThread_create_key(); + return 0; +} +static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { + Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); + *key = Py_tss_NEEDS_INIT; + return key; +} +static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { + PyObject_Free(key); +} +static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { + return *key != Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { + PyThread_delete_key(*key); + *key = Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { + return PyThread_set_key_value(*key, value); +} +static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { + return PyThread_get_key_value(*key); +} +#endif +#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +#else +#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) +#endif +#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) + #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #endif +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) + #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#ifndef PyObject_Unicode + #define PyObject_Unicode PyObject_Str +#endif +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) +#else + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t PyInt_AsLong +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) +#else + #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif + +#if defined(WIN32) || defined(MS_WINDOWS) + #define _USE_MATH_DEFINES +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#define __PYX_MARK_ERR_POS(f_index, lineno) \ + { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__numba_dppy__dpnp_glue__dpnp_fptr_interface +#define __PYX_HAVE_API__numba_dppy__dpnp_glue__dpnp_fptr_interface +/* Early includes */ +#include "backend_iface_fptr.hpp" +#include +#include +#include +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +static PyObject *__pyx_m = NULL; +static PyObject *__pyx_d; +static PyObject *__pyx_b; +static PyObject *__pyx_cython_runtime = NULL; +static PyObject *__pyx_empty_tuple; +static PyObject *__pyx_empty_bytes; +static PyObject *__pyx_empty_unicode; +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm= __FILE__; +static const char *__pyx_filename; + + +static const char *__pyx_f[] = { + "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx", +}; + +/*--- Type declarations ---*/ + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, int); + void (*DECREF)(void*, PyObject*, int); + void (*GOTREF)(void*, PyObject*, int); + void (*GIVEREF)(void*, PyObject*, int); + void* (*SetupContext)(const char*, int, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) +#endif + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* IncludeStringH.proto */ +#include + +/* BytesEquals.proto */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* WriteUnraisableException.proto */ +static void __Pyx_WriteUnraisable(const char *name, int clineno, + int lineno, const char *filename, + int full_traceback, int nogil); + +/* GetItemInt.proto */ +#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ + __Pyx_GetItemInt_Generic(o, to_py_func(i)))) +#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, + int is_list, int wraparound, int boundscheck); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ + const char* function_name); + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* PyDictVersioning.proto */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(void); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + + +/* Module declarations from 'libc.string' */ + +/* Module declarations from 'libc.stdio' */ + +/* Module declarations from 'libc.stdint' */ + +/* Module declarations from 'numba_dppy.dpnp_glue.dpnp_fptr_interface' */ +static enum DPNPFuncName __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_DPNPFuncName_from_str(PyObject *); /*proto*/ +static enum DPNPFuncType __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_DPNPFuncType_from_str(PyObject *); /*proto*/ +static PyObject *__pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_dpnp_fn_ptr(PyObject *, PyObject *, int __pyx_skip_dispatch); /*proto*/ +#define __Pyx_MODULE_NAME "numba_dppy.dpnp_glue.dpnp_fptr_interface" +extern int __pyx_module_is_main_numba_dppy__dpnp_glue__dpnp_fptr_interface; +int __pyx_module_is_main_numba_dppy__dpnp_glue__dpnp_fptr_interface = 0; + +/* Implementation of 'numba_dppy.dpnp_glue.dpnp_fptr_interface' */ +static const char __pyx_k_bool[] = "bool"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_name[] = "name"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_int32[] = "int32"; +static const char __pyx_k_int64[] = "int64"; +static const char __pyx_k_types[] = "types"; +static const char __pyx_k_ctypes[] = "ctypes"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_name_2[] = "__name__"; +static const char __pyx_k_uint32[] = "uint32"; +static const char __pyx_k_uint64[] = "uint64"; +static const char __pyx_k_float32[] = "float32"; +static const char __pyx_k_float64[] = "float64"; +static const char __pyx_k_dpnp_cov[] = "dpnp_cov"; +static const char __pyx_k_dpnp_dot[] = "dpnp_dot"; +static const char __pyx_k_dpnp_max[] = "dpnp_max"; +static const char __pyx_k_dpnp_min[] = "dpnp_min"; +static const char __pyx_k_dpnp_sum[] = "dpnp_sum"; +static const char __pyx_k_dpnp_mean[] = "dpnp_mean"; +static const char __pyx_k_dpnp_prod[] = "dpnp_prod"; +static const char __pyx_k_dpnp_argmax[] = "dpnp_argmax"; +static const char __pyx_k_dpnp_argmin[] = "dpnp_argmin"; +static const char __pyx_k_dpnp_matmul[] = "dpnp_matmul"; +static const char __pyx_k_dpnp_median[] = "dpnp_median"; +static const char __pyx_k_dpnp_argsort[] = "dpnp_argsort"; +static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static PyObject *__pyx_n_u_bool; +static PyObject *__pyx_n_s_cline_in_traceback; +static PyObject *__pyx_n_s_ctypes; +static PyObject *__pyx_n_u_dpnp_argmax; +static PyObject *__pyx_n_u_dpnp_argmin; +static PyObject *__pyx_n_u_dpnp_argsort; +static PyObject *__pyx_n_u_dpnp_cov; +static PyObject *__pyx_n_u_dpnp_dot; +static PyObject *__pyx_n_u_dpnp_matmul; +static PyObject *__pyx_n_u_dpnp_max; +static PyObject *__pyx_n_u_dpnp_mean; +static PyObject *__pyx_n_u_dpnp_median; +static PyObject *__pyx_n_u_dpnp_min; +static PyObject *__pyx_n_u_dpnp_prod; +static PyObject *__pyx_n_u_dpnp_sum; +static PyObject *__pyx_n_u_float32; +static PyObject *__pyx_n_u_float64; +static PyObject *__pyx_n_s_import; +static PyObject *__pyx_n_u_int32; +static PyObject *__pyx_n_u_int64; +static PyObject *__pyx_n_s_main; +static PyObject *__pyx_n_s_name; +static PyObject *__pyx_n_s_name_2; +static PyObject *__pyx_n_s_test; +static PyObject *__pyx_n_s_types; +static PyObject *__pyx_n_u_uint32; +static PyObject *__pyx_n_u_uint64; +static PyObject *__pyx_pf_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_dpnp_fn_ptr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_name, PyObject *__pyx_v_types); /* proto */ +/* Late includes */ + +/* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":87 + * + * + * cdef DPNPFuncName get_DPNPFuncName_from_str(name): # <<<<<<<<<<<<<< + * if name == "dpnp_dot": + * return DPNPFuncName.DPNP_FN_DOT + */ + +static enum DPNPFuncName __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_DPNPFuncName_from_str(PyObject *__pyx_v_name) { + enum DPNPFuncName __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("get_DPNPFuncName_from_str", 0); + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":88 + * + * cdef DPNPFuncName get_DPNPFuncName_from_str(name): + * if name == "dpnp_dot": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_DOT + * elif name == "dpnp_matmul": + */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_dot, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 88, __pyx_L1_error) + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":89 + * cdef DPNPFuncName get_DPNPFuncName_from_str(name): + * if name == "dpnp_dot": + * return DPNPFuncName.DPNP_FN_DOT # <<<<<<<<<<<<<< + * elif name == "dpnp_matmul": + * return DPNPFuncName.DPNP_FN_MATMUL + */ + __pyx_r = DPNPFuncName::DPNP_FN_DOT; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":88 + * + * cdef DPNPFuncName get_DPNPFuncName_from_str(name): + * if name == "dpnp_dot": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_DOT + * elif name == "dpnp_matmul": + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":90 + * if name == "dpnp_dot": + * return DPNPFuncName.DPNP_FN_DOT + * elif name == "dpnp_matmul": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_MATMUL + * elif name == "dpnp_sum": + */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_matmul, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 90, __pyx_L1_error) + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":91 + * return DPNPFuncName.DPNP_FN_DOT + * elif name == "dpnp_matmul": + * return DPNPFuncName.DPNP_FN_MATMUL # <<<<<<<<<<<<<< + * elif name == "dpnp_sum": + * return DPNPFuncName.DPNP_FN_SUM + */ + __pyx_r = DPNPFuncName::DPNP_FN_MATMUL; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":90 + * if name == "dpnp_dot": + * return DPNPFuncName.DPNP_FN_DOT + * elif name == "dpnp_matmul": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_MATMUL + * elif name == "dpnp_sum": + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":92 + * elif name == "dpnp_matmul": + * return DPNPFuncName.DPNP_FN_MATMUL + * elif name == "dpnp_sum": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_SUM + * elif name == "dpnp_prod": + */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_sum, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 92, __pyx_L1_error) + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":93 + * return DPNPFuncName.DPNP_FN_MATMUL + * elif name == "dpnp_sum": + * return DPNPFuncName.DPNP_FN_SUM # <<<<<<<<<<<<<< + * elif name == "dpnp_prod": + * return DPNPFuncName.DPNP_FN_PROD + */ + __pyx_r = DPNPFuncName::DPNP_FN_SUM; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":92 + * elif name == "dpnp_matmul": + * return DPNPFuncName.DPNP_FN_MATMUL + * elif name == "dpnp_sum": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_SUM + * elif name == "dpnp_prod": + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":94 + * elif name == "dpnp_sum": + * return DPNPFuncName.DPNP_FN_SUM + * elif name == "dpnp_prod": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_PROD + * elif name == "dpnp_argmax": + */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_prod, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 94, __pyx_L1_error) + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":95 + * return DPNPFuncName.DPNP_FN_SUM + * elif name == "dpnp_prod": + * return DPNPFuncName.DPNP_FN_PROD # <<<<<<<<<<<<<< + * elif name == "dpnp_argmax": + * return DPNPFuncName.DPNP_FN_ARGMAX + */ + __pyx_r = DPNPFuncName::DPNP_FN_PROD; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":94 + * elif name == "dpnp_sum": + * return DPNPFuncName.DPNP_FN_SUM + * elif name == "dpnp_prod": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_PROD + * elif name == "dpnp_argmax": + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":96 + * elif name == "dpnp_prod": + * return DPNPFuncName.DPNP_FN_PROD + * elif name == "dpnp_argmax": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_ARGMAX + * elif name == "dpnp_max": + */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_argmax, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 96, __pyx_L1_error) + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":97 + * return DPNPFuncName.DPNP_FN_PROD + * elif name == "dpnp_argmax": + * return DPNPFuncName.DPNP_FN_ARGMAX # <<<<<<<<<<<<<< + * elif name == "dpnp_max": + * return DPNPFuncName.DPNP_FN_MAX + */ + __pyx_r = DPNPFuncName::DPNP_FN_ARGMAX; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":96 + * elif name == "dpnp_prod": + * return DPNPFuncName.DPNP_FN_PROD + * elif name == "dpnp_argmax": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_ARGMAX + * elif name == "dpnp_max": + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":98 + * elif name == "dpnp_argmax": + * return DPNPFuncName.DPNP_FN_ARGMAX + * elif name == "dpnp_max": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_MAX + * elif name == "dpnp_argmin": + */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_max, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 98, __pyx_L1_error) + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":99 + * return DPNPFuncName.DPNP_FN_ARGMAX + * elif name == "dpnp_max": + * return DPNPFuncName.DPNP_FN_MAX # <<<<<<<<<<<<<< + * elif name == "dpnp_argmin": + * return DPNPFuncName.DPNP_FN_ARGMIN + */ + __pyx_r = DPNPFuncName::DPNP_FN_MAX; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":98 + * elif name == "dpnp_argmax": + * return DPNPFuncName.DPNP_FN_ARGMAX + * elif name == "dpnp_max": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_MAX + * elif name == "dpnp_argmin": + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":100 + * elif name == "dpnp_max": + * return DPNPFuncName.DPNP_FN_MAX + * elif name == "dpnp_argmin": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_ARGMIN + * elif name == "dpnp_min": + */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_argmin, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 100, __pyx_L1_error) + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":101 + * return DPNPFuncName.DPNP_FN_MAX + * elif name == "dpnp_argmin": + * return DPNPFuncName.DPNP_FN_ARGMIN # <<<<<<<<<<<<<< + * elif name == "dpnp_min": + * return DPNPFuncName.DPNP_FN_MIN + */ + __pyx_r = DPNPFuncName::DPNP_FN_ARGMIN; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":100 + * elif name == "dpnp_max": + * return DPNPFuncName.DPNP_FN_MAX + * elif name == "dpnp_argmin": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_ARGMIN + * elif name == "dpnp_min": + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":102 + * elif name == "dpnp_argmin": + * return DPNPFuncName.DPNP_FN_ARGMIN + * elif name == "dpnp_min": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_MIN + * elif name == "dpnp_mean": + */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_min, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 102, __pyx_L1_error) + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":103 + * return DPNPFuncName.DPNP_FN_ARGMIN + * elif name == "dpnp_min": + * return DPNPFuncName.DPNP_FN_MIN # <<<<<<<<<<<<<< + * elif name == "dpnp_mean": + * return DPNPFuncName.DPNP_FN_MEAN + */ + __pyx_r = DPNPFuncName::DPNP_FN_MIN; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":102 + * elif name == "dpnp_argmin": + * return DPNPFuncName.DPNP_FN_ARGMIN + * elif name == "dpnp_min": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_MIN + * elif name == "dpnp_mean": + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":104 + * elif name == "dpnp_min": + * return DPNPFuncName.DPNP_FN_MIN + * elif name == "dpnp_mean": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_MEAN + * elif name == "dpnp_median": + */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_mean, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 104, __pyx_L1_error) + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":105 + * return DPNPFuncName.DPNP_FN_MIN + * elif name == "dpnp_mean": + * return DPNPFuncName.DPNP_FN_MEAN # <<<<<<<<<<<<<< + * elif name == "dpnp_median": + * return DPNPFuncName.DPNP_FN_MEDIAN + */ + __pyx_r = DPNPFuncName::DPNP_FN_MEAN; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":104 + * elif name == "dpnp_min": + * return DPNPFuncName.DPNP_FN_MIN + * elif name == "dpnp_mean": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_MEAN + * elif name == "dpnp_median": + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":106 + * elif name == "dpnp_mean": + * return DPNPFuncName.DPNP_FN_MEAN + * elif name == "dpnp_median": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_MEDIAN + * elif name == "dpnp_argsort": + */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_median, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 106, __pyx_L1_error) + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":107 + * return DPNPFuncName.DPNP_FN_MEAN + * elif name == "dpnp_median": + * return DPNPFuncName.DPNP_FN_MEDIAN # <<<<<<<<<<<<<< + * elif name == "dpnp_argsort": + * return DPNPFuncName.DPNP_FN_ARGSORT + */ + __pyx_r = DPNPFuncName::DPNP_FN_MEDIAN; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":106 + * elif name == "dpnp_mean": + * return DPNPFuncName.DPNP_FN_MEAN + * elif name == "dpnp_median": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_MEDIAN + * elif name == "dpnp_argsort": + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":108 + * elif name == "dpnp_median": + * return DPNPFuncName.DPNP_FN_MEDIAN + * elif name == "dpnp_argsort": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_ARGSORT + * elif name == "dpnp_cov": + */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_argsort, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 108, __pyx_L1_error) + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":109 + * return DPNPFuncName.DPNP_FN_MEDIAN + * elif name == "dpnp_argsort": + * return DPNPFuncName.DPNP_FN_ARGSORT # <<<<<<<<<<<<<< + * elif name == "dpnp_cov": + * return DPNPFuncName.DPNP_FN_COV + */ + __pyx_r = DPNPFuncName::DPNP_FN_ARGSORT; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":108 + * elif name == "dpnp_median": + * return DPNPFuncName.DPNP_FN_MEDIAN + * elif name == "dpnp_argsort": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_ARGSORT + * elif name == "dpnp_cov": + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":110 + * elif name == "dpnp_argsort": + * return DPNPFuncName.DPNP_FN_ARGSORT + * elif name == "dpnp_cov": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_COV + * else: + */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_cov, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 110, __pyx_L1_error) + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":111 + * return DPNPFuncName.DPNP_FN_ARGSORT + * elif name == "dpnp_cov": + * return DPNPFuncName.DPNP_FN_COV # <<<<<<<<<<<<<< + * else: + * return DPNPFuncName.DPNP_FN_DOT + */ + __pyx_r = DPNPFuncName::DPNP_FN_COV; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":110 + * elif name == "dpnp_argsort": + * return DPNPFuncName.DPNP_FN_ARGSORT + * elif name == "dpnp_cov": # <<<<<<<<<<<<<< + * return DPNPFuncName.DPNP_FN_COV + * else: + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":113 + * return DPNPFuncName.DPNP_FN_COV + * else: + * return DPNPFuncName.DPNP_FN_DOT # <<<<<<<<<<<<<< + * + * + */ + /*else*/ { + __pyx_r = DPNPFuncName::DPNP_FN_DOT; + goto __pyx_L0; + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":87 + * + * + * cdef DPNPFuncName get_DPNPFuncName_from_str(name): # <<<<<<<<<<<<<< + * if name == "dpnp_dot": + * return DPNPFuncName.DPNP_FN_DOT + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_WriteUnraisable("numba_dppy.dpnp_glue.dpnp_fptr_interface.get_DPNPFuncName_from_str", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); + __pyx_r = (enum DPNPFuncName) 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":116 + * + * + * cdef DPNPFuncType get_DPNPFuncType_from_str(name): # <<<<<<<<<<<<<< + * if name == "float32": + * return DPNPFuncType.DPNP_FT_FLOAT + */ + +static enum DPNPFuncType __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_DPNPFuncType_from_str(PyObject *__pyx_v_name) { + enum DPNPFuncType __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("get_DPNPFuncType_from_str", 0); + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":117 + * + * cdef DPNPFuncType get_DPNPFuncType_from_str(name): + * if name == "float32": # <<<<<<<<<<<<<< + * return DPNPFuncType.DPNP_FT_FLOAT + * elif name == "int32" or name == "uint32" or name == "bool": + */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_float32, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 117, __pyx_L1_error) + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":118 + * cdef DPNPFuncType get_DPNPFuncType_from_str(name): + * if name == "float32": + * return DPNPFuncType.DPNP_FT_FLOAT # <<<<<<<<<<<<<< + * elif name == "int32" or name == "uint32" or name == "bool": + * return DPNPFuncType.DPNP_FT_INT + */ + __pyx_r = DPNPFuncType::DPNP_FT_FLOAT; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":117 + * + * cdef DPNPFuncType get_DPNPFuncType_from_str(name): + * if name == "float32": # <<<<<<<<<<<<<< + * return DPNPFuncType.DPNP_FT_FLOAT + * elif name == "int32" or name == "uint32" or name == "bool": + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":119 + * if name == "float32": + * return DPNPFuncType.DPNP_FT_FLOAT + * elif name == "int32" or name == "uint32" or name == "bool": # <<<<<<<<<<<<<< + * return DPNPFuncType.DPNP_FT_INT + * elif name == "float64": + */ + __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_int32, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 119, __pyx_L1_error) + if (!__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_uint32, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 119, __pyx_L1_error) + if (!__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_bool, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 119, __pyx_L1_error) + __pyx_t_1 = __pyx_t_2; + __pyx_L4_bool_binop_done:; + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":120 + * return DPNPFuncType.DPNP_FT_FLOAT + * elif name == "int32" or name == "uint32" or name == "bool": + * return DPNPFuncType.DPNP_FT_INT # <<<<<<<<<<<<<< + * elif name == "float64": + * return DPNPFuncType.DPNP_FT_DOUBLE + */ + __pyx_r = DPNPFuncType::DPNP_FT_INT; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":119 + * if name == "float32": + * return DPNPFuncType.DPNP_FT_FLOAT + * elif name == "int32" or name == "uint32" or name == "bool": # <<<<<<<<<<<<<< + * return DPNPFuncType.DPNP_FT_INT + * elif name == "float64": + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":121 + * elif name == "int32" or name == "uint32" or name == "bool": + * return DPNPFuncType.DPNP_FT_INT + * elif name == "float64": # <<<<<<<<<<<<<< + * return DPNPFuncType.DPNP_FT_DOUBLE + * elif name == "int64" or name == "uint64": + */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_float64, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 121, __pyx_L1_error) + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":122 + * return DPNPFuncType.DPNP_FT_INT + * elif name == "float64": + * return DPNPFuncType.DPNP_FT_DOUBLE # <<<<<<<<<<<<<< + * elif name == "int64" or name == "uint64": + * return DPNPFuncType.DPNP_FT_LONG + */ + __pyx_r = DPNPFuncType::DPNP_FT_DOUBLE; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":121 + * elif name == "int32" or name == "uint32" or name == "bool": + * return DPNPFuncType.DPNP_FT_INT + * elif name == "float64": # <<<<<<<<<<<<<< + * return DPNPFuncType.DPNP_FT_DOUBLE + * elif name == "int64" or name == "uint64": + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":123 + * elif name == "float64": + * return DPNPFuncType.DPNP_FT_DOUBLE + * elif name == "int64" or name == "uint64": # <<<<<<<<<<<<<< + * return DPNPFuncType.DPNP_FT_LONG + * else: + */ + __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_int64, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 123, __pyx_L1_error) + if (!__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L7_bool_binop_done; + } + __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_uint64, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 123, __pyx_L1_error) + __pyx_t_1 = __pyx_t_2; + __pyx_L7_bool_binop_done:; + if (__pyx_t_1) { + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":124 + * return DPNPFuncType.DPNP_FT_DOUBLE + * elif name == "int64" or name == "uint64": + * return DPNPFuncType.DPNP_FT_LONG # <<<<<<<<<<<<<< + * else: + * return DPNPFuncType.DPNP_FT_NONE + */ + __pyx_r = DPNPFuncType::DPNP_FT_LONG; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":123 + * elif name == "float64": + * return DPNPFuncType.DPNP_FT_DOUBLE + * elif name == "int64" or name == "uint64": # <<<<<<<<<<<<<< + * return DPNPFuncType.DPNP_FT_LONG + * else: + */ + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":126 + * return DPNPFuncType.DPNP_FT_LONG + * else: + * return DPNPFuncType.DPNP_FT_NONE # <<<<<<<<<<<<<< + * + * from libc.stdio cimport printf + */ + /*else*/ { + __pyx_r = DPNPFuncType::DPNP_FT_NONE; + goto __pyx_L0; + } + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":116 + * + * + * cdef DPNPFuncType get_DPNPFuncType_from_str(name): # <<<<<<<<<<<<<< + * if name == "float32": + * return DPNPFuncType.DPNP_FT_FLOAT + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_WriteUnraisable("numba_dppy.dpnp_glue.dpnp_fptr_interface.get_DPNPFuncType_from_str", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); + __pyx_r = (enum DPNPFuncType) 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":131 + * from libc.stdint cimport uintptr_t + * + * cpdef get_dpnp_fn_ptr(name, types): # <<<<<<<<<<<<<< + * cdef DPNPFuncName func_name = get_DPNPFuncName_from_str(name) + * cdef DPNPFuncType first_type = get_DPNPFuncType_from_str(types[0]) + */ + +static PyObject *__pyx_pw_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_1get_dpnp_fn_ptr(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_dpnp_fn_ptr(PyObject *__pyx_v_name, PyObject *__pyx_v_types, CYTHON_UNUSED int __pyx_skip_dispatch) { + enum DPNPFuncName __pyx_v_func_name; + enum DPNPFuncType __pyx_v_first_type; + enum DPNPFuncType __pyx_v_second_type; + struct DPNPFuncData __pyx_v_kernel_data; + uintptr_t __pyx_v_fn_ptr; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("get_dpnp_fn_ptr", 0); + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":132 + * + * cpdef get_dpnp_fn_ptr(name, types): + * cdef DPNPFuncName func_name = get_DPNPFuncName_from_str(name) # <<<<<<<<<<<<<< + * cdef DPNPFuncType first_type = get_DPNPFuncType_from_str(types[0]) + * cdef DPNPFuncType second_type = get_DPNPFuncType_from_str(types[1]) + */ + __pyx_v_func_name = __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_DPNPFuncName_from_str(__pyx_v_name); + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":133 + * cpdef get_dpnp_fn_ptr(name, types): + * cdef DPNPFuncName func_name = get_DPNPFuncName_from_str(name) + * cdef DPNPFuncType first_type = get_DPNPFuncType_from_str(types[0]) # <<<<<<<<<<<<<< + * cdef DPNPFuncType second_type = get_DPNPFuncType_from_str(types[1]) + * + */ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_types, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 133, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_first_type = __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_DPNPFuncType_from_str(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":134 + * cdef DPNPFuncName func_name = get_DPNPFuncName_from_str(name) + * cdef DPNPFuncType first_type = get_DPNPFuncType_from_str(types[0]) + * cdef DPNPFuncType second_type = get_DPNPFuncType_from_str(types[1]) # <<<<<<<<<<<<<< + * + * cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(func_name, first_type, second_type) + */ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_types, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 134, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_second_type = __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_DPNPFuncType_from_str(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":136 + * cdef DPNPFuncType second_type = get_DPNPFuncType_from_str(types[1]) + * + * cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(func_name, first_type, second_type) # <<<<<<<<<<<<<< + * cdef uintptr_t fn_ptr = kernel_data.ptr + * + */ + __pyx_v_kernel_data = get_dpnp_function_ptr(__pyx_v_func_name, __pyx_v_first_type, __pyx_v_second_type); + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":137 + * + * cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(func_name, first_type, second_type) + * cdef uintptr_t fn_ptr = kernel_data.ptr # <<<<<<<<<<<<<< + * + * return fn_ptr + */ + __pyx_v_fn_ptr = ((uintptr_t)__pyx_v_kernel_data.ptr); + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":139 + * cdef uintptr_t fn_ptr = kernel_data.ptr + * + * return fn_ptr # <<<<<<<<<<<<<< + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_v_fn_ptr); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 139, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(((PyObject *)__pyx_t_1)); + __pyx_r = __pyx_t_1; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + goto __pyx_L0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":131 + * from libc.stdint cimport uintptr_t + * + * cpdef get_dpnp_fn_ptr(name, types): # <<<<<<<<<<<<<< + * cdef DPNPFuncName func_name = get_DPNPFuncName_from_str(name) + * cdef DPNPFuncType first_type = get_DPNPFuncType_from_str(types[0]) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numba_dppy.dpnp_glue.dpnp_fptr_interface.get_dpnp_fn_ptr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* Python wrapper */ +static PyObject *__pyx_pw_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_1get_dpnp_fn_ptr(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_pw_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_1get_dpnp_fn_ptr(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_name = 0; + PyObject *__pyx_v_types = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("get_dpnp_fn_ptr (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,&__pyx_n_s_types,0}; + PyObject* values[2] = {0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_types)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("get_dpnp_fn_ptr", 1, 2, 2, 1); __PYX_ERR(0, 131, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_dpnp_fn_ptr") < 0)) __PYX_ERR(0, 131, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + } + __pyx_v_name = values[0]; + __pyx_v_types = values[1]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("get_dpnp_fn_ptr", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 131, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("numba_dppy.dpnp_glue.dpnp_fptr_interface.get_dpnp_fn_ptr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_dpnp_fn_ptr(__pyx_self, __pyx_v_name, __pyx_v_types); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_dpnp_fn_ptr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_name, PyObject *__pyx_v_types) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("get_dpnp_fn_ptr", 0); + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_dpnp_fn_ptr(__pyx_v_name, __pyx_v_types, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numba_dppy.dpnp_glue.dpnp_fptr_interface.get_dpnp_fn_ptr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyMethodDef __pyx_methods[] = { + {"get_dpnp_fn_ptr", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_1get_dpnp_fn_ptr, METH_VARARGS|METH_KEYWORDS, 0}, + {0, 0, 0, 0} +}; + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_dpnp_fptr_interface(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_dpnp_fptr_interface}, + {0, NULL} +}; +#endif + +static struct PyModuleDef __pyx_moduledef = { + PyModuleDef_HEAD_INIT, + "dpnp_fptr_interface", + 0, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; +#endif +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif + +static __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_n_u_bool, __pyx_k_bool, sizeof(__pyx_k_bool), 0, 1, 0, 1}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_ctypes, __pyx_k_ctypes, sizeof(__pyx_k_ctypes), 0, 0, 1, 1}, + {&__pyx_n_u_dpnp_argmax, __pyx_k_dpnp_argmax, sizeof(__pyx_k_dpnp_argmax), 0, 1, 0, 1}, + {&__pyx_n_u_dpnp_argmin, __pyx_k_dpnp_argmin, sizeof(__pyx_k_dpnp_argmin), 0, 1, 0, 1}, + {&__pyx_n_u_dpnp_argsort, __pyx_k_dpnp_argsort, sizeof(__pyx_k_dpnp_argsort), 0, 1, 0, 1}, + {&__pyx_n_u_dpnp_cov, __pyx_k_dpnp_cov, sizeof(__pyx_k_dpnp_cov), 0, 1, 0, 1}, + {&__pyx_n_u_dpnp_dot, __pyx_k_dpnp_dot, sizeof(__pyx_k_dpnp_dot), 0, 1, 0, 1}, + {&__pyx_n_u_dpnp_matmul, __pyx_k_dpnp_matmul, sizeof(__pyx_k_dpnp_matmul), 0, 1, 0, 1}, + {&__pyx_n_u_dpnp_max, __pyx_k_dpnp_max, sizeof(__pyx_k_dpnp_max), 0, 1, 0, 1}, + {&__pyx_n_u_dpnp_mean, __pyx_k_dpnp_mean, sizeof(__pyx_k_dpnp_mean), 0, 1, 0, 1}, + {&__pyx_n_u_dpnp_median, __pyx_k_dpnp_median, sizeof(__pyx_k_dpnp_median), 0, 1, 0, 1}, + {&__pyx_n_u_dpnp_min, __pyx_k_dpnp_min, sizeof(__pyx_k_dpnp_min), 0, 1, 0, 1}, + {&__pyx_n_u_dpnp_prod, __pyx_k_dpnp_prod, sizeof(__pyx_k_dpnp_prod), 0, 1, 0, 1}, + {&__pyx_n_u_dpnp_sum, __pyx_k_dpnp_sum, sizeof(__pyx_k_dpnp_sum), 0, 1, 0, 1}, + {&__pyx_n_u_float32, __pyx_k_float32, sizeof(__pyx_k_float32), 0, 1, 0, 1}, + {&__pyx_n_u_float64, __pyx_k_float64, sizeof(__pyx_k_float64), 0, 1, 0, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_u_int32, __pyx_k_int32, sizeof(__pyx_k_int32), 0, 1, 0, 1}, + {&__pyx_n_u_int64, __pyx_k_int64, sizeof(__pyx_k_int64), 0, 1, 0, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, + {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_types, __pyx_k_types, sizeof(__pyx_k_types), 0, 0, 1, 1}, + {&__pyx_n_u_uint32, __pyx_k_uint32, sizeof(__pyx_k_uint32), 0, 1, 0, 1}, + {&__pyx_n_u_uint64, __pyx_k_uint64, sizeof(__pyx_k_uint64), 0, 1, 0, 1}, + {0, 0, 0, 0, 0, 0, 0} +}; +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { + return 0; +} + +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + __Pyx_RefNannyFinishContext(); + return 0; +} + +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { + if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + return 0; + __pyx_L1_error:; + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + + +#ifndef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#elif PY_MAJOR_VERSION < 3 +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" void +#else +#define __Pyx_PyMODINIT_FUNC void +#endif +#else +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyObject * +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC initdpnp_fptr_interface(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC initdpnp_fptr_interface(void) +#else +__Pyx_PyMODINIT_FUNC PyInit_dpnp_fptr_interface(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit_dpnp_fptr_interface(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + if (__Pyx_check_single_interpreter()) + return NULL; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec_dpnp_fptr_interface(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module 'dpnp_fptr_interface' has already been imported. Re-initialisation is not supported."); + return -1; + } + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit_dpnp_fptr_interface(void)", 0); + if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + #ifdef WITH_THREAD /* Python build with threading support? */ + PyEval_InitThreads(); + #endif + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("dpnp_fptr_interface", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + #endif + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_b); + __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_cython_runtime); + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_numba_dppy__dpnp_glue__dpnp_fptr_interface) { + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name_2, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "numba_dppy.dpnp_glue.dpnp_fptr_interface")) { + if (unlikely(PyDict_SetItemString(modules, "numba_dppy.dpnp_glue.dpnp_fptr_interface", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + (void)__Pyx_modinit_type_init_code(); + (void)__Pyx_modinit_type_import_code(); + (void)__Pyx_modinit_variable_import_code(); + (void)__Pyx_modinit_function_import_code(); + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":4 + * # cython: language_level=3 + * + * import ctypes # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_1 = __Pyx_Import(__pyx_n_s_ctypes, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_ctypes, __pyx_t_1) < 0) __PYX_ERR(0, 4, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":1 + * # distutils: language = c++ # <<<<<<<<<<<<<< + * # cython: language_level=3 + * + */ + __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + if (__pyx_m) { + if (__pyx_d) { + __Pyx_AddTraceback("init numba_dppy.dpnp_glue.dpnp_fptr_interface", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + Py_CLEAR(__pyx_m); + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init numba_dppy.dpnp_glue.dpnp_fptr_interface"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* BytesEquals */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY + return PyObject_RichCompareBool(s1, s2, equals); +#else +#if PY_MAJOR_VERSION < 3 + PyObject* owned_ref = NULL; +#endif + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); +#if PY_MAJOR_VERSION < 3 + if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { + owned_ref = PyUnicode_FromObject(s2); + if (unlikely(!owned_ref)) + return -1; + s2 = owned_ref; + s2_is_unicode = 1; + } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { + owned_ref = PyUnicode_FromObject(s1); + if (unlikely(!owned_ref)) + return -1; + s1 = owned_ref; + s1_is_unicode = 1; + } else if (((!s2_is_unicode) & (!s1_is_unicode))) { + return __Pyx_PyBytes_Equals(s1, s2, equals); + } +#endif + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length; + int kind; + void *data1, *data2; + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + length = __Pyx_PyUnicode_GET_LENGTH(s1); + if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + #if CYTHON_PEP393_ENABLED + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + #else + hash1 = ((PyUnicodeObject*)s1)->hash; + hash2 = ((PyUnicodeObject*)s2)->hash; + #endif + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ); +return_ne: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_NE); +#endif +} + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +} +#endif + +/* WriteUnraisableException */ +static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno, + CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename, + int full_traceback, CYTHON_UNUSED int nogil) { + PyObject *old_exc, *old_val, *old_tb; + PyObject *ctx; + __Pyx_PyThreadState_declare +#ifdef WITH_THREAD + PyGILState_STATE state; + if (nogil) + state = PyGILState_Ensure(); +#ifdef _MSC_VER + else state = (PyGILState_STATE)-1; +#endif +#endif + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&old_exc, &old_val, &old_tb); + if (full_traceback) { + Py_XINCREF(old_exc); + Py_XINCREF(old_val); + Py_XINCREF(old_tb); + __Pyx_ErrRestore(old_exc, old_val, old_tb); + PyErr_PrintEx(1); + } + #if PY_MAJOR_VERSION < 3 + ctx = PyString_FromString(name); + #else + ctx = PyUnicode_FromString(name); + #endif + __Pyx_ErrRestore(old_exc, old_val, old_tb); + if (!ctx) { + PyErr_WriteUnraisable(Py_None); + } else { + PyErr_WriteUnraisable(ctx); + Py_DECREF(ctx); + } +#ifdef WITH_THREAD + if (nogil) + PyGILState_Release(state); +#endif +} + +/* GetItemInt */ +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (!j) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyList_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { + PyObject *r = PyList_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyTuple_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); + if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { + PyObject *r = PyList_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } + else if (PyTuple_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } else { + PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; + if (likely(m && m->sq_item)) { + if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { + Py_ssize_t l = m->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + } + } + return m->sq_item(o, i); + } + } +#else + if (is_list || PySequence_Check(o)) { + return PySequence_GetItem(o, i); + } +#endif + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +} + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* RaiseDoubleKeywords */ +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION >= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + while (PyDict_Next(kwds, &pos, &key, &value)) { + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; + continue; + } + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = (**name == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION < 3 + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + return -1; +} + +/* PyObjectGetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* Import */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *empty_list = 0; + PyObject *module = 0; + PyObject *global_dict = 0; + PyObject *empty_dict = 0; + PyObject *list; + #if PY_MAJOR_VERSION < 3 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (!py_import) + goto bad; + #endif + if (from_list) + list = from_list; + else { + empty_list = PyList_New(0); + if (!empty_list) + goto bad; + list = empty_list; + } + global_dict = PyModule_GetDict(__pyx_m); + if (!global_dict) + goto bad; + empty_dict = PyDict_New(); + if (!empty_dict) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) { + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, 1); + if (!module) { + if (!PyErr_ExceptionMatches(PyExc_ImportError)) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (!py_level) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, level); + #endif + } + } +bad: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + Py_XDECREF(empty_list); + Py_XDECREF(empty_dict); + return module; +} + +/* PyDictVersioning */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* CLineInTraceback */ +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { + PyObject *use_cline; + PyObject *ptype, *pvalue, *ptraceback; +#if CYTHON_COMPILING_IN_CPYTHON + PyObject **cython_runtime_dict; +#endif + if (unlikely(!__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); +#if CYTHON_COMPILING_IN_CPYTHON + cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) + } else +#endif + { + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + if (use_cline_obj) { + use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; + Py_DECREF(use_cline_obj); + } else { + PyErr_Clear(); + use_cline = NULL; + } + } + if (!use_cline) { + c_line = 0; + PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); + } + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache */ +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyObject *py_srcfile = 0; + PyObject *py_funcname = 0; + #if PY_MAJOR_VERSION < 3 + py_srcfile = PyString_FromString(filename); + #else + py_srcfile = PyUnicode_FromString(filename); + #endif + if (!py_srcfile) goto bad; + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + #else + py_funcname = PyUnicode_FromString(funcname); + #endif + } + if (!py_funcname) goto bad; + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + Py_DECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_srcfile); + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) goto bad; + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); + } +} + +/* CIntFromPyVerify */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(long) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(long) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) + case -2: + if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } +#endif + if (sizeof(long) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(int) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(int) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) + case -2: + if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } +#endif + if (sizeof(int) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = a->tp_base; + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; + if (!res) { + res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } + return res; +} +#endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; ip) { + #if PY_MAJOR_VERSION < 3 + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + #else + if (t->is_unicode | t->is_str) { + if (t->intern) { + *t->p = PyUnicode_InternFromString(t->s); + } else if (t->encoding) { + *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); + } else { + *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); + } + } else { + *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); + } + #endif + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + return -1; + ++t; + } + return 0; +} + +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + Py_TYPE(result)->tp_name)) { + Py_DECREF(result); + return NULL; + } + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type %.200s)", + type_name, type_name, Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(b); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)b)->ob_digit; + const Py_ssize_t size = Py_SIZE(b); + if (likely(__Pyx_sst_abs(size) <= 1)) { + ival = likely(size) ? digits[0] : 0; + if (size == -1) ival = -ival; + return ival; + } else { + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +#endif /* Py_PYTHON_H */ diff --git a/numba_dppy/dpnp_glue/dpnpdecl.py b/numba_dppy/dpnp_glue/dpnpdecl.py new file mode 100644 index 0000000000..b15802fc11 --- /dev/null +++ b/numba_dppy/dpnp_glue/dpnpdecl.py @@ -0,0 +1,28 @@ +from numba.core.typing.templates import (AttributeTemplate, infer, infer_getattr, AbstractTemplate, signature) +import numba +from numba import types + + +@infer +class DpnpSum(AbstractTemplate): + key = numba.dppl.dpnp.sum + + def generic(self, args, kws): + assert not kws + return_type = args[0].dtype + return signature(return_type, *args) + + +@infer_getattr +class DpnpTemplate(AttributeTemplate): + key = types.Module(numba.dppl.dpnp) + + def resolve_sum(self, mod): + return types.Function(DpnpSum) + +@infer_getattr +class DpplDpnpTemplate(AttributeTemplate): + key = types.Module(numba.dppl) + + def resolve_dpnp(self, mod): + return types.Module(numba.dppl.dpnp) diff --git a/numba_dppy/dpnp_glue/dpnpimpl.py b/numba_dppy/dpnp_glue/dpnpimpl.py new file mode 100644 index 0000000000..89a529d5af --- /dev/null +++ b/numba_dppy/dpnp_glue/dpnpimpl.py @@ -0,0 +1,12 @@ +from numba.core.imputils import (lower_builtin) +import numba.dppl.experimental_numpy_lowering_overload as dpnp_lowering +from numba import types +from . import stubs + + +@lower_builtin(stubs.dpnp.sum, types.Array) +def array_sum(context, builder, sig, args): + dpnp_lowering.ensure_dpnp("sum") + return dpnp_lowering.common_sum_prod_impl(context, builder, sig, args, "dpnp_sum") + + diff --git a/numba_dppy/dpnp_glue/stubs.py b/numba_dppy/dpnp_glue/stubs.py new file mode 100644 index 0000000000..db7cae0bf0 --- /dev/null +++ b/numba_dppy/dpnp_glue/stubs.py @@ -0,0 +1,11 @@ +from numba.dppl.ocl.stubs import Stub + +class dpnp(Stub): + """dpnp namespace + """ + _description_ = '' + + class sum(Stub): + pass + + diff --git a/numba_dppy/dppl_passbuilder.py b/numba_dppy/dppl_passbuilder.py index 0ddaea6d0b..57535a5314 100644 --- a/numba_dppy/dppl_passbuilder.py +++ b/numba_dppy/dppl_passbuilder.py @@ -24,6 +24,7 @@ SpirvFriendlyLowering, DPPLAddNumpyOverloadPass, DPPLAddNumpyRemoveOverloadPass, + DPPLRewriteOverloadedFunctions, DPPLNoPythonBackend ) @@ -44,6 +45,9 @@ def default_numba_nopython_pipeline(state, pm): pm.add_pass(IRProcessing, "processing IR") pm.add_pass(WithLifting, "Handle with contexts") + # this pass rewrite name of functions + pm.add_pass(DPPLRewriteOverloadedFunctions, "dppl rewrite name of functions") + # this pass adds required logic to overload default implementation of # Numpy functions pm.add_pass(DPPLAddNumpyOverloadPass, "dppl add typing template for Numpy functions") diff --git a/numba_dppy/dppl_passes.py b/numba_dppy/dppl_passes.py index f9e2633c3c..7c6aca7d69 100644 --- a/numba_dppy/dppl_passes.py +++ b/numba_dppy/dppl_passes.py @@ -3,6 +3,7 @@ import warnings import numpy as np +import numba from numba.core import ir import weakref from collections import namedtuple, deque @@ -17,7 +18,8 @@ types, ) -from numba.core.ir_utils import remove_dels +from numba.core.ir_utils import (remove_dels, find_topo_order, mk_unique_var, + simplify_CFG) from numba.core.errors import (LoweringError, new_error_context, TypingError, LiteralTypingError) @@ -38,6 +40,91 @@ def dpnp_available(): except: return False +rewrite_function_name_map = {"sum": (["numpy"], "sum")} + +class RewriteOverloadedFunctions(object): + def __init__(self, state, rewrite_function_name_map=rewrite_function_name_map): + self.state = state + self.function_name_map = rewrite_function_name_map + + def run(self): + func_ir = self.state.func_ir + blocks = func_ir.blocks + topo_order = find_topo_order(blocks) + + import pdb + import numba.dppl.dpnp_glue.dpnpdecl + import numba.dppl.dpnp_glue.dpnpimpl + for label in topo_order: + block = blocks[label] + saved_arr_arg = {} + new_body = [] + for stmt in block.body: + if isinstance(stmt, ir.Assign) and isinstance(stmt.value, ir.Expr): + #pdb.set_trace() + lhs = stmt.target.name + rhs = stmt.value + # replace np.func with name from map np.func + if (rhs.op == 'getattr' and rhs.attr in rewrite_function_name_map): + rhs = stmt.value + rhs.attr = rewrite_function_name_map[rhs.attr][1] + + global_module = rhs.value + saved_arr_arg[lhs] = global_module + + scope = global_module.scope + loc = global_module.loc + + g_dppl_var = ir.Var(scope, mk_unique_var("$dppl_replaced_var"), loc) + g_dppl = ir.Global('dppl', numba.dppl, loc) + g_dppl_assign = ir.Assign(g_dppl, g_dppl_var, loc) + + dpnp_var = ir.Var(scope, mk_unique_var("$dpnp_var"), loc) + getattr_dpnp = ir.Expr.getattr(g_dppl_var, 'dpnp', loc) + dpnp_assign = ir.Assign(getattr_dpnp, dpnp_var, loc) + + rhs.value = dpnp_var + new_body.append(g_dppl_assign) + new_body.append(dpnp_assign) + func_ir._definitions[dpnp_var.name] = [getattr_dpnp] + func_ir._definitions[g_dppl_var.name] = [g_dppl] + + new_body.append(stmt) + block.body = new_body + #pdb.set_trace() + + + ''' + work_list = list(func_ir.blocks.items()) + while work_list: + label, block = work_list.pop() + for i, instr in enumerate(block.body): + if isinstance(instr, ir.Assign): + expr = instr.value + if isinstance(expr, ir.Expr): + if expr.op == 'call': + call_node = block.find_variable_assignment(expr.func.name).value + pass + + ''' + +@register_pass(mutates_CFG=True, analysis_only=False) +class DPPLRewriteOverloadedFunctions(FunctionPass): + _name = "dppl_rewrite_overloaded_functions_pass" + + def __init__(self): + FunctionPass.__init__(self) + self.function_name_map = rewrite_function_name_map + + def run_pass(self, state): + rewrite_function_name_pass = RewriteOverloadedFunctions(state, rewrite_function_name_map) + + rewrite_function_name_pass.run() + + state.func_ir.blocks = simplify_CFG(state.func_ir.blocks) + + return True + @register_pass(mutates_CFG=False, analysis_only=True) class DPPLAddNumpyOverloadPass(FunctionPass): @@ -49,7 +136,7 @@ def __init__(self): def run_pass(self, state): if dpnp_available(): typingctx = state.typingctx - from numba.core.typing.templates import builtin_registry as reg, infer_global + from numba.core.typing.templates import (builtin_registry as reg, infer_global, infer_getattr) from numba.core.typing.templates import (AbstractTemplate, CallableTemplate, signature) from numba.core.typing.npydecl import MatMulTyperMixin diff --git a/numba_dppy/examples/sum.py b/numba_dppy/examples/sum.py index f97b8243cb..c24ca429fa 100644 --- a/numba_dppy/examples/sum.py +++ b/numba_dppy/examples/sum.py @@ -11,6 +11,7 @@ @dppl.kernel def data_parallel_sum(a, b, c): i = dppl.get_global_id(0) + d = dppl.atomic.add(c[i], 1) c[i] = a[i] + b[i] From 1d346cd045ea9d11293e6ff6a75ebeab53a0247e Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Mon, 23 Nov 2020 10:28:52 -0600 Subject: [PATCH 02/34] Moved from infer_type, lower_builtin to overload --- numba_dppy/dpnp_glue/dpnpdecl.py | 18 ------- numba_dppy/dpnp_glue/dpnpimpl.py | 89 ++++++++++++++++++++++++++++++-- numba_dppy/examples/sum.py | 1 - 3 files changed, 85 insertions(+), 23 deletions(-) diff --git a/numba_dppy/dpnp_glue/dpnpdecl.py b/numba_dppy/dpnp_glue/dpnpdecl.py index b15802fc11..29f77ee65e 100644 --- a/numba_dppy/dpnp_glue/dpnpdecl.py +++ b/numba_dppy/dpnp_glue/dpnpdecl.py @@ -2,24 +2,6 @@ import numba from numba import types - -@infer -class DpnpSum(AbstractTemplate): - key = numba.dppl.dpnp.sum - - def generic(self, args, kws): - assert not kws - return_type = args[0].dtype - return signature(return_type, *args) - - -@infer_getattr -class DpnpTemplate(AttributeTemplate): - key = types.Module(numba.dppl.dpnp) - - def resolve_sum(self, mod): - return types.Function(DpnpSum) - @infer_getattr class DpplDpnpTemplate(AttributeTemplate): key = types.Module(numba.dppl) diff --git a/numba_dppy/dpnp_glue/dpnpimpl.py b/numba_dppy/dpnp_glue/dpnpimpl.py index 89a529d5af..9a3b63a883 100644 --- a/numba_dppy/dpnp_glue/dpnpimpl.py +++ b/numba_dppy/dpnp_glue/dpnpimpl.py @@ -1,12 +1,93 @@ from numba.core.imputils import (lower_builtin) import numba.dppl.experimental_numpy_lowering_overload as dpnp_lowering from numba import types +from numba.core.typing import signature +from numba.core.extending import overload from . import stubs +import numpy as np -@lower_builtin(stubs.dpnp.sum, types.Array) -def array_sum(context, builder, sig, args): - dpnp_lowering.ensure_dpnp("sum") - return dpnp_lowering.common_sum_prod_impl(context, builder, sig, args, "dpnp_sum") +def get_dpnp_fptr(fn_name, type_names): + from . import dpnp_fptr_interface as dpnp_glue + f_ptr = dpnp_glue.get_dpnp_fn_ptr(fn_name, type_names) + return f_ptr +class RetrieveDpnpFnPtr(types.ExternalFunctionPointer): + def __init__(self, fn_name, type_names, sig, get_pointer): + self.fn_name = fn_name + self.type_names = type_names + super(RetrieveDpnpFnPtr, self).__init__(sig, get_pointer) + +class _DPNP_EXTENSION: + def __init__(self, name): + dpnp_lowering.ensure_dpnp(name) + + @classmethod + def get_sycl_queue(cls): + ret_type = types.voidptr + sig = signature(ret_type) + return types.ExternalFunction("DPPLQueueMgr_GetCurrentQueue", sig) + + @classmethod + def allocate_usm_shared(cls): + ret_type = types.voidptr + sig = signature(ret_type, types.int64, types.voidptr) + return types.ExternalFunction("DPPLmalloc_shared", sig) + + @classmethod + def copy_usm(cls): + ret_type = types.void + sig = signature(ret_type, types.voidptr, types.voidptr, types.voidptr, types.int64) + return types.ExternalFunction("DPPLQueue_Memcpy", sig) + + @classmethod + def free_usm(cls): + ret_type = types.void + sig = signature(ret_type, types.voidptr, types.voidptr) + return types.ExternalFunction("DPPLfree_with_queue", sig) + + + @classmethod + def dpnp_sum(cls, fn_name, type_names): + ret_type = types.void + sig = signature(ret_type, types.voidptr, types.voidptr, types.int64) + f_ptr = get_dpnp_fptr(fn_name, type_names) + def get_pointer(obj): + return f_ptr + return types.ExternalFunctionPointer(sig, get_pointer=get_pointer) + + +@overload(stubs.dpnp.sum) +def dpnp_sum_impl(a): + dpnp_extension = _DPNP_EXTENSION("sum") + + dpnp_sum = dpnp_extension.dpnp_sum("dpnp_sum", [a.dtype.name, "NONE"]) + + get_sycl_queue = dpnp_extension.get_sycl_queue() + allocate_usm_shared = dpnp_extension.allocate_usm_shared() + copy_usm = dpnp_extension.copy_usm() + free_usm = dpnp_extension.free_usm() + + def dpnp_sum_impl(a): + if a.size == 0: + raise ValueError("Passed Empty array") + + sycl_queue = get_sycl_queue() + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + out_usm = allocate_usm_shared(a.itemsize, sycl_queue) + + dpnp_sum(a_usm, out_usm, a.size) + + out = np.empty(1, dtype=a.dtype) + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + return out[0] + + return dpnp_sum_impl + diff --git a/numba_dppy/examples/sum.py b/numba_dppy/examples/sum.py index c24ca429fa..f97b8243cb 100644 --- a/numba_dppy/examples/sum.py +++ b/numba_dppy/examples/sum.py @@ -11,7 +11,6 @@ @dppl.kernel def data_parallel_sum(a, b, c): i = dppl.get_global_id(0) - d = dppl.atomic.add(c[i], 1) c[i] = a[i] + b[i] From 3dd9f24c3d97d52e39369558e2a10ad504082fbd Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Wed, 2 Dec 2020 11:48:30 -0600 Subject: [PATCH 03/34] Added two level module name functions --- numba_dppy/dpnp_glue/dpnpimpl.py | 1 - numba_dppy/dppl_passes.py | 69 ++++++++++++++------------------ 2 files changed, 29 insertions(+), 41 deletions(-) diff --git a/numba_dppy/dpnp_glue/dpnpimpl.py b/numba_dppy/dpnp_glue/dpnpimpl.py index 9a3b63a883..52695f985c 100644 --- a/numba_dppy/dpnp_glue/dpnpimpl.py +++ b/numba_dppy/dpnp_glue/dpnpimpl.py @@ -12,7 +12,6 @@ def get_dpnp_fptr(fn_name, type_names): f_ptr = dpnp_glue.get_dpnp_fn_ptr(fn_name, type_names) return f_ptr - class RetrieveDpnpFnPtr(types.ExternalFunctionPointer): def __init__(self, fn_name, type_names, sig, get_pointer): self.fn_name = fn_name diff --git a/numba_dppy/dppl_passes.py b/numba_dppy/dppl_passes.py index 7c6aca7d69..2f914b332b 100644 --- a/numba_dppy/dppl_passes.py +++ b/numba_dppy/dppl_passes.py @@ -40,7 +40,8 @@ def dpnp_available(): except: return False -rewrite_function_name_map = {"sum": (["numpy"], "sum")} +rewrite_function_name_map = {"sum": (["np"], "sum"), + "eig": (["linalg"], "eig")} class RewriteOverloadedFunctions(object): def __init__(self, state, rewrite_function_name_map=rewrite_function_name_map): @@ -52,7 +53,6 @@ def run(self): blocks = func_ir.blocks topo_order = find_topo_order(blocks) - import pdb import numba.dppl.dpnp_glue.dpnpdecl import numba.dppl.dpnp_glue.dpnpimpl for label in topo_order: @@ -61,52 +61,41 @@ def run(self): new_body = [] for stmt in block.body: if isinstance(stmt, ir.Assign) and isinstance(stmt.value, ir.Expr): - #pdb.set_trace() lhs = stmt.target.name rhs = stmt.value # replace np.func with name from map np.func if (rhs.op == 'getattr' and rhs.attr in rewrite_function_name_map): - rhs = stmt.value - rhs.attr = rewrite_function_name_map[rhs.attr][1] - - global_module = rhs.value - saved_arr_arg[lhs] = global_module - - scope = global_module.scope - loc = global_module.loc - - g_dppl_var = ir.Var(scope, mk_unique_var("$dppl_replaced_var"), loc) - g_dppl = ir.Global('dppl', numba.dppl, loc) - g_dppl_assign = ir.Assign(g_dppl, g_dppl_var, loc) - - dpnp_var = ir.Var(scope, mk_unique_var("$dpnp_var"), loc) - getattr_dpnp = ir.Expr.getattr(g_dppl_var, 'dpnp', loc) - dpnp_assign = ir.Assign(getattr_dpnp, dpnp_var, loc) - - rhs.value = dpnp_var - new_body.append(g_dppl_assign) - new_body.append(dpnp_assign) - func_ir._definitions[dpnp_var.name] = [getattr_dpnp] - func_ir._definitions[g_dppl_var.name] = [g_dppl] + module_node = block.find_variable_assignment(rhs.value.name).value + if ((isinstance(module_node, ir.Global) and + module_node.name in rewrite_function_name_map[rhs.attr][0]) or + (isinstance(module_node, ir.Expr) and + module_node.attr in rewrite_function_name_map[rhs.attr][0])): + rhs = stmt.value + rhs.attr = rewrite_function_name_map[rhs.attr][1] + + global_module = rhs.value + saved_arr_arg[lhs] = global_module + + scope = global_module.scope + loc = global_module.loc + + g_dppl_var = ir.Var(scope, mk_unique_var("$dppl_replaced_var"), loc) + g_dppl = ir.Global('dppl', numba.dppl, loc) + g_dppl_assign = ir.Assign(g_dppl, g_dppl_var, loc) + + dpnp_var = ir.Var(scope, mk_unique_var("$dpnp_var"), loc) + getattr_dpnp = ir.Expr.getattr(g_dppl_var, 'dpnp', loc) + dpnp_assign = ir.Assign(getattr_dpnp, dpnp_var, loc) + + rhs.value = dpnp_var + new_body.append(g_dppl_assign) + new_body.append(dpnp_assign) + func_ir._definitions[dpnp_var.name] = [getattr_dpnp] + func_ir._definitions[g_dppl_var.name] = [g_dppl] new_body.append(stmt) block.body = new_body - #pdb.set_trace() - - - ''' - work_list = list(func_ir.blocks.items()) - while work_list: - label, block = work_list.pop() - for i, instr in enumerate(block.body): - if isinstance(instr, ir.Assign): - expr = instr.value - if isinstance(expr, ir.Expr): - if expr.op == 'call': - call_node = block.find_variable_assignment(expr.func.name).value - pass - ''' @register_pass(mutates_CFG=True, analysis_only=False) class DPPLRewriteOverloadedFunctions(FunctionPass): From 0003586c2da266486d3913cd1b18e25acb90b974 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Wed, 2 Dec 2020 12:00:51 -0600 Subject: [PATCH 04/34] Remove cython generated file --- numba_dppy/dpnp_glue/dpnp_fptr_interface.cpp | 3936 ------------------ 1 file changed, 3936 deletions(-) delete mode 100644 numba_dppy/dpnp_glue/dpnp_fptr_interface.cpp diff --git a/numba_dppy/dpnp_glue/dpnp_fptr_interface.cpp b/numba_dppy/dpnp_glue/dpnp_fptr_interface.cpp deleted file mode 100644 index b4ab803a03..0000000000 --- a/numba_dppy/dpnp_glue/dpnp_fptr_interface.cpp +++ /dev/null @@ -1,3936 +0,0 @@ -/* Generated by Cython 0.29.21 */ - -/* BEGIN: Cython Metadata -{ - "distutils": { - "depends": [ - "/localdisk/work/rhoque/conda_envs/ms141/lib/python3.7/site-packages/dpnp/backend/backend_iface_fptr.hpp" - ], - "include_dirs": [ - "/localdisk/work/rhoque/conda_envs/ms141/lib/python3.7/site-packages/dpnp/backend" - ], - "language": "c++", - "libraries": [ - "dpnp_backend_c" - ], - "library_dirs": [ - "/localdisk/work/rhoque/conda_envs/ms141/lib/python3.7/site-packages/dpnp" - ], - "name": "numba_dppy.dpnp_glue.dpnp_fptr_interface", - "runtime_library_dirs": [ - "/localdisk/work/rhoque/conda_envs/ms141/lib/python3.7/site-packages/dpnp" - ], - "sources": [ - "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx" - ] - }, - "module_name": "numba_dppy.dpnp_glue.dpnp_fptr_interface" -} -END: Cython Metadata */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#ifndef Py_PYTHON_H - #error Python headers needed to compile C extensions, please install development version of Python. -#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) - #error Cython requires Python 2.6+ or Python 3.3+. -#else -#define CYTHON_ABI "0_29_21" -#define CYTHON_HEX_VERSION 0x001D15F0 -#define CYTHON_FUTURE_DIVISION 1 -#include -#ifndef offsetof - #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) -#endif -#if !defined(WIN32) && !defined(MS_WINDOWS) - #ifndef __stdcall - #define __stdcall - #endif - #ifndef __cdecl - #define __cdecl - #endif - #ifndef __fastcall - #define __fastcall - #endif -#endif -#ifndef DL_IMPORT - #define DL_IMPORT(t) t -#endif -#ifndef DL_EXPORT - #define DL_EXPORT(t) t -#endif -#define __PYX_COMMA , -#ifndef HAVE_LONG_LONG - #if PY_VERSION_HEX >= 0x02070000 - #define HAVE_LONG_LONG - #endif -#endif -#ifndef PY_LONG_LONG - #define PY_LONG_LONG LONG_LONG -#endif -#ifndef Py_HUGE_VAL - #define Py_HUGE_VAL HUGE_VAL -#endif -#ifdef PYPY_VERSION - #define CYTHON_COMPILING_IN_PYPY 1 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #undef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 1 - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#elif defined(PYSTON_VERSION) - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 1 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#else - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 1 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) - #define CYTHON_USE_PYTYPE_LOOKUP 1 - #endif - #if PY_MAJOR_VERSION < 3 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #elif !defined(CYTHON_USE_PYLONG_INTERNALS) - #define CYTHON_USE_PYLONG_INTERNALS 1 - #endif - #ifndef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 1 - #endif - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #if PY_VERSION_HEX < 0x030300F0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #elif !defined(CYTHON_USE_UNICODE_WRITER) - #define CYTHON_USE_UNICODE_WRITER 1 - #endif - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #ifndef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 1 - #endif - #ifndef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 1 - #endif - #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) - #endif - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) - #endif - #ifndef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) - #endif - #ifndef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) - #endif -#endif -#if !defined(CYTHON_FAST_PYCCALL) -#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) -#endif -#if CYTHON_USE_PYLONG_INTERNALS - #include "longintrepr.h" - #undef SHIFT - #undef BASE - #undef MASK - #ifdef SIZEOF_VOID_P - enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; - #endif -#endif -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#ifndef __has_cpp_attribute - #define __has_cpp_attribute(x) 0 -#endif -#ifndef CYTHON_RESTRICT - #if defined(__GNUC__) - #define CYTHON_RESTRICT __restrict__ - #elif defined(_MSC_VER) && _MSC_VER >= 1400 - #define CYTHON_RESTRICT __restrict - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_RESTRICT restrict - #else - #define CYTHON_RESTRICT - #endif -#endif -#ifndef CYTHON_UNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -#endif -#ifndef CYTHON_MAYBE_UNUSED_VAR -# if defined(__cplusplus) - template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } -# else -# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) -# endif -#endif -#ifndef CYTHON_NCP_UNUSED -# if CYTHON_COMPILING_IN_CPYTHON -# define CYTHON_NCP_UNUSED -# else -# define CYTHON_NCP_UNUSED CYTHON_UNUSED -# endif -#endif -#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) -#ifdef _MSC_VER - #ifndef _MSC_STDINT_H_ - #if _MSC_VER < 1300 - typedef unsigned char uint8_t; - typedef unsigned int uint32_t; - #else - typedef unsigned __int8 uint8_t; - typedef unsigned __int32 uint32_t; - #endif - #endif -#else - #include -#endif -#ifndef CYTHON_FALLTHROUGH - #if defined(__cplusplus) && __cplusplus >= 201103L - #if __has_cpp_attribute(fallthrough) - #define CYTHON_FALLTHROUGH [[fallthrough]] - #elif __has_cpp_attribute(clang::fallthrough) - #define CYTHON_FALLTHROUGH [[clang::fallthrough]] - #elif __has_cpp_attribute(gnu::fallthrough) - #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] - #endif - #endif - #ifndef CYTHON_FALLTHROUGH - #if __has_attribute(fallthrough) - #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) - #else - #define CYTHON_FALLTHROUGH - #endif - #endif - #if defined(__clang__ ) && defined(__apple_build_version__) - #if __apple_build_version__ < 7000000 - #undef CYTHON_FALLTHROUGH - #define CYTHON_FALLTHROUGH - #endif - #endif -#endif - -#ifndef __cplusplus - #error "Cython files generated with the C++ option must be compiled with a C++ compiler." -#endif -#ifndef CYTHON_INLINE - #if defined(__clang__) - #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) - #else - #define CYTHON_INLINE inline - #endif -#endif -template -void __Pyx_call_destructor(T& x) { - x.~T(); -} -template -class __Pyx_FakeReference { - public: - __Pyx_FakeReference() : ptr(NULL) { } - __Pyx_FakeReference(const T& ref) : ptr(const_cast(&ref)) { } - T *operator->() { return ptr; } - T *operator&() { return ptr; } - operator T&() { return *ptr; } - template bool operator ==(U other) { return *ptr == other; } - template bool operator !=(U other) { return *ptr != other; } - private: - T *ptr; -}; - -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) - #define Py_OptimizeFlag 0 -#endif -#define __PYX_BUILD_PY_SSIZE_T "n" -#define CYTHON_FORMAT_SSIZE_T "z" -#if PY_MAJOR_VERSION < 3 - #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) - #define __Pyx_DefaultClassType PyClass_Type -#else - #define __Pyx_BUILTIN_MODULE_NAME "builtins" -#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#else - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#endif - #define __Pyx_DefaultClassType PyType_Type -#endif -#ifndef Py_TPFLAGS_CHECKTYPES - #define Py_TPFLAGS_CHECKTYPES 0 -#endif -#ifndef Py_TPFLAGS_HAVE_INDEX - #define Py_TPFLAGS_HAVE_INDEX 0 -#endif -#ifndef Py_TPFLAGS_HAVE_NEWBUFFER - #define Py_TPFLAGS_HAVE_NEWBUFFER 0 -#endif -#ifndef Py_TPFLAGS_HAVE_FINALIZE - #define Py_TPFLAGS_HAVE_FINALIZE 0 -#endif -#ifndef METH_STACKLESS - #define METH_STACKLESS 0 -#endif -#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) - #ifndef METH_FASTCALL - #define METH_FASTCALL 0x80 - #endif - typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); - typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, - Py_ssize_t nargs, PyObject *kwnames); -#else - #define __Pyx_PyCFunctionFast _PyCFunctionFast - #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords -#endif -#if CYTHON_FAST_PYCCALL -#define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) -#else -#define __Pyx_PyFastCFunction_Check(func) 0 -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) - #define PyObject_Malloc(s) PyMem_Malloc(s) - #define PyObject_Free(p) PyMem_Free(p) - #define PyObject_Realloc(p) PyMem_Realloc(p) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 - #define PyMem_RawMalloc(n) PyMem_Malloc(n) - #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) - #define PyMem_RawFree(p) PyMem_Free(p) -#endif -#if CYTHON_COMPILING_IN_PYSTON - #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) -#else - #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) -#endif -#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#elif PY_VERSION_HEX >= 0x03060000 - #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() -#elif PY_VERSION_HEX >= 0x03000000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#else - #define __Pyx_PyThreadState_Current _PyThreadState_Current -#endif -#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) -#include "pythread.h" -#define Py_tss_NEEDS_INIT 0 -typedef int Py_tss_t; -static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { - *key = PyThread_create_key(); - return 0; -} -static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { - Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); - *key = Py_tss_NEEDS_INIT; - return key; -} -static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { - PyObject_Free(key); -} -static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { - return *key != Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { - PyThread_delete_key(*key); - *key = Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { - return PyThread_set_key_value(*key, value); -} -static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { - return PyThread_get_key_value(*key); -} -#endif -#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) -#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) -#else -#define __Pyx_PyDict_NewPresized(n) PyDict_New() -#endif -#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION - #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) -#else - #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS -#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) -#else -#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) -#endif -#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) - #define CYTHON_PEP393_ENABLED 1 - #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ - 0 : _PyUnicode_Ready((PyObject *)(op))) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) - #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) - #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) - #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) - #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) - #else - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) - #endif -#else - #define CYTHON_PEP393_ENABLED 0 - #define PyUnicode_1BYTE_KIND 1 - #define PyUnicode_2BYTE_KIND 2 - #define PyUnicode_4BYTE_KIND 4 - #define __Pyx_PyUnicode_READY(op) (0) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) - #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) - #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) - #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) -#endif -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) -#else - #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ - PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) - #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) - #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) - #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) -#endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) -#else - #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) -#endif -#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) - #define PyObject_ASCII(o) PyObject_Repr(o) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBaseString_Type PyUnicode_Type - #define PyStringObject PyUnicodeObject - #define PyString_Type PyUnicode_Type - #define PyString_Check PyUnicode_Check - #define PyString_CheckExact PyUnicode_CheckExact -#ifndef PyObject_Unicode - #define PyObject_Unicode PyObject_Str -#endif -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) - #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) -#else - #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) - #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) -#endif -#ifndef PySet_CheckExact - #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) -#endif -#if PY_VERSION_HEX >= 0x030900A4 - #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) -#else - #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) -#endif -#if CYTHON_ASSUME_SAFE_MACROS - #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) -#else - #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyIntObject PyLongObject - #define PyInt_Type PyLong_Type - #define PyInt_Check(op) PyLong_Check(op) - #define PyInt_CheckExact(op) PyLong_CheckExact(op) - #define PyInt_FromString PyLong_FromString - #define PyInt_FromUnicode PyLong_FromUnicode - #define PyInt_FromLong PyLong_FromLong - #define PyInt_FromSize_t PyLong_FromSize_t - #define PyInt_FromSsize_t PyLong_FromSsize_t - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_AsSsize_t PyLong_AsSsize_t - #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask - #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask - #define PyNumber_Int PyNumber_Long -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBoolObject PyLongObject -#endif -#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY - #ifndef PyUnicode_InternFromString - #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) - #endif -#endif -#if PY_VERSION_HEX < 0x030200A4 - typedef long Py_hash_t; - #define __Pyx_PyInt_FromHash_t PyInt_FromLong - #define __Pyx_PyInt_AsHash_t PyInt_AsLong -#else - #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t - #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) -#else - #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) -#endif -#if CYTHON_USE_ASYNC_SLOTS - #if PY_VERSION_HEX >= 0x030500B1 - #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods - #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) - #else - #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) - #endif -#else - #define __Pyx_PyType_AsAsync(obj) NULL -#endif -#ifndef __Pyx_PyAsyncMethodsStruct - typedef struct { - unaryfunc am_await; - unaryfunc am_aiter; - unaryfunc am_anext; - } __Pyx_PyAsyncMethodsStruct; -#endif - -#if defined(WIN32) || defined(MS_WINDOWS) - #define _USE_MATH_DEFINES -#endif -#include -#ifdef NAN -#define __PYX_NAN() ((float) NAN) -#else -static CYTHON_INLINE float __PYX_NAN() { - float value; - memset(&value, 0xFF, sizeof(value)); - return value; -} -#endif -#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) -#define __Pyx_truncl trunc -#else -#define __Pyx_truncl truncl -#endif - -#define __PYX_MARK_ERR_POS(f_index, lineno) \ - { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } -#define __PYX_ERR(f_index, lineno, Ln_error) \ - { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } - -#ifndef __PYX_EXTERN_C - #ifdef __cplusplus - #define __PYX_EXTERN_C extern "C" - #else - #define __PYX_EXTERN_C extern - #endif -#endif - -#define __PYX_HAVE__numba_dppy__dpnp_glue__dpnp_fptr_interface -#define __PYX_HAVE_API__numba_dppy__dpnp_glue__dpnp_fptr_interface -/* Early includes */ -#include "backend_iface_fptr.hpp" -#include -#include -#include -#ifdef _OPENMP -#include -#endif /* _OPENMP */ - -#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) -#define CYTHON_WITHOUT_ASSERTIONS -#endif - -typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; - const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; - -#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) -#define __PYX_DEFAULT_STRING_ENCODING "" -#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString -#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#define __Pyx_uchar_cast(c) ((unsigned char)c) -#define __Pyx_long_cast(x) ((long)x) -#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ - (sizeof(type) < sizeof(Py_ssize_t)) ||\ - (sizeof(type) > sizeof(Py_ssize_t) &&\ - likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX) &&\ - (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ - v == (type)PY_SSIZE_T_MIN))) ||\ - (sizeof(type) == sizeof(Py_ssize_t) &&\ - (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX))) ) -static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { - return (size_t) i < (size_t) limit; -} -#if defined (__cplusplus) && __cplusplus >= 201103L - #include - #define __Pyx_sst_abs(value) std::abs(value) -#elif SIZEOF_INT >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) abs(value) -#elif SIZEOF_LONG >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) labs(value) -#elif defined (_MSC_VER) - #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define __Pyx_sst_abs(value) llabs(value) -#elif defined (__GNUC__) - #define __Pyx_sst_abs(value) __builtin_llabs(value) -#else - #define __Pyx_sst_abs(value) ((value<0) ? -value : value) -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); -#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) -#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) -#define __Pyx_PyBytes_FromString PyBytes_FromString -#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#else - #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize -#endif -#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) -#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) -#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) -#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) -#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) -static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { - const Py_UNICODE *u_end = u; - while (*u_end++) ; - return (size_t)(u_end - u - 1); -} -#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) -#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode -#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode -#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) -#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); -#define __Pyx_PySequence_Tuple(obj)\ - (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); -#if CYTHON_ASSUME_SAFE_MACROS -#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) -#else -#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) -#endif -#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) -#else -#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) -#endif -#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII -static int __Pyx_sys_getdefaultencoding_not_ascii; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - PyObject* ascii_chars_u = NULL; - PyObject* ascii_chars_b = NULL; - const char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - if (strcmp(default_encoding_c, "ascii") == 0) { - __Pyx_sys_getdefaultencoding_not_ascii = 0; - } else { - char ascii_chars[128]; - int c; - for (c = 0; c < 128; c++) { - ascii_chars[c] = c; - } - __Pyx_sys_getdefaultencoding_not_ascii = 1; - ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); - if (!ascii_chars_u) goto bad; - ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); - if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { - PyErr_Format( - PyExc_ValueError, - "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", - default_encoding_c); - goto bad; - } - Py_DECREF(ascii_chars_u); - Py_DECREF(ascii_chars_b); - } - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - Py_XDECREF(ascii_chars_u); - Py_XDECREF(ascii_chars_b); - return -1; -} -#endif -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) -#else -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -static char* __PYX_DEFAULT_STRING_ENCODING; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); - if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; - strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - return -1; -} -#endif -#endif - - -/* Test for GCC > 2.95 */ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) - #define likely(x) __builtin_expect(!!(x), 1) - #define unlikely(x) __builtin_expect(!!(x), 0) -#else /* !__GNUC__ or GCC < 2.95 */ - #define likely(x) (x) - #define unlikely(x) (x) -#endif /* __GNUC__ */ -static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } - -static PyObject *__pyx_m = NULL; -static PyObject *__pyx_d; -static PyObject *__pyx_b; -static PyObject *__pyx_cython_runtime = NULL; -static PyObject *__pyx_empty_tuple; -static PyObject *__pyx_empty_bytes; -static PyObject *__pyx_empty_unicode; -static int __pyx_lineno; -static int __pyx_clineno = 0; -static const char * __pyx_cfilenm= __FILE__; -static const char *__pyx_filename; - - -static const char *__pyx_f[] = { - "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx", -}; - -/*--- Type declarations ---*/ - -/* --- Runtime support code (head) --- */ -/* Refnanny.proto */ -#ifndef CYTHON_REFNANNY - #define CYTHON_REFNANNY 0 -#endif -#if CYTHON_REFNANNY - typedef struct { - void (*INCREF)(void*, PyObject*, int); - void (*DECREF)(void*, PyObject*, int); - void (*GOTREF)(void*, PyObject*, int); - void (*GIVEREF)(void*, PyObject*, int); - void* (*SetupContext)(const char*, int, const char*); - void (*FinishContext)(void**); - } __Pyx_RefNannyAPIStruct; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); - #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; -#ifdef WITH_THREAD - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - if (acquire_gil) {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - PyGILState_Release(__pyx_gilstate_save);\ - } else {\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - } -#else - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) -#endif - #define __Pyx_RefNannyFinishContext()\ - __Pyx_RefNanny->FinishContext(&__pyx_refnanny) - #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) - #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) - #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) - #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) -#else - #define __Pyx_RefNannyDeclarations - #define __Pyx_RefNannySetupContext(name, acquire_gil) - #define __Pyx_RefNannyFinishContext() - #define __Pyx_INCREF(r) Py_INCREF(r) - #define __Pyx_DECREF(r) Py_DECREF(r) - #define __Pyx_GOTREF(r) - #define __Pyx_GIVEREF(r) - #define __Pyx_XINCREF(r) Py_XINCREF(r) - #define __Pyx_XDECREF(r) Py_XDECREF(r) - #define __Pyx_XGOTREF(r) - #define __Pyx_XGIVEREF(r) -#endif -#define __Pyx_XDECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_XDECREF(tmp);\ - } while (0) -#define __Pyx_DECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_DECREF(tmp);\ - } while (0) -#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) -#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) - -/* IncludeStringH.proto */ -#include - -/* BytesEquals.proto */ -static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); - -/* UnicodeEquals.proto */ -static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); - -/* PyThreadStateGet.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; -#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; -#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type -#else -#define __Pyx_PyThreadState_declare -#define __Pyx_PyThreadState_assign -#define __Pyx_PyErr_Occurred() PyErr_Occurred() -#endif - -/* PyErrFetchRestore.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) -#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) -#else -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#endif -#else -#define __Pyx_PyErr_Clear() PyErr_Clear() -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) -#endif - -/* WriteUnraisableException.proto */ -static void __Pyx_WriteUnraisable(const char *name, int clineno, - int lineno, const char *filename, - int full_traceback, int nogil); - -/* GetItemInt.proto */ -#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ - (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ - __Pyx_GetItemInt_Generic(o, to_py_func(i)))) -#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, - int is_list, int wraparound, int boundscheck); - -/* RaiseArgTupleInvalid.proto */ -static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, - Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); - -/* RaiseDoubleKeywords.proto */ -static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); - -/* ParseKeywords.proto */ -static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ - PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ - const char* function_name); - -/* PyObjectGetAttrStr.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) -#endif - -/* Import.proto */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); - -/* PyDictVersioning.proto */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) -#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ - (version_var) = __PYX_GET_DICT_VERSION(dict);\ - (cache_var) = (value); -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ - (VAR) = __pyx_dict_cached_value;\ - } else {\ - (VAR) = __pyx_dict_cached_value = (LOOKUP);\ - __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ - }\ -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); -#else -#define __PYX_GET_DICT_VERSION(dict) (0) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); -#endif - -/* CLineInTraceback.proto */ -#ifdef CYTHON_CLINE_IN_TRACEBACK -#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) -#else -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); -#endif - -/* CodeObjectCache.proto */ -typedef struct { - PyCodeObject* code_object; - int code_line; -} __Pyx_CodeObjectCacheEntry; -struct __Pyx_CodeObjectCache { - int count; - int max_count; - __Pyx_CodeObjectCacheEntry* entries; -}; -static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); -static PyCodeObject *__pyx_find_code_object(int code_line); -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); - -/* AddTraceback.proto */ -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); - -/* FastTypeChecks.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); -#else -#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) -#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) -#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) -#endif -#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) - -/* CheckBinaryVersion.proto */ -static int __Pyx_check_binary_version(void); - -/* InitStrings.proto */ -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); - - -/* Module declarations from 'libc.string' */ - -/* Module declarations from 'libc.stdio' */ - -/* Module declarations from 'libc.stdint' */ - -/* Module declarations from 'numba_dppy.dpnp_glue.dpnp_fptr_interface' */ -static enum DPNPFuncName __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_DPNPFuncName_from_str(PyObject *); /*proto*/ -static enum DPNPFuncType __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_DPNPFuncType_from_str(PyObject *); /*proto*/ -static PyObject *__pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_dpnp_fn_ptr(PyObject *, PyObject *, int __pyx_skip_dispatch); /*proto*/ -#define __Pyx_MODULE_NAME "numba_dppy.dpnp_glue.dpnp_fptr_interface" -extern int __pyx_module_is_main_numba_dppy__dpnp_glue__dpnp_fptr_interface; -int __pyx_module_is_main_numba_dppy__dpnp_glue__dpnp_fptr_interface = 0; - -/* Implementation of 'numba_dppy.dpnp_glue.dpnp_fptr_interface' */ -static const char __pyx_k_bool[] = "bool"; -static const char __pyx_k_main[] = "__main__"; -static const char __pyx_k_name[] = "name"; -static const char __pyx_k_test[] = "__test__"; -static const char __pyx_k_int32[] = "int32"; -static const char __pyx_k_int64[] = "int64"; -static const char __pyx_k_types[] = "types"; -static const char __pyx_k_ctypes[] = "ctypes"; -static const char __pyx_k_import[] = "__import__"; -static const char __pyx_k_name_2[] = "__name__"; -static const char __pyx_k_uint32[] = "uint32"; -static const char __pyx_k_uint64[] = "uint64"; -static const char __pyx_k_float32[] = "float32"; -static const char __pyx_k_float64[] = "float64"; -static const char __pyx_k_dpnp_cov[] = "dpnp_cov"; -static const char __pyx_k_dpnp_dot[] = "dpnp_dot"; -static const char __pyx_k_dpnp_max[] = "dpnp_max"; -static const char __pyx_k_dpnp_min[] = "dpnp_min"; -static const char __pyx_k_dpnp_sum[] = "dpnp_sum"; -static const char __pyx_k_dpnp_mean[] = "dpnp_mean"; -static const char __pyx_k_dpnp_prod[] = "dpnp_prod"; -static const char __pyx_k_dpnp_argmax[] = "dpnp_argmax"; -static const char __pyx_k_dpnp_argmin[] = "dpnp_argmin"; -static const char __pyx_k_dpnp_matmul[] = "dpnp_matmul"; -static const char __pyx_k_dpnp_median[] = "dpnp_median"; -static const char __pyx_k_dpnp_argsort[] = "dpnp_argsort"; -static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; -static PyObject *__pyx_n_u_bool; -static PyObject *__pyx_n_s_cline_in_traceback; -static PyObject *__pyx_n_s_ctypes; -static PyObject *__pyx_n_u_dpnp_argmax; -static PyObject *__pyx_n_u_dpnp_argmin; -static PyObject *__pyx_n_u_dpnp_argsort; -static PyObject *__pyx_n_u_dpnp_cov; -static PyObject *__pyx_n_u_dpnp_dot; -static PyObject *__pyx_n_u_dpnp_matmul; -static PyObject *__pyx_n_u_dpnp_max; -static PyObject *__pyx_n_u_dpnp_mean; -static PyObject *__pyx_n_u_dpnp_median; -static PyObject *__pyx_n_u_dpnp_min; -static PyObject *__pyx_n_u_dpnp_prod; -static PyObject *__pyx_n_u_dpnp_sum; -static PyObject *__pyx_n_u_float32; -static PyObject *__pyx_n_u_float64; -static PyObject *__pyx_n_s_import; -static PyObject *__pyx_n_u_int32; -static PyObject *__pyx_n_u_int64; -static PyObject *__pyx_n_s_main; -static PyObject *__pyx_n_s_name; -static PyObject *__pyx_n_s_name_2; -static PyObject *__pyx_n_s_test; -static PyObject *__pyx_n_s_types; -static PyObject *__pyx_n_u_uint32; -static PyObject *__pyx_n_u_uint64; -static PyObject *__pyx_pf_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_dpnp_fn_ptr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_name, PyObject *__pyx_v_types); /* proto */ -/* Late includes */ - -/* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":87 - * - * - * cdef DPNPFuncName get_DPNPFuncName_from_str(name): # <<<<<<<<<<<<<< - * if name == "dpnp_dot": - * return DPNPFuncName.DPNP_FN_DOT - */ - -static enum DPNPFuncName __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_DPNPFuncName_from_str(PyObject *__pyx_v_name) { - enum DPNPFuncName __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("get_DPNPFuncName_from_str", 0); - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":88 - * - * cdef DPNPFuncName get_DPNPFuncName_from_str(name): - * if name == "dpnp_dot": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_DOT - * elif name == "dpnp_matmul": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_dot, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 88, __pyx_L1_error) - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":89 - * cdef DPNPFuncName get_DPNPFuncName_from_str(name): - * if name == "dpnp_dot": - * return DPNPFuncName.DPNP_FN_DOT # <<<<<<<<<<<<<< - * elif name == "dpnp_matmul": - * return DPNPFuncName.DPNP_FN_MATMUL - */ - __pyx_r = DPNPFuncName::DPNP_FN_DOT; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":88 - * - * cdef DPNPFuncName get_DPNPFuncName_from_str(name): - * if name == "dpnp_dot": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_DOT - * elif name == "dpnp_matmul": - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":90 - * if name == "dpnp_dot": - * return DPNPFuncName.DPNP_FN_DOT - * elif name == "dpnp_matmul": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_MATMUL - * elif name == "dpnp_sum": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_matmul, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 90, __pyx_L1_error) - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":91 - * return DPNPFuncName.DPNP_FN_DOT - * elif name == "dpnp_matmul": - * return DPNPFuncName.DPNP_FN_MATMUL # <<<<<<<<<<<<<< - * elif name == "dpnp_sum": - * return DPNPFuncName.DPNP_FN_SUM - */ - __pyx_r = DPNPFuncName::DPNP_FN_MATMUL; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":90 - * if name == "dpnp_dot": - * return DPNPFuncName.DPNP_FN_DOT - * elif name == "dpnp_matmul": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_MATMUL - * elif name == "dpnp_sum": - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":92 - * elif name == "dpnp_matmul": - * return DPNPFuncName.DPNP_FN_MATMUL - * elif name == "dpnp_sum": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_SUM - * elif name == "dpnp_prod": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_sum, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 92, __pyx_L1_error) - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":93 - * return DPNPFuncName.DPNP_FN_MATMUL - * elif name == "dpnp_sum": - * return DPNPFuncName.DPNP_FN_SUM # <<<<<<<<<<<<<< - * elif name == "dpnp_prod": - * return DPNPFuncName.DPNP_FN_PROD - */ - __pyx_r = DPNPFuncName::DPNP_FN_SUM; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":92 - * elif name == "dpnp_matmul": - * return DPNPFuncName.DPNP_FN_MATMUL - * elif name == "dpnp_sum": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_SUM - * elif name == "dpnp_prod": - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":94 - * elif name == "dpnp_sum": - * return DPNPFuncName.DPNP_FN_SUM - * elif name == "dpnp_prod": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_PROD - * elif name == "dpnp_argmax": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_prod, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 94, __pyx_L1_error) - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":95 - * return DPNPFuncName.DPNP_FN_SUM - * elif name == "dpnp_prod": - * return DPNPFuncName.DPNP_FN_PROD # <<<<<<<<<<<<<< - * elif name == "dpnp_argmax": - * return DPNPFuncName.DPNP_FN_ARGMAX - */ - __pyx_r = DPNPFuncName::DPNP_FN_PROD; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":94 - * elif name == "dpnp_sum": - * return DPNPFuncName.DPNP_FN_SUM - * elif name == "dpnp_prod": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_PROD - * elif name == "dpnp_argmax": - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":96 - * elif name == "dpnp_prod": - * return DPNPFuncName.DPNP_FN_PROD - * elif name == "dpnp_argmax": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_ARGMAX - * elif name == "dpnp_max": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_argmax, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 96, __pyx_L1_error) - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":97 - * return DPNPFuncName.DPNP_FN_PROD - * elif name == "dpnp_argmax": - * return DPNPFuncName.DPNP_FN_ARGMAX # <<<<<<<<<<<<<< - * elif name == "dpnp_max": - * return DPNPFuncName.DPNP_FN_MAX - */ - __pyx_r = DPNPFuncName::DPNP_FN_ARGMAX; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":96 - * elif name == "dpnp_prod": - * return DPNPFuncName.DPNP_FN_PROD - * elif name == "dpnp_argmax": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_ARGMAX - * elif name == "dpnp_max": - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":98 - * elif name == "dpnp_argmax": - * return DPNPFuncName.DPNP_FN_ARGMAX - * elif name == "dpnp_max": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_MAX - * elif name == "dpnp_argmin": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_max, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 98, __pyx_L1_error) - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":99 - * return DPNPFuncName.DPNP_FN_ARGMAX - * elif name == "dpnp_max": - * return DPNPFuncName.DPNP_FN_MAX # <<<<<<<<<<<<<< - * elif name == "dpnp_argmin": - * return DPNPFuncName.DPNP_FN_ARGMIN - */ - __pyx_r = DPNPFuncName::DPNP_FN_MAX; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":98 - * elif name == "dpnp_argmax": - * return DPNPFuncName.DPNP_FN_ARGMAX - * elif name == "dpnp_max": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_MAX - * elif name == "dpnp_argmin": - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":100 - * elif name == "dpnp_max": - * return DPNPFuncName.DPNP_FN_MAX - * elif name == "dpnp_argmin": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_ARGMIN - * elif name == "dpnp_min": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_argmin, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 100, __pyx_L1_error) - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":101 - * return DPNPFuncName.DPNP_FN_MAX - * elif name == "dpnp_argmin": - * return DPNPFuncName.DPNP_FN_ARGMIN # <<<<<<<<<<<<<< - * elif name == "dpnp_min": - * return DPNPFuncName.DPNP_FN_MIN - */ - __pyx_r = DPNPFuncName::DPNP_FN_ARGMIN; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":100 - * elif name == "dpnp_max": - * return DPNPFuncName.DPNP_FN_MAX - * elif name == "dpnp_argmin": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_ARGMIN - * elif name == "dpnp_min": - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":102 - * elif name == "dpnp_argmin": - * return DPNPFuncName.DPNP_FN_ARGMIN - * elif name == "dpnp_min": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_MIN - * elif name == "dpnp_mean": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_min, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 102, __pyx_L1_error) - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":103 - * return DPNPFuncName.DPNP_FN_ARGMIN - * elif name == "dpnp_min": - * return DPNPFuncName.DPNP_FN_MIN # <<<<<<<<<<<<<< - * elif name == "dpnp_mean": - * return DPNPFuncName.DPNP_FN_MEAN - */ - __pyx_r = DPNPFuncName::DPNP_FN_MIN; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":102 - * elif name == "dpnp_argmin": - * return DPNPFuncName.DPNP_FN_ARGMIN - * elif name == "dpnp_min": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_MIN - * elif name == "dpnp_mean": - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":104 - * elif name == "dpnp_min": - * return DPNPFuncName.DPNP_FN_MIN - * elif name == "dpnp_mean": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_MEAN - * elif name == "dpnp_median": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_mean, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 104, __pyx_L1_error) - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":105 - * return DPNPFuncName.DPNP_FN_MIN - * elif name == "dpnp_mean": - * return DPNPFuncName.DPNP_FN_MEAN # <<<<<<<<<<<<<< - * elif name == "dpnp_median": - * return DPNPFuncName.DPNP_FN_MEDIAN - */ - __pyx_r = DPNPFuncName::DPNP_FN_MEAN; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":104 - * elif name == "dpnp_min": - * return DPNPFuncName.DPNP_FN_MIN - * elif name == "dpnp_mean": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_MEAN - * elif name == "dpnp_median": - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":106 - * elif name == "dpnp_mean": - * return DPNPFuncName.DPNP_FN_MEAN - * elif name == "dpnp_median": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_MEDIAN - * elif name == "dpnp_argsort": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_median, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 106, __pyx_L1_error) - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":107 - * return DPNPFuncName.DPNP_FN_MEAN - * elif name == "dpnp_median": - * return DPNPFuncName.DPNP_FN_MEDIAN # <<<<<<<<<<<<<< - * elif name == "dpnp_argsort": - * return DPNPFuncName.DPNP_FN_ARGSORT - */ - __pyx_r = DPNPFuncName::DPNP_FN_MEDIAN; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":106 - * elif name == "dpnp_mean": - * return DPNPFuncName.DPNP_FN_MEAN - * elif name == "dpnp_median": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_MEDIAN - * elif name == "dpnp_argsort": - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":108 - * elif name == "dpnp_median": - * return DPNPFuncName.DPNP_FN_MEDIAN - * elif name == "dpnp_argsort": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_ARGSORT - * elif name == "dpnp_cov": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_argsort, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 108, __pyx_L1_error) - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":109 - * return DPNPFuncName.DPNP_FN_MEDIAN - * elif name == "dpnp_argsort": - * return DPNPFuncName.DPNP_FN_ARGSORT # <<<<<<<<<<<<<< - * elif name == "dpnp_cov": - * return DPNPFuncName.DPNP_FN_COV - */ - __pyx_r = DPNPFuncName::DPNP_FN_ARGSORT; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":108 - * elif name == "dpnp_median": - * return DPNPFuncName.DPNP_FN_MEDIAN - * elif name == "dpnp_argsort": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_ARGSORT - * elif name == "dpnp_cov": - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":110 - * elif name == "dpnp_argsort": - * return DPNPFuncName.DPNP_FN_ARGSORT - * elif name == "dpnp_cov": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_COV - * else: - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_dpnp_cov, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 110, __pyx_L1_error) - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":111 - * return DPNPFuncName.DPNP_FN_ARGSORT - * elif name == "dpnp_cov": - * return DPNPFuncName.DPNP_FN_COV # <<<<<<<<<<<<<< - * else: - * return DPNPFuncName.DPNP_FN_DOT - */ - __pyx_r = DPNPFuncName::DPNP_FN_COV; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":110 - * elif name == "dpnp_argsort": - * return DPNPFuncName.DPNP_FN_ARGSORT - * elif name == "dpnp_cov": # <<<<<<<<<<<<<< - * return DPNPFuncName.DPNP_FN_COV - * else: - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":113 - * return DPNPFuncName.DPNP_FN_COV - * else: - * return DPNPFuncName.DPNP_FN_DOT # <<<<<<<<<<<<<< - * - * - */ - /*else*/ { - __pyx_r = DPNPFuncName::DPNP_FN_DOT; - goto __pyx_L0; - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":87 - * - * - * cdef DPNPFuncName get_DPNPFuncName_from_str(name): # <<<<<<<<<<<<<< - * if name == "dpnp_dot": - * return DPNPFuncName.DPNP_FN_DOT - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_WriteUnraisable("numba_dppy.dpnp_glue.dpnp_fptr_interface.get_DPNPFuncName_from_str", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); - __pyx_r = (enum DPNPFuncName) 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":116 - * - * - * cdef DPNPFuncType get_DPNPFuncType_from_str(name): # <<<<<<<<<<<<<< - * if name == "float32": - * return DPNPFuncType.DPNP_FT_FLOAT - */ - -static enum DPNPFuncType __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_DPNPFuncType_from_str(PyObject *__pyx_v_name) { - enum DPNPFuncType __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("get_DPNPFuncType_from_str", 0); - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":117 - * - * cdef DPNPFuncType get_DPNPFuncType_from_str(name): - * if name == "float32": # <<<<<<<<<<<<<< - * return DPNPFuncType.DPNP_FT_FLOAT - * elif name == "int32" or name == "uint32" or name == "bool": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_float32, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 117, __pyx_L1_error) - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":118 - * cdef DPNPFuncType get_DPNPFuncType_from_str(name): - * if name == "float32": - * return DPNPFuncType.DPNP_FT_FLOAT # <<<<<<<<<<<<<< - * elif name == "int32" or name == "uint32" or name == "bool": - * return DPNPFuncType.DPNP_FT_INT - */ - __pyx_r = DPNPFuncType::DPNP_FT_FLOAT; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":117 - * - * cdef DPNPFuncType get_DPNPFuncType_from_str(name): - * if name == "float32": # <<<<<<<<<<<<<< - * return DPNPFuncType.DPNP_FT_FLOAT - * elif name == "int32" or name == "uint32" or name == "bool": - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":119 - * if name == "float32": - * return DPNPFuncType.DPNP_FT_FLOAT - * elif name == "int32" or name == "uint32" or name == "bool": # <<<<<<<<<<<<<< - * return DPNPFuncType.DPNP_FT_INT - * elif name == "float64": - */ - __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_int32, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 119, __pyx_L1_error) - if (!__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_uint32, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 119, __pyx_L1_error) - if (!__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_bool, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 119, __pyx_L1_error) - __pyx_t_1 = __pyx_t_2; - __pyx_L4_bool_binop_done:; - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":120 - * return DPNPFuncType.DPNP_FT_FLOAT - * elif name == "int32" or name == "uint32" or name == "bool": - * return DPNPFuncType.DPNP_FT_INT # <<<<<<<<<<<<<< - * elif name == "float64": - * return DPNPFuncType.DPNP_FT_DOUBLE - */ - __pyx_r = DPNPFuncType::DPNP_FT_INT; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":119 - * if name == "float32": - * return DPNPFuncType.DPNP_FT_FLOAT - * elif name == "int32" or name == "uint32" or name == "bool": # <<<<<<<<<<<<<< - * return DPNPFuncType.DPNP_FT_INT - * elif name == "float64": - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":121 - * elif name == "int32" or name == "uint32" or name == "bool": - * return DPNPFuncType.DPNP_FT_INT - * elif name == "float64": # <<<<<<<<<<<<<< - * return DPNPFuncType.DPNP_FT_DOUBLE - * elif name == "int64" or name == "uint64": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_float64, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 121, __pyx_L1_error) - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":122 - * return DPNPFuncType.DPNP_FT_INT - * elif name == "float64": - * return DPNPFuncType.DPNP_FT_DOUBLE # <<<<<<<<<<<<<< - * elif name == "int64" or name == "uint64": - * return DPNPFuncType.DPNP_FT_LONG - */ - __pyx_r = DPNPFuncType::DPNP_FT_DOUBLE; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":121 - * elif name == "int32" or name == "uint32" or name == "bool": - * return DPNPFuncType.DPNP_FT_INT - * elif name == "float64": # <<<<<<<<<<<<<< - * return DPNPFuncType.DPNP_FT_DOUBLE - * elif name == "int64" or name == "uint64": - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":123 - * elif name == "float64": - * return DPNPFuncType.DPNP_FT_DOUBLE - * elif name == "int64" or name == "uint64": # <<<<<<<<<<<<<< - * return DPNPFuncType.DPNP_FT_LONG - * else: - */ - __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_int64, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 123, __pyx_L1_error) - if (!__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L7_bool_binop_done; - } - __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_uint64, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 123, __pyx_L1_error) - __pyx_t_1 = __pyx_t_2; - __pyx_L7_bool_binop_done:; - if (__pyx_t_1) { - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":124 - * return DPNPFuncType.DPNP_FT_DOUBLE - * elif name == "int64" or name == "uint64": - * return DPNPFuncType.DPNP_FT_LONG # <<<<<<<<<<<<<< - * else: - * return DPNPFuncType.DPNP_FT_NONE - */ - __pyx_r = DPNPFuncType::DPNP_FT_LONG; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":123 - * elif name == "float64": - * return DPNPFuncType.DPNP_FT_DOUBLE - * elif name == "int64" or name == "uint64": # <<<<<<<<<<<<<< - * return DPNPFuncType.DPNP_FT_LONG - * else: - */ - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":126 - * return DPNPFuncType.DPNP_FT_LONG - * else: - * return DPNPFuncType.DPNP_FT_NONE # <<<<<<<<<<<<<< - * - * from libc.stdio cimport printf - */ - /*else*/ { - __pyx_r = DPNPFuncType::DPNP_FT_NONE; - goto __pyx_L0; - } - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":116 - * - * - * cdef DPNPFuncType get_DPNPFuncType_from_str(name): # <<<<<<<<<<<<<< - * if name == "float32": - * return DPNPFuncType.DPNP_FT_FLOAT - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_WriteUnraisable("numba_dppy.dpnp_glue.dpnp_fptr_interface.get_DPNPFuncType_from_str", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); - __pyx_r = (enum DPNPFuncType) 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":131 - * from libc.stdint cimport uintptr_t - * - * cpdef get_dpnp_fn_ptr(name, types): # <<<<<<<<<<<<<< - * cdef DPNPFuncName func_name = get_DPNPFuncName_from_str(name) - * cdef DPNPFuncType first_type = get_DPNPFuncType_from_str(types[0]) - */ - -static PyObject *__pyx_pw_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_1get_dpnp_fn_ptr(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyObject *__pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_dpnp_fn_ptr(PyObject *__pyx_v_name, PyObject *__pyx_v_types, CYTHON_UNUSED int __pyx_skip_dispatch) { - enum DPNPFuncName __pyx_v_func_name; - enum DPNPFuncType __pyx_v_first_type; - enum DPNPFuncType __pyx_v_second_type; - struct DPNPFuncData __pyx_v_kernel_data; - uintptr_t __pyx_v_fn_ptr; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("get_dpnp_fn_ptr", 0); - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":132 - * - * cpdef get_dpnp_fn_ptr(name, types): - * cdef DPNPFuncName func_name = get_DPNPFuncName_from_str(name) # <<<<<<<<<<<<<< - * cdef DPNPFuncType first_type = get_DPNPFuncType_from_str(types[0]) - * cdef DPNPFuncType second_type = get_DPNPFuncType_from_str(types[1]) - */ - __pyx_v_func_name = __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_DPNPFuncName_from_str(__pyx_v_name); - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":133 - * cpdef get_dpnp_fn_ptr(name, types): - * cdef DPNPFuncName func_name = get_DPNPFuncName_from_str(name) - * cdef DPNPFuncType first_type = get_DPNPFuncType_from_str(types[0]) # <<<<<<<<<<<<<< - * cdef DPNPFuncType second_type = get_DPNPFuncType_from_str(types[1]) - * - */ - __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_types, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 133, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_first_type = __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_DPNPFuncType_from_str(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":134 - * cdef DPNPFuncName func_name = get_DPNPFuncName_from_str(name) - * cdef DPNPFuncType first_type = get_DPNPFuncType_from_str(types[0]) - * cdef DPNPFuncType second_type = get_DPNPFuncType_from_str(types[1]) # <<<<<<<<<<<<<< - * - * cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(func_name, first_type, second_type) - */ - __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_types, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 134, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_second_type = __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_DPNPFuncType_from_str(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":136 - * cdef DPNPFuncType second_type = get_DPNPFuncType_from_str(types[1]) - * - * cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(func_name, first_type, second_type) # <<<<<<<<<<<<<< - * cdef uintptr_t fn_ptr = kernel_data.ptr - * - */ - __pyx_v_kernel_data = get_dpnp_function_ptr(__pyx_v_func_name, __pyx_v_first_type, __pyx_v_second_type); - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":137 - * - * cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(func_name, first_type, second_type) - * cdef uintptr_t fn_ptr = kernel_data.ptr # <<<<<<<<<<<<<< - * - * return fn_ptr - */ - __pyx_v_fn_ptr = ((uintptr_t)__pyx_v_kernel_data.ptr); - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":139 - * cdef uintptr_t fn_ptr = kernel_data.ptr - * - * return fn_ptr # <<<<<<<<<<<<<< - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_v_fn_ptr); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 139, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(((PyObject *)__pyx_t_1)); - __pyx_r = __pyx_t_1; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - goto __pyx_L0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":131 - * from libc.stdint cimport uintptr_t - * - * cpdef get_dpnp_fn_ptr(name, types): # <<<<<<<<<<<<<< - * cdef DPNPFuncName func_name = get_DPNPFuncName_from_str(name) - * cdef DPNPFuncType first_type = get_DPNPFuncType_from_str(types[0]) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numba_dppy.dpnp_glue.dpnp_fptr_interface.get_dpnp_fn_ptr", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* Python wrapper */ -static PyObject *__pyx_pw_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_1get_dpnp_fn_ptr(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyObject *__pyx_pw_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_1get_dpnp_fn_ptr(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_name = 0; - PyObject *__pyx_v_types = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("get_dpnp_fn_ptr (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,&__pyx_n_s_types,0}; - PyObject* values[2] = {0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_types)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("get_dpnp_fn_ptr", 1, 2, 2, 1); __PYX_ERR(0, 131, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_dpnp_fn_ptr") < 0)) __PYX_ERR(0, 131, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - } - __pyx_v_name = values[0]; - __pyx_v_types = values[1]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("get_dpnp_fn_ptr", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 131, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("numba_dppy.dpnp_glue.dpnp_fptr_interface.get_dpnp_fn_ptr", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_dpnp_fn_ptr(__pyx_self, __pyx_v_name, __pyx_v_types); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_dpnp_fn_ptr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_name, PyObject *__pyx_v_types) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("get_dpnp_fn_ptr", 0); - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __pyx_f_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_get_dpnp_fn_ptr(__pyx_v_name, __pyx_v_types, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 131, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numba_dppy.dpnp_glue.dpnp_fptr_interface.get_dpnp_fn_ptr", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyMethodDef __pyx_methods[] = { - {"get_dpnp_fn_ptr", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_10numba_dppy_9dpnp_glue_19dpnp_fptr_interface_1get_dpnp_fn_ptr, METH_VARARGS|METH_KEYWORDS, 0}, - {0, 0, 0, 0} -}; - -#if PY_MAJOR_VERSION >= 3 -#if CYTHON_PEP489_MULTI_PHASE_INIT -static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ -static int __pyx_pymod_exec_dpnp_fptr_interface(PyObject* module); /*proto*/ -static PyModuleDef_Slot __pyx_moduledef_slots[] = { - {Py_mod_create, (void*)__pyx_pymod_create}, - {Py_mod_exec, (void*)__pyx_pymod_exec_dpnp_fptr_interface}, - {0, NULL} -}; -#endif - -static struct PyModuleDef __pyx_moduledef = { - PyModuleDef_HEAD_INIT, - "dpnp_fptr_interface", - 0, /* m_doc */ - #if CYTHON_PEP489_MULTI_PHASE_INIT - 0, /* m_size */ - #else - -1, /* m_size */ - #endif - __pyx_methods /* m_methods */, - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_moduledef_slots, /* m_slots */ - #else - NULL, /* m_reload */ - #endif - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; -#endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif - -static __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_n_u_bool, __pyx_k_bool, sizeof(__pyx_k_bool), 0, 1, 0, 1}, - {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, - {&__pyx_n_s_ctypes, __pyx_k_ctypes, sizeof(__pyx_k_ctypes), 0, 0, 1, 1}, - {&__pyx_n_u_dpnp_argmax, __pyx_k_dpnp_argmax, sizeof(__pyx_k_dpnp_argmax), 0, 1, 0, 1}, - {&__pyx_n_u_dpnp_argmin, __pyx_k_dpnp_argmin, sizeof(__pyx_k_dpnp_argmin), 0, 1, 0, 1}, - {&__pyx_n_u_dpnp_argsort, __pyx_k_dpnp_argsort, sizeof(__pyx_k_dpnp_argsort), 0, 1, 0, 1}, - {&__pyx_n_u_dpnp_cov, __pyx_k_dpnp_cov, sizeof(__pyx_k_dpnp_cov), 0, 1, 0, 1}, - {&__pyx_n_u_dpnp_dot, __pyx_k_dpnp_dot, sizeof(__pyx_k_dpnp_dot), 0, 1, 0, 1}, - {&__pyx_n_u_dpnp_matmul, __pyx_k_dpnp_matmul, sizeof(__pyx_k_dpnp_matmul), 0, 1, 0, 1}, - {&__pyx_n_u_dpnp_max, __pyx_k_dpnp_max, sizeof(__pyx_k_dpnp_max), 0, 1, 0, 1}, - {&__pyx_n_u_dpnp_mean, __pyx_k_dpnp_mean, sizeof(__pyx_k_dpnp_mean), 0, 1, 0, 1}, - {&__pyx_n_u_dpnp_median, __pyx_k_dpnp_median, sizeof(__pyx_k_dpnp_median), 0, 1, 0, 1}, - {&__pyx_n_u_dpnp_min, __pyx_k_dpnp_min, sizeof(__pyx_k_dpnp_min), 0, 1, 0, 1}, - {&__pyx_n_u_dpnp_prod, __pyx_k_dpnp_prod, sizeof(__pyx_k_dpnp_prod), 0, 1, 0, 1}, - {&__pyx_n_u_dpnp_sum, __pyx_k_dpnp_sum, sizeof(__pyx_k_dpnp_sum), 0, 1, 0, 1}, - {&__pyx_n_u_float32, __pyx_k_float32, sizeof(__pyx_k_float32), 0, 1, 0, 1}, - {&__pyx_n_u_float64, __pyx_k_float64, sizeof(__pyx_k_float64), 0, 1, 0, 1}, - {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, - {&__pyx_n_u_int32, __pyx_k_int32, sizeof(__pyx_k_int32), 0, 1, 0, 1}, - {&__pyx_n_u_int64, __pyx_k_int64, sizeof(__pyx_k_int64), 0, 1, 0, 1}, - {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, - {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, - {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1}, - {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, - {&__pyx_n_s_types, __pyx_k_types, sizeof(__pyx_k_types), 0, 0, 1, 1}, - {&__pyx_n_u_uint32, __pyx_k_uint32, sizeof(__pyx_k_uint32), 0, 1, 0, 1}, - {&__pyx_n_u_uint64, __pyx_k_uint64, sizeof(__pyx_k_uint64), 0, 1, 0, 1}, - {0, 0, 0, 0, 0, 0, 0} -}; -static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { - return 0; -} - -static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - __Pyx_RefNannyFinishContext(); - return 0; -} - -static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { - if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ - -static int __Pyx_modinit_global_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); - /*--- Global init code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); - /*--- Variable export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); - /*--- Function export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); - /*--- Type init code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); - /*--- Type import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); - /*--- Variable import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); - /*--- Function import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - - -#ifndef CYTHON_NO_PYINIT_EXPORT -#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC -#elif PY_MAJOR_VERSION < 3 -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" void -#else -#define __Pyx_PyMODINIT_FUNC void -#endif -#else -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * -#else -#define __Pyx_PyMODINIT_FUNC PyObject * -#endif -#endif - - -#if PY_MAJOR_VERSION < 3 -__Pyx_PyMODINIT_FUNC initdpnp_fptr_interface(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC initdpnp_fptr_interface(void) -#else -__Pyx_PyMODINIT_FUNC PyInit_dpnp_fptr_interface(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC PyInit_dpnp_fptr_interface(void) -#if CYTHON_PEP489_MULTI_PHASE_INIT -{ - return PyModuleDef_Init(&__pyx_moduledef); -} -static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { - #if PY_VERSION_HEX >= 0x030700A1 - static PY_INT64_T main_interpreter_id = -1; - PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); - if (main_interpreter_id == -1) { - main_interpreter_id = current_id; - return (unlikely(current_id == -1)) ? -1 : 0; - } else if (unlikely(main_interpreter_id != current_id)) - #else - static PyInterpreterState *main_interpreter = NULL; - PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; - if (!main_interpreter) { - main_interpreter = current_interpreter; - } else if (unlikely(main_interpreter != current_interpreter)) - #endif - { - PyErr_SetString( - PyExc_ImportError, - "Interpreter change detected - this module can only be loaded into one interpreter per process."); - return -1; - } - return 0; -} -static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { - PyObject *value = PyObject_GetAttrString(spec, from_name); - int result = 0; - if (likely(value)) { - if (allow_none || value != Py_None) { - result = PyDict_SetItemString(moddict, to_name, value); - } - Py_DECREF(value); - } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } else { - result = -1; - } - return result; -} -static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { - PyObject *module = NULL, *moddict, *modname; - if (__Pyx_check_single_interpreter()) - return NULL; - if (__pyx_m) - return __Pyx_NewRef(__pyx_m); - modname = PyObject_GetAttrString(spec, "name"); - if (unlikely(!modname)) goto bad; - module = PyModule_NewObject(modname); - Py_DECREF(modname); - if (unlikely(!module)) goto bad; - moddict = PyModule_GetDict(module); - if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; - return module; -bad: - Py_XDECREF(module); - return NULL; -} - - -static CYTHON_SMALL_CODE int __pyx_pymod_exec_dpnp_fptr_interface(PyObject *__pyx_pyinit_module) -#endif -#endif -{ - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannyDeclarations - #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m) { - if (__pyx_m == __pyx_pyinit_module) return 0; - PyErr_SetString(PyExc_RuntimeError, "Module 'dpnp_fptr_interface' has already been imported. Re-initialisation is not supported."); - return -1; - } - #elif PY_MAJOR_VERSION >= 3 - if (__pyx_m) return __Pyx_NewRef(__pyx_m); - #endif - #if CYTHON_REFNANNY -__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); -if (!__Pyx_RefNanny) { - PyErr_Clear(); - __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); - if (!__Pyx_RefNanny) - Py_FatalError("failed to import 'refnanny' module"); -} -#endif - __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit_dpnp_fptr_interface(void)", 0); - if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pxy_PyFrame_Initialize_Offsets - __Pxy_PyFrame_Initialize_Offsets(); - #endif - __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pyx_CyFunction_USED - if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_FusedFunction_USED - if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Coroutine_USED - if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Generator_USED - if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_StopAsyncIteration_USED - if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - /*--- Library function declarations ---*/ - /*--- Threads initialization code ---*/ - #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS - #ifdef WITH_THREAD /* Python build with threading support? */ - PyEval_InitThreads(); - #endif - #endif - /*--- Module creation code ---*/ - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_m = __pyx_pyinit_module; - Py_INCREF(__pyx_m); - #else - #if PY_MAJOR_VERSION < 3 - __pyx_m = Py_InitModule4("dpnp_fptr_interface", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); - #else - __pyx_m = PyModule_Create(&__pyx_moduledef); - #endif - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_d); - __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_b); - __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_cython_runtime); - if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - /*--- Initialize various global constants etc. ---*/ - if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) - if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - if (__pyx_module_is_main_numba_dppy__dpnp_glue__dpnp_fptr_interface) { - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name_2, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - } - #if PY_MAJOR_VERSION >= 3 - { - PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) - if (!PyDict_GetItemString(modules, "numba_dppy.dpnp_glue.dpnp_fptr_interface")) { - if (unlikely(PyDict_SetItemString(modules, "numba_dppy.dpnp_glue.dpnp_fptr_interface", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - } - } - #endif - /*--- Builtin init code ---*/ - if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Constants init code ---*/ - if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Global type/function init code ---*/ - (void)__Pyx_modinit_global_init_code(); - (void)__Pyx_modinit_variable_export_code(); - (void)__Pyx_modinit_function_export_code(); - (void)__Pyx_modinit_type_init_code(); - (void)__Pyx_modinit_type_import_code(); - (void)__Pyx_modinit_variable_import_code(); - (void)__Pyx_modinit_function_import_code(); - /*--- Execution code ---*/ - #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":4 - * # cython: language_level=3 - * - * import ctypes # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_ctypes, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_ctypes, __pyx_t_1) < 0) __PYX_ERR(0, 4, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx":1 - * # distutils: language = c++ # <<<<<<<<<<<<<< - * # cython: language_level=3 - * - */ - __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /*--- Wrapped vars code ---*/ - - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - if (__pyx_m) { - if (__pyx_d) { - __Pyx_AddTraceback("init numba_dppy.dpnp_glue.dpnp_fptr_interface", __pyx_clineno, __pyx_lineno, __pyx_filename); - } - Py_CLEAR(__pyx_m); - } else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "init numba_dppy.dpnp_glue.dpnp_fptr_interface"); - } - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - #if CYTHON_PEP489_MULTI_PHASE_INIT - return (__pyx_m != NULL) ? 0 : -1; - #elif PY_MAJOR_VERSION >= 3 - return __pyx_m; - #else - return; - #endif -} - -/* --- Runtime support code --- */ -/* Refnanny */ -#if CYTHON_REFNANNY -static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { - PyObject *m = NULL, *p = NULL; - void *r = NULL; - m = PyImport_ImportModule(modname); - if (!m) goto end; - p = PyObject_GetAttrString(m, "RefNannyAPI"); - if (!p) goto end; - r = PyLong_AsVoidPtr(p); -end: - Py_XDECREF(p); - Py_XDECREF(m); - return (__Pyx_RefNannyAPIStruct *)r; -} -#endif - -/* BytesEquals */ -static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { -#if CYTHON_COMPILING_IN_PYPY - return PyObject_RichCompareBool(s1, s2, equals); -#else - if (s1 == s2) { - return (equals == Py_EQ); - } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { - const char *ps1, *ps2; - Py_ssize_t length = PyBytes_GET_SIZE(s1); - if (length != PyBytes_GET_SIZE(s2)) - return (equals == Py_NE); - ps1 = PyBytes_AS_STRING(s1); - ps2 = PyBytes_AS_STRING(s2); - if (ps1[0] != ps2[0]) { - return (equals == Py_NE); - } else if (length == 1) { - return (equals == Py_EQ); - } else { - int result; -#if CYTHON_USE_UNICODE_INTERNALS - Py_hash_t hash1, hash2; - hash1 = ((PyBytesObject*)s1)->ob_shash; - hash2 = ((PyBytesObject*)s2)->ob_shash; - if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { - return (equals == Py_NE); - } -#endif - result = memcmp(ps1, ps2, (size_t)length); - return (equals == Py_EQ) ? (result == 0) : (result != 0); - } - } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { - return (equals == Py_NE); - } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { - return (equals == Py_NE); - } else { - int result; - PyObject* py_result = PyObject_RichCompare(s1, s2, equals); - if (!py_result) - return -1; - result = __Pyx_PyObject_IsTrue(py_result); - Py_DECREF(py_result); - return result; - } -#endif -} - -/* UnicodeEquals */ -static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { -#if CYTHON_COMPILING_IN_PYPY - return PyObject_RichCompareBool(s1, s2, equals); -#else -#if PY_MAJOR_VERSION < 3 - PyObject* owned_ref = NULL; -#endif - int s1_is_unicode, s2_is_unicode; - if (s1 == s2) { - goto return_eq; - } - s1_is_unicode = PyUnicode_CheckExact(s1); - s2_is_unicode = PyUnicode_CheckExact(s2); -#if PY_MAJOR_VERSION < 3 - if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { - owned_ref = PyUnicode_FromObject(s2); - if (unlikely(!owned_ref)) - return -1; - s2 = owned_ref; - s2_is_unicode = 1; - } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { - owned_ref = PyUnicode_FromObject(s1); - if (unlikely(!owned_ref)) - return -1; - s1 = owned_ref; - s1_is_unicode = 1; - } else if (((!s2_is_unicode) & (!s1_is_unicode))) { - return __Pyx_PyBytes_Equals(s1, s2, equals); - } -#endif - if (s1_is_unicode & s2_is_unicode) { - Py_ssize_t length; - int kind; - void *data1, *data2; - if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) - return -1; - length = __Pyx_PyUnicode_GET_LENGTH(s1); - if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { - goto return_ne; - } -#if CYTHON_USE_UNICODE_INTERNALS - { - Py_hash_t hash1, hash2; - #if CYTHON_PEP393_ENABLED - hash1 = ((PyASCIIObject*)s1)->hash; - hash2 = ((PyASCIIObject*)s2)->hash; - #else - hash1 = ((PyUnicodeObject*)s1)->hash; - hash2 = ((PyUnicodeObject*)s2)->hash; - #endif - if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { - goto return_ne; - } - } -#endif - kind = __Pyx_PyUnicode_KIND(s1); - if (kind != __Pyx_PyUnicode_KIND(s2)) { - goto return_ne; - } - data1 = __Pyx_PyUnicode_DATA(s1); - data2 = __Pyx_PyUnicode_DATA(s2); - if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { - goto return_ne; - } else if (length == 1) { - goto return_eq; - } else { - int result = memcmp(data1, data2, (size_t)(length * kind)); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_EQ) ? (result == 0) : (result != 0); - } - } else if ((s1 == Py_None) & s2_is_unicode) { - goto return_ne; - } else if ((s2 == Py_None) & s1_is_unicode) { - goto return_ne; - } else { - int result; - PyObject* py_result = PyObject_RichCompare(s1, s2, equals); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - if (!py_result) - return -1; - result = __Pyx_PyObject_IsTrue(py_result); - Py_DECREF(py_result); - return result; - } -return_eq: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_EQ); -return_ne: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_NE); -#endif -} - -/* PyErrFetchRestore */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -} -#endif - -/* WriteUnraisableException */ -static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno, - CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename, - int full_traceback, CYTHON_UNUSED int nogil) { - PyObject *old_exc, *old_val, *old_tb; - PyObject *ctx; - __Pyx_PyThreadState_declare -#ifdef WITH_THREAD - PyGILState_STATE state; - if (nogil) - state = PyGILState_Ensure(); -#ifdef _MSC_VER - else state = (PyGILState_STATE)-1; -#endif -#endif - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&old_exc, &old_val, &old_tb); - if (full_traceback) { - Py_XINCREF(old_exc); - Py_XINCREF(old_val); - Py_XINCREF(old_tb); - __Pyx_ErrRestore(old_exc, old_val, old_tb); - PyErr_PrintEx(1); - } - #if PY_MAJOR_VERSION < 3 - ctx = PyString_FromString(name); - #else - ctx = PyUnicode_FromString(name); - #endif - __Pyx_ErrRestore(old_exc, old_val, old_tb); - if (!ctx) { - PyErr_WriteUnraisable(Py_None); - } else { - PyErr_WriteUnraisable(ctx); - Py_DECREF(ctx); - } -#ifdef WITH_THREAD - if (nogil) - PyGILState_Release(state); -#endif -} - -/* GetItemInt */ -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { - PyObject *r; - if (!j) return NULL; - r = PyObject_GetItem(o, j); - Py_DECREF(j); - return r; -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyList_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { - PyObject *r = PyList_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyTuple_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS - if (is_list || PyList_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); - if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { - PyObject *r = PyList_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } - else if (PyTuple_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); - if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } else { - PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; - if (likely(m && m->sq_item)) { - if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { - Py_ssize_t l = m->sq_length(o); - if (likely(l >= 0)) { - i += l; - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); - } - } - return m->sq_item(o, i); - } - } -#else - if (is_list || PySequence_Check(o)) { - return PySequence_GetItem(o, i); - } -#endif - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -} - -/* RaiseArgTupleInvalid */ -static void __Pyx_RaiseArgtupleInvalid( - const char* func_name, - int exact, - Py_ssize_t num_min, - Py_ssize_t num_max, - Py_ssize_t num_found) -{ - Py_ssize_t num_expected; - const char *more_or_less; - if (num_found < num_min) { - num_expected = num_min; - more_or_less = "at least"; - } else { - num_expected = num_max; - more_or_less = "at most"; - } - if (exact) { - more_or_less = "exactly"; - } - PyErr_Format(PyExc_TypeError, - "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", - func_name, more_or_less, num_expected, - (num_expected == 1) ? "" : "s", num_found); -} - -/* RaiseDoubleKeywords */ -static void __Pyx_RaiseDoubleKeywordsError( - const char* func_name, - PyObject* kw_name) -{ - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION >= 3 - "%s() got multiple values for keyword argument '%U'", func_name, kw_name); - #else - "%s() got multiple values for keyword argument '%s'", func_name, - PyString_AsString(kw_name)); - #endif -} - -/* ParseKeywords */ -static int __Pyx_ParseOptionalKeywords( - PyObject *kwds, - PyObject **argnames[], - PyObject *kwds2, - PyObject *values[], - Py_ssize_t num_pos_args, - const char* function_name) -{ - PyObject *key = 0, *value = 0; - Py_ssize_t pos = 0; - PyObject*** name; - PyObject*** first_kw_arg = argnames + num_pos_args; - while (PyDict_Next(kwds, &pos, &key, &value)) { - name = first_kw_arg; - while (*name && (**name != key)) name++; - if (*name) { - values[name-argnames] = value; - continue; - } - name = first_kw_arg; - #if PY_MAJOR_VERSION < 3 - if (likely(PyString_Check(key))) { - while (*name) { - if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) - && _PyString_Eq(**name, key)) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - if ((**argname == key) || ( - (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) - && _PyString_Eq(**argname, key))) { - goto arg_passed_twice; - } - argname++; - } - } - } else - #endif - if (likely(PyUnicode_Check(key))) { - while (*name) { - int cmp = (**name == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**name, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - int cmp = (**argname == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**argname, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) goto arg_passed_twice; - argname++; - } - } - } else - goto invalid_keyword_type; - if (kwds2) { - if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; - } else { - goto invalid_keyword; - } - } - return 0; -arg_passed_twice: - __Pyx_RaiseDoubleKeywordsError(function_name, key); - goto bad; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - goto bad; -invalid_keyword: - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION < 3 - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif -bad: - return -1; -} - -/* PyObjectGetAttrStr */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro)) - return tp->tp_getattro(obj, attr_name); -#if PY_MAJOR_VERSION < 3 - if (likely(tp->tp_getattr)) - return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); -#endif - return PyObject_GetAttr(obj, attr_name); -} -#endif - -/* Import */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { - PyObject *empty_list = 0; - PyObject *module = 0; - PyObject *global_dict = 0; - PyObject *empty_dict = 0; - PyObject *list; - #if PY_MAJOR_VERSION < 3 - PyObject *py_import; - py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); - if (!py_import) - goto bad; - #endif - if (from_list) - list = from_list; - else { - empty_list = PyList_New(0); - if (!empty_list) - goto bad; - list = empty_list; - } - global_dict = PyModule_GetDict(__pyx_m); - if (!global_dict) - goto bad; - empty_dict = PyDict_New(); - if (!empty_dict) - goto bad; - { - #if PY_MAJOR_VERSION >= 3 - if (level == -1) { - if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) { - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, 1); - if (!module) { - if (!PyErr_ExceptionMatches(PyExc_ImportError)) - goto bad; - PyErr_Clear(); - } - } - level = 0; - } - #endif - if (!module) { - #if PY_MAJOR_VERSION < 3 - PyObject *py_level = PyInt_FromLong(level); - if (!py_level) - goto bad; - module = PyObject_CallFunctionObjArgs(py_import, - name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); - Py_DECREF(py_level); - #else - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, level); - #endif - } - } -bad: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_import); - #endif - Py_XDECREF(empty_list); - Py_XDECREF(empty_dict); - return module; -} - -/* PyDictVersioning */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { - PyObject **dictptr = NULL; - Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; - if (offset) { -#if CYTHON_COMPILING_IN_CPYTHON - dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); -#else - dictptr = _PyObject_GetDictPtr(obj); -#endif - } - return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; -} -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) - return 0; - return obj_dict_version == __Pyx_get_object_dict_version(obj); -} -#endif - -/* CLineInTraceback */ -#ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { - PyObject *use_cline; - PyObject *ptype, *pvalue, *ptraceback; -#if CYTHON_COMPILING_IN_CPYTHON - PyObject **cython_runtime_dict; -#endif - if (unlikely(!__pyx_cython_runtime)) { - return c_line; - } - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); -#if CYTHON_COMPILING_IN_CPYTHON - cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); - if (likely(cython_runtime_dict)) { - __PYX_PY_DICT_LOOKUP_IF_MODIFIED( - use_cline, *cython_runtime_dict, - __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) - } else -#endif - { - PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); - if (use_cline_obj) { - use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; - Py_DECREF(use_cline_obj); - } else { - PyErr_Clear(); - use_cline = NULL; - } - } - if (!use_cline) { - c_line = 0; - PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); - } - else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { - c_line = 0; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - return c_line; -} -#endif - -/* CodeObjectCache */ -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { - int start = 0, mid = 0, end = count - 1; - if (end >= 0 && code_line > entries[end].code_line) { - return count; - } - while (start < end) { - mid = start + (end - start) / 2; - if (code_line < entries[mid].code_line) { - end = mid; - } else if (code_line > entries[mid].code_line) { - start = mid + 1; - } else { - return mid; - } - } - if (code_line <= entries[mid].code_line) { - return mid; - } else { - return mid + 1; - } -} -static PyCodeObject *__pyx_find_code_object(int code_line) { - PyCodeObject* code_object; - int pos; - if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { - return NULL; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { - return NULL; - } - code_object = __pyx_code_cache.entries[pos].code_object; - Py_INCREF(code_object); - return code_object; -} -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { - int pos, i; - __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; - if (unlikely(!code_line)) { - return; - } - if (unlikely(!entries)) { - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); - if (likely(entries)) { - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = 64; - __pyx_code_cache.count = 1; - entries[0].code_line = code_line; - entries[0].code_object = code_object; - Py_INCREF(code_object); - } - return; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { - PyCodeObject* tmp = entries[pos].code_object; - entries[pos].code_object = code_object; - Py_DECREF(tmp); - return; - } - if (__pyx_code_cache.count == __pyx_code_cache.max_count) { - int new_max = __pyx_code_cache.max_count + 64; - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( - __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); - if (unlikely(!entries)) { - return; - } - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = new_max; - } - for (i=__pyx_code_cache.count; i>pos; i--) { - entries[i] = entries[i-1]; - } - entries[pos].code_line = code_line; - entries[pos].code_object = code_object; - __pyx_code_cache.count++; - Py_INCREF(code_object); -} - -/* AddTraceback */ -#include "compile.h" -#include "frameobject.h" -#include "traceback.h" -static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( - const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyObject *py_srcfile = 0; - PyObject *py_funcname = 0; - #if PY_MAJOR_VERSION < 3 - py_srcfile = PyString_FromString(filename); - #else - py_srcfile = PyUnicode_FromString(filename); - #endif - if (!py_srcfile) goto bad; - if (c_line) { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #else - py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #endif - } - else { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromString(funcname); - #else - py_funcname = PyUnicode_FromString(funcname); - #endif - } - if (!py_funcname) goto bad; - py_code = __Pyx_PyCode_New( - 0, - 0, - 0, - 0, - 0, - __pyx_empty_bytes, /*PyObject *code,*/ - __pyx_empty_tuple, /*PyObject *consts,*/ - __pyx_empty_tuple, /*PyObject *names,*/ - __pyx_empty_tuple, /*PyObject *varnames,*/ - __pyx_empty_tuple, /*PyObject *freevars,*/ - __pyx_empty_tuple, /*PyObject *cellvars,*/ - py_srcfile, /*PyObject *filename,*/ - py_funcname, /*PyObject *name,*/ - py_line, - __pyx_empty_bytes /*PyObject *lnotab*/ - ); - Py_DECREF(py_srcfile); - Py_DECREF(py_funcname); - return py_code; -bad: - Py_XDECREF(py_srcfile); - Py_XDECREF(py_funcname); - return NULL; -} -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - if (c_line) { - c_line = __Pyx_CLineForTraceback(tstate, c_line); - } - py_code = __pyx_find_code_object(c_line ? -c_line : py_line); - if (!py_code) { - py_code = __Pyx_CreateCodeObjectForTraceback( - funcname, c_line, py_line, filename); - if (!py_code) goto bad; - __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); - } - py_frame = PyFrame_New( - tstate, /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - __pyx_d, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) goto bad; - __Pyx_PyFrame_SetLineNumber(py_frame, py_line); - PyTraceBack_Here(py_frame); -bad: - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(long) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(long) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(long) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(long), - little, !is_unsigned); - } -} - -/* CIntFromPyVerify */ -#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) -#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) -#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ - {\ - func_type value = func_value;\ - if (sizeof(target_type) < sizeof(func_type)) {\ - if (unlikely(value != (func_type) (target_type) value)) {\ - func_type zero = 0;\ - if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ - return (target_type) -1;\ - if (is_unsigned && unlikely(value < zero))\ - goto raise_neg_overflow;\ - else\ - goto raise_overflow;\ - }\ - }\ - return (target_type) value;\ - } - -/* CIntFromPy */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(long) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (long) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { - return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { - return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { - return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (long) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(long) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) - case -2: - if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - } -#endif - if (sizeof(long) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - long val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (long) -1; - } - } else { - long val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (long) -1; - val = __Pyx_PyInt_As_long(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to long"); - return (long) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to long"); - return (long) -1; -} - -/* CIntFromPy */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { - const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(int) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (int) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { - return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { - return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { - return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (int) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(int) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) - case -2: - if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - } -#endif - if (sizeof(int) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - int val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (int) -1; - } - } else { - int val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (int) -1; - val = __Pyx_PyInt_As_int(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to int"); - return (int) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to int"); - return (int) -1; -} - -/* FastTypeChecks */ -#if CYTHON_COMPILING_IN_CPYTHON -static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { - while (a) { - a = a->tp_base; - if (a == b) - return 1; - } - return b == &PyBaseObject_Type; -} -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (a == b) return 1; - mro = a->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(a, b); -} -#if PY_MAJOR_VERSION == 2 -static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { - PyObject *exception, *value, *tb; - int res; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&exception, &value, &tb); - res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - if (!res) { - res = PyObject_IsSubclass(err, exc_type2); - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - } - __Pyx_ErrRestore(exception, value, tb); - return res; -} -#else -static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { - int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; - if (!res) { - res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); - } - return res; -} -#endif -static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - assert(PyExceptionClass_Check(exc_type)); - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; ip) { - #if PY_MAJOR_VERSION < 3 - if (t->is_unicode) { - *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); - } else if (t->intern) { - *t->p = PyString_InternFromString(t->s); - } else { - *t->p = PyString_FromStringAndSize(t->s, t->n - 1); - } - #else - if (t->is_unicode | t->is_str) { - if (t->intern) { - *t->p = PyUnicode_InternFromString(t->s); - } else if (t->encoding) { - *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); - } else { - *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); - } - } else { - *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); - } - #endif - if (!*t->p) - return -1; - if (PyObject_Hash(*t->p) == -1) - return -1; - ++t; - } - return 0; -} - -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { - return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); -} -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { - Py_ssize_t ignore; - return __Pyx_PyObject_AsStringAndSize(o, &ignore); -} -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -#if !CYTHON_PEP393_ENABLED -static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - char* defenc_c; - PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); - if (!defenc) return NULL; - defenc_c = PyBytes_AS_STRING(defenc); -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - { - char* end = defenc_c + PyBytes_GET_SIZE(defenc); - char* c; - for (c = defenc_c; c < end; c++) { - if ((unsigned char) (*c) >= 128) { - PyUnicode_AsASCIIString(o); - return NULL; - } - } - } -#endif - *length = PyBytes_GET_SIZE(defenc); - return defenc_c; -} -#else -static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - if (likely(PyUnicode_IS_ASCII(o))) { - *length = PyUnicode_GET_LENGTH(o); - return PyUnicode_AsUTF8(o); - } else { - PyUnicode_AsASCIIString(o); - return NULL; - } -#else - return PyUnicode_AsUTF8AndSize(o, length); -#endif -} -#endif -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT - if ( -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - __Pyx_sys_getdefaultencoding_not_ascii && -#endif - PyUnicode_Check(o)) { - return __Pyx_PyUnicode_AsStringAndSize(o, length); - } else -#endif -#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) - if (PyByteArray_Check(o)) { - *length = PyByteArray_GET_SIZE(o); - return PyByteArray_AS_STRING(o); - } else -#endif - { - char* result; - int r = PyBytes_AsStringAndSize(o, &result, length); - if (unlikely(r < 0)) { - return NULL; - } else { - return result; - } - } -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - int is_true = x == Py_True; - if (is_true | (x == Py_False) | (x == Py_None)) return is_true; - else return PyObject_IsTrue(x); -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { - int retval; - if (unlikely(!x)) return -1; - retval = __Pyx_PyObject_IsTrue(x); - Py_DECREF(x); - return retval; -} -static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { -#if PY_MAJOR_VERSION >= 3 - if (PyLong_Check(result)) { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__int__ returned non-int (type %.200s). " - "The ability to return an instance of a strict subclass of int " - "is deprecated, and may be removed in a future version of Python.", - Py_TYPE(result)->tp_name)) { - Py_DECREF(result); - return NULL; - } - return result; - } -#endif - PyErr_Format(PyExc_TypeError, - "__%.4s__ returned non-%.4s (type %.200s)", - type_name, type_name, Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { -#if CYTHON_USE_TYPE_SLOTS - PyNumberMethods *m; -#endif - const char *name = NULL; - PyObject *res = NULL; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x) || PyLong_Check(x))) -#else - if (likely(PyLong_Check(x))) -#endif - return __Pyx_NewRef(x); -#if CYTHON_USE_TYPE_SLOTS - m = Py_TYPE(x)->tp_as_number; - #if PY_MAJOR_VERSION < 3 - if (m && m->nb_int) { - name = "int"; - res = m->nb_int(x); - } - else if (m && m->nb_long) { - name = "long"; - res = m->nb_long(x); - } - #else - if (likely(m && m->nb_int)) { - name = "int"; - res = m->nb_int(x); - } - #endif -#else - if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { - res = PyNumber_Int(x); - } -#endif - if (likely(res)) { -#if PY_MAJOR_VERSION < 3 - if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { -#else - if (unlikely(!PyLong_CheckExact(res))) { -#endif - return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); - } - } - else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - } - return res; -} -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { - Py_ssize_t ival; - PyObject *x; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(b))) { - if (sizeof(Py_ssize_t) >= sizeof(long)) - return PyInt_AS_LONG(b); - else - return PyInt_AsSsize_t(b); - } -#endif - if (likely(PyLong_CheckExact(b))) { - #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)b)->ob_digit; - const Py_ssize_t size = Py_SIZE(b); - if (likely(__Pyx_sst_abs(size) <= 1)) { - ival = likely(size) ? digits[0] : 0; - if (size == -1) ival = -ival; - return ival; - } else { - switch (size) { - case 2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - } - } - #endif - return PyLong_AsSsize_t(b); - } - x = PyNumber_Index(b); - if (!x) return -1; - ival = PyInt_AsSsize_t(x); - Py_DECREF(x); - return ival; -} -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { - return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); -} -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { - return PyInt_FromSize_t(ival); -} - - -#endif /* Py_PYTHON_H */ From 1f85af9827ebcdb37deabb53bd0984193ab7d6a8 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Wed, 2 Dec 2020 13:49:10 -0600 Subject: [PATCH 05/34] Module name fix for moving to new extension --- numba_dppy/dpnp_glue/dpnpdecl.py | 6 +++--- numba_dppy/dpnp_glue/dpnpimpl.py | 2 +- numba_dppy/dpnp_glue/stubs.py | 2 +- numba_dppy/dppl_passes.py | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/numba_dppy/dpnp_glue/dpnpdecl.py b/numba_dppy/dpnp_glue/dpnpdecl.py index 29f77ee65e..fe08c70437 100644 --- a/numba_dppy/dpnp_glue/dpnpdecl.py +++ b/numba_dppy/dpnp_glue/dpnpdecl.py @@ -1,10 +1,10 @@ from numba.core.typing.templates import (AttributeTemplate, infer, infer_getattr, AbstractTemplate, signature) -import numba +import numba_dppy from numba import types @infer_getattr class DpplDpnpTemplate(AttributeTemplate): - key = types.Module(numba.dppl) + key = types.Module(numba_dppy) def resolve_dpnp(self, mod): - return types.Module(numba.dppl.dpnp) + return types.Module(numba_dppy.dpnp) diff --git a/numba_dppy/dpnp_glue/dpnpimpl.py b/numba_dppy/dpnp_glue/dpnpimpl.py index 52695f985c..318c8d83f1 100644 --- a/numba_dppy/dpnp_glue/dpnpimpl.py +++ b/numba_dppy/dpnp_glue/dpnpimpl.py @@ -1,5 +1,5 @@ from numba.core.imputils import (lower_builtin) -import numba.dppl.experimental_numpy_lowering_overload as dpnp_lowering +import numba_dppy.experimental_numpy_lowering_overload as dpnp_lowering from numba import types from numba.core.typing import signature from numba.core.extending import overload diff --git a/numba_dppy/dpnp_glue/stubs.py b/numba_dppy/dpnp_glue/stubs.py index db7cae0bf0..34c3d6c1c2 100644 --- a/numba_dppy/dpnp_glue/stubs.py +++ b/numba_dppy/dpnp_glue/stubs.py @@ -1,4 +1,4 @@ -from numba.dppl.ocl.stubs import Stub +from numba_dppy.ocl.stubs import Stub class dpnp(Stub): """dpnp namespace diff --git a/numba_dppy/dppl_passes.py b/numba_dppy/dppl_passes.py index 2f914b332b..fb94bbfc15 100644 --- a/numba_dppy/dppl_passes.py +++ b/numba_dppy/dppl_passes.py @@ -53,8 +53,8 @@ def run(self): blocks = func_ir.blocks topo_order = find_topo_order(blocks) - import numba.dppl.dpnp_glue.dpnpdecl - import numba.dppl.dpnp_glue.dpnpimpl + import numba_dppy.dpnp_glue.dpnpdecl + import numba_dppy.dpnp_glue.dpnpimpl for label in topo_order: block = blocks[label] saved_arr_arg = {} @@ -80,7 +80,7 @@ def run(self): loc = global_module.loc g_dppl_var = ir.Var(scope, mk_unique_var("$dppl_replaced_var"), loc) - g_dppl = ir.Global('dppl', numba.dppl, loc) + g_dppl = ir.Global('numba_dppy', numba_dppy, loc) g_dppl_assign = ir.Assign(g_dppl, g_dppl_var, loc) dpnp_var = ir.Var(scope, mk_unique_var("$dpnp_var"), loc) From a41b9a281db94cba12da287df4fac7e0ea4a5480 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Wed, 2 Dec 2020 16:40:08 -0600 Subject: [PATCH 06/34] Incomplete linalg.eig implementation --- numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx | 2 + numba_dppy/dpnp_glue/dpnpimpl.py | 79 +++++++++++++++++++- numba_dppy/dpnp_glue/stubs.py | 2 + 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx b/numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx index 8eba8bf74c..d93b3a1321 100644 --- a/numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx +++ b/numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx @@ -109,6 +109,8 @@ cdef DPNPFuncName get_DPNPFuncName_from_str(name): return DPNPFuncName.DPNP_FN_ARGSORT elif name == "dpnp_cov": return DPNPFuncName.DPNP_FN_COV + elif name == "dpnp_eig": + return DPNPFuncName.DPNP_FN_EIG else: return DPNPFuncName.DPNP_FN_DOT diff --git a/numba_dppy/dpnp_glue/dpnpimpl.py b/numba_dppy/dpnp_glue/dpnpimpl.py index 318c8d83f1..e430c08413 100644 --- a/numba_dppy/dpnp_glue/dpnpimpl.py +++ b/numba_dppy/dpnp_glue/dpnpimpl.py @@ -2,7 +2,7 @@ import numba_dppy.experimental_numpy_lowering_overload as dpnp_lowering from numba import types from numba.core.typing import signature -from numba.core.extending import overload +from numba.core.extending import overload, register_jitable from . import stubs import numpy as np @@ -12,6 +12,20 @@ def get_dpnp_fptr(fn_name, type_names): f_ptr = dpnp_glue.get_dpnp_fn_ptr(fn_name, type_names) return f_ptr +@register_jitable +def _check_finite_matrix(a): + for v in np.nditer(a): + if not np.isfinite(v.item()): + raise np.linalg.LinAlgError( + "Array must not contain infs or NaNs.") + +@register_jitable +def _dummy_liveness_func(a): + """pass a list of variables to be preserved through dead code elimination""" + return a[0] + + + class RetrieveDpnpFnPtr(types.ExternalFunctionPointer): def __init__(self, fn_name, type_names, sig, get_pointer): self.fn_name = fn_name @@ -56,6 +70,15 @@ def get_pointer(obj): return f_ptr return types.ExternalFunctionPointer(sig, get_pointer=get_pointer) + @classmethod + def dpnp_eig(cls, fn_name, type_names): + ret_type = types.void + sig = signature(ret_type, types.voidptr, types.voidptr, types.voidptr, types.int64) + f_ptr = get_dpnp_fptr(fn_name, type_names) + def get_pointer(obj): + return f_ptr + return types.ExternalFunctionPointer(sig, get_pointer=get_pointer) + @overload(stubs.dpnp.sum) def dpnp_sum_impl(a): @@ -90,3 +113,57 @@ def dpnp_sum_impl(a): return dpnp_sum_impl +''' +@overload(stubs.dpnp.eig) +def dpnp_eig_impl(a): + dpnp_extension = _DPNP_EXTENSION("eig") + + dpnp_eig = dpnp_extension.dpnp_eig("dpnp_eig", [a.dtype.name, "NONE"]) + + get_sycl_queue = dpnp_extension.get_sycl_queue() + allocate_usm_shared = dpnp_extension.allocate_usm_shared() + copy_usm = dpnp_extension.copy_usm() + free_usm = dpnp_extension.free_usm() + + + res_dtype = np.float64 + if a.dtype == np.float32: + res_dtype = np.float32 + + def dpnp_eig_impl(a): + n = a.shape[-1] + if a.shape[-2] != n: + msg = "Last 2 dimensions of the array must be square." + raise ValueError(msg) + + _check_finite_matrix(a) + + wr = np.empty(n, dtype=res_dtype) + vr = np.empty((n, n), dtype=res_dtype) + + if n == 0: + return (wr, vr) + + print(n, a.itemsize, a.size, wr.size, vr.size) + sycl_queue = get_sycl_queue() + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + wr_usm = allocate_usm_shared(wr.size * wr.itemsize, sycl_queue) + vr_usm = allocate_usm_shared(vr.size * vr.itemsize, sycl_queue) + + dpnp_eig(a_usm, wr_usm, vr_usm, n) + + copy_usm(sycl_queue, wr.ctypes, wr_usm, wr.size * wr.itemsize) + copy_usm(sycl_queue, vr.ctypes, vr_usm, vr.size * vr.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(wr_usm, sycl_queue) + free_usm(vr_usm, sycl_queue) + + _dummy_liveness_func([wr.size, vr.size]) + + return (wr, vr) + + return dpnp_eig_impl +''' diff --git a/numba_dppy/dpnp_glue/stubs.py b/numba_dppy/dpnp_glue/stubs.py index 34c3d6c1c2..d7ad65f1a4 100644 --- a/numba_dppy/dpnp_glue/stubs.py +++ b/numba_dppy/dpnp_glue/stubs.py @@ -8,4 +8,6 @@ class dpnp(Stub): class sum(Stub): pass + class eig(Stub): + pass From 55ff89692086d7d9e1c46b8c06dbde4fd3992c23 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Mon, 7 Dec 2020 17:18:03 -0600 Subject: [PATCH 07/34] Updted all dppl to dppy and moved rewrite_numpy_function_pass to it's own file --- numba_dppy/device_init.py | 9 ++- numba_dppy/dpnp_glue/dpnpdecl.py | 2 +- numba_dppy/dpnp_glue/dpnpimpl.py | 32 ++++----- numba_dppy/dppy_passbuilder.py | 7 +- numba_dppy/dppy_passes.py | 74 --------------------- numba_dppy/rename_numpy_functions_pass.py | 79 +++++++++++++++++++++++ 6 files changed, 104 insertions(+), 99 deletions(-) create mode 100644 numba_dppy/rename_numpy_functions_pass.py diff --git a/numba_dppy/device_init.py b/numba_dppy/device_init.py index 201ae09650..efec55ba83 100644 --- a/numba_dppy/device_init.py +++ b/numba_dppy/device_init.py @@ -18,6 +18,10 @@ CLK_GLOBAL_MEM_FENCE, ) +""" +We are importing dpnp stub module to make Numba recognize the +module when we rename Numpy functions. +""" from .dpnp_glue.stubs import ( dpnp ) @@ -39,9 +43,4 @@ def is_available(): return dpctl.has_gpu_queues() -#def ocl_error(): -# """Returns None or an exception if the OpenCL driver fails to initialize. -# """ -# return driver.driver.initialization_error - initialize.initialize_all() diff --git a/numba_dppy/dpnp_glue/dpnpdecl.py b/numba_dppy/dpnp_glue/dpnpdecl.py index fe08c70437..e7c33cb7ca 100644 --- a/numba_dppy/dpnp_glue/dpnpdecl.py +++ b/numba_dppy/dpnp_glue/dpnpdecl.py @@ -3,7 +3,7 @@ from numba import types @infer_getattr -class DpplDpnpTemplate(AttributeTemplate): +class DppyDpnpTemplate(AttributeTemplate): key = types.Module(numba_dppy) def resolve_dpnp(self, mod): diff --git a/numba_dppy/dpnp_glue/dpnpimpl.py b/numba_dppy/dpnp_glue/dpnpimpl.py index e430c08413..02552c8550 100644 --- a/numba_dppy/dpnp_glue/dpnpimpl.py +++ b/numba_dppy/dpnp_glue/dpnpimpl.py @@ -37,28 +37,28 @@ def __init__(self, name): dpnp_lowering.ensure_dpnp(name) @classmethod - def get_sycl_queue(cls): + def dpctl_get_current_queue(cls): ret_type = types.voidptr sig = signature(ret_type) - return types.ExternalFunction("DPPLQueueMgr_GetCurrentQueue", sig) + return types.ExternalFunction("DPCTLQueueMgr_GetCurrentQueue", sig) @classmethod - def allocate_usm_shared(cls): + def dpctl_malloc_shared(cls): ret_type = types.voidptr sig = signature(ret_type, types.int64, types.voidptr) - return types.ExternalFunction("DPPLmalloc_shared", sig) + return types.ExternalFunction("DPCTLmalloc_shared", sig) @classmethod - def copy_usm(cls): + def dpctl_queue_memcpy(cls): ret_type = types.void sig = signature(ret_type, types.voidptr, types.voidptr, types.voidptr, types.int64) - return types.ExternalFunction("DPPLQueue_Memcpy", sig) + return types.ExternalFunction("DPCTLQueue_Memcpy", sig) @classmethod - def free_usm(cls): + def dpctl_free_with_queue(cls): ret_type = types.void sig = signature(ret_type, types.voidptr, types.voidptr) - return types.ExternalFunction("DPPLfree_with_queue", sig) + return types.ExternalFunction("DPCTLfree_with_queue", sig) @classmethod @@ -86,10 +86,10 @@ def dpnp_sum_impl(a): dpnp_sum = dpnp_extension.dpnp_sum("dpnp_sum", [a.dtype.name, "NONE"]) - get_sycl_queue = dpnp_extension.get_sycl_queue() - allocate_usm_shared = dpnp_extension.allocate_usm_shared() - copy_usm = dpnp_extension.copy_usm() - free_usm = dpnp_extension.free_usm() + get_sycl_queue = dpnp_extension.dpctl_get_current_queue() + allocate_usm_shared = dpnp_extension.dpctl_malloc_shared() + copy_usm = dpnp_extension.dpctl_queue_memcpy() + free_usm = dpnp_extension.dpctl_free_with_queue() def dpnp_sum_impl(a): if a.size == 0: @@ -120,10 +120,10 @@ def dpnp_eig_impl(a): dpnp_eig = dpnp_extension.dpnp_eig("dpnp_eig", [a.dtype.name, "NONE"]) - get_sycl_queue = dpnp_extension.get_sycl_queue() - allocate_usm_shared = dpnp_extension.allocate_usm_shared() - copy_usm = dpnp_extension.copy_usm() - free_usm = dpnp_extension.free_usm() + get_sycl_queue = dpnp_extension.dpctl_get_current_queue() + allocate_usm_shared = dpnp_extension.dpctl_malloc_shared() + copy_usm = dpnp_extension.dpctl_queue_memcpy() + free_usm = dpnp_extension.dpctl_free_with_queue() res_dtype = np.float64 diff --git a/numba_dppy/dppy_passbuilder.py b/numba_dppy/dppy_passbuilder.py index 475e78f1bf..8628b0fcf3 100644 --- a/numba_dppy/dppy_passbuilder.py +++ b/numba_dppy/dppy_passbuilder.py @@ -24,10 +24,11 @@ SpirvFriendlyLowering, DPPYAddNumpyOverloadPass, DPPYAddNumpyRemoveOverloadPass, - DPPYNoPythonBackend, - DPPYRewriteOverloadedFunctions, + DPPYNoPythonBackend ) +from .rename_numpy_functions_pass import (DPPYRewriteOverloadedFunctions) + class DPPYPassBuilder(object): """ This is the DPPY pass builder to run Intel GPU/CPU specific @@ -46,7 +47,7 @@ def default_numba_nopython_pipeline(state, pm): pm.add_pass(WithLifting, "Handle with contexts") # this pass rewrite name of functions - pm.add_pass(DPPYRewriteOverloadedFunctions, "dppl rewrite name of functions") + pm.add_pass(DPPYRewriteOverloadedFunctions, "dppy rewrite name of functions") # this pass adds required logic to overload default implementation of # Numpy functions diff --git a/numba_dppy/dppy_passes.py b/numba_dppy/dppy_passes.py index 334950f32e..34a5406310 100644 --- a/numba_dppy/dppy_passes.py +++ b/numba_dppy/dppy_passes.py @@ -40,80 +40,6 @@ def dpnp_available(): except: return False -rewrite_function_name_map = {"sum": (["np"], "sum"), - "eig": (["linalg"], "eig")} - -class RewriteOverloadedFunctions(object): - def __init__(self, state, rewrite_function_name_map=rewrite_function_name_map): - self.state = state - self.function_name_map = rewrite_function_name_map - - def run(self): - func_ir = self.state.func_ir - blocks = func_ir.blocks - topo_order = find_topo_order(blocks) - - import numba_dppy.dpnp_glue.dpnpdecl - import numba_dppy.dpnp_glue.dpnpimpl - for label in topo_order: - block = blocks[label] - saved_arr_arg = {} - new_body = [] - for stmt in block.body: - if isinstance(stmt, ir.Assign) and isinstance(stmt.value, ir.Expr): - lhs = stmt.target.name - rhs = stmt.value - # replace np.func with name from map np.func - if (rhs.op == 'getattr' and rhs.attr in rewrite_function_name_map): - module_node = block.find_variable_assignment(rhs.value.name).value - if ((isinstance(module_node, ir.Global) and - module_node.name in rewrite_function_name_map[rhs.attr][0]) or - (isinstance(module_node, ir.Expr) and - module_node.attr in rewrite_function_name_map[rhs.attr][0])): - rhs = stmt.value - rhs.attr = rewrite_function_name_map[rhs.attr][1] - - global_module = rhs.value - saved_arr_arg[lhs] = global_module - - scope = global_module.scope - loc = global_module.loc - - g_dppl_var = ir.Var(scope, mk_unique_var("$dppy_replaced_var"), loc) - g_dppl = ir.Global('numba_dppy', numba_dppy, loc) - g_dppl_assign = ir.Assign(g_dppl, g_dppl_var, loc) - - dpnp_var = ir.Var(scope, mk_unique_var("$dpnp_var"), loc) - getattr_dpnp = ir.Expr.getattr(g_dppl_var, 'dpnp', loc) - dpnp_assign = ir.Assign(getattr_dpnp, dpnp_var, loc) - - rhs.value = dpnp_var - new_body.append(g_dppl_assign) - new_body.append(dpnp_assign) - func_ir._definitions[dpnp_var.name] = [getattr_dpnp] - func_ir._definitions[g_dppl_var.name] = [g_dppl] - - new_body.append(stmt) - block.body = new_body - - -@register_pass(mutates_CFG=True, analysis_only=False) -class DPPYRewriteOverloadedFunctions(FunctionPass): - _name = "dppl_rewrite_overloaded_functions_pass" - - def __init__(self): - FunctionPass.__init__(self) - self.function_name_map = rewrite_function_name_map - - def run_pass(self, state): - rewrite_function_name_pass = RewriteOverloadedFunctions(state, rewrite_function_name_map) - - rewrite_function_name_pass.run() - - state.func_ir.blocks = simplify_CFG(state.func_ir.blocks) - - return True - @register_pass(mutates_CFG=False, analysis_only=True) class DPPYAddNumpyOverloadPass(FunctionPass): diff --git a/numba_dppy/rename_numpy_functions_pass.py b/numba_dppy/rename_numpy_functions_pass.py new file mode 100644 index 0000000000..2f99483671 --- /dev/null +++ b/numba_dppy/rename_numpy_functions_pass.py @@ -0,0 +1,79 @@ +from numba.core import ir +from numba.core.compiler_machinery import FunctionPass, register_pass +from numba.core.ir_utils import (find_topo_order, mk_unique_var, + simplify_CFG) + +rewrite_function_name_map = {"sum": (["np"], "sum"), + "eig": (["linalg"], "eig")} + +class RewriteOverloadedFunctions(object): + def __init__(self, state, rewrite_function_name_map=rewrite_function_name_map): + self.state = state + self.function_name_map = rewrite_function_name_map + + def run(self): + func_ir = self.state.func_ir + blocks = func_ir.blocks + topo_order = find_topo_order(blocks) + + import numba_dppy.dpnp_glue.dpnpdecl + import numba_dppy.dpnp_glue.dpnpimpl + for label in topo_order: + block = blocks[label] + saved_arr_arg = {} + new_body = [] + for stmt in block.body: + if isinstance(stmt, ir.Assign) and isinstance(stmt.value, ir.Expr): + lhs = stmt.target.name + rhs = stmt.value + # replace np.func with name from map np.func + if (rhs.op == 'getattr' and rhs.attr in self.function_name_map): + module_node = block.find_variable_assignment(rhs.value.name).value + if ((isinstance(module_node, ir.Global) and + module_node.name in self.function_name_map[rhs.attr][0]) or + (isinstance(module_node, ir.Expr) and + module_node.attr in self.function_name_map[rhs.attr][0])): + rhs = stmt.value + rhs.attr = self.function_name_map[rhs.attr][1] + + global_module = rhs.value + saved_arr_arg[lhs] = global_module + + scope = global_module.scope + loc = global_module.loc + + g_dppy_var = ir.Var(scope, mk_unique_var("$dppy_replaced_var"), loc) + g_dppy = ir.Global('numba_dppy', numba_dppy, loc) + g_dppy_assign = ir.Assign(g_dppy, g_dppy_var, loc) + + dpnp_var = ir.Var(scope, mk_unique_var("$dpnp_var"), loc) + getattr_dpnp = ir.Expr.getattr(g_dppy_var, 'dpnp', loc) + dpnp_assign = ir.Assign(getattr_dpnp, dpnp_var, loc) + + rhs.value = dpnp_var + new_body.append(g_dppy_assign) + new_body.append(dpnp_assign) + func_ir._definitions[dpnp_var.name] = [getattr_dpnp] + func_ir._definitions[g_dppy_var.name] = [g_dppy] + + new_body.append(stmt) + block.body = new_body + import pdb + pdb.set_trace() + + +@register_pass(mutates_CFG=True, analysis_only=False) +class DPPYRewriteOverloadedFunctions(FunctionPass): + _name = "dppy_rewrite_overloaded_functions_pass" + + def __init__(self): + FunctionPass.__init__(self) + + def run_pass(self, state): + rewrite_function_name_pass = RewriteOverloadedFunctions(state, rewrite_function_name_map) + + rewrite_function_name_pass.run() + + state.func_ir.blocks = simplify_CFG(state.func_ir.blocks) + + return True From 687a52a7d6cfeb06ff6d76c95e9f39dbe58309e4 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Mon, 7 Dec 2020 17:27:01 -0600 Subject: [PATCH 08/34] Import module at correct locations --- numba_dppy/dpnp_glue/dpnpdecl.py | 2 +- numba_dppy/rename_numpy_functions_pass.py | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/numba_dppy/dpnp_glue/dpnpdecl.py b/numba_dppy/dpnp_glue/dpnpdecl.py index e7c33cb7ca..e77739eeda 100644 --- a/numba_dppy/dpnp_glue/dpnpdecl.py +++ b/numba_dppy/dpnp_glue/dpnpdecl.py @@ -1,4 +1,4 @@ -from numba.core.typing.templates import (AttributeTemplate, infer, infer_getattr, AbstractTemplate, signature) +from numba.core.typing.templates import (AttributeTemplate, infer_getattr) import numba_dppy from numba import types diff --git a/numba_dppy/rename_numpy_functions_pass.py b/numba_dppy/rename_numpy_functions_pass.py index 2f99483671..f78b2cef50 100644 --- a/numba_dppy/rename_numpy_functions_pass.py +++ b/numba_dppy/rename_numpy_functions_pass.py @@ -2,6 +2,7 @@ from numba.core.compiler_machinery import FunctionPass, register_pass from numba.core.ir_utils import (find_topo_order, mk_unique_var, simplify_CFG) +import numba_dppy rewrite_function_name_map = {"sum": (["np"], "sum"), "eig": (["linalg"], "eig")} @@ -16,8 +17,6 @@ def run(self): blocks = func_ir.blocks topo_order = find_topo_order(blocks) - import numba_dppy.dpnp_glue.dpnpdecl - import numba_dppy.dpnp_glue.dpnpimpl for label in topo_order: block = blocks[label] saved_arr_arg = {} @@ -58,8 +57,6 @@ def run(self): new_body.append(stmt) block.body = new_body - import pdb - pdb.set_trace() @register_pass(mutates_CFG=True, analysis_only=False) @@ -68,6 +65,8 @@ class DPPYRewriteOverloadedFunctions(FunctionPass): def __init__(self): FunctionPass.__init__(self) + import numba_dppy.dpnp_glue.dpnpdecl + import numba_dppy.dpnp_glue.dpnpimpl def run_pass(self, state): rewrite_function_name_pass = RewriteOverloadedFunctions(state, rewrite_function_name_map) From 0fc597a3aa83e928d26c1b6412a47c8d02b7bdca Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Tue, 8 Dec 2020 10:43:11 -0600 Subject: [PATCH 09/34] Added comments --- numba_dppy/dppy_passbuilder.py | 94 +++++++++++++++-------- numba_dppy/rename_numpy_functions_pass.py | 71 +++++++++++++---- 2 files changed, 115 insertions(+), 50 deletions(-) diff --git a/numba_dppy/dppy_passbuilder.py b/numba_dppy/dppy_passbuilder.py index 8628b0fcf3..6806dbea8e 100644 --- a/numba_dppy/dppy_passbuilder.py +++ b/numba_dppy/dppy_passbuilder.py @@ -2,32 +2,49 @@ from numba.core.compiler_machinery import PassManager -from numba.core.untyped_passes import (ExtractByteCode, TranslateByteCode, FixupArgs, - IRProcessing, DeadBranchPrune, - RewriteSemanticConstants, InlineClosureLikes, - GenericRewrites, WithLifting, - InlineInlinables, FindLiterallyCalls, - MakeFunctionToJitFunction, - CanonicalizeLoopExit, CanonicalizeLoopEntry, - ReconstructSSA, - LiteralUnroll) - -from numba.core.typed_passes import (NopythonTypeInference, AnnotateTypes, - NopythonRewrites, PreParforPass, ParforPass, - DumpParforDiagnostics, IRLegalization, - InlineOverloads, PreLowerStripPhis) +from numba.core.untyped_passes import ( + ExtractByteCode, + TranslateByteCode, + FixupArgs, + IRProcessing, + DeadBranchPrune, + RewriteSemanticConstants, + InlineClosureLikes, + GenericRewrites, + WithLifting, + InlineInlinables, + FindLiterallyCalls, + MakeFunctionToJitFunction, + CanonicalizeLoopExit, + CanonicalizeLoopEntry, + ReconstructSSA, + LiteralUnroll, +) + +from numba.core.typed_passes import ( + NopythonTypeInference, + AnnotateTypes, + NopythonRewrites, + PreParforPass, + ParforPass, + DumpParforDiagnostics, + IRLegalization, + InlineOverloads, + PreLowerStripPhis, +) from .dppy_passes import ( - DPPYConstantSizeStaticLocalMemoryPass, - DPPYPreParforPass, - DPPYParforPass, - SpirvFriendlyLowering, - DPPYAddNumpyOverloadPass, - DPPYAddNumpyRemoveOverloadPass, - DPPYNoPythonBackend - ) + DPPYConstantSizeStaticLocalMemoryPass, + DPPYPreParforPass, + DPPYParforPass, + SpirvFriendlyLowering, + DPPYAddNumpyOverloadPass, + DPPYAddNumpyRemoveOverloadPass, + DPPYNoPythonBackend, +) + +from .rename_numpy_functions_pass import DPPYRewriteOverloadedFunctions -from .rename_numpy_functions_pass import (DPPYRewriteOverloadedFunctions) class DPPYPassBuilder(object): """ @@ -47,16 +64,24 @@ def default_numba_nopython_pipeline(state, pm): pm.add_pass(WithLifting, "Handle with contexts") # this pass rewrite name of functions - pm.add_pass(DPPYRewriteOverloadedFunctions, "dppy rewrite name of functions") + pm.add_pass( + DPPYRewriteOverloadedFunctions, + "Rewrite name of Numpy functions to overload already overloaded function", + ) # this pass adds required logic to overload default implementation of # Numpy functions - pm.add_pass(DPPYAddNumpyOverloadPass, "dppy add typing template for Numpy functions") + pm.add_pass( + DPPYAddNumpyOverloadPass, "dppy add typing template for Numpy functions" + ) # Add pass to ensure when users are allocating static # constant memory the size is a constant and can not # come from a closure variable - pm.add_pass(DPPYConstantSizeStaticLocalMemoryPass, "dppy constant size for static local memory") + pm.add_pass( + DPPYConstantSizeStaticLocalMemoryPass, + "dppy constant size for static local memory", + ) # pre typing if not state.flags.no_rewrites: @@ -64,11 +89,11 @@ def default_numba_nopython_pipeline(state, pm): pm.add_pass(DeadBranchPrune, "dead branch pruning") pm.add_pass(GenericRewrites, "nopython rewrites") - pm.add_pass(InlineClosureLikes, - "inline calls to locally defined closures") + pm.add_pass(InlineClosureLikes, "inline calls to locally defined closures") # convert any remaining closures into functions - pm.add_pass(MakeFunctionToJitFunction, - "convert make_function into JIT functions") + pm.add_pass( + MakeFunctionToJitFunction, "convert make_function into JIT functions" + ) # inline functions that have been determined as inlinable and rerun # branch pruning, this needs to be run after closures are inlined as # the IR repr of a closure masks call sites if an inlinable is called @@ -92,10 +117,8 @@ def default_numba_nopython_pipeline(state, pm): # optimisation pm.add_pass(InlineOverloads, "inline overloaded functions") - - @staticmethod - def define_nopython_pipeline(state, name='dppy_nopython'): + def define_nopython_pipeline(state, name="dppy_nopython"): """Returns an nopython mode pipeline based PassManager """ pm = PassManager(name) @@ -113,6 +136,9 @@ def define_nopython_pipeline(state, name='dppy_nopython'): # lower pm.add_pass(SpirvFriendlyLowering, "SPIRV-friendly lowering pass") pm.add_pass(DPPYNoPythonBackend, "nopython mode backend") - pm.add_pass(DPPYAddNumpyRemoveOverloadPass, "dppy remove typing template for Numpy functions") + pm.add_pass( + DPPYAddNumpyRemoveOverloadPass, + "dppy remove typing template for Numpy functions", + ) pm.finalize() return pm diff --git a/numba_dppy/rename_numpy_functions_pass.py b/numba_dppy/rename_numpy_functions_pass.py index f78b2cef50..f98b9adc83 100644 --- a/numba_dppy/rename_numpy_functions_pass.py +++ b/numba_dppy/rename_numpy_functions_pass.py @@ -1,18 +1,42 @@ from numba.core import ir from numba.core.compiler_machinery import FunctionPass, register_pass -from numba.core.ir_utils import (find_topo_order, mk_unique_var, - simplify_CFG) +from numba.core.ir_utils import find_topo_order, mk_unique_var, simplify_CFG import numba_dppy -rewrite_function_name_map = {"sum": (["np"], "sum"), - "eig": (["linalg"], "eig")} +rewrite_function_name_map = {"sum": (["np"], "sum"), "eig": (["linalg"], "eig")} -class RewriteOverloadedFunctions(object): + +class RewriteNumPyOverloadedFunctions(object): def __init__(self, state, rewrite_function_name_map=rewrite_function_name_map): self.state = state self.function_name_map = rewrite_function_name_map def run(self): + """ + This function rewrites the name of NumPy functions that exist in self.function_name_map + e.g np.sum(a) would produce the following: + + np.sum() --> numba_dppy.dpnp.sum() + + --------------------------------------------------------------------------------------- + Numba IR Before Rewrite: + --------------------------------------------------------------------------------------- + + $2load_global.0 = global(np: ) ['$2load_global.0'] + $4load_method.1 = getattr(value=$2load_global.0, attr=sum) ['$2load_global.0', '$4load_method.1'] + $8call_method.3 = call $4load_method.1(a, func=$4load_method.1, args=[Var(a, test_rewrite.py:7)], kws=(), vararg=None) ['$4load_method.1', '$8call_method.3', 'a'] + + --------------------------------------------------------------------------------------- + Numba IR After Rewrite: + --------------------------------------------------------------------------------------- + + $dppy_replaced_var.0 = global(numba_dppy: ) ['$dppy_replaced_var.0'] + $dpnp_var.1 = getattr(value=$dppy_replaced_var.0, attr=dpnp) ['$dpnp_var.1', '$dppy_replaced_var.0'] + $4load_method.1 = getattr(value=$dpnp_var.1, attr=sum) ['$4load_method.1', '$dpnp_var.1'] + $8call_method.3 = call $4load_method.1(a, func=$4load_method.1, args=[Var(a, test_rewrite.py:7)], kws=(), vararg=None) ['$4load_method.1', '$8call_method.3', 'a'] + + --------------------------------------------------------------------------------------- + """ func_ir = self.state.func_ir blocks = func_ir.blocks topo_order = find_topo_order(blocks) @@ -25,13 +49,19 @@ def run(self): if isinstance(stmt, ir.Assign) and isinstance(stmt.value, ir.Expr): lhs = stmt.target.name rhs = stmt.value - # replace np.func with name from map np.func - if (rhs.op == 'getattr' and rhs.attr in self.function_name_map): - module_node = block.find_variable_assignment(rhs.value.name).value - if ((isinstance(module_node, ir.Global) and - module_node.name in self.function_name_map[rhs.attr][0]) or - (isinstance(module_node, ir.Expr) and - module_node.attr in self.function_name_map[rhs.attr][0])): + # replace np.func(sum) with name from self.function_name_map + # np.sum will be replaced with numba_dppy.dpnp.sum + if rhs.op == "getattr" and rhs.attr in self.function_name_map: + module_node = block.find_variable_assignment( + rhs.value.name + ).value + if ( + isinstance(module_node, ir.Global) + and module_node.name in self.function_name_map[rhs.attr][0] + ) or ( + isinstance(module_node, ir.Expr) + and module_node.attr in self.function_name_map[rhs.attr][0] + ): rhs = stmt.value rhs.attr = self.function_name_map[rhs.attr][1] @@ -41,12 +71,19 @@ def run(self): scope = global_module.scope loc = global_module.loc - g_dppy_var = ir.Var(scope, mk_unique_var("$dppy_replaced_var"), loc) - g_dppy = ir.Global('numba_dppy', numba_dppy, loc) + g_dppy_var = ir.Var( + scope, mk_unique_var("$dppy_replaced_var"), loc + ) + # We are trying to rename np.function_name/np.linalg.function_name with + # numba_dppy.dpnp.function_name. + # Hence, we need to have a global variable representing module numba_dppy. + # Next, we add attribute dpnp to global module numba_dppy to + # represent numba_dppy.dpnp. + g_dppy = ir.Global("numba_dppy", numba_dppy, loc) g_dppy_assign = ir.Assign(g_dppy, g_dppy_var, loc) dpnp_var = ir.Var(scope, mk_unique_var("$dpnp_var"), loc) - getattr_dpnp = ir.Expr.getattr(g_dppy_var, 'dpnp', loc) + getattr_dpnp = ir.Expr.getattr(g_dppy_var, "dpnp", loc) dpnp_assign = ir.Assign(getattr_dpnp, dpnp_var, loc) rhs.value = dpnp_var @@ -69,7 +106,9 @@ def __init__(self): import numba_dppy.dpnp_glue.dpnpimpl def run_pass(self, state): - rewrite_function_name_pass = RewriteOverloadedFunctions(state, rewrite_function_name_map) + rewrite_function_name_pass = RewriteNumPyOverloadedFunctions( + state, rewrite_function_name_map + ) rewrite_function_name_pass.run() From 35c22ef035498a213f289e391849372ecfa80d5c Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Tue, 8 Dec 2020 16:40:02 -0600 Subject: [PATCH 10/34] Added test and updated comments --- numba_dppy/dpctl_functions.py | 30 ++++++ numba_dppy/dpnp_glue/dpnpimpl.py | 35 ++----- numba_dppy/dppy_passbuilder.py | 94 +++++++------------ numba_dppy/rename_numpy_functions_pass.py | 22 +++-- .../tests/test_rename_numpy_function_pass.py | 43 +++++++++ 5 files changed, 129 insertions(+), 95 deletions(-) create mode 100644 numba_dppy/dpctl_functions.py create mode 100644 numba_dppy/tests/test_rename_numpy_function_pass.py diff --git a/numba_dppy/dpctl_functions.py b/numba_dppy/dpctl_functions.py new file mode 100644 index 0000000000..67bc358185 --- /dev/null +++ b/numba_dppy/dpctl_functions.py @@ -0,0 +1,30 @@ +from numba import types +from numba.core.typing import signature + + +class _DPCTL_FUNCTIONS: + @classmethod + def dpctl_get_current_queue(cls): + ret_type = types.voidptr + sig = signature(ret_type) + return types.ExternalFunction("DPCTLQueueMgr_GetCurrentQueue", sig) + + @classmethod + def dpctl_malloc_shared(cls): + ret_type = types.voidptr + sig = signature(ret_type, types.int64, types.voidptr) + return types.ExternalFunction("DPCTLmalloc_shared", sig) + + @classmethod + def dpctl_queue_memcpy(cls): + ret_type = types.void + sig = signature( + ret_type, types.voidptr, types.voidptr, types.voidptr, types.int64 + ) + return types.ExternalFunction("DPCTLQueue_Memcpy", sig) + + @classmethod + def dpctl_free_with_queue(cls): + ret_type = types.void + sig = signature(ret_type, types.voidptr, types.voidptr) + return types.ExternalFunction("DPCTLfree_with_queue", sig) diff --git a/numba_dppy/dpnp_glue/dpnpimpl.py b/numba_dppy/dpnp_glue/dpnpimpl.py index 02552c8550..835a79abbd 100644 --- a/numba_dppy/dpnp_glue/dpnpimpl.py +++ b/numba_dppy/dpnp_glue/dpnpimpl.py @@ -5,6 +5,7 @@ from numba.core.extending import overload, register_jitable from . import stubs import numpy as np +from numba_dppy.dpctl_functions import _DPCTL_FUNCTIONS def get_dpnp_fptr(fn_name, type_names): @@ -36,31 +37,6 @@ class _DPNP_EXTENSION: def __init__(self, name): dpnp_lowering.ensure_dpnp(name) - @classmethod - def dpctl_get_current_queue(cls): - ret_type = types.voidptr - sig = signature(ret_type) - return types.ExternalFunction("DPCTLQueueMgr_GetCurrentQueue", sig) - - @classmethod - def dpctl_malloc_shared(cls): - ret_type = types.voidptr - sig = signature(ret_type, types.int64, types.voidptr) - return types.ExternalFunction("DPCTLmalloc_shared", sig) - - @classmethod - def dpctl_queue_memcpy(cls): - ret_type = types.void - sig = signature(ret_type, types.voidptr, types.voidptr, types.voidptr, types.int64) - return types.ExternalFunction("DPCTLQueue_Memcpy", sig) - - @classmethod - def dpctl_free_with_queue(cls): - ret_type = types.void - sig = signature(ret_type, types.voidptr, types.voidptr) - return types.ExternalFunction("DPCTLfree_with_queue", sig) - - @classmethod def dpnp_sum(cls, fn_name, type_names): ret_type = types.void @@ -83,13 +59,14 @@ def get_pointer(obj): @overload(stubs.dpnp.sum) def dpnp_sum_impl(a): dpnp_extension = _DPNP_EXTENSION("sum") + dpctl_functions = _DPCTL_FUNCTIONS() dpnp_sum = dpnp_extension.dpnp_sum("dpnp_sum", [a.dtype.name, "NONE"]) - get_sycl_queue = dpnp_extension.dpctl_get_current_queue() - allocate_usm_shared = dpnp_extension.dpctl_malloc_shared() - copy_usm = dpnp_extension.dpctl_queue_memcpy() - free_usm = dpnp_extension.dpctl_free_with_queue() + get_sycl_queue = dpctl_functions.dpctl_get_current_queue() + allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() + copy_usm = dpctl_functions.dpctl_queue_memcpy() + free_usm = dpctl_functions.dpctl_free_with_queue() def dpnp_sum_impl(a): if a.size == 0: diff --git a/numba_dppy/dppy_passbuilder.py b/numba_dppy/dppy_passbuilder.py index 6806dbea8e..b3c632a85a 100644 --- a/numba_dppy/dppy_passbuilder.py +++ b/numba_dppy/dppy_passbuilder.py @@ -2,50 +2,33 @@ from numba.core.compiler_machinery import PassManager -from numba.core.untyped_passes import ( - ExtractByteCode, - TranslateByteCode, - FixupArgs, - IRProcessing, - DeadBranchPrune, - RewriteSemanticConstants, - InlineClosureLikes, - GenericRewrites, - WithLifting, - InlineInlinables, - FindLiterallyCalls, - MakeFunctionToJitFunction, - CanonicalizeLoopExit, - CanonicalizeLoopEntry, - ReconstructSSA, - LiteralUnroll, -) - -from numba.core.typed_passes import ( - NopythonTypeInference, - AnnotateTypes, - NopythonRewrites, - PreParforPass, - ParforPass, - DumpParforDiagnostics, - IRLegalization, - InlineOverloads, - PreLowerStripPhis, -) +from numba.core.untyped_passes import (ExtractByteCode, TranslateByteCode, FixupArgs, + IRProcessing, DeadBranchPrune, + RewriteSemanticConstants, InlineClosureLikes, + GenericRewrites, WithLifting, + InlineInlinables, FindLiterallyCalls, + MakeFunctionToJitFunction, + CanonicalizeLoopExit, CanonicalizeLoopEntry, + ReconstructSSA, + LiteralUnroll) + +from numba.core.typed_passes import (NopythonTypeInference, AnnotateTypes, + NopythonRewrites, PreParforPass, ParforPass, + DumpParforDiagnostics, IRLegalization, + InlineOverloads, PreLowerStripPhis) from .dppy_passes import ( - DPPYConstantSizeStaticLocalMemoryPass, - DPPYPreParforPass, - DPPYParforPass, - SpirvFriendlyLowering, - DPPYAddNumpyOverloadPass, - DPPYAddNumpyRemoveOverloadPass, - DPPYNoPythonBackend, -) + DPPYConstantSizeStaticLocalMemoryPass, + DPPYPreParforPass, + DPPYParforPass, + SpirvFriendlyLowering, + DPPYAddNumpyOverloadPass, + DPPYAddNumpyRemoveOverloadPass, + DPPYNoPythonBackend + ) from .rename_numpy_functions_pass import DPPYRewriteOverloadedFunctions - class DPPYPassBuilder(object): """ This is the DPPY pass builder to run Intel GPU/CPU specific @@ -63,25 +46,19 @@ def default_numba_nopython_pipeline(state, pm): pm.add_pass(IRProcessing, "processing IR") pm.add_pass(WithLifting, "Handle with contexts") - # this pass rewrite name of functions - pm.add_pass( - DPPYRewriteOverloadedFunctions, - "Rewrite name of Numpy functions to overload already overloaded function", + # this pass rewrites name of NumPy functions we intend to overload + pm.add_pass(DPPYRewriteOverloadedFunctions, + "Rewrite name of Numpy functions to overload already overloaded function", ) # this pass adds required logic to overload default implementation of # Numpy functions - pm.add_pass( - DPPYAddNumpyOverloadPass, "dppy add typing template for Numpy functions" - ) + pm.add_pass(DPPYAddNumpyOverloadPass, "dppy add typing template for Numpy functions") # Add pass to ensure when users are allocating static # constant memory the size is a constant and can not # come from a closure variable - pm.add_pass( - DPPYConstantSizeStaticLocalMemoryPass, - "dppy constant size for static local memory", - ) + pm.add_pass(DPPYConstantSizeStaticLocalMemoryPass, "dppy constant size for static local memory") # pre typing if not state.flags.no_rewrites: @@ -89,11 +66,11 @@ def default_numba_nopython_pipeline(state, pm): pm.add_pass(DeadBranchPrune, "dead branch pruning") pm.add_pass(GenericRewrites, "nopython rewrites") - pm.add_pass(InlineClosureLikes, "inline calls to locally defined closures") + pm.add_pass(InlineClosureLikes, + "inline calls to locally defined closures") # convert any remaining closures into functions - pm.add_pass( - MakeFunctionToJitFunction, "convert make_function into JIT functions" - ) + pm.add_pass(MakeFunctionToJitFunction, + "convert make_function into JIT functions") # inline functions that have been determined as inlinable and rerun # branch pruning, this needs to be run after closures are inlined as # the IR repr of a closure masks call sites if an inlinable is called @@ -117,8 +94,10 @@ def default_numba_nopython_pipeline(state, pm): # optimisation pm.add_pass(InlineOverloads, "inline overloaded functions") + + @staticmethod - def define_nopython_pipeline(state, name="dppy_nopython"): + def define_nopython_pipeline(state, name='dppy_nopython'): """Returns an nopython mode pipeline based PassManager """ pm = PassManager(name) @@ -136,9 +115,6 @@ def define_nopython_pipeline(state, name="dppy_nopython"): # lower pm.add_pass(SpirvFriendlyLowering, "SPIRV-friendly lowering pass") pm.add_pass(DPPYNoPythonBackend, "nopython mode backend") - pm.add_pass( - DPPYAddNumpyRemoveOverloadPass, - "dppy remove typing template for Numpy functions", - ) + pm.add_pass(DPPYAddNumpyRemoveOverloadPass, "dppy remove typing template for Numpy functions") pm.finalize() return pm diff --git a/numba_dppy/rename_numpy_functions_pass.py b/numba_dppy/rename_numpy_functions_pass.py index f98b9adc83..0117fb3297 100644 --- a/numba_dppy/rename_numpy_functions_pass.py +++ b/numba_dppy/rename_numpy_functions_pass.py @@ -1,6 +1,11 @@ from numba.core import ir from numba.core.compiler_machinery import FunctionPass, register_pass -from numba.core.ir_utils import find_topo_order, mk_unique_var, simplify_CFG +from numba.core.ir_utils import ( + find_topo_order, + mk_unique_var, + remove_dead, + simplify_CFG, +) import numba_dppy rewrite_function_name_map = {"sum": (["np"], "sum"), "eig": (["linalg"], "eig")} @@ -24,7 +29,8 @@ def run(self): $2load_global.0 = global(np: ) ['$2load_global.0'] $4load_method.1 = getattr(value=$2load_global.0, attr=sum) ['$2load_global.0', '$4load_method.1'] - $8call_method.3 = call $4load_method.1(a, func=$4load_method.1, args=[Var(a, test_rewrite.py:7)], kws=(), vararg=None) ['$4load_method.1', '$8call_method.3', 'a'] + $8call_method.3 = call $4load_method.1(a, func=$4load_method.1, args=[Var(a, test_rewrite.py:7)], + kws=(), vararg=None) ['$4load_method.1', '$8call_method.3', 'a'] --------------------------------------------------------------------------------------- Numba IR After Rewrite: @@ -33,7 +39,8 @@ def run(self): $dppy_replaced_var.0 = global(numba_dppy: ) ['$dppy_replaced_var.0'] $dpnp_var.1 = getattr(value=$dppy_replaced_var.0, attr=dpnp) ['$dpnp_var.1', '$dppy_replaced_var.0'] $4load_method.1 = getattr(value=$dpnp_var.1, attr=sum) ['$4load_method.1', '$dpnp_var.1'] - $8call_method.3 = call $4load_method.1(a, func=$4load_method.1, args=[Var(a, test_rewrite.py:7)], kws=(), vararg=None) ['$4load_method.1', '$8call_method.3', 'a'] + $8call_method.3 = call $4load_method.1(a, func=$4load_method.1, args=[Var(a, test_rewrite.py:7)], + kws=(), vararg=None) ['$4load_method.1', '$8call_method.3', 'a'] --------------------------------------------------------------------------------------- """ @@ -49,8 +56,8 @@ def run(self): if isinstance(stmt, ir.Assign) and isinstance(stmt.value, ir.Expr): lhs = stmt.target.name rhs = stmt.value - # replace np.func(sum) with name from self.function_name_map - # np.sum will be replaced with numba_dppy.dpnp.sum + # replace np.FOO with name from self.function_name_map["FOO"] + # e.g. np.sum will be replaced with numba_dppy.dpnp.sum if rhs.op == "getattr" and rhs.attr in self.function_name_map: module_node = block.find_variable_assignment( rhs.value.name @@ -72,7 +79,7 @@ def run(self): loc = global_module.loc g_dppy_var = ir.Var( - scope, mk_unique_var("$dppy_replaced_var"), loc + scope, mk_unique_var("$2load_global"), loc ) # We are trying to rename np.function_name/np.linalg.function_name with # numba_dppy.dpnp.function_name. @@ -82,7 +89,7 @@ def run(self): g_dppy = ir.Global("numba_dppy", numba_dppy, loc) g_dppy_assign = ir.Assign(g_dppy, g_dppy_var, loc) - dpnp_var = ir.Var(scope, mk_unique_var("$dpnp_var"), loc) + dpnp_var = ir.Var(scope, mk_unique_var("$4load_attr"), loc) getattr_dpnp = ir.Expr.getattr(g_dppy_var, "dpnp", loc) dpnp_assign = ir.Assign(getattr_dpnp, dpnp_var, loc) @@ -112,6 +119,7 @@ def run_pass(self, state): rewrite_function_name_pass.run() + remove_dead(state.func_ir.blocks, state.func_ir.arg_names, state.func_ir) state.func_ir.blocks = simplify_CFG(state.func_ir.blocks) return True diff --git a/numba_dppy/tests/test_rename_numpy_function_pass.py b/numba_dppy/tests/test_rename_numpy_function_pass.py new file mode 100644 index 0000000000..5d8fafbb85 --- /dev/null +++ b/numba_dppy/tests/test_rename_numpy_function_pass.py @@ -0,0 +1,43 @@ +#! /usr/bin/env python + +import unittest +import numpy as np + +import numba +from numba import njit, prange +import numba_dppy, numba_dppy as dppy + + +from numba.core import compiler +from numba_dppy.rename_numpy_functions_pass import DPPYRewriteOverloadedFunctions + + +class MyPipeline(object): + def __init__(self, test_ir): + self.state = compiler.StateDict() + self.state.func_ir = test_ir + + +class TestRenameNumpyFunctionsPass(unittest.TestCase): + def test_rename(self): + def expected(a): + b = numba_dppy.dpnp.sum(a) + return b + + def got(a): + b = np.sum(a) + return b + + expected_ir = compiler.run_frontend(expected) + got_ir = compiler.run_frontend(got) + + pipeline = MyPipeline(got_ir) + + rewrite_numpy_functions_pass = DPPYRewriteOverloadedFunctions() + rewrite_numpy_functions_pass.run_pass(pipeline.state) + + self.assertEqual(got_ir, pipeline.state.func_ir) + + +if __name__ == "__main__": + unittest.main() From ab646b67ffdcbc775ae08dd2e3c4e36ffa3d7ee8 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Tue, 8 Dec 2020 16:43:07 -0600 Subject: [PATCH 11/34] Revert unneeded changes --- numba_dppy/dpnp_glue/dpnpimpl.py | 33 ++++++++++++++++++++------------ numba_dppy/dppy_passes.py | 5 ++--- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/numba_dppy/dpnp_glue/dpnpimpl.py b/numba_dppy/dpnp_glue/dpnpimpl.py index 835a79abbd..2df395c970 100644 --- a/numba_dppy/dpnp_glue/dpnpimpl.py +++ b/numba_dppy/dpnp_glue/dpnpimpl.py @@ -1,4 +1,4 @@ -from numba.core.imputils import (lower_builtin) +from numba.core.imputils import lower_builtin import numba_dppy.experimental_numpy_lowering_overload as dpnp_lowering from numba import types from numba.core.typing import signature @@ -10,15 +10,17 @@ def get_dpnp_fptr(fn_name, type_names): from . import dpnp_fptr_interface as dpnp_glue + f_ptr = dpnp_glue.get_dpnp_fn_ptr(fn_name, type_names) return f_ptr + @register_jitable def _check_finite_matrix(a): for v in np.nditer(a): if not np.isfinite(v.item()): - raise np.linalg.LinAlgError( - "Array must not contain infs or NaNs.") + raise np.linalg.LinAlgError("Array must not contain infs or NaNs.") + @register_jitable def _dummy_liveness_func(a): @@ -26,33 +28,39 @@ def _dummy_liveness_func(a): return a[0] - class RetrieveDpnpFnPtr(types.ExternalFunctionPointer): def __init__(self, fn_name, type_names, sig, get_pointer): self.fn_name = fn_name self.type_names = type_names super(RetrieveDpnpFnPtr, self).__init__(sig, get_pointer) + class _DPNP_EXTENSION: def __init__(self, name): dpnp_lowering.ensure_dpnp(name) @classmethod def dpnp_sum(cls, fn_name, type_names): - ret_type = types.void - sig = signature(ret_type, types.voidptr, types.voidptr, types.int64) - f_ptr = get_dpnp_fptr(fn_name, type_names) + ret_type = types.void + sig = signature(ret_type, types.voidptr, types.voidptr, types.int64) + f_ptr = get_dpnp_fptr(fn_name, type_names) + def get_pointer(obj): return f_ptr + return types.ExternalFunctionPointer(sig, get_pointer=get_pointer) @classmethod def dpnp_eig(cls, fn_name, type_names): - ret_type = types.void - sig = signature(ret_type, types.voidptr, types.voidptr, types.voidptr, types.int64) - f_ptr = get_dpnp_fptr(fn_name, type_names) + ret_type = types.void + sig = signature( + ret_type, types.voidptr, types.voidptr, types.voidptr, types.int64 + ) + f_ptr = get_dpnp_fptr(fn_name, type_names) + def get_pointer(obj): return f_ptr + return types.ExternalFunctionPointer(sig, get_pointer=get_pointer) @@ -90,7 +98,8 @@ def dpnp_sum_impl(a): return dpnp_sum_impl -''' + +""" @overload(stubs.dpnp.eig) def dpnp_eig_impl(a): dpnp_extension = _DPNP_EXTENSION("eig") @@ -143,4 +152,4 @@ def dpnp_eig_impl(a): return (wr, vr) return dpnp_eig_impl -''' +""" diff --git a/numba_dppy/dppy_passes.py b/numba_dppy/dppy_passes.py index 34a5406310..c73f5a7736 100644 --- a/numba_dppy/dppy_passes.py +++ b/numba_dppy/dppy_passes.py @@ -18,8 +18,7 @@ types, ) -from numba.core.ir_utils import (remove_dels, find_topo_order, mk_unique_var, - simplify_CFG) +from numba.core.ir_utils import remove_dels from numba.core.errors import (LoweringError, new_error_context, TypingError, LiteralTypingError) @@ -51,7 +50,7 @@ def __init__(self): def run_pass(self, state): if dpnp_available(): typingctx = state.typingctx - from numba.core.typing.templates import (builtin_registry as reg, infer_global, infer_getattr) + from numba.core.typing.templates import (builtin_registry as reg, infer_global) from numba.core.typing.templates import (AbstractTemplate, CallableTemplate, signature) from numba.core.typing.npydecl import MatMulTyperMixin From 10b90f1bbbba52fdc52e9f40c2f6f0175267743d Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Tue, 8 Dec 2020 17:35:51 -0600 Subject: [PATCH 12/34] Update Eigen implementation --- numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx | 42 +++++++++++++++++++- numba_dppy/dpnp_glue/dpnpimpl.py | 16 ++++---- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx b/numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx index d93b3a1321..a63d4fdafa 100644 --- a/numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx +++ b/numba_dppy/dpnp_glue/dpnp_fptr_interface.pyx @@ -8,6 +8,7 @@ cdef extern from "backend_iface_fptr.hpp" namespace "DPNPFuncName": # need this cdef enum DPNPFuncName "DPNPFuncName": DPNP_FN_ABSOLUTE DPNP_FN_ADD + DPNP_FN_ARANGE DPNP_FN_ARCCOS DPNP_FN_ARCCOSH DPNP_FN_ARCSIN @@ -18,40 +19,77 @@ cdef extern from "backend_iface_fptr.hpp" namespace "DPNPFuncName": # need this DPNP_FN_ARGMAX DPNP_FN_ARGMIN DPNP_FN_ARGSORT + DPNP_FN_BITWISE_AND + DPNP_FN_BITWISE_OR + DPNP_FN_BITWISE_XOR DPNP_FN_CBRT DPNP_FN_CEIL + DPNP_FN_CHOLESKY + DPNP_FN_COPYSIGN + DPNP_FN_CORRELATE DPNP_FN_COS DPNP_FN_COSH DPNP_FN_COV DPNP_FN_DEGREES + DPNP_FN_DET DPNP_FN_DIVIDE DPNP_FN_DOT DPNP_FN_EIG + DPNP_FN_EIGVALS DPNP_FN_EXP DPNP_FN_EXP2 DPNP_FN_EXPM1 DPNP_FN_FABS + DPNP_FN_FFT_FFT DPNP_FN_FLOOR + DPNP_FN_FLOOR_DIVIDE DPNP_FN_FMOD - DPNP_FN_GAUSSIAN DPNP_FN_HYPOT + DPNP_FN_INVERT + DPNP_FN_LEFT_SHIFT DPNP_FN_LOG DPNP_FN_LOG10 DPNP_FN_LOG1P DPNP_FN_LOG2 DPNP_FN_MATMUL + DPNP_FN_MATRIX_RANK DPNP_FN_MAX DPNP_FN_MAXIMUM DPNP_FN_MEAN DPNP_FN_MEDIAN DPNP_FN_MIN DPNP_FN_MINIMUM + DPNP_FN_MODF DPNP_FN_MULTIPLY DPNP_FN_POWER DPNP_FN_PROD - DPNP_FN_UNIFORM DPNP_FN_RADIANS + DPNP_FN_REMAINDER DPNP_FN_RECIP + DPNP_FN_RIGHT_SHIFT + DPNP_FN_RNG_BETA + DPNP_FN_RNG_BINOMIAL + DPNP_FN_RNG_CHISQUARE + DPNP_FN_RNG_EXPONENTIAL + DPNP_FN_RNG_GAMMA + DPNP_FN_RNG_GAUSSIAN + DPNP_FN_RNG_GEOMETRIC + DPNP_FN_RNG_GUMBEL + DPNP_FN_RNG_HYPERGEOMETRIC + DPNP_FN_RNG_LAPLACE + DPNP_FN_RNG_LOGNORMAL + DPNP_FN_RNG_MULTINOMIAL + DPNP_FN_RNG_MULTIVARIATE_NORMAL + DPNP_FN_RNG_NEGATIVE_BINOMIAL + DPNP_FN_RNG_NORMAL + DPNP_FN_RNG_POISSON + DPNP_FN_RNG_RAYLEIGH + DPNP_FN_RNG_STANDARD_CAUCHY + DPNP_FN_RNG_STANDARD_EXPONENTIAL + DPNP_FN_RNG_STANDARD_GAMMA + DPNP_FN_RNG_STANDARD_NORMAL + DPNP_FN_RNG_UNIFORM + DPNP_FN_RNG_WEIBULL DPNP_FN_SIGN DPNP_FN_SIN DPNP_FN_SINH diff --git a/numba_dppy/dpnp_glue/dpnpimpl.py b/numba_dppy/dpnp_glue/dpnpimpl.py index 2df395c970..77f17ed348 100644 --- a/numba_dppy/dpnp_glue/dpnpimpl.py +++ b/numba_dppy/dpnp_glue/dpnpimpl.py @@ -94,23 +94,25 @@ def dpnp_sum_impl(a): free_usm(a_usm, sycl_queue) free_usm(out_usm, sycl_queue) + + _dummy_liveness_func([out.size]) + return out[0] return dpnp_sum_impl -""" @overload(stubs.dpnp.eig) def dpnp_eig_impl(a): dpnp_extension = _DPNP_EXTENSION("eig") + dpctl_functions = _DPCTL_FUNCTIONS() dpnp_eig = dpnp_extension.dpnp_eig("dpnp_eig", [a.dtype.name, "NONE"]) - get_sycl_queue = dpnp_extension.dpctl_get_current_queue() - allocate_usm_shared = dpnp_extension.dpctl_malloc_shared() - copy_usm = dpnp_extension.dpctl_queue_memcpy() - free_usm = dpnp_extension.dpctl_free_with_queue() - + get_sycl_queue = dpctl_functions.dpctl_get_current_queue() + allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() + copy_usm = dpctl_functions.dpctl_queue_memcpy() + free_usm = dpctl_functions.dpctl_free_with_queue() res_dtype = np.float64 if a.dtype == np.float32: @@ -130,7 +132,6 @@ def dpnp_eig_impl(a): if n == 0: return (wr, vr) - print(n, a.itemsize, a.size, wr.size, vr.size) sycl_queue = get_sycl_queue() a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) @@ -152,4 +153,3 @@ def dpnp_eig_impl(a): return (wr, vr) return dpnp_eig_impl -""" From a10d90d9422ea748e8aac1f0c29036197a1da8f0 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Wed, 9 Dec 2020 14:56:05 -0600 Subject: [PATCH 13/34] Separate the implementations into their own category files --- numba_dppy/dpnp_glue/dpnp_linalgimpl.py | 75 +++++++++++ .../dpnp_glue/dpnp_transcendentalsimpl.py | 58 +++++++++ numba_dppy/dpnp_glue/dpnpimpl.py | 120 ------------------ numba_dppy/rename_numpy_functions_pass.py | 3 +- 4 files changed, 135 insertions(+), 121 deletions(-) create mode 100644 numba_dppy/dpnp_glue/dpnp_linalgimpl.py create mode 100644 numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py diff --git a/numba_dppy/dpnp_glue/dpnp_linalgimpl.py b/numba_dppy/dpnp_glue/dpnp_linalgimpl.py new file mode 100644 index 0000000000..db8cb2c036 --- /dev/null +++ b/numba_dppy/dpnp_glue/dpnp_linalgimpl.py @@ -0,0 +1,75 @@ +import numba_dppy.dpnp_glue.dpnpimpl as dpnp_ext +from numba import types +from numba.core.typing import signature +from . import stubs +import numba_dppy.experimental_numpy_lowering_overload as dpnp_lowering +from numba.core.extending import overload, register_jitable +import numpy as np + +class _DPNP_LINALG_EXTENSION: + @classmethod + def dpnp_eig(cls, fn_name, type_names): + ret_type = types.void + sig = signature( + ret_type, types.voidptr, types.voidptr, types.voidptr, types.int64 + ) + f_ptr = dpnp_ext.get_dpnp_fptr(fn_name, type_names) + + def get_pointer(obj): + return f_ptr + + return types.ExternalFunctionPointer(sig, get_pointer=get_pointer) + + +@overload(stubs.dpnp.eig) +def dpnp_eig_impl(a): + dpnp_lowering.ensure_dpnp("eig") + dpnp_extension = _DPNP_LINALG_EXTENSION() + dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() + + dpnp_eig = dpnp_extension.dpnp_eig("dpnp_eig", [a.dtype.name, "NONE"]) + + get_sycl_queue = dpctl_functions.dpctl_get_current_queue() + allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() + copy_usm = dpctl_functions.dpctl_queue_memcpy() + free_usm = dpctl_functions.dpctl_free_with_queue() + + res_dtype = np.float64 + if a.dtype == np.float32: + res_dtype = np.float32 + + def dpnp_eig_impl(a): + n = a.shape[-1] + if a.shape[-2] != n: + msg = "Last 2 dimensions of the array must be square." + raise ValueError(msg) + + dpnp_ext._check_finite_matrix(a) + + wr = np.empty(n, dtype=res_dtype) + vr = np.empty((n, n), dtype=res_dtype) + + if n == 0: + return (wr, vr) + + sycl_queue = get_sycl_queue() + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + wr_usm = allocate_usm_shared(wr.size * wr.itemsize, sycl_queue) + vr_usm = allocate_usm_shared(vr.size * vr.itemsize, sycl_queue) + + dpnp_eig(a_usm, wr_usm, vr_usm, n) + + copy_usm(sycl_queue, wr.ctypes, wr_usm, wr.size * wr.itemsize) + copy_usm(sycl_queue, vr.ctypes, vr_usm, vr.size * vr.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(wr_usm, sycl_queue) + free_usm(vr_usm, sycl_queue) + + dpnp_ext._dummy_liveness_func([wr.size, vr.size]) + + return (wr, vr) + + return dpnp_eig_impl diff --git a/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py b/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py new file mode 100644 index 0000000000..562b16798b --- /dev/null +++ b/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py @@ -0,0 +1,58 @@ +import numba_dppy.dpnp_glue.dpnpimpl as dpnp_ext +from numba import types +from numba.core.typing import signature +from . import stubs +import numba_dppy.experimental_numpy_lowering_overload as dpnp_lowering +from numba.core.extending import overload, register_jitable +import numpy as np + +class _DPNP_TRANSCENDENTALS_EXTENSION: + @classmethod + def dpnp_sum(cls, fn_name, type_names): + ret_type = types.void + sig = signature(ret_type, types.voidptr, types.voidptr, types.int64) + f_ptr = dpnp_ext.get_dpnp_fptr(fn_name, type_names) + + def get_pointer(obj): + return f_ptr + + return types.ExternalFunctionPointer(sig, get_pointer=get_pointer) + + +@overload(stubs.dpnp.sum) +def dpnp_sum_impl(a): + dpnp_lowering.ensure_dpnp("sum") + dpnp_extension = _DPNP_TRANSCENDENTALS_EXTENSION() + dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() + + dpnp_sum = dpnp_extension.dpnp_sum("dpnp_sum", [a.dtype.name, "NONE"]) + + get_sycl_queue = dpctl_functions.dpctl_get_current_queue() + allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() + copy_usm = dpctl_functions.dpctl_queue_memcpy() + free_usm = dpctl_functions.dpctl_free_with_queue() + + def dpnp_sum_impl(a): + if a.size == 0: + raise ValueError("Passed Empty array") + + sycl_queue = get_sycl_queue() + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + out_usm = allocate_usm_shared(a.itemsize, sycl_queue) + + dpnp_sum(a_usm, out_usm, a.size) + + out = np.empty(1, dtype=a.dtype) + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + + dpnp_ext._dummy_liveness_func([out.size]) + + return out[0] + + return dpnp_sum_impl diff --git a/numba_dppy/dpnp_glue/dpnpimpl.py b/numba_dppy/dpnp_glue/dpnpimpl.py index 77f17ed348..97f6d0a7ac 100644 --- a/numba_dppy/dpnp_glue/dpnpimpl.py +++ b/numba_dppy/dpnp_glue/dpnpimpl.py @@ -33,123 +33,3 @@ def __init__(self, fn_name, type_names, sig, get_pointer): self.fn_name = fn_name self.type_names = type_names super(RetrieveDpnpFnPtr, self).__init__(sig, get_pointer) - - -class _DPNP_EXTENSION: - def __init__(self, name): - dpnp_lowering.ensure_dpnp(name) - - @classmethod - def dpnp_sum(cls, fn_name, type_names): - ret_type = types.void - sig = signature(ret_type, types.voidptr, types.voidptr, types.int64) - f_ptr = get_dpnp_fptr(fn_name, type_names) - - def get_pointer(obj): - return f_ptr - - return types.ExternalFunctionPointer(sig, get_pointer=get_pointer) - - @classmethod - def dpnp_eig(cls, fn_name, type_names): - ret_type = types.void - sig = signature( - ret_type, types.voidptr, types.voidptr, types.voidptr, types.int64 - ) - f_ptr = get_dpnp_fptr(fn_name, type_names) - - def get_pointer(obj): - return f_ptr - - return types.ExternalFunctionPointer(sig, get_pointer=get_pointer) - - -@overload(stubs.dpnp.sum) -def dpnp_sum_impl(a): - dpnp_extension = _DPNP_EXTENSION("sum") - dpctl_functions = _DPCTL_FUNCTIONS() - - dpnp_sum = dpnp_extension.dpnp_sum("dpnp_sum", [a.dtype.name, "NONE"]) - - get_sycl_queue = dpctl_functions.dpctl_get_current_queue() - allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() - copy_usm = dpctl_functions.dpctl_queue_memcpy() - free_usm = dpctl_functions.dpctl_free_with_queue() - - def dpnp_sum_impl(a): - if a.size == 0: - raise ValueError("Passed Empty array") - - sycl_queue = get_sycl_queue() - a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) - copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) - - out_usm = allocate_usm_shared(a.itemsize, sycl_queue) - - dpnp_sum(a_usm, out_usm, a.size) - - out = np.empty(1, dtype=a.dtype) - copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) - - free_usm(a_usm, sycl_queue) - free_usm(out_usm, sycl_queue) - - - _dummy_liveness_func([out.size]) - - return out[0] - - return dpnp_sum_impl - - -@overload(stubs.dpnp.eig) -def dpnp_eig_impl(a): - dpnp_extension = _DPNP_EXTENSION("eig") - dpctl_functions = _DPCTL_FUNCTIONS() - - dpnp_eig = dpnp_extension.dpnp_eig("dpnp_eig", [a.dtype.name, "NONE"]) - - get_sycl_queue = dpctl_functions.dpctl_get_current_queue() - allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() - copy_usm = dpctl_functions.dpctl_queue_memcpy() - free_usm = dpctl_functions.dpctl_free_with_queue() - - res_dtype = np.float64 - if a.dtype == np.float32: - res_dtype = np.float32 - - def dpnp_eig_impl(a): - n = a.shape[-1] - if a.shape[-2] != n: - msg = "Last 2 dimensions of the array must be square." - raise ValueError(msg) - - _check_finite_matrix(a) - - wr = np.empty(n, dtype=res_dtype) - vr = np.empty((n, n), dtype=res_dtype) - - if n == 0: - return (wr, vr) - - sycl_queue = get_sycl_queue() - a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) - copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) - - wr_usm = allocate_usm_shared(wr.size * wr.itemsize, sycl_queue) - vr_usm = allocate_usm_shared(vr.size * vr.itemsize, sycl_queue) - - dpnp_eig(a_usm, wr_usm, vr_usm, n) - - copy_usm(sycl_queue, wr.ctypes, wr_usm, wr.size * wr.itemsize) - copy_usm(sycl_queue, vr.ctypes, vr_usm, vr.size * vr.itemsize) - - free_usm(a_usm, sycl_queue) - free_usm(wr_usm, sycl_queue) - free_usm(vr_usm, sycl_queue) - - _dummy_liveness_func([wr.size, vr.size]) - - return (wr, vr) - - return dpnp_eig_impl diff --git a/numba_dppy/rename_numpy_functions_pass.py b/numba_dppy/rename_numpy_functions_pass.py index 0117fb3297..329003f881 100644 --- a/numba_dppy/rename_numpy_functions_pass.py +++ b/numba_dppy/rename_numpy_functions_pass.py @@ -110,7 +110,8 @@ class DPPYRewriteOverloadedFunctions(FunctionPass): def __init__(self): FunctionPass.__init__(self) import numba_dppy.dpnp_glue.dpnpdecl - import numba_dppy.dpnp_glue.dpnpimpl + import numba_dppy.dpnp_glue.dpnp_linalgimpl + import numba_dppy.dpnp_glue.dpnp_transcendentalsimpl def run_pass(self, state): rewrite_function_name_pass = RewriteNumPyOverloadedFunctions( From aa96e28c9fd642e06e08876140602a5c0572ccb3 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Wed, 9 Dec 2020 16:25:43 -0600 Subject: [PATCH 14/34] Fix float32 precision --- numba_dppy/dpnp_glue/dpnp_linalgimpl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numba_dppy/dpnp_glue/dpnp_linalgimpl.py b/numba_dppy/dpnp_glue/dpnp_linalgimpl.py index db8cb2c036..1bee46918b 100644 --- a/numba_dppy/dpnp_glue/dpnp_linalgimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_linalgimpl.py @@ -35,7 +35,7 @@ def dpnp_eig_impl(a): free_usm = dpctl_functions.dpctl_free_with_queue() res_dtype = np.float64 - if a.dtype == np.float32: + if a.dtype == types.float32: res_dtype = np.float32 def dpnp_eig_impl(a): From 67663d7158df53d3f4cf1395a8b0bf69321e4342 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Wed, 9 Dec 2020 16:43:45 -0600 Subject: [PATCH 15/34] Added test for eigen --- numba_dppy/tests/test_dpnp_functions.py | 50 +++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/numba_dppy/tests/test_dpnp_functions.py b/numba_dppy/tests/test_dpnp_functions.py index b0837f5ba6..1db1edb061 100644 --- a/numba_dppy/tests/test_dpnp_functions.py +++ b/numba_dppy/tests/test_dpnp_functions.py @@ -9,6 +9,7 @@ from numba_dppy.testing import unittest from numba_dppy.testing import DPPYTestCase +import dpctl def test_for_different_datatypes(fn, test_fn, dims, arg_count, tys, np_all=False, matrix=None): if arg_count == 1: @@ -74,8 +75,57 @@ def ensure_dpnp(): except: return False +# From https://github.com/IntelPython/dpnp/blob/master/tests/test_linalg.py +def vvsort(val, vec, size): + for i in range(size): + imax = i + for j in range(i + 1, size): + if np.abs(val[imax]) < np.abs(val[j]): + imax = j + + temp = val[i] + val[i] = val[imax] + val[imax] = temp + + for k in range(size): + temp = vec[k, i] + vec[k, i] = vec[k, imax] + vec[k, imax] = temp + @unittest.skipUnless(ensure_dpnp(), 'test only when dpNP is available') +class Testdpnp_linalg_functions(unittest.TestCase): + tys = [np.int32, np.uint32, np.int64, np.uint64, np.float, np.double] + def test_eig(self): + @njit + def f(a): + return np.linalg.eig(a) + + size = 3 + for ty in self.tys: + a = np.arange(size * size, dtype=ty).reshape((size, size)) + symm_a = np.tril(a) + np.tril(a, -1).T + np.diag(np.full((size,), size * size, dtype=ty)) + + with dpctl.device_context("opencl:gpu"): + got_val, got_vec = f(symm_a) + + np_val, np_vec = np.linalg.eig(symm_a) + + # sort val/vec by abs value + vvsort(got_val, got_vec, size) + vvsort(np_val, np_vec, size) + + + # NP change sign of vectors + for i in range(np_vec.shape[1]): + if np_vec[0, i] * got_vec[0, i] < 0: + np_vec[:, i] = -np_vec[:, i] + + self.assertTrue(np.allclose(got_val, np_val)) + self.assertTrue(np.allclose(got_vec, np_vec)) + + +@unittest.skipUnless(enusre_dpnp(), 'test only when dpNP is available') class Testdpnp_functions(DPPYTestCase): N = 10 From d6eae93436c8755a9a0fc940e18adcbfb0dcd79c Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Thu, 10 Dec 2020 15:52:23 -0600 Subject: [PATCH 16/34] Added typed pass to rename ndarray.function_name --- .../dpnp_glue/dpnp_transcendentalsimpl.py | 1 - numba_dppy/dppy_passbuilder.py | 9 +- numba_dppy/rename_numpy_functions_pass.py | 110 +++++++++++++++++- .../tests/test_rename_numpy_function_pass.py | 57 +++++++-- 4 files changed, 166 insertions(+), 11 deletions(-) diff --git a/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py b/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py index 562b16798b..d4c91ae794 100644 --- a/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py @@ -50,7 +50,6 @@ def dpnp_sum_impl(a): free_usm(a_usm, sycl_queue) free_usm(out_usm, sycl_queue) - dpnp_ext._dummy_liveness_func([out.size]) return out[0] diff --git a/numba_dppy/dppy_passbuilder.py b/numba_dppy/dppy_passbuilder.py index b3c632a85a..a8c1428256 100644 --- a/numba_dppy/dppy_passbuilder.py +++ b/numba_dppy/dppy_passbuilder.py @@ -27,7 +27,8 @@ DPPYNoPythonBackend ) -from .rename_numpy_functions_pass import DPPYRewriteOverloadedFunctions +from .rename_numpy_functions_pass import (DPPYRewriteOverloadedNumPyFunctions, + DPPYRewriteNdarrayFunctions) class DPPYPassBuilder(object): """ @@ -47,7 +48,7 @@ def default_numba_nopython_pipeline(state, pm): pm.add_pass(WithLifting, "Handle with contexts") # this pass rewrites name of NumPy functions we intend to overload - pm.add_pass(DPPYRewriteOverloadedFunctions, + pm.add_pass(DPPYRewriteOverloadedNumPyFunctions, "Rewrite name of Numpy functions to overload already overloaded function", ) @@ -88,6 +89,10 @@ def default_numba_nopython_pipeline(state, pm): pm.add_pass(NopythonTypeInference, "nopython frontend") pm.add_pass(AnnotateTypes, "annotate types") + pm.add_pass(DPPYRewriteNdarrayFunctions, + "Rewrite ndarray functions to dppy supported functions", + ) + # strip phis pm.add_pass(PreLowerStripPhis, "remove phis nodes") diff --git a/numba_dppy/rename_numpy_functions_pass.py b/numba_dppy/rename_numpy_functions_pass.py index 329003f881..bf8af9b661 100644 --- a/numba_dppy/rename_numpy_functions_pass.py +++ b/numba_dppy/rename_numpy_functions_pass.py @@ -7,6 +7,7 @@ simplify_CFG, ) import numba_dppy +from numba.core import types rewrite_function_name_map = {"sum": (["np"], "sum"), "eig": (["linalg"], "eig")} @@ -104,7 +105,7 @@ def run(self): @register_pass(mutates_CFG=True, analysis_only=False) -class DPPYRewriteOverloadedFunctions(FunctionPass): +class DPPYRewriteOverloadedNumPyFunctions(FunctionPass): _name = "dppy_rewrite_overloaded_functions_pass" def __init__(self): @@ -124,3 +125,110 @@ def run_pass(self, state): state.func_ir.blocks = simplify_CFG(state.func_ir.blocks) return True + + +def get_dpnp_func_typ(func): + from numba.core.typing.templates import builtin_registry + for (k, v) in builtin_registry.globals: + if k == func: + return v + raise RuntimeError("type for func ", func, " not found") + + +class RewriteNdarrayFunctions(object): + def __init__(self, state, rewrite_function_name_map=rewrite_function_name_map): + self.state = state + self.function_name_map = rewrite_function_name_map + self.typemap = state.type_annotation.typemap + self.calltypes = state.type_annotation.calltypes + + def run(self): + typingctx = self.state.typingctx + + # save array arg to call + # call_varname -> array + func_ir = self.state.func_ir + blocks = func_ir.blocks + saved_arr_arg = {} + topo_order = find_topo_order(blocks) + + for label in topo_order: + block = blocks[label] + new_body = [] + for stmt in block.body: + if isinstance(stmt, ir.Assign) and isinstance(stmt.value, ir.Expr): + lhs = stmt.target.name + rhs = stmt.value + # replace A.func with np.func, and save A in saved_arr_arg + if (rhs.op == 'getattr' and rhs.attr in self.function_name_map + and isinstance( + self.typemap[rhs.value.name], types.npytypes.Array)): + rhs = stmt.value + arr = rhs.value + saved_arr_arg[lhs] = arr + scope = arr.scope + loc = arr.loc + + g_dppy_var = ir.Var(scope, mk_unique_var("$load_global"), loc) + self.typemap[g_dppy_var.name] = types.misc.Module(numba_dppy) + g_dppy = ir.Global("numba_dppy", numba_dppy, loc) + g_dppy_assign = ir.Assign(g_dppy, g_dppy_var, loc) + + dpnp_var = ir.Var(scope, mk_unique_var("$load_attr"), loc) + self.typemap[dpnp_var.name] = types.misc.Module(numba_dppy.dpnp) + getattr_dpnp = ir.Expr.getattr(g_dppy_var, "dpnp", loc) + dpnp_assign = ir.Assign(getattr_dpnp, dpnp_var, loc) + + rhs.value = dpnp_var + new_body.append(g_dppy_assign) + new_body.append(dpnp_assign) + + func_ir._definitions[g_dppy_var.name] = [getattr_dpnp] + func_ir._definitions[dpnp_var.name] = [getattr_dpnp] + + # update func var type + func = getattr(numba_dppy.dpnp, rhs.attr) + func_typ = get_dpnp_func_typ(func) + + self.typemap.pop(lhs) + self.typemap[lhs] = func_typ + + if rhs.op == 'call' and rhs.func.name in saved_arr_arg: + # add array as first arg + arr = saved_arr_arg[rhs.func.name] + # update call type signature to include array arg + old_sig = self.calltypes.pop(rhs) + # argsort requires kws for typing so sig.args can't be used + # reusing sig.args since some types become Const in sig + argtyps = old_sig.args[:len(rhs.args)] + kwtyps = {name: self.typemap[v.name] for name, v in rhs.kws} + self.calltypes[rhs] = self.typemap[rhs.func.name].get_call_type( + typingctx, [self.typemap[arr.name]] + list(argtyps), kwtyps) + rhs.args = [arr] + rhs.args + + new_body.append(stmt) + block.body = new_body + return + + + +@register_pass(mutates_CFG=True, analysis_only=False) +class DPPYRewriteNdarrayFunctions(FunctionPass): + _name = "dppy_rewrite_ndarray_functions_pass" + + def __init__(self): + FunctionPass.__init__(self) + + def run_pass(self, state): + rewrite_ndarray_function_name_pass = RewriteNdarrayFunctions( + state, rewrite_function_name_map + ) + + rewrite_ndarray_function_name_pass.run() + + remove_dead(state.func_ir.blocks, state.func_ir.arg_names, state.func_ir) + state.func_ir.blocks = simplify_CFG(state.func_ir.blocks) + + return True + + diff --git a/numba_dppy/tests/test_rename_numpy_function_pass.py b/numba_dppy/tests/test_rename_numpy_function_pass.py index b06a03b5e0..f9588481b7 100644 --- a/numba_dppy/tests/test_rename_numpy_function_pass.py +++ b/numba_dppy/tests/test_rename_numpy_function_pass.py @@ -4,18 +4,32 @@ import numpy as np import numba -from numba import njit, prange +from numba import njit, typeof import numba_dppy, numba_dppy as dppy -from numba.core import compiler -from numba_dppy.rename_numpy_functions_pass import DPPYRewriteOverloadedFunctions +from numba.core import (compiler, typing, cpu) +from numba_dppy.rename_numpy_functions_pass import (DPPYRewriteOverloadedNumPyFunctions, + DPPYRewriteNdarrayFunctions) +from numba.core.typed_passes import (NopythonTypeInference, AnnotateTypes) class MyPipeline(object): - def __init__(self, test_ir): + def __init__(self, test_ir, args): self.state = compiler.StateDict() + self.state.typingctx = typing.Context() + self.state.targetctx = cpu.CPUContext(self.state.typingctx) self.state.func_ir = test_ir + self.state.func_id = test_ir.func_id + self.state.args = args + self.state.return_type = None + self.state.locals = dict() + self.state.status = None + self.state.lifted = dict() + self.state.lifted_from = None + + self.state.typingctx.refresh() + self.state.targetctx.refresh() def check_equivalent(expected_ir, got_ir): @@ -45,7 +59,7 @@ def check_equivalent(expected_ir, got_ir): class TestRenameNumpyFunctionsPass(unittest.TestCase): - def test_rename(self): + def test_rename_numpy(self): def expected(a): return numba_dppy.dpnp.sum(a) @@ -55,13 +69,42 @@ def got(a): expected_ir = compiler.run_frontend(expected) got_ir = compiler.run_frontend(got) - pipeline = MyPipeline(got_ir) + pipeline = MyPipeline(got_ir, None) - rewrite_numpy_functions_pass = DPPYRewriteOverloadedFunctions() + rewrite_numpy_functions_pass = DPPYRewriteOverloadedNumPyFunctions() rewrite_numpy_functions_pass.run_pass(pipeline.state) self.assertTrue(check_equivalent(expected_ir, pipeline.state.func_ir)) +class TestRenameNdarrayFunctionsPass(unittest.TestCase): + def test_rename_ndarray(self): + def expected(a): + return numba_dppy.dpnp.sum(a) + + def got(a): + return a.sum() + + expected_ir = compiler.run_frontend(expected) + got_ir = compiler.run_frontend(got) + + a = np.arange(10) + args = [a] + argtypes = [typeof(x) for x in args] + + pipeline = MyPipeline(got_ir, argtypes) + + tyinfer_pass = NopythonTypeInference() + tyinfer_pass.run_pass(pipeline.state) + + annotate_ty_pass = AnnotateTypes() + annotate_ty_pass.run_pass(pipeline.state) + + rewrite_ndarray_functions_pass = DPPYRewriteNdarrayFunctions() + rewrite_ndarray_functions_pass.run_pass(pipeline.state) + + self.assertTrue(check_equivalent(expected_ir, pipeline.state.func_ir)) + + if __name__ == "__main__": unittest.main() From 66974a1375cabb835affef08db121b957180e394 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Thu, 10 Dec 2020 16:35:45 -0600 Subject: [PATCH 17/34] Added test for ndarray.sum --- numba_dppy/tests/test_dpnp_functions.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/numba_dppy/tests/test_dpnp_functions.py b/numba_dppy/tests/test_dpnp_functions.py index 1db1edb061..86691625b3 100644 --- a/numba_dppy/tests/test_dpnp_functions.py +++ b/numba_dppy/tests/test_dpnp_functions.py @@ -125,7 +125,25 @@ def f(a): self.assertTrue(np.allclose(got_vec, np_vec)) -@unittest.skipUnless(enusre_dpnp(), 'test only when dpNP is available') +@unittest.skipUnless(ensure_dpnp(), 'test only when dpNP is available') +class Testdpnp_ndarray_functions(unittest.TestCase): + tys = [np.int32, np.uint32, np.int64, np.uint64, np.float, np.double] + def test_ndarray_sum(self): + @njit + def f(a): + return a.sum() + + size = 3 + for ty in self.tys: + a = np.arange(size * size, dtype=ty).reshape((size, size)) + + with dpctl.device_context("opencl:gpu"): + got = f(a) + expected = a.sum() + + self.assertTrue(expected == got) + +@unittest.skipUnless(ensure_dpnp(), 'test only when dpNP is available') class Testdpnp_functions(DPPYTestCase): N = 10 From 1b7833683d922e74ceabd08f87f102c0b3a6d593 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Fri, 11 Dec 2020 17:23:31 -0600 Subject: [PATCH 18/34] Started inital port --- numba_dppy/dpnp_glue/dpnp_linalgimpl.py | 32 ++++---- numba_dppy/dpnp_glue/dpnp_statisticsimpl.py | 64 ++++++++++++++++ .../dpnp_glue/dpnp_transcendentalsimpl.py | 73 +++++++++++++++---- numba_dppy/dpnp_glue/dpnpdecl.py | 8 ++ numba_dppy/dpnp_glue/dpnpimpl.py | 32 +++++--- numba_dppy/dpnp_glue/stubs.py | 9 +++ numba_dppy/rename_numpy_functions_pass.py | 9 ++- numba_dppy/tests/test_dpnp_functions.py | 45 ++++++++++++ 8 files changed, 231 insertions(+), 41 deletions(-) create mode 100644 numba_dppy/dpnp_glue/dpnp_statisticsimpl.py diff --git a/numba_dppy/dpnp_glue/dpnp_linalgimpl.py b/numba_dppy/dpnp_glue/dpnp_linalgimpl.py index 1bee46918b..1d9cc356c3 100644 --- a/numba_dppy/dpnp_glue/dpnp_linalgimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_linalgimpl.py @@ -5,29 +5,26 @@ import numba_dppy.experimental_numpy_lowering_overload as dpnp_lowering from numba.core.extending import overload, register_jitable import numpy as np - -class _DPNP_LINALG_EXTENSION: - @classmethod - def dpnp_eig(cls, fn_name, type_names): - ret_type = types.void - sig = signature( - ret_type, types.voidptr, types.voidptr, types.voidptr, types.int64 - ) - f_ptr = dpnp_ext.get_dpnp_fptr(fn_name, type_names) - - def get_pointer(obj): - return f_ptr - - return types.ExternalFunctionPointer(sig, get_pointer=get_pointer) - +from numba_dppy.dpctl_functions import _DPCTL_FUNCTIONS @overload(stubs.dpnp.eig) def dpnp_eig_impl(a): dpnp_lowering.ensure_dpnp("eig") - dpnp_extension = _DPNP_LINALG_EXTENSION() dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() - dpnp_eig = dpnp_extension.dpnp_eig("dpnp_eig", [a.dtype.name, "NONE"]) + ret_type = types.void + """ + dpnp source: + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels.cpp#L180 + + Function declaration: + void dpnp_eig_c(const void* array_in, void* result1, void* result2, size_t size) + + """ + sig = signature( + ret_type, types.voidptr, types.voidptr, types.voidptr, types.intp + ) + dpnp_eig = dpnp_ext.dpnp_func("dpnp_eig", [a.dtype.name, "NONE"], sig) get_sycl_queue = dpctl_functions.dpctl_get_current_queue() allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() @@ -69,6 +66,7 @@ def dpnp_eig_impl(a): free_usm(vr_usm, sycl_queue) dpnp_ext._dummy_liveness_func([wr.size, vr.size]) + print("CCCC") return (wr, vr) diff --git a/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py b/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py new file mode 100644 index 0000000000..19d7a6d951 --- /dev/null +++ b/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py @@ -0,0 +1,64 @@ +import numba_dppy.dpnp_glue.dpnpimpl as dpnp_ext +from numba.core import types, cgutils +from numba.core.typing import signature +from . import stubs +import numba_dppy.experimental_numpy_lowering_overload as dpnp_lowering +from numba.core.extending import overload, register_jitable +import numpy as np + +@overload(stubs.dpnp.max) +@overload(stubs.dpnp.amax) +def dpnp_amax_impl(a): + dpnp_lowering.ensure_dpnp("amax") + dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() + + ret_type = types.void + """ + dpnp source: + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_statistics.cpp + + Function declaration: + void custom_max_c(void* array1_in, void* result1, const size_t* shape, + size_t ndim, const size_t* axis, size_t naxis) + + We are using void * in case of size_t * as Numba currently does not have + any type to represent size_t *. Since, both the types are pointers, + if the compiler allows there should not be any mismatch in the size of + the container to hold different types of pointer. + """ + sig = signature(ret_type, types.voidptr, types.voidptr, + types.voidptr, types.intp, + types.voidptr, types.intp) + dpnp_max = dpnp_ext.dpnp_func("dpnp_max", [a.dtype.name, "NONE"], sig) + + get_sycl_queue = dpctl_functions.dpctl_get_current_queue() + allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() + copy_usm = dpctl_functions.dpctl_queue_memcpy() + free_usm = dpctl_functions.dpctl_free_with_queue() + + + def dpnp_amax_impl(a): + if a.size == 0: + raise ValueError("Passed Empty array") + + sycl_queue = get_sycl_queue() + + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + out_usm = allocate_usm_shared(a.itemsize, sycl_queue) + + dpnp_max(a_usm, out_usm, a.shapeptr, a.ndim, a.shapeptr, a.ndim) + + out = np.empty(1, dtype=a.dtype) + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + dpnp_ext._dummy_liveness_func([out.size]) + + print("DDD") + return out[0] + + return dpnp_amax_impl diff --git a/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py b/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py index d4c91ae794..f3d1ae69be 100644 --- a/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py @@ -6,26 +6,23 @@ from numba.core.extending import overload, register_jitable import numpy as np -class _DPNP_TRANSCENDENTALS_EXTENSION: - @classmethod - def dpnp_sum(cls, fn_name, type_names): - ret_type = types.void - sig = signature(ret_type, types.voidptr, types.voidptr, types.int64) - f_ptr = dpnp_ext.get_dpnp_fptr(fn_name, type_names) - - def get_pointer(obj): - return f_ptr - - return types.ExternalFunctionPointer(sig, get_pointer=get_pointer) - @overload(stubs.dpnp.sum) def dpnp_sum_impl(a): dpnp_lowering.ensure_dpnp("sum") - dpnp_extension = _DPNP_TRANSCENDENTALS_EXTENSION() dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() - dpnp_sum = dpnp_extension.dpnp_sum("dpnp_sum", [a.dtype.name, "NONE"]) + ret_type = types.void + """ + dpnp source: + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_reduction.cpp#L39 + + Function declaration: + void custom_sum_c(void* array1_in, void* result1, size_t size) + + """ + sig = signature(ret_type, types.voidptr, types.voidptr, types.intp) + dpnp_sum = dpnp_ext.dpnp_func("dpnp_sum", [a.dtype.name, "NONE"], sig) get_sycl_queue = dpctl_functions.dpctl_get_current_queue() allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() @@ -52,6 +49,54 @@ def dpnp_sum_impl(a): dpnp_ext._dummy_liveness_func([out.size]) + print("AAAAA") return out[0] return dpnp_sum_impl + + +@overload(stubs.dpnp.prod) +def dpnp_prod_impl(a): + dpnp_lowering.ensure_dpnp("prod") + dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() + + ret_type = types.void + """ + dpnp source: + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_reduction.cpp#L83 + + Function declaration: + void custom_prod_c(void* array1_in, void* result1, size_t size) + """ + sig = signature(ret_type, types.voidptr, types.voidptr, types.intp) + dpnp_prod = dpnp_ext.dpnp_func("dpnp_prod", [a.dtype.name, "NONE"], sig) + + get_sycl_queue = dpctl_functions.dpctl_get_current_queue() + allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() + copy_usm = dpctl_functions.dpctl_queue_memcpy() + free_usm = dpctl_functions.dpctl_free_with_queue() + + def dpnp_prod_impl(a): + if a.size == 0: + raise ValueError("Passed Empty array") + + sycl_queue = get_sycl_queue() + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + out_usm = allocate_usm_shared(a.itemsize, sycl_queue) + + dpnp_prod(a_usm, out_usm, a.size) + + out = np.empty(1, dtype=a.dtype) + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + dpnp_ext._dummy_liveness_func([out.size]) + + print("BBB") + return out[0] + + return dpnp_prod_impl diff --git a/numba_dppy/dpnp_glue/dpnpdecl.py b/numba_dppy/dpnp_glue/dpnpdecl.py index e77739eeda..1f2cfca281 100644 --- a/numba_dppy/dpnp_glue/dpnpdecl.py +++ b/numba_dppy/dpnp_glue/dpnpdecl.py @@ -1,6 +1,7 @@ from numba.core.typing.templates import (AttributeTemplate, infer_getattr) import numba_dppy from numba import types +from numba.core.types.misc import RawPointer @infer_getattr class DppyDpnpTemplate(AttributeTemplate): @@ -8,3 +9,10 @@ class DppyDpnpTemplate(AttributeTemplate): def resolve_dpnp(self, mod): return types.Module(numba_dppy.dpnp) + +@infer_getattr +class ArrayAttribute(AttributeTemplate): + key = types.Array + + def resolve_shapeptr(self, ary): + return types.voidptr diff --git a/numba_dppy/dpnp_glue/dpnpimpl.py b/numba_dppy/dpnp_glue/dpnpimpl.py index 97f6d0a7ac..dff440103c 100644 --- a/numba_dppy/dpnp_glue/dpnpimpl.py +++ b/numba_dppy/dpnp_glue/dpnpimpl.py @@ -1,12 +1,15 @@ from numba.core.imputils import lower_builtin import numba_dppy.experimental_numpy_lowering_overload as dpnp_lowering -from numba import types +from numba.core import types from numba.core.typing import signature from numba.core.extending import overload, register_jitable from . import stubs import numpy as np from numba_dppy.dpctl_functions import _DPCTL_FUNCTIONS +from llvmlite import ir +from numba.core.imputils import lower_getattr +ll_void_p = ir.IntType(8).as_pointer() def get_dpnp_fptr(fn_name, type_names): from . import dpnp_fptr_interface as dpnp_glue @@ -14,22 +17,33 @@ def get_dpnp_fptr(fn_name, type_names): f_ptr = dpnp_glue.get_dpnp_fn_ptr(fn_name, type_names) return f_ptr - @register_jitable def _check_finite_matrix(a): for v in np.nditer(a): if not np.isfinite(v.item()): raise np.linalg.LinAlgError("Array must not contain infs or NaNs.") - @register_jitable def _dummy_liveness_func(a): """pass a list of variables to be preserved through dead code elimination""" return a[0] - -class RetrieveDpnpFnPtr(types.ExternalFunctionPointer): - def __init__(self, fn_name, type_names, sig, get_pointer): - self.fn_name = fn_name - self.type_names = type_names - super(RetrieveDpnpFnPtr, self).__init__(sig, get_pointer) +def dpnp_func(fn_name, type_names, sig): + f_ptr = get_dpnp_fptr(fn_name, type_names) + + def get_pointer(obj): + return f_ptr + + return types.ExternalFunctionPointer(sig, get_pointer=get_pointer) + +""" +This function retrieves the pointer to the structure where the shape +of an ndarray is stored. We cast it to void * to make it easier to +pass around. +""" +@lower_getattr(types.Array, "shapeptr") +def array_shape(context, builder, typ, value): + shape_ptr = builder.gep(value.operands[0], + [context.get_constant(types.int32, 0), + context.get_constant(types.int32, 5)]) + return builder.bitcast(shape_ptr, ll_void_p) diff --git a/numba_dppy/dpnp_glue/stubs.py b/numba_dppy/dpnp_glue/stubs.py index 041a30c074..30166c32e0 100644 --- a/numba_dppy/dpnp_glue/stubs.py +++ b/numba_dppy/dpnp_glue/stubs.py @@ -10,3 +10,12 @@ class sum(Stub): class eig(Stub): pass + + class prod(Stub): + pass + + class max(Stub): + pass + + class amax(Stub): + pass diff --git a/numba_dppy/rename_numpy_functions_pass.py b/numba_dppy/rename_numpy_functions_pass.py index bf8af9b661..a17dd668cb 100644 --- a/numba_dppy/rename_numpy_functions_pass.py +++ b/numba_dppy/rename_numpy_functions_pass.py @@ -9,7 +9,11 @@ import numba_dppy from numba.core import types -rewrite_function_name_map = {"sum": (["np"], "sum"), "eig": (["linalg"], "eig")} +rewrite_function_name_map = {"sum": (["np"], "sum"), + "eig": (["linalg"], "eig"), + "prod": (["np"], "prod"), + "max": (["np"], "max"), + "amax": (["np"], "amax")} class RewriteNumPyOverloadedFunctions(object): @@ -110,9 +114,12 @@ class DPPYRewriteOverloadedNumPyFunctions(FunctionPass): def __init__(self): FunctionPass.__init__(self) + import numba_dppy.dpnp_glue.dpnpdecl + import numba_dppy.dpnp_glue.dpnpimpl import numba_dppy.dpnp_glue.dpnp_linalgimpl import numba_dppy.dpnp_glue.dpnp_transcendentalsimpl + import numba_dppy.dpnp_glue.dpnp_statisticsimpl def run_pass(self, state): rewrite_function_name_pass = RewriteNumPyOverloadedFunctions( diff --git a/numba_dppy/tests/test_dpnp_functions.py b/numba_dppy/tests/test_dpnp_functions.py index ff5c0fb63f..dd60b5b0af 100644 --- a/numba_dppy/tests/test_dpnp_functions.py +++ b/numba_dppy/tests/test_dpnp_functions.py @@ -156,6 +156,38 @@ def f(a): self.assertTrue(expected == got) + def test_ndarray_prod(self): + @njit + def f(a): + return a.prod() + + size = 3 + for ty in self.tys: + a = np.arange(1, (size * size) + 1, dtype=ty).reshape((size, size)) + + with dpctl.device_context("opencl:gpu"): + got = f(a) + expected = a.prod() + + self.assertTrue(expected == got) + + def test_ndarray_max(self): + @njit + def f(a): + return a.max() + + size = 3 + for ty in self.tys: + a = np.arange(1, (size * size) + 1, dtype=ty).reshape((size, size)) + + with dpctl.device_context("opencl:gpu"): + got = f(a) + expected = a.max() + + self.assertTrue(expected == got) + + + @unittest.skipUnless(ensure_dpnp() and dpctl.has_gpu_queues(), 'test only when dpNP and GPU is available') class Testdpnp_functions(unittest.TestCase): @@ -210,6 +242,19 @@ def f(a): self.assertTrue(test_for_dimensions(f, np.max, [10, 2], self.tys)) self.assertTrue(test_for_dimensions(f, np.max, [10, 2, 3], self.tys)) + def test_amax(self): + @njit + def f(a): + c = np.amax(a) + return c + + self.assertTrue(test_for_different_datatypes( + f, np.amax, [10], 1, self.tys)) + self.assertTrue(test_for_dimensions(f, np.amax, [10, 2], self.tys)) + self.assertTrue(test_for_dimensions(f, np.amax, [10, 2, 3], self.tys)) + + + def test_argmin(self): @njit def f(a): From fb03df8b6ad8293cd84bbab64460730b4acd70b4 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Mon, 14 Dec 2020 10:33:51 -0600 Subject: [PATCH 19/34] Add min, amin, ndarray.min --- numba_dppy/dpnp_glue/dpnp_statisticsimpl.py | 62 ++++++++++++++++++++- numba_dppy/dpnp_glue/dpnpdecl.py | 5 ++ numba_dppy/dpnp_glue/stubs.py | 6 ++ numba_dppy/rename_numpy_functions_pass.py | 4 +- numba_dppy/tests/test_dpnp_functions.py | 26 ++++++++- 5 files changed, 100 insertions(+), 3 deletions(-) diff --git a/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py b/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py index 19d7a6d951..45374ddb18 100644 --- a/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py @@ -15,7 +15,7 @@ def dpnp_amax_impl(a): ret_type = types.void """ dpnp source: - https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_statistics.cpp + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_statistics.cpp#L129 Function declaration: void custom_max_c(void* array1_in, void* result1, const size_t* shape, @@ -62,3 +62,63 @@ def dpnp_amax_impl(a): return out[0] return dpnp_amax_impl + + +@overload(stubs.dpnp.min) +@overload(stubs.dpnp.amin) +def dpnp_amin_impl(a): + dpnp_lowering.ensure_dpnp("amin") + dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() + + ret_type = types.void + """ + dpnp source: + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_statistics.cpp#L247 + + Function declaration: + void custom_min_c(void* array1_in, void* result1, const size_t* shape, + size_t ndim, const size_t* axis, size_t naxis) + + We are using void * in case of size_t * as Numba currently does not have + any type to represent size_t *. Since, both the types are pointers, + if the compiler allows there should not be any mismatch in the size of + the container to hold different types of pointer. + """ + sig = signature(ret_type, types.voidptr, types.voidptr, + types.voidptr, types.intp, + types.voidptr, types.intp) + dpnp_max = dpnp_ext.dpnp_func("dpnp_min", [a.dtype.name, "NONE"], sig) + + get_sycl_queue = dpctl_functions.dpctl_get_current_queue() + allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() + copy_usm = dpctl_functions.dpctl_queue_memcpy() + free_usm = dpctl_functions.dpctl_free_with_queue() + + + def dpnp_amin_impl(a): + if a.size == 0: + raise ValueError("Passed Empty array") + + sycl_queue = get_sycl_queue() + + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + out_usm = allocate_usm_shared(a.itemsize, sycl_queue) + + dpnp_max(a_usm, out_usm, a.shapeptr, a.ndim, a.shapeptr, 0) + + out = np.empty(1, dtype=a.dtype) + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + dpnp_ext._dummy_liveness_func([out.size]) + + print("EEE") + return out[0] + + return dpnp_amin_impl + + diff --git a/numba_dppy/dpnp_glue/dpnpdecl.py b/numba_dppy/dpnp_glue/dpnpdecl.py index 1f2cfca281..ce1f7d3583 100644 --- a/numba_dppy/dpnp_glue/dpnpdecl.py +++ b/numba_dppy/dpnp_glue/dpnpdecl.py @@ -10,6 +10,11 @@ class DppyDpnpTemplate(AttributeTemplate): def resolve_dpnp(self, mod): return types.Module(numba_dppy.dpnp) +""" +This adds a shapeptr attribute to Numba type representing np.ndarray. +This allows us to get the raw pointer to the structure where the shape +of an ndarray is stored from an overloaded implementation +""" @infer_getattr class ArrayAttribute(AttributeTemplate): key = types.Array diff --git a/numba_dppy/dpnp_glue/stubs.py b/numba_dppy/dpnp_glue/stubs.py index 30166c32e0..11a000a749 100644 --- a/numba_dppy/dpnp_glue/stubs.py +++ b/numba_dppy/dpnp_glue/stubs.py @@ -19,3 +19,9 @@ class max(Stub): class amax(Stub): pass + + class min(Stub): + pass + + class amin(Stub): + pass diff --git a/numba_dppy/rename_numpy_functions_pass.py b/numba_dppy/rename_numpy_functions_pass.py index a17dd668cb..b85fba0365 100644 --- a/numba_dppy/rename_numpy_functions_pass.py +++ b/numba_dppy/rename_numpy_functions_pass.py @@ -13,7 +13,9 @@ "eig": (["linalg"], "eig"), "prod": (["np"], "prod"), "max": (["np"], "max"), - "amax": (["np"], "amax")} + "amax": (["np"], "amax"), + "min": (["np"], "min"), + "amin": (["np"], "amin")} class RewriteNumPyOverloadedFunctions(object): diff --git a/numba_dppy/tests/test_dpnp_functions.py b/numba_dppy/tests/test_dpnp_functions.py index dd60b5b0af..cb1a194dba 100644 --- a/numba_dppy/tests/test_dpnp_functions.py +++ b/numba_dppy/tests/test_dpnp_functions.py @@ -186,6 +186,20 @@ def f(a): self.assertTrue(expected == got) + def test_ndarray_min(self): + @njit + def f(a): + return a.min() + + size = 3 + for ty in self.tys: + a = np.arange(1, (size * size) + 1, dtype=ty).reshape((size, size)) + + with dpctl.device_context("opencl:gpu"): + got = f(a) + expected = a.min() + + self.assertTrue(expected == got) @unittest.skipUnless(ensure_dpnp() and dpctl.has_gpu_queues(), 'test only when dpNP and GPU is available') @@ -254,7 +268,6 @@ def f(a): self.assertTrue(test_for_dimensions(f, np.amax, [10, 2, 3], self.tys)) - def test_argmin(self): @njit def f(a): @@ -278,6 +291,17 @@ def f(a): self.assertTrue(test_for_dimensions(f, np.min, [10, 2], self.tys)) self.assertTrue(test_for_dimensions(f, np.min, [10, 2, 3], self.tys)) + def test_amin(self): + @njit + def f(a): + c = np.amin(a) + return c + + self.assertTrue(test_for_different_datatypes( + f, np.min, [10], 1, self.tys)) + self.assertTrue(test_for_dimensions(f, np.min, [10, 2], self.tys)) + self.assertTrue(test_for_dimensions(f, np.min, [10, 2, 3], self.tys)) + def test_argsort(self): @njit def f(a): From 8fced179ed15ffe07318da54b22d8bbf7bc0a752 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Mon, 14 Dec 2020 14:30:43 -0600 Subject: [PATCH 20/34] mean WIP --- numba_dppy/dpnp_glue/dpnp_statisticsimpl.py | 151 ++++++++++++++++-- .../dpnp_glue/dpnp_transcendentalsimpl.py | 22 +-- numba_dppy/dpnp_glue/dpnpimpl.py | 2 + numba_dppy/dpnp_glue/stubs.py | 6 + numba_dppy/dppy_passbuilder.py | 12 +- numba_dppy/dppy_passes.py | 1 - .../experimental_numpy_lowering_overload.py | 3 + numba_dppy/rename_numpy_functions_pass.py | 4 +- 8 files changed, 171 insertions(+), 30 deletions(-) diff --git a/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py b/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py index 45374ddb18..7b17210627 100644 --- a/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py @@ -6,10 +6,12 @@ from numba.core.extending import overload, register_jitable import numpy as np + @overload(stubs.dpnp.max) @overload(stubs.dpnp.amax) def dpnp_amax_impl(a): - dpnp_lowering.ensure_dpnp("amax") + name = "max" + dpnp_lowering.ensure_dpnp(name) dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() ret_type = types.void @@ -29,15 +31,14 @@ def dpnp_amax_impl(a): sig = signature(ret_type, types.voidptr, types.voidptr, types.voidptr, types.intp, types.voidptr, types.intp) - dpnp_max = dpnp_ext.dpnp_func("dpnp_max", [a.dtype.name, "NONE"], sig) + dpnp_func = dpnp_ext.dpnp_func("dpnp_"+name, [a.dtype.name, "NONE"], sig) get_sycl_queue = dpctl_functions.dpctl_get_current_queue() allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() copy_usm = dpctl_functions.dpctl_queue_memcpy() free_usm = dpctl_functions.dpctl_free_with_queue() - - def dpnp_amax_impl(a): + def dpnp_impl(a): if a.size == 0: raise ValueError("Passed Empty array") @@ -48,7 +49,7 @@ def dpnp_amax_impl(a): out_usm = allocate_usm_shared(a.itemsize, sycl_queue) - dpnp_max(a_usm, out_usm, a.shapeptr, a.ndim, a.shapeptr, a.ndim) + dpnp_func(a_usm, out_usm, a.shapeptr, a.ndim, a.shapeptr, a.ndim) out = np.empty(1, dtype=a.dtype) copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) @@ -61,13 +62,14 @@ def dpnp_amax_impl(a): print("DDD") return out[0] - return dpnp_amax_impl + return dpnp_impl @overload(stubs.dpnp.min) @overload(stubs.dpnp.amin) def dpnp_amin_impl(a): - dpnp_lowering.ensure_dpnp("amin") + name = "min" + dpnp_lowering.ensure_dpnp(name) dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() ret_type = types.void @@ -87,15 +89,14 @@ def dpnp_amin_impl(a): sig = signature(ret_type, types.voidptr, types.voidptr, types.voidptr, types.intp, types.voidptr, types.intp) - dpnp_max = dpnp_ext.dpnp_func("dpnp_min", [a.dtype.name, "NONE"], sig) + dpnp_func = dpnp_ext.dpnp_func("dpnp_"+name, [a.dtype.name, "NONE"], sig) get_sycl_queue = dpctl_functions.dpctl_get_current_queue() allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() copy_usm = dpctl_functions.dpctl_queue_memcpy() free_usm = dpctl_functions.dpctl_free_with_queue() - - def dpnp_amin_impl(a): + def dpnp_impl(a): if a.size == 0: raise ValueError("Passed Empty array") @@ -106,7 +107,7 @@ def dpnp_amin_impl(a): out_usm = allocate_usm_shared(a.itemsize, sycl_queue) - dpnp_max(a_usm, out_usm, a.shapeptr, a.ndim, a.shapeptr, 0) + dpnp_func(a_usm, out_usm, a.shapeptr, a.ndim, a.shapeptr, 0) out = np.empty(1, dtype=a.dtype) copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) @@ -119,6 +120,132 @@ def dpnp_amin_impl(a): print("EEE") return out[0] - return dpnp_amin_impl + return dpnp_impl + + +@overload(stubs.dpnp.mean) +def dpnp_mean_impl(a): + name = "mean" + dpnp_lowering.ensure_dpnp(name) + dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() + + ret_type = types.void + """ + dpnp source: + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_statistics.cpp#L169 + + Function declaration: + void custom_mean_c(void* array1_in, void* result1, const size_t* shape, + size_t ndim, const size_t* axis, size_t naxis) + + We are using void * in case of size_t * as Numba currently does not have + any type to represent size_t *. Since, both the types are pointers, + if the compiler allows there should not be any mismatch in the size of + the container to hold different types of pointer. + """ + sig = signature(ret_type, types.voidptr, types.voidptr, + types.voidptr, types.intp, + types.voidptr, types.intp) + dpnp_func = dpnp_ext.dpnp_func("dpnp_"+name, [a.dtype.name, "NONE"], sig) + + get_sycl_queue = dpctl_functions.dpctl_get_current_queue() + allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() + copy_usm = dpctl_functions.dpctl_queue_memcpy() + free_usm = dpctl_functions.dpctl_free_with_queue() + + res_dtype = np.float64 + if a.dtype == types.float32: + res_dtype = np.float32 + + res_itemsize = np.dtype(res_dtype).itemsize + + def dpnp_impl(a): + if a.size == 0: + raise ValueError("Passed Empty array") + + sycl_queue = get_sycl_queue() + + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + out_usm = allocate_usm_shared(res_itemsize, sycl_queue) + + print(res_itemsize) + + dpnp_func(a_usm, out_usm, a.shapeptr, a.ndim, a.shapeptr, a.ndim) + + out = np.empty(1, dtype=res_dtype) + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + dpnp_ext._dummy_liveness_func([out.size]) + + print("FFFF") + return out[0] + + return dpnp_impl + + +@overload(stubs.dpnp.median) +def dpnp_median_impl(a): + name = "median" + dpnp_lowering.ensure_dpnp(name) + dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() + + ret_type = types.void + """ + dpnp source: + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_statistics.cpp#L169 + + Function declaration: + void custom_mean_c(void* array1_in, void* result1, const size_t* shape, + size_t ndim, const size_t* axis, size_t naxis) + + We are using void * in case of size_t * as Numba currently does not have + any type to represent size_t *. Since, both the types are pointers, + if the compiler allows there should not be any mismatch in the size of + the container to hold different types of pointer. + """ + sig = signature(ret_type, types.voidptr, types.voidptr, + types.voidptr, types.intp, + types.voidptr, types.intp) + dpnp_func = dpnp_ext.dpnp_func("dpnp_"+name, [a.dtype.name, "NONE"], sig) + + get_sycl_queue = dpctl_functions.dpctl_get_current_queue() + allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() + copy_usm = dpctl_functions.dpctl_queue_memcpy() + free_usm = dpctl_functions.dpctl_free_with_queue() + + res_dtype = np.float64 + if a.dtype == types.float32: + res_dtype = np.float32 + + def dpnp_impl(a): + if a.size == 0: + raise ValueError("Passed Empty array") + + sycl_queue = get_sycl_queue() + + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + out = np.empty(1, dtype=res_dtype) + out_usm = allocate_usm_shared(out.itemsize, sycl_queue) + + dpnp_func(a_usm, out_usm, a.shapeptr, a.ndim, a.shapeptr, a.ndim) + + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + dpnp_ext._dummy_liveness_func([out.size]) + + print("GG") + return out[0] + + return dpnp_impl diff --git a/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py b/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py index f3d1ae69be..f6e6e0d84d 100644 --- a/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py @@ -9,7 +9,8 @@ @overload(stubs.dpnp.sum) def dpnp_sum_impl(a): - dpnp_lowering.ensure_dpnp("sum") + name = "sum" + dpnp_lowering.ensure_dpnp(name) dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() ret_type = types.void @@ -22,14 +23,14 @@ def dpnp_sum_impl(a): """ sig = signature(ret_type, types.voidptr, types.voidptr, types.intp) - dpnp_sum = dpnp_ext.dpnp_func("dpnp_sum", [a.dtype.name, "NONE"], sig) + dpnp_func = dpnp_ext.dpnp_func("dpnp_"+name, [a.dtype.name, "NONE"], sig) get_sycl_queue = dpctl_functions.dpctl_get_current_queue() allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() copy_usm = dpctl_functions.dpctl_queue_memcpy() free_usm = dpctl_functions.dpctl_free_with_queue() - def dpnp_sum_impl(a): + def dpnp_impl(a): if a.size == 0: raise ValueError("Passed Empty array") @@ -39,7 +40,7 @@ def dpnp_sum_impl(a): out_usm = allocate_usm_shared(a.itemsize, sycl_queue) - dpnp_sum(a_usm, out_usm, a.size) + dpnp_func(a_usm, out_usm, a.size) out = np.empty(1, dtype=a.dtype) copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) @@ -52,12 +53,13 @@ def dpnp_sum_impl(a): print("AAAAA") return out[0] - return dpnp_sum_impl + return dpnp_impl @overload(stubs.dpnp.prod) def dpnp_prod_impl(a): - dpnp_lowering.ensure_dpnp("prod") + name = "prod" + dpnp_lowering.ensure_dpnp(name) dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() ret_type = types.void @@ -69,14 +71,14 @@ def dpnp_prod_impl(a): void custom_prod_c(void* array1_in, void* result1, size_t size) """ sig = signature(ret_type, types.voidptr, types.voidptr, types.intp) - dpnp_prod = dpnp_ext.dpnp_func("dpnp_prod", [a.dtype.name, "NONE"], sig) + dpnp_func = dpnp_ext.dpnp_func("dpnp_"+name, [a.dtype.name, "NONE"], sig) get_sycl_queue = dpctl_functions.dpctl_get_current_queue() allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() copy_usm = dpctl_functions.dpctl_queue_memcpy() free_usm = dpctl_functions.dpctl_free_with_queue() - def dpnp_prod_impl(a): + def dpnp_impl(a): if a.size == 0: raise ValueError("Passed Empty array") @@ -86,7 +88,7 @@ def dpnp_prod_impl(a): out_usm = allocate_usm_shared(a.itemsize, sycl_queue) - dpnp_prod(a_usm, out_usm, a.size) + dpnp_func(a_usm, out_usm, a.size) out = np.empty(1, dtype=a.dtype) copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) @@ -99,4 +101,4 @@ def dpnp_prod_impl(a): print("BBB") return out[0] - return dpnp_prod_impl + return dpnp_impl diff --git a/numba_dppy/dpnp_glue/dpnpimpl.py b/numba_dppy/dpnp_glue/dpnpimpl.py index dff440103c..583f312c6c 100644 --- a/numba_dppy/dpnp_glue/dpnpimpl.py +++ b/numba_dppy/dpnp_glue/dpnpimpl.py @@ -43,6 +43,8 @@ def get_pointer(obj): """ @lower_getattr(types.Array, "shapeptr") def array_shape(context, builder, typ, value): + import pdb + pdb.set_trace() shape_ptr = builder.gep(value.operands[0], [context.get_constant(types.int32, 0), context.get_constant(types.int32, 5)]) diff --git a/numba_dppy/dpnp_glue/stubs.py b/numba_dppy/dpnp_glue/stubs.py index 11a000a749..7d1e384cf3 100644 --- a/numba_dppy/dpnp_glue/stubs.py +++ b/numba_dppy/dpnp_glue/stubs.py @@ -25,3 +25,9 @@ class min(Stub): class amin(Stub): pass + + class mean(Stub): + pass + + class median(Stub): + pass diff --git a/numba_dppy/dppy_passbuilder.py b/numba_dppy/dppy_passbuilder.py index a8c1428256..79ce15ca0b 100644 --- a/numba_dppy/dppy_passbuilder.py +++ b/numba_dppy/dppy_passbuilder.py @@ -48,9 +48,9 @@ def default_numba_nopython_pipeline(state, pm): pm.add_pass(WithLifting, "Handle with contexts") # this pass rewrites name of NumPy functions we intend to overload - pm.add_pass(DPPYRewriteOverloadedNumPyFunctions, - "Rewrite name of Numpy functions to overload already overloaded function", - ) + #pm.add_pass(DPPYRewriteOverloadedNumPyFunctions, + # "Rewrite name of Numpy functions to overload already overloaded function", + #) # this pass adds required logic to overload default implementation of # Numpy functions @@ -89,9 +89,9 @@ def default_numba_nopython_pipeline(state, pm): pm.add_pass(NopythonTypeInference, "nopython frontend") pm.add_pass(AnnotateTypes, "annotate types") - pm.add_pass(DPPYRewriteNdarrayFunctions, - "Rewrite ndarray functions to dppy supported functions", - ) + #pm.add_pass(DPPYRewriteNdarrayFunctions, + # "Rewrite ndarray functions to dppy supported functions", + #) # strip phis pm.add_pass(PreLowerStripPhis, "remove phis nodes") diff --git a/numba_dppy/dppy_passes.py b/numba_dppy/dppy_passes.py index c73f5a7736..f9d4e44239 100644 --- a/numba_dppy/dppy_passes.py +++ b/numba_dppy/dppy_passes.py @@ -85,7 +85,6 @@ def generic(self, args, kws): return signature(retty, *args) @infer_global(np.mean) - #@infer_global("array.mean") class NPMean(AbstractTemplate): def generic(self, args, kws): assert not kws diff --git a/numba_dppy/experimental_numpy_lowering_overload.py b/numba_dppy/experimental_numpy_lowering_overload.py index dd1e2a1eb6..9ab548a52d 100644 --- a/numba_dppy/experimental_numpy_lowering_overload.py +++ b/numba_dppy/experimental_numpy_lowering_overload.py @@ -452,6 +452,8 @@ def array_size_checker(arry): signature(types.none, *sig.args), args) sycl_queue = get_sycl_queue(context, builder) + import pdb + pdb.set_trace() aty = sig.args[0] a = make_array(aty)(context, builder, args[0]) @@ -493,6 +495,7 @@ def array_size_checker(arry): @lower_builtin(np.max, types.Array) @lower_builtin("array.max", types.Array) def array_max(context, builder, sig, args): + print("ASDASDAS") ensure_dpnp("max") return common_max_min_impl(context, builder, sig, args, "dpnp_max") diff --git a/numba_dppy/rename_numpy_functions_pass.py b/numba_dppy/rename_numpy_functions_pass.py index b85fba0365..6abf87ac25 100644 --- a/numba_dppy/rename_numpy_functions_pass.py +++ b/numba_dppy/rename_numpy_functions_pass.py @@ -15,7 +15,9 @@ "max": (["np"], "max"), "amax": (["np"], "amax"), "min": (["np"], "min"), - "amin": (["np"], "amin")} + "amin": (["np"], "amin"), + #"mean": (["np"], "mean"), + "median": (["np"], "median")} class RewriteNumPyOverloadedFunctions(object): From 13e7574d9c42e16d337862a46808821256fdf139 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Mon, 14 Dec 2020 16:51:45 -0600 Subject: [PATCH 21/34] Add median --- numba_dppy/dpnp_glue/dpnp_statisticsimpl.py | 19 +++++++------------ numba_dppy/dpnp_glue/dpnpimpl.py | 7 +++---- numba_dppy/dppy_passbuilder.py | 13 ++++++------- numba_dppy/rename_numpy_functions_pass.py | 2 +- numba_dppy/tests/test_dpnp_functions.py | 15 +++++++++++++++ 5 files changed, 32 insertions(+), 24 deletions(-) diff --git a/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py b/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py index 7b17210627..57bc0dd7b4 100644 --- a/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py @@ -157,8 +157,6 @@ def dpnp_mean_impl(a): if a.dtype == types.float32: res_dtype = np.float32 - res_itemsize = np.dtype(res_dtype).itemsize - def dpnp_impl(a): if a.size == 0: raise ValueError("Passed Empty array") @@ -168,20 +166,17 @@ def dpnp_impl(a): a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) - out_usm = allocate_usm_shared(res_itemsize, sycl_queue) - - print(res_itemsize) + out = np.empty(1, dtype=res_dtype) + out_usm = allocate_usm_shared(out.itemsize, sycl_queue) dpnp_func(a_usm, out_usm, a.shapeptr, a.ndim, a.shapeptr, a.ndim) - out = np.empty(1, dtype=res_dtype) copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) free_usm(a_usm, sycl_queue) free_usm(out_usm, sycl_queue) - dpnp_ext._dummy_liveness_func([out.size]) - + dpnp_ext._dummy_liveness_func([a.size, out.size]) print("FFFF") return out[0] @@ -197,11 +192,11 @@ def dpnp_median_impl(a): ret_type = types.void """ dpnp source: - https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_statistics.cpp#L169 + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_statistics.cpp#L213 Function declaration: - void custom_mean_c(void* array1_in, void* result1, const size_t* shape, - size_t ndim, const size_t* axis, size_t naxis) + void custom_median_c(void* array1_in, void* result1, const size_t* shape, + size_t ndim, const size_t* axis, size_t naxis) We are using void * in case of size_t * as Numba currently does not have any type to represent size_t *. Since, both the types are pointers, @@ -241,7 +236,7 @@ def dpnp_impl(a): free_usm(a_usm, sycl_queue) free_usm(out_usm, sycl_queue) - dpnp_ext._dummy_liveness_func([out.size]) + dpnp_ext._dummy_liveness_func([a.size, out.size]) print("GG") return out[0] diff --git a/numba_dppy/dpnp_glue/dpnpimpl.py b/numba_dppy/dpnp_glue/dpnpimpl.py index 583f312c6c..1af39ca2e4 100644 --- a/numba_dppy/dpnp_glue/dpnpimpl.py +++ b/numba_dppy/dpnp_glue/dpnpimpl.py @@ -43,9 +43,8 @@ def get_pointer(obj): """ @lower_getattr(types.Array, "shapeptr") def array_shape(context, builder, typ, value): - import pdb - pdb.set_trace() shape_ptr = builder.gep(value.operands[0], - [context.get_constant(types.int32, 0), - context.get_constant(types.int32, 5)]) + [context.get_constant(types.int32, 0), + context.get_constant(types.int32, 5)]) + return builder.bitcast(shape_ptr, ll_void_p) diff --git a/numba_dppy/dppy_passbuilder.py b/numba_dppy/dppy_passbuilder.py index 79ce15ca0b..cf427bbd8c 100644 --- a/numba_dppy/dppy_passbuilder.py +++ b/numba_dppy/dppy_passbuilder.py @@ -48,9 +48,9 @@ def default_numba_nopython_pipeline(state, pm): pm.add_pass(WithLifting, "Handle with contexts") # this pass rewrites name of NumPy functions we intend to overload - #pm.add_pass(DPPYRewriteOverloadedNumPyFunctions, - # "Rewrite name of Numpy functions to overload already overloaded function", - #) + pm.add_pass(DPPYRewriteOverloadedNumPyFunctions, + "Rewrite name of Numpy functions to overload already overloaded function", + ) # this pass adds required logic to overload default implementation of # Numpy functions @@ -89,9 +89,9 @@ def default_numba_nopython_pipeline(state, pm): pm.add_pass(NopythonTypeInference, "nopython frontend") pm.add_pass(AnnotateTypes, "annotate types") - #pm.add_pass(DPPYRewriteNdarrayFunctions, - # "Rewrite ndarray functions to dppy supported functions", - #) + pm.add_pass(DPPYRewriteNdarrayFunctions, + "Rewrite ndarray functions to dppy supported functions", + ) # strip phis pm.add_pass(PreLowerStripPhis, "remove phis nodes") @@ -100,7 +100,6 @@ def default_numba_nopython_pipeline(state, pm): pm.add_pass(InlineOverloads, "inline overloaded functions") - @staticmethod def define_nopython_pipeline(state, name='dppy_nopython'): """Returns an nopython mode pipeline based PassManager diff --git a/numba_dppy/rename_numpy_functions_pass.py b/numba_dppy/rename_numpy_functions_pass.py index 6abf87ac25..3a6409bde8 100644 --- a/numba_dppy/rename_numpy_functions_pass.py +++ b/numba_dppy/rename_numpy_functions_pass.py @@ -16,7 +16,7 @@ "amax": (["np"], "amax"), "min": (["np"], "min"), "amin": (["np"], "amin"), - #"mean": (["np"], "mean"), + "mean": (["np"], "mean"), "median": (["np"], "median")} diff --git a/numba_dppy/tests/test_dpnp_functions.py b/numba_dppy/tests/test_dpnp_functions.py index cb1a194dba..96fcf280b2 100644 --- a/numba_dppy/tests/test_dpnp_functions.py +++ b/numba_dppy/tests/test_dpnp_functions.py @@ -201,6 +201,21 @@ def f(a): self.assertTrue(expected == got) + def test_ndarray_mean(self): + @njit + def f(a): + return a.mean() + + size = 3 + for ty in self.tys: + a = np.arange(1, (size * size) + 1, dtype=ty).reshape((size, size)) + + with dpctl.device_context("opencl:gpu"): + got = f(a) + expected = a.mean() + + self.assertTrue(expected == got) + @unittest.skipUnless(ensure_dpnp() and dpctl.has_gpu_queues(), 'test only when dpNP and GPU is available') class Testdpnp_functions(unittest.TestCase): From 7ffb550e18fe5755552da0dd2e90951074bc82a4 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Mon, 14 Dec 2020 17:55:58 -0600 Subject: [PATCH 22/34] Add argsort, argmax, argmin --- numba_dppy/dpnp_glue/stubs.py | 9 +++++ numba_dppy/rename_numpy_functions_pass.py | 6 ++- numba_dppy/tests/test_dpnp_functions.py | 47 +++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/numba_dppy/dpnp_glue/stubs.py b/numba_dppy/dpnp_glue/stubs.py index 7d1e384cf3..dcd162c0ee 100644 --- a/numba_dppy/dpnp_glue/stubs.py +++ b/numba_dppy/dpnp_glue/stubs.py @@ -31,3 +31,12 @@ class mean(Stub): class median(Stub): pass + + class argmax(Stub): + pass + + class argmin(Stub): + pass + + class argsort(Stub): + pass diff --git a/numba_dppy/rename_numpy_functions_pass.py b/numba_dppy/rename_numpy_functions_pass.py index 3a6409bde8..8e896d4325 100644 --- a/numba_dppy/rename_numpy_functions_pass.py +++ b/numba_dppy/rename_numpy_functions_pass.py @@ -17,7 +17,10 @@ "min": (["np"], "min"), "amin": (["np"], "amin"), "mean": (["np"], "mean"), - "median": (["np"], "median")} + "median": (["np"], "median"), + "argmax": (["np"], "argmax"), + "argmin": (["np"], "argmin"), + "argsort": (["np"], "argsort")} class RewriteNumPyOverloadedFunctions(object): @@ -124,6 +127,7 @@ def __init__(self): import numba_dppy.dpnp_glue.dpnp_linalgimpl import numba_dppy.dpnp_glue.dpnp_transcendentalsimpl import numba_dppy.dpnp_glue.dpnp_statisticsimpl + import numba_dppy.dpnp_glue.dpnp_sort_search_countimpl def run_pass(self, state): rewrite_function_name_pass = RewriteNumPyOverloadedFunctions( diff --git a/numba_dppy/tests/test_dpnp_functions.py b/numba_dppy/tests/test_dpnp_functions.py index 96fcf280b2..61650af87c 100644 --- a/numba_dppy/tests/test_dpnp_functions.py +++ b/numba_dppy/tests/test_dpnp_functions.py @@ -216,6 +216,53 @@ def f(a): self.assertTrue(expected == got) + def test_ndarray_argmax(self): + @njit + def f(a): + return a.argmax() + + size = 3 + for ty in self.tys: + a = np.arange(1, (size * size) + 1, dtype=ty).reshape((size, size)) + + with dpctl.device_context("opencl:gpu"): + got = f(a) + expected = a.argmax() + + self.assertTrue(expected == got) + + + def test_ndarray_argmin(self): + @njit + def f(a): + return a.argmin() + + size = 3 + for ty in self.tys: + a = np.arange(1, (size * size) + 1, dtype=ty).reshape((size, size)) + + with dpctl.device_context("opencl:gpu"): + got = f(a) + expected = a.argmin() + + self.assertTrue(expected == got) + + def test_ndarray_argsort(self): + @njit + def f(a): + return a.argsort() + + size = 3 + for ty in self.tys: + a = np.arange(1, (size * size) + 1, dtype=ty) + + with dpctl.device_context("opencl:gpu"): + got = f(a) + expected = a.argsort() + + self.assertTrue(np.array_equal(expected, got)) + + @unittest.skipUnless(ensure_dpnp() and dpctl.has_gpu_queues(), 'test only when dpNP and GPU is available') class Testdpnp_functions(unittest.TestCase): From 59f95b87e1ded71088a206875d599afa8c934429 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Mon, 14 Dec 2020 19:44:03 -0600 Subject: [PATCH 23/34] Added cov --- .../dpnp_glue/dpnp_sort_search_countimpl.py | 160 ++++++++++++++++++ numba_dppy/dpnp_glue/dpnp_statisticsimpl.py | 73 ++++++++ numba_dppy/dpnp_glue/stubs.py | 3 + numba_dppy/rename_numpy_functions_pass.py | 3 +- 4 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 numba_dppy/dpnp_glue/dpnp_sort_search_countimpl.py diff --git a/numba_dppy/dpnp_glue/dpnp_sort_search_countimpl.py b/numba_dppy/dpnp_glue/dpnp_sort_search_countimpl.py new file mode 100644 index 0000000000..7e814b0c92 --- /dev/null +++ b/numba_dppy/dpnp_glue/dpnp_sort_search_countimpl.py @@ -0,0 +1,160 @@ +import numba_dppy.dpnp_glue.dpnpimpl as dpnp_ext +from numba.core import types, cgutils +from numba.core.typing import signature +from . import stubs +import numba_dppy.experimental_numpy_lowering_overload as dpnp_lowering +from numba.core.extending import overload, register_jitable +import numpy as np + + +@overload(stubs.dpnp.argmax) +def dpnp_argmax_impl(a): + name = "argmax" + dpnp_lowering.ensure_dpnp(name) + dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() + + ret_type = types.void + """ + dpnp source: + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_searching.cpp#L36 + + Function declaration: + void custom_argmax_c(void* array1_in, void* result1, size_t size) + """ + sig = signature(ret_type, types.voidptr, types.voidptr, types.intp) + dpnp_func = dpnp_ext.dpnp_func("dpnp_"+name, [a.dtype.name, np.dtype(np.int64).name], sig) + + get_sycl_queue = dpctl_functions.dpctl_get_current_queue() + allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() + copy_usm = dpctl_functions.dpctl_queue_memcpy() + free_usm = dpctl_functions.dpctl_free_with_queue() + + res_dtype = np.int64 + + def dpnp_impl(a): + if a.size == 0: + raise ValueError("Passed Empty array") + + sycl_queue = get_sycl_queue() + + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + out = np.empty(1, dtype=res_dtype) + out_usm = allocate_usm_shared(out.itemsize, sycl_queue) + + dpnp_func(a_usm, out_usm, a.size) + + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + dpnp_ext._dummy_liveness_func([a.size, out.size]) + + print("HH") + return out[0] + + return dpnp_impl + + +@overload(stubs.dpnp.argmin) +def dpnp_argmin_impl(a): + name = "argmin" + dpnp_lowering.ensure_dpnp(name) + dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() + + ret_type = types.void + """ + dpnp source: + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_searching.cpp#L56 + + Function declaration: + void custom_argmin_c(void* array1_in, void* result1, size_t size) + """ + sig = signature(ret_type, types.voidptr, types.voidptr, types.intp) + dpnp_func = dpnp_ext.dpnp_func("dpnp_"+name, [a.dtype.name, np.dtype(np.int64).name], sig) + + get_sycl_queue = dpctl_functions.dpctl_get_current_queue() + allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() + copy_usm = dpctl_functions.dpctl_queue_memcpy() + free_usm = dpctl_functions.dpctl_free_with_queue() + + res_dtype = np.int64 + + def dpnp_impl(a): + if a.size == 0: + raise ValueError("Passed Empty array") + + sycl_queue = get_sycl_queue() + + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + out = np.empty(1, dtype=res_dtype) + out_usm = allocate_usm_shared(out.itemsize, sycl_queue) + + dpnp_func(a_usm, out_usm, a.size) + + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + dpnp_ext._dummy_liveness_func([a.size, out.size]) + + print("II") + return out[0] + + return dpnp_impl + + +@overload(stubs.dpnp.argsort) +def dpnp_argsort_impl(a): + name = "argsort" + dpnp_lowering.ensure_dpnp(name) + dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() + + ret_type = types.void + """ + dpnp source: + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_searching.cpp#L56 + + Function declaration: + void custom_argmin_c(void* array1_in, void* result1, size_t size) + """ + sig = signature(ret_type, types.voidptr, types.voidptr, types.intp) + dpnp_func = dpnp_ext.dpnp_func("dpnp_"+name, [a.dtype.name, "NONE"], sig) + + get_sycl_queue = dpctl_functions.dpctl_get_current_queue() + allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() + copy_usm = dpctl_functions.dpctl_queue_memcpy() + free_usm = dpctl_functions.dpctl_free_with_queue() + + res_dtype = np.int64 + + def dpnp_impl(a): + if a.size == 0: + raise ValueError("Passed Empty array") + + sycl_queue = get_sycl_queue() + + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + out = np.arange(a.size, dtype=res_dtype) + out_usm = allocate_usm_shared(out.size * out.itemsize, sycl_queue) + + dpnp_func(a_usm, out_usm, a.size) + + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + dpnp_ext._dummy_liveness_func([a.size, out.size]) + + print("JJ") + return out + + return dpnp_impl diff --git a/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py b/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py index 57bc0dd7b4..70a99c4ee0 100644 --- a/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py @@ -244,3 +244,76 @@ def dpnp_impl(a): return dpnp_impl +@overload(stubs.dpnp.cov) +def dpnp_cov_impl(a): + name = "cov" + dpnp_lowering.ensure_dpnp(name) + dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() + + ret_type = types.void + """ + dpnp source: + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels_statistics.cpp#L51 + + Function declaration: + void custom_cov_c(void* array1_in, void* result1, size_t nrows, size_t ncols) + """ + sig = signature(ret_type, types.voidptr, types.voidptr, + types.intp, types.intp) + dpnp_func = dpnp_ext.dpnp_func("dpnp_"+name, [a.dtype.name, "NONE"], sig) + + get_sycl_queue = dpctl_functions.dpctl_get_current_queue() + allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() + copy_usm = dpctl_functions.dpctl_queue_memcpy() + free_usm = dpctl_functions.dpctl_free_with_queue() + + res_dtype = np.float64 + copy_input_to_double = True + if a.dtype == types.float64: + copy_input_to_double = False + + + def dpnp_impl(a): + if a.size == 0: + raise ValueError("Passed Empty array") + + sycl_queue = get_sycl_queue() + + """ We have to pass a array in double precision to DpNp """ + if copy_input_to_double: + a_copy_in_double = a.astype(np.float64) + else: + a_copy_in_double = a + a_usm = allocate_usm_shared(a_copy_in_double.size * a_copy_in_double.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a_copy_in_double.ctypes, + a_copy_in_double.size * a_copy_in_double.itemsize) + + if a.ndim == 2: + rows = a.shape[0] + cols = a.shape[1] + out = np.empty((rows, rows), dtype=res_dtype) + elif a.ndim == 1: + rows = 1 + cols = a.shape[0] + out = np.empty(rows, dtype=res_dtype) + + out_usm = allocate_usm_shared(out.size * out.itemsize, sycl_queue) + + dpnp_func(a_usm, out_usm, rows, cols) + + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + dpnp_ext._dummy_liveness_func([a_copy_in_double.size, a.size, out.size]) + + print("KK") + if a.ndim == 2: + return out + elif a.ndim == 1: + return out[0] + + return dpnp_impl + + diff --git a/numba_dppy/dpnp_glue/stubs.py b/numba_dppy/dpnp_glue/stubs.py index dcd162c0ee..4fa556bb1c 100644 --- a/numba_dppy/dpnp_glue/stubs.py +++ b/numba_dppy/dpnp_glue/stubs.py @@ -40,3 +40,6 @@ class argmin(Stub): class argsort(Stub): pass + + class cov(Stub): + pass diff --git a/numba_dppy/rename_numpy_functions_pass.py b/numba_dppy/rename_numpy_functions_pass.py index 8e896d4325..01bf0b5cb2 100644 --- a/numba_dppy/rename_numpy_functions_pass.py +++ b/numba_dppy/rename_numpy_functions_pass.py @@ -20,7 +20,8 @@ "median": (["np"], "median"), "argmax": (["np"], "argmax"), "argmin": (["np"], "argmin"), - "argsort": (["np"], "argsort")} + "argsort": (["np"], "argsort"), + "cov": (["np"], "cov")} class RewriteNumPyOverloadedFunctions(object): From e43cf17313be9620f92593d5a79297631d5e679b Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Mon, 14 Dec 2020 20:22:27 -0600 Subject: [PATCH 24/34] Added dot --- numba_dppy/dpnp_glue/dpnp_linalgimpl.py | 209 +++++++++++++++++++++- numba_dppy/dpnp_glue/stubs.py | 3 + numba_dppy/rename_numpy_functions_pass.py | 3 +- 3 files changed, 212 insertions(+), 3 deletions(-) diff --git a/numba_dppy/dpnp_glue/dpnp_linalgimpl.py b/numba_dppy/dpnp_glue/dpnp_linalgimpl.py index 1d9cc356c3..4448fc8e62 100644 --- a/numba_dppy/dpnp_glue/dpnp_linalgimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_linalgimpl.py @@ -9,7 +9,8 @@ @overload(stubs.dpnp.eig) def dpnp_eig_impl(a): - dpnp_lowering.ensure_dpnp("eig") + name = "eig" + dpnp_lowering.ensure_dpnp(name) dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() ret_type = types.void @@ -24,7 +25,7 @@ def dpnp_eig_impl(a): sig = signature( ret_type, types.voidptr, types.voidptr, types.voidptr, types.intp ) - dpnp_eig = dpnp_ext.dpnp_func("dpnp_eig", [a.dtype.name, "NONE"], sig) + dpnp_eig = dpnp_ext.dpnp_func("dpnp_"+name, [a.dtype.name, "NONE"], sig) get_sycl_queue = dpctl_functions.dpctl_get_current_queue() allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() @@ -71,3 +72,207 @@ def dpnp_eig_impl(a): return (wr, vr) return dpnp_eig_impl + + +@overload(stubs.dpnp.dot) +def dpnp_dot_impl(a, b): + dpnp_lowering.ensure_dpnp("dot") + dpctl_functions = dpnp_ext._DPCTL_FUNCTIONS() + + ret_type = types.void + """ + dpnp source: + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels.cpp#L42 + https://github.com/IntelPython/dpnp/blob/0.4.0/dpnp/backend/custom_kernels.cpp#L118 + + Function declaration: + void dpnp_matmul_c(void* array1_in, void* array2_in, void* result1, size_t size_m, + size_t size_n, size_t size_k) + void dpnp_dot_c(void* array1_in, void* array2_in, void* result1, size_t size) + + """ + sig = signature( + ret_type, types.voidptr, types.voidptr, types.voidptr, + types.intp, types.intp, types.intp) + + get_sycl_queue = dpctl_functions.dpctl_get_current_queue() + allocate_usm_shared = dpctl_functions.dpctl_malloc_shared() + copy_usm = dpctl_functions.dpctl_queue_memcpy() + free_usm = dpctl_functions.dpctl_free_with_queue() + + res_dtype = np.float64 + if a.dtype == types.int32 and b.dtype == types.int32: + res_dtype = np.int32 + elif a.dtype == types.int32 and b.dtype == types.int64: + res_dtype = np.int64 + elif a.dtype == types.int32 and b.dtype == types.float32: + res_dtype = np.float64 + elif a.dtype == types.int32 and b.dtype == types.float64: + res_dtype = np.float64 + elif a.dtype == types.int64 and b.dtype == types.int32: + res_dtype = np.int64 + elif a.dtype == types.int64 and b.dtype == types.int64: + res_dtype = np.int64 + elif a.dtype == types.int64 and b.dtype == types.float32: + res_dtype = np.float64 + elif a.dtype == types.int64 and b.dtype == types.float64: + res_dtype = np.float64 + elif a.dtype == types.float32 and b.dtype == types.int32: + res_dtype = np.float64 + elif a.dtype == types.float32 and b.dtype == types.int64: + res_dtype = np.float64 + elif a.dtype == types.float32 and b.dtype == types.float32: + res_dtype = np.float32 + elif a.dtype == types.float32 and b.dtype == types.float64: + res_dtype = np.float64 + elif a.dtype == types.float64 and b.dtype == types.int32: + res_dtype = np.float64 + elif a.dtype == types.float64 and b.dtype == types.int64: + res_dtype = np.float64 + elif a.dtype == types.float64 and b.dtype == types.float32: + res_dtype = np.float32 + elif a.dtype == types.float64 and b.dtype == types.float64: + res_dtype = np.float64 + + ndims = [a.ndim, b.ndim] + if ndims == [2, 2]: + dpnp_func = dpnp_ext.dpnp_func("dpnp_matmul", [a.dtype.name, "NONE"], sig) + def dot_2_mm(a, b): + sycl_queue = get_sycl_queue() + + m, k = a.shape + _k, n = b.shape + + if _k != k: + raise ValueError("Incompatible array sizes for np.dot(a, b)") + + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + b_usm = allocate_usm_shared(b.size * b.itemsize, sycl_queue) + copy_usm(sycl_queue, b_usm, b.ctypes, b.size * b.itemsize) + + out = np.empty((m, n), dtype=res_dtype) + out_usm = allocate_usm_shared(out.size * out.itemsize, sycl_queue) + + dpnp_func(a_usm, b_usm, out_usm, m, n, k) + + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(b_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + dpnp_ext._dummy_liveness_func([a.size, b.size, out.size]) + print("MM") + + return out + + return dot_2_mm + elif ndims == [2, 1]: + dpnp_func = dpnp_ext.dpnp_func("dpnp_matmul", [a.dtype.name, "NONE"], sig) + def dot_2_mv(a, b): + sycl_queue = get_sycl_queue() + + m, k = a.shape + _n, = b.shape + n = 1 + + if _n != k: + raise ValueError("Incompatible array sizes for np.dot(a, b)") + + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + b_usm = allocate_usm_shared(b.size * b.itemsize, sycl_queue) + copy_usm(sycl_queue, b_usm, b.ctypes, b.size * b.itemsize) + + out = np.empty((m, ), dtype=res_dtype) + out_usm = allocate_usm_shared(out.size * out.itemsize, sycl_queue) + + dpnp_func(a_usm, b_usm, out_usm, m, n, k) + + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(b_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + dpnp_ext._dummy_liveness_func([a.size, b.size, out.size]) + print("MV") + + return out + + return dot_2_mv + elif ndims == [1, 2]: + dpnp_func = dpnp_ext.dpnp_func("dpnp_matmul", [a.dtype.name, "NONE"], sig) + def dot_2_vm(a, b): + sycl_queue = get_sycl_queue() + + m, = a.shape + k, n = b.shape + + if m != k: + raise ValueError("Incompatible array sizes for np.dot(a, b)") + + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + b_usm = allocate_usm_shared(b.size * b.itemsize, sycl_queue) + copy_usm(sycl_queue, b_usm, b.ctypes, b.size * b.itemsize) + + out = np.empty((n, ), dtype=res_dtype) + out_usm = allocate_usm_shared(out.size * out.itemsize, sycl_queue) + + dpnp_func(a_usm, b_usm, out_usm, m, n, k) + + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(b_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + dpnp_ext._dummy_liveness_func([a.size, b.size, out.size]) + print("VM") + + return out + + return dot_2_vm + elif ndims == [1, 1]: + sig = signature(ret_type, types.voidptr, types.voidptr, types.voidptr, + types.intp) + dpnp_func = dpnp_ext.dpnp_func("dpnp_dot", [a.dtype.name, "NONE"], sig) + def dot_2_vv(a, b): + sycl_queue = get_sycl_queue() + + m, = a.shape + n, = b.shape + + if m != n: + raise ValueError("Incompatible array sizes for np.dot(a, b)") + + a_usm = allocate_usm_shared(a.size * a.itemsize, sycl_queue) + copy_usm(sycl_queue, a_usm, a.ctypes, a.size * a.itemsize) + + b_usm = allocate_usm_shared(b.size * b.itemsize, sycl_queue) + copy_usm(sycl_queue, b_usm, b.ctypes, b.size * b.itemsize) + + out = np.empty(1, dtype=res_dtype) + out_usm = allocate_usm_shared(out.size * out.itemsize, sycl_queue) + + dpnp_func(a_usm, b_usm, out_usm, m) + + copy_usm(sycl_queue, out.ctypes, out_usm, out.size * out.itemsize) + + free_usm(a_usm, sycl_queue) + free_usm(b_usm, sycl_queue) + free_usm(out_usm, sycl_queue) + + dpnp_ext._dummy_liveness_func([a.size, b.size, out.size]) + + print("VV") + return out[0] + + return dot_2_vv + else: + assert 0 diff --git a/numba_dppy/dpnp_glue/stubs.py b/numba_dppy/dpnp_glue/stubs.py index 4fa556bb1c..10270ef951 100644 --- a/numba_dppy/dpnp_glue/stubs.py +++ b/numba_dppy/dpnp_glue/stubs.py @@ -43,3 +43,6 @@ class argsort(Stub): class cov(Stub): pass + + class dot(Stub): + pass diff --git a/numba_dppy/rename_numpy_functions_pass.py b/numba_dppy/rename_numpy_functions_pass.py index 01bf0b5cb2..2fa2f97db1 100644 --- a/numba_dppy/rename_numpy_functions_pass.py +++ b/numba_dppy/rename_numpy_functions_pass.py @@ -21,7 +21,8 @@ "argmax": (["np"], "argmax"), "argmin": (["np"], "argmin"), "argsort": (["np"], "argsort"), - "cov": (["np"], "cov")} + "cov": (["np"], "cov"), + "dot": (["np"], "dot")} class RewriteNumPyOverloadedFunctions(object): From f5b76b76edf8592f69b0433dd9cfb1bdd47365c4 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Mon, 14 Dec 2020 20:27:52 -0600 Subject: [PATCH 25/34] Addd matmul --- numba_dppy/dpnp_glue/dpnp_linalgimpl.py | 1 + numba_dppy/dpnp_glue/stubs.py | 3 +++ numba_dppy/rename_numpy_functions_pass.py | 6 ++---- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/numba_dppy/dpnp_glue/dpnp_linalgimpl.py b/numba_dppy/dpnp_glue/dpnp_linalgimpl.py index 4448fc8e62..52ef7b2a48 100644 --- a/numba_dppy/dpnp_glue/dpnp_linalgimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_linalgimpl.py @@ -74,6 +74,7 @@ def dpnp_eig_impl(a): return dpnp_eig_impl +@overload(stubs.dpnp.matmul) @overload(stubs.dpnp.dot) def dpnp_dot_impl(a, b): dpnp_lowering.ensure_dpnp("dot") diff --git a/numba_dppy/dpnp_glue/stubs.py b/numba_dppy/dpnp_glue/stubs.py index 10270ef951..2fdd6ecbe3 100644 --- a/numba_dppy/dpnp_glue/stubs.py +++ b/numba_dppy/dpnp_glue/stubs.py @@ -46,3 +46,6 @@ class cov(Stub): class dot(Stub): pass + + class matmul(Stub): + pass diff --git a/numba_dppy/rename_numpy_functions_pass.py b/numba_dppy/rename_numpy_functions_pass.py index 2fa2f97db1..c1d58ce036 100644 --- a/numba_dppy/rename_numpy_functions_pass.py +++ b/numba_dppy/rename_numpy_functions_pass.py @@ -22,7 +22,8 @@ "argmin": (["np"], "argmin"), "argsort": (["np"], "argsort"), "cov": (["np"], "cov"), - "dot": (["np"], "dot")} + "dot": (["np"], "dot"), + "matmul": (["np"], "matmul")} class RewriteNumPyOverloadedFunctions(object): @@ -228,7 +229,6 @@ def run(self): return - @register_pass(mutates_CFG=True, analysis_only=False) class DPPYRewriteNdarrayFunctions(FunctionPass): _name = "dppy_rewrite_ndarray_functions_pass" @@ -247,5 +247,3 @@ def run_pass(self, state): state.func_ir.blocks = simplify_CFG(state.func_ir.blocks) return True - - From 03d7b735cd463c7da227fa514c08e2464dea26a2 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Mon, 14 Dec 2020 20:50:29 -0600 Subject: [PATCH 26/34] Cleanup old method to call dpnp --- numba_dppy/dpnp_glue/__init__.py | 6 + numba_dppy/dpnp_glue/dpnp_linalgimpl.py | 2 +- .../dpnp_glue/dpnp_sort_search_countimpl.py | 2 +- numba_dppy/dpnp_glue/dpnp_statisticsimpl.py | 2 +- .../dpnp_glue/dpnp_transcendentalsimpl.py | 2 +- numba_dppy/dpnp_glue/dpnpimpl.py | 7 +- numba_dppy/dppy_passbuilder.py | 7 - numba_dppy/dppy_passes.py | 123 --- .../experimental_numpy_lowering_overload.py | 726 ------------------ 9 files changed, 12 insertions(+), 865 deletions(-) delete mode 100644 numba_dppy/experimental_numpy_lowering_overload.py diff --git a/numba_dppy/dpnp_glue/__init__.py b/numba_dppy/dpnp_glue/__init__.py index e69de29bb2..17d6b5ad6a 100644 --- a/numba_dppy/dpnp_glue/__init__.py +++ b/numba_dppy/dpnp_glue/__init__.py @@ -0,0 +1,6 @@ +def ensure_dpnp(name): + try: + # import dpnp + from . import dpnp_fptr_interface as dpnp_glue + except ImportError: + raise ImportError("dpNP is needed to call np.%s" % name) diff --git a/numba_dppy/dpnp_glue/dpnp_linalgimpl.py b/numba_dppy/dpnp_glue/dpnp_linalgimpl.py index 52ef7b2a48..598283bc10 100644 --- a/numba_dppy/dpnp_glue/dpnp_linalgimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_linalgimpl.py @@ -2,7 +2,7 @@ from numba import types from numba.core.typing import signature from . import stubs -import numba_dppy.experimental_numpy_lowering_overload as dpnp_lowering +import numba_dppy.dpnp_glue as dpnp_lowering from numba.core.extending import overload, register_jitable import numpy as np from numba_dppy.dpctl_functions import _DPCTL_FUNCTIONS diff --git a/numba_dppy/dpnp_glue/dpnp_sort_search_countimpl.py b/numba_dppy/dpnp_glue/dpnp_sort_search_countimpl.py index 7e814b0c92..f129757a29 100644 --- a/numba_dppy/dpnp_glue/dpnp_sort_search_countimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_sort_search_countimpl.py @@ -2,7 +2,7 @@ from numba.core import types, cgutils from numba.core.typing import signature from . import stubs -import numba_dppy.experimental_numpy_lowering_overload as dpnp_lowering +import numba_dppy.dpnp_glue as dpnp_lowering from numba.core.extending import overload, register_jitable import numpy as np diff --git a/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py b/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py index 70a99c4ee0..b831f4280a 100644 --- a/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py @@ -2,7 +2,7 @@ from numba.core import types, cgutils from numba.core.typing import signature from . import stubs -import numba_dppy.experimental_numpy_lowering_overload as dpnp_lowering +import numba_dppy.dpnp_glue as dpnp_lowering from numba.core.extending import overload, register_jitable import numpy as np diff --git a/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py b/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py index f6e6e0d84d..161eb37e43 100644 --- a/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py @@ -2,7 +2,7 @@ from numba import types from numba.core.typing import signature from . import stubs -import numba_dppy.experimental_numpy_lowering_overload as dpnp_lowering +import numba_dppy.dpnp_glue as dpnp_lowering from numba.core.extending import overload, register_jitable import numpy as np diff --git a/numba_dppy/dpnp_glue/dpnpimpl.py b/numba_dppy/dpnp_glue/dpnpimpl.py index 1af39ca2e4..fa429f923f 100644 --- a/numba_dppy/dpnp_glue/dpnpimpl.py +++ b/numba_dppy/dpnp_glue/dpnpimpl.py @@ -1,13 +1,10 @@ from numba.core.imputils import lower_builtin -import numba_dppy.experimental_numpy_lowering_overload as dpnp_lowering from numba.core import types -from numba.core.typing import signature -from numba.core.extending import overload, register_jitable -from . import stubs +from numba.core.extending import register_jitable import numpy as np -from numba_dppy.dpctl_functions import _DPCTL_FUNCTIONS from llvmlite import ir from numba.core.imputils import lower_getattr +from numba_dppy.dpctl_functions import _DPCTL_FUNCTIONS ll_void_p = ir.IntType(8).as_pointer() diff --git a/numba_dppy/dppy_passbuilder.py b/numba_dppy/dppy_passbuilder.py index cf427bbd8c..e832ed51eb 100644 --- a/numba_dppy/dppy_passbuilder.py +++ b/numba_dppy/dppy_passbuilder.py @@ -22,8 +22,6 @@ DPPYPreParforPass, DPPYParforPass, SpirvFriendlyLowering, - DPPYAddNumpyOverloadPass, - DPPYAddNumpyRemoveOverloadPass, DPPYNoPythonBackend ) @@ -52,10 +50,6 @@ def default_numba_nopython_pipeline(state, pm): "Rewrite name of Numpy functions to overload already overloaded function", ) - # this pass adds required logic to overload default implementation of - # Numpy functions - pm.add_pass(DPPYAddNumpyOverloadPass, "dppy add typing template for Numpy functions") - # Add pass to ensure when users are allocating static # constant memory the size is a constant and can not # come from a closure variable @@ -119,6 +113,5 @@ def define_nopython_pipeline(state, name='dppy_nopython'): # lower pm.add_pass(SpirvFriendlyLowering, "SPIRV-friendly lowering pass") pm.add_pass(DPPYNoPythonBackend, "nopython mode backend") - pm.add_pass(DPPYAddNumpyRemoveOverloadPass, "dppy remove typing template for Numpy functions") pm.finalize() return pm diff --git a/numba_dppy/dppy_passes.py b/numba_dppy/dppy_passes.py index f9d4e44239..96eb3feee6 100644 --- a/numba_dppy/dppy_passes.py +++ b/numba_dppy/dppy_passes.py @@ -31,116 +31,6 @@ from numba.parfors.parfor import ParforPass as _parfor_ParforPass from numba.parfors.parfor import Parfor -def dpnp_available(): - try: - # import dpnp - from numba_dppy.dpnp_glue import dpnp_fptr_interface as dpnp_glue - return True - except: - return False - - -@register_pass(mutates_CFG=False, analysis_only=True) -class DPPYAddNumpyOverloadPass(FunctionPass): - _name = "dppy_add_numpy_overload_pass" - - def __init__(self): - FunctionPass.__init__(self) - - def run_pass(self, state): - if dpnp_available(): - typingctx = state.typingctx - from numba.core.typing.templates import (builtin_registry as reg, infer_global) - from numba.core.typing.templates import (AbstractTemplate, CallableTemplate, signature) - from numba.core.typing.npydecl import MatMulTyperMixin - - @infer_global(np.cov) - class NPCov(AbstractTemplate): - def generic(self, args, kws): - assert not kws - if args[0].ndim > 2: - return - - nb_dtype = types.float64 - return_type = types.Array(dtype=nb_dtype, ndim=args[0].ndim, layout='C') - return signature(return_type, *args) - - @infer_global(np.matmul, typing_key="np.matmul") - class matmul(MatMulTyperMixin, AbstractTemplate): - key = np.matmul - func_name = "np.matmul()" - - def generic(self, args, kws): - assert not kws - restype = self.matmul_typer(*args) - if restype is not None: - return signature(restype, *args) - - @infer_global(np.median) - class NPMedian(AbstractTemplate): - def generic(self, args, kws): - assert not kws - - retty = args[0].dtype - return signature(retty, *args) - - @infer_global(np.mean) - class NPMean(AbstractTemplate): - def generic(self, args, kws): - assert not kws - - if args[0].dtype == types.float32: - retty = types.float32 - else: - retty = types.float64 - return signature(retty, *args) - - - prev_cov = None - prev_median = None - prev_mean = None - for idx, g in enumerate(reg.globals): - if g[0] == np.cov: - if not prev_cov: - prev_cov = g[1] - else: - prev_cov.templates = g[1].templates - - if g[0] == np.median: - if not prev_median: - prev_median = g[1] - else: - prev_median.templates = g[1].templates - - if g[0] == np.mean: - if not prev_mean: - prev_mean = g[1] - else: - prev_mean.templates = g[1].templates - - typingctx.refresh() - return True - -@register_pass(mutates_CFG=False, analysis_only=True) -class DPPYAddNumpyRemoveOverloadPass(FunctionPass): - _name = "dppy_remove_numpy_overload_pass" - - def __init__(self): - FunctionPass.__init__(self) - - def run_pass(self, state): - if dpnp_available(): - typingctx = state.typingctx - targetctx = state.targetctx - - from importlib import reload - from numba.np import npyimpl, arrayobj, arraymath - reload(npyimpl) - reload(arrayobj) - reload(arraymath) - targetctx.refresh() - - return True @register_pass(mutates_CFG=True, analysis_only=False) class DPPYConstantSizeStaticLocalMemoryPass(FunctionPass): @@ -339,21 +229,8 @@ def run_pass(self, state): # be later serialized. state.library.enable_object_caching() - targetctx = state.targetctx - # This should not happen here, after we have the notion of context in Numba - # we should have specialized dispatcher for dppy context and that dispatcher - # should be a cpu dispatcher that will overload the lowering functions for - # linalg for dppy.cpu_dispatcher and the dppy.gpu_dipatcher should be the - # current target context we have to launch kernels. - # This is broken as this essentially adds the new lowering in a list which - # means it does not get replaced with the new lowering_buitins - - if dpnp_available(): - from . import experimental_numpy_lowering_overload - targetctx.refresh() - library = state.library interp = state.func_ir # why is it called this?! typemap = state.typemap diff --git a/numba_dppy/experimental_numpy_lowering_overload.py b/numba_dppy/experimental_numpy_lowering_overload.py deleted file mode 100644 index 9ab548a52d..0000000000 --- a/numba_dppy/experimental_numpy_lowering_overload.py +++ /dev/null @@ -1,726 +0,0 @@ -import numpy as np -from numba.core import types, cgutils -from numba.core.imputils import (lower_builtin) -from numba.core.typing import signature -from numba.np.arrayobj import make_array, _empty_nd_impl, array_copy -from numba.core import itanium_mangler -from llvmlite import ir -import llvmlite.llvmpy.core as lc -import contextlib - -from numba import int32, int64, uint32, uint64, float32, float64 - - -@contextlib.contextmanager -def make_contiguous(context, builder, sig, args): - """ - Ensure that all array arguments are contiguous, if necessary by - copying them. - A new (sig, args) tuple is yielded. - """ - newtys = [] - newargs = [] - copies = [] - for ty, val in zip(sig.args, args): - if not isinstance(ty, types.Array) or ty.layout in 'CF': - newty, newval = ty, val - else: - newty = ty.copy(layout='C') - copysig = signature(newty, ty) - newval = array_copy(context, builder, copysig, (val,)) - copies.append((newty, newval)) - newtys.append(newty) - newargs.append(newval) - yield signature(sig.return_type, *newtys), tuple(newargs) - for ty, val in copies: - context.nrt.decref(builder, ty, val) - -def check_c_int(context, builder, n): - """ - Check whether *n* fits in a C `int`. - """ - _maxint = 2**31 - 1 - - def impl(n): - if n > _maxint: - raise OverflowError("array size too large to fit in C int") - - context.compile_internal(builder, impl, - signature(types.none, types.intp), (n,)) - - -ll_char = ir.IntType(8) -ll_char_p = ll_char.as_pointer() -ll_void = ir.VoidType() -ll_void_p = ll_char_p -ll_intc = ir.IntType(32) -ll_intc_p = ll_intc.as_pointer() -intp_t = cgutils.intp_t -ll_intp_t = ir.IntType(64) -ll_intp_p = intp_t.as_pointer() - - -def ensure_dpnp(name): - try: - # import dpnp - from .dpnp_glue import dpnp_fptr_interface as dpnp_glue - except ImportError: - raise ImportError("dpNP is needed to call np.%s" % name) - -def get_total_size_of_array(context, builder, aty, ary): - total_size = cgutils.alloca_once(builder, ll_intp_t) - builder.store(builder.sext(builder.mul(ary.nitems, - context.get_constant(types.intp, context.get_abi_sizeof(context.get_value_type(aty)))), ll_intp_t), total_size) - return builder.load(total_size) - -def get_sycl_queue(context, builder): - void_ptr_t = context.get_value_type(types.voidptr) - get_queue_fnty = lc.Type.function(void_ptr_t, ()) - get_queue = builder.module.get_or_insert_function(get_queue_fnty, - name="DPCTLQueueMgr_GetCurrentQueue") - sycl_queue_val = cgutils.alloca_once(builder, void_ptr_t) - builder.store(builder.call(get_queue, []), sycl_queue_val) - - return sycl_queue_val - -def allocate_usm(context, builder, size, sycl_queue): - void_ptr_t = context.get_value_type(types.voidptr) - usm_shared_fnty = lc.Type.function(void_ptr_t, [ll_intp_t, void_ptr_t]) - usm_shared = builder.module.get_or_insert_function(usm_shared_fnty, - name="DPCTLmalloc_shared") - - buffer_ptr = cgutils.alloca_once(builder, void_ptr_t) - args = [size, builder.load(sycl_queue)] - builder.store(builder.call(usm_shared, args), buffer_ptr) - - return builder.load(buffer_ptr) - -def copy_usm(context, builder, src, dst, size, sycl_queue): - void_ptr_t = context.get_value_type(types.voidptr) - queue_memcpy_fnty = lc.Type.function(ir.VoidType(), [void_ptr_t, void_ptr_t, void_ptr_t, - ll_intp_t]) - queue_memcpy = builder.module.get_or_insert_function(queue_memcpy_fnty, - name="DPCTLQueue_Memcpy") - args = [builder.load(sycl_queue), - builder.bitcast(dst, void_ptr_t), - builder.bitcast(src, void_ptr_t), - size] - builder.call(queue_memcpy, args) - - -def free_usm(context, builder, usm_buf, sycl_queue): - void_ptr_t = context.get_value_type(types.voidptr) - - usm_free_fnty = lc.Type.function(ir.VoidType(), [void_ptr_t, void_ptr_t]) - usm_free = builder.module.get_or_insert_function(usm_free_fnty, - name="DPCTLfree_with_queue") - - builder.call(usm_free, [usm_buf, builder.load(sycl_queue)]) - - -def call_dpnp(context, builder, fn_name, type_names, params, param_tys, ret_ty): - from .dpnp_glue import dpnp_fptr_interface as dpnp_glue - f_ptr = dpnp_glue.get_dpnp_fn_ptr(fn_name, type_names) - - fnty = ir.FunctionType(ret_ty, param_tys) - addr_constant = context.get_constant(int64, f_ptr) - fn_ptr = builder.inttoptr(addr_constant, fnty.as_pointer()) - - res = builder.call(fn_ptr, params) - - -def dot_2_vv(context, builder, sig, args, conjugate=False): - """ - np.dot(vector, vector) - np.vdot(vector, vector) - """ - def check_args(a, b): - m, = a.shape - n, = b.shape - if m != n: - print("SIZES ", m, n) - raise ValueError("incompatible array sizes for np.dot(a, b) " - "(vector * vector)") - - context.compile_internal(builder, check_args, - signature(types.none, *sig.args), args) - - - sycl_queue = get_sycl_queue(context, builder) - aty, bty = sig.args - a = make_array(aty)(context, builder, args[0]) - b = make_array(bty)(context, builder, args[1]) - size, = cgutils.unpack_tuple(builder, a.shape) - - check_c_int(context, builder, size) - - total_size_a = get_total_size_of_array(context, builder, aty.dtype, a) - a_usm = allocate_usm(context, builder, total_size_a, sycl_queue) - copy_usm(context, builder, a.data, a_usm, total_size_a, sycl_queue) - - total_size_b = get_total_size_of_array(context, builder, bty.dtype, b) - b_usm = allocate_usm(context, builder, total_size_b, sycl_queue) - copy_usm(context, builder, b.data, b_usm, total_size_b, sycl_queue) - - out = cgutils.alloca_once(builder, context.get_value_type(sig.return_type)) - builder.store(context.get_constant(sig.return_type, 0), out) - out_usm = allocate_usm(context, builder, - context.get_constant(types.intp, context.get_abi_sizeof(context.get_value_type(sig.return_type))), sycl_queue) - - # arguments are : a->void*, b->void*, result->void*, size->int64 - param_tys = [ll_void_p, ll_void_p, ll_void_p, ir.IntType(64)] - params = (a_usm, b_usm, out_usm, size) - - type_names = [] - type_names.append(aty.dtype.name) - type_names.append(sig.return_type.name) - - call_dpnp(context, builder, "dpnp_dot", type_names, params, param_tys, ll_void) - - copy_usm(context, builder, out_usm, out, - context.get_constant(types.intp, context.get_abi_sizeof(context.get_value_type(sig.return_type))), sycl_queue) - - free_usm(context, builder, a_usm, sycl_queue) - free_usm(context, builder, out_usm, sycl_queue) - - return builder.load(out) - - -def dot_2_mv(context, builder, sig, args): - """ - np.dot(matrix, matrix) - """ - def make_res(a, b): - m, n = a.shape - _n, = b.shape - if _n != n: - raise ValueError("incompatible array sizes for np.dot(a, b)") - return np.empty((m, ), a.dtype) - - sycl_queue = get_sycl_queue(context, builder) - - aty, bty = sig.args - a = make_array(aty)(context, builder, args[0]) - b = make_array(bty)(context, builder, args[1]) - m, k = cgutils.unpack_tuple(builder, a.shape) - _n, = cgutils.unpack_tuple(builder, b.shape) - n = context.get_constant(types.int64, 1) - - total_size_a = get_total_size_of_array(context, builder, aty.dtype, a) - a_usm = allocate_usm(context, builder, total_size_a, sycl_queue) - copy_usm(context, builder, a.data, a_usm, total_size_a, sycl_queue) - - total_size_b = get_total_size_of_array(context, builder, bty.dtype, b) - b_usm = allocate_usm(context, builder, total_size_b, sycl_queue) - copy_usm(context, builder, b.data, b_usm, total_size_b, sycl_queue) - - out = context.compile_internal(builder, make_res, - signature(sig.return_type, *sig.args), args) - - outary = make_array(sig.return_type)(context, builder, out) - - total_size_out = get_total_size_of_array(context, builder, sig.return_type.dtype, outary) - out_usm = allocate_usm(context, builder, total_size_out, sycl_queue) - - # arguments are : a->void*, b->void*, result->void*, m->int64, n->int64, k->int64 - param_tys = [ll_void_p, ll_void_p, ll_void_p, ir.IntType(64), ir.IntType(64), ir.IntType(64)] - params = (a_usm, b_usm, out_usm, m, n, k) - - type_names = [] - type_names.append(aty.dtype.name) - type_names.append(sig.return_type.name) - - call_dpnp(context, builder, "dpnp_matmul", type_names, params, param_tys, ll_void) - - copy_usm(context, builder, out_usm, outary.data, total_size_out, sycl_queue) - - free_usm(context, builder, a_usm, sycl_queue) - free_usm(context, builder, b_usm, sycl_queue) - free_usm(context, builder, out_usm, sycl_queue) - return out - - -def dot_2_vm(context, builder, sig, args): - """ - np.dot(vector, matrix) - """ - def make_res(a, b): - m, = a.shape - _m, n = b.shape - if m != _m: - raise ValueError("incompatible array sizes for np.dot(a, b)") - return np.empty((n, ), a.dtype) - - sycl_queue = get_sycl_queue(context, builder) - aty, bty = sig.args - a = make_array(aty)(context, builder, args[0]) - b = make_array(bty)(context, builder, args[1]) - m, = cgutils.unpack_tuple(builder, a.shape) - k, n = cgutils.unpack_tuple(builder, b.shape) - - total_size_a = get_total_size_of_array(context, builder, aty.dtype, a) - a_usm = allocate_usm(context, builder, total_size_a, sycl_queue) - copy_usm(context, builder, a.data, a_usm, total_size_a, sycl_queue) - - total_size_b = get_total_size_of_array(context, builder, bty.dtype, b) - b_usm = allocate_usm(context, builder, total_size_b, sycl_queue) - copy_usm(context, builder, b.data, b_usm, total_size_b, sycl_queue) - - out = context.compile_internal(builder, make_res, - signature(sig.return_type, *sig.args), args) - - outary = make_array(sig.return_type)(context, builder, out) - - total_size_out = get_total_size_of_array(context, builder, sig.return_type.dtype, outary) - out_usm = allocate_usm(context, builder, total_size_out, sycl_queue) - - - # arguments are : a->void*, b->void*, result->void*, m->int64, n->int64, k->int64 - param_tys = [ll_void_p, ll_void_p, ll_void_p, ir.IntType(64), ir.IntType(64), ir.IntType(64)] - params = (a_usm, b_usm, out_usm, m, n, k) - - type_names = [] - type_names.append(aty.dtype.name) - type_names.append(sig.return_type.name) - - call_dpnp(context, builder, "dpnp_matmul", type_names, params, param_tys, ll_void) - - copy_usm(context, builder, out_usm, outary.data, total_size_out, sycl_queue) - - free_usm(context, builder, a_usm, sycl_queue) - free_usm(context, builder, b_usm, sycl_queue) - free_usm(context, builder, out_usm, sycl_queue) - return out - - -def dot_2_mm(context, builder, sig, args): - """ - np.dot(matrix, matrix), np.matmul(matrix, matrix) - """ - def make_res(a, b): - m, k = a.shape - _k, n = b.shape - if _k != k: - raise ValueError("incompatible array sizes for np.dot(a, b)") - return np.empty((m, n), a.dtype) - - sycl_queue = get_sycl_queue(context, builder) - aty, bty = sig.args - a = make_array(aty)(context, builder, args[0]) - b = make_array(bty)(context, builder, args[1]) - m, k = cgutils.unpack_tuple(builder, a.shape) - _k, n = cgutils.unpack_tuple(builder, b.shape) - - total_size_a = get_total_size_of_array(context, builder, aty.dtype, a) - a_usm = allocate_usm(context, builder, total_size_a, sycl_queue) - copy_usm(context, builder, a.data, a_usm, total_size_a, sycl_queue) - - total_size_b = get_total_size_of_array(context, builder, bty.dtype, b) - b_usm = allocate_usm(context, builder, total_size_b, sycl_queue) - copy_usm(context, builder, b.data, b_usm, total_size_b, sycl_queue) - - - out = context.compile_internal(builder, make_res, - signature(sig.return_type, *sig.args), args) - - outary = make_array(sig.return_type)(context, builder, out) - total_size_out = get_total_size_of_array(context, builder, sig.return_type.dtype, outary) - out_usm = allocate_usm(context, builder, total_size_out, sycl_queue) - - - # arguments are : a->void*, b->void*, result->void*, m->int64, n->int64, k->int64 - param_tys = [ll_void_p, ll_void_p, ll_void_p, ir.IntType(64), ir.IntType(64), ir.IntType(64)] - params = (a_usm, - b_usm, - out_usm, - m, n, k) - - type_names = [] - type_names.append(aty.dtype.name) - type_names.append(sig.return_type.name) - - call_dpnp(context, builder, "dpnp_matmul", type_names, params, param_tys, ll_void) - - copy_usm(context, builder, out_usm, outary.data, total_size_out, sycl_queue) - - free_usm(context, builder, a_usm, sycl_queue) - free_usm(context, builder, b_usm, sycl_queue) - free_usm(context, builder, out_usm, sycl_queue) - return out - - -@lower_builtin(np.dot, types.Array, types.Array) -def dot_dppy(context, builder, sig, args): - """ - np.dot(a, b) - a @ b - """ - - ensure_dpnp("dot") - - with make_contiguous(context, builder, sig, args) as (sig, args): - ndims = [x.ndim for x in sig.args[:2]] - if ndims == [2, 2]: - return dot_2_mm(context, builder, sig, args) - elif ndims == [2, 1]: - return dot_2_mv(context, builder, sig, args) - elif ndims == [1, 2]: - return dot_2_vm(context, builder, sig, args) - elif ndims == [1, 1]: - return dot_2_vv(context, builder, sig, args) - else: - assert 0 - raise ImportError("scipy 0.16+ is required for linear algebra") - - -@lower_builtin("np.matmul", types.Array, types.Array) -def matmul_dppy(context, builder, sig, args): - """ - np.matmul(matrix, matrix) - """ - ensure_dpnp("matmul") - with make_contiguous(context, builder, sig, args) as (sig, args): - ndims = [x.ndim for x in sig.args[:2]] - if ndims != [2, 2]: - raise ValueError("array dimension has to be 2 for np.matmul(a, b)") - - return dot_2_mm(context, builder, sig, args) - - -def common_sum_prod_impl(context, builder, sig, args, fn_type): - def array_size_checker(arry): - if arry.size == 0: - raise ValueError("Passed Empty array") - - context.compile_internal(builder, array_size_checker, - signature(types.none, *sig.args), args) - - sycl_queue = get_sycl_queue(context, builder) - - aty = sig.args[0] - a = make_array(aty)(context, builder, args[0]) - size = a.nitems - - total_size_a = get_total_size_of_array(context, builder, aty.dtype, a) - a_usm = allocate_usm(context, builder, total_size_a, sycl_queue) - copy_usm(context, builder, a.data, a_usm, total_size_a, sycl_queue) - - out = cgutils.alloca_once(builder, context.get_value_type(sig.return_type)) - builder.store(context.get_constant(sig.return_type, 0), out) - out_usm = allocate_usm(context, builder, - context.get_constant(types.intp, context.get_abi_sizeof(context.get_value_type(aty.dtype))), sycl_queue) - - # arguments are : a ->void*, result->void*, size->int64 - param_tys = [ll_void_p, ll_void_p, ir.IntType(64)] - params = (a_usm, out_usm, size) - - type_names = [] - type_names.append(aty.dtype.name) - type_names.append("NONE") - - call_dpnp(context, builder, fn_type, type_names, params, param_tys, ll_void) - - copy_usm(context, builder, out_usm, out, - context.get_constant(types.intp, context.get_abi_sizeof(context.get_value_type(aty.dtype))), sycl_queue) - - free_usm(context, builder, a_usm, sycl_queue) - free_usm(context, builder, out_usm, sycl_queue) - - return builder.load(out) - - - -@lower_builtin(np.sum, types.Array) -def array_sum(context, builder, sig, args): - ensure_dpnp("sum") - return common_sum_prod_impl(context, builder, sig, args, "dpnp_sum") - - -@lower_builtin(np.prod, types.Array) -def array_prod(context, builder, sig, args): - ensure_dpnp("prod") - - return common_sum_prod_impl(context, builder, sig, args, "dpnp_prod") - - -def common_max_min_impl(context, builder, sig, args, fn_type): - def array_size_checker(arry): - if arry.size == 0: - raise ValueError("Passed Empty array") - - context.compile_internal(builder, array_size_checker, - signature(types.none, *sig.args), args) - - sycl_queue = get_sycl_queue(context, builder) - import pdb - pdb.set_trace() - - aty = sig.args[0] - a = make_array(aty)(context, builder, args[0]) - a_shape = builder.gep(args[0].operands[0], [context.get_constant(types.int32, 0), context.get_constant(types.int32, 5)]) - a_ndim = context.get_constant(types.intp, aty.ndim) - - total_size_a = get_total_size_of_array(context, builder, aty.dtype, a) - a_usm = allocate_usm(context, builder, total_size_a, sycl_queue) - copy_usm(context, builder, a.data, a_usm, total_size_a, sycl_queue) - - out = cgutils.alloca_once(builder, context.get_value_type(sig.return_type)) - builder.store(context.get_constant(sig.return_type, 0), out) - out_usm = allocate_usm(context, builder, - context.get_constant(types.intp, context.get_abi_sizeof(context.get_value_type(sig.return_type))), sycl_queue) - - # arguments are : a ->void*, result->void* - param_tys = [ll_void_p, ll_void_p, ll_intp_p, ir.IntType(64), ll_intp_p, ir.IntType(64)] - params = (a_usm, out_usm, builder.bitcast(a_shape, ll_intp_p), a_ndim, - builder.bitcast(a_shape, ll_intp_p), a_ndim) - - type_names = [] - type_names.append(aty.dtype.name) - if fn_type == "dpnp_mean": - type_names.append(aty.dtype.name) - else: - type_names.append(sig.return_type.name) - - call_dpnp(context, builder, fn_type, type_names, params, param_tys, ll_void) - - copy_usm(context, builder, out_usm, out, - context.get_constant(types.intp, context.get_abi_sizeof(context.get_value_type(sig.return_type))), sycl_queue) - - free_usm(context, builder, a_usm, sycl_queue) - free_usm(context, builder, out_usm, sycl_queue) - - return builder.load(out) - - -@lower_builtin(np.max, types.Array) -@lower_builtin("array.max", types.Array) -def array_max(context, builder, sig, args): - print("ASDASDAS") - ensure_dpnp("max") - - return common_max_min_impl(context, builder, sig, args, "dpnp_max") - -@lower_builtin(np.min, types.Array) -@lower_builtin("array.min", types.Array) -def array_min(context, builder, sig, args): - ensure_dpnp("min") - - return common_max_min_impl(context, builder, sig, args, "dpnp_min") - -@lower_builtin(np.mean, types.Array) -@lower_builtin("array.mean", types.Array) -def array_mean(context, builder, sig, args): - ensure_dpnp("mean") - - return common_max_min_impl(context, builder, sig, args, "dpnp_mean") - -@lower_builtin(np.median, types.Array) -def array_median(context, builder, sig, args): - ensure_dpnp("median") - - return common_max_min_impl(context, builder, sig, args, "dpnp_median") - - -def common_argmax_argmin_impl(context, builder, sig, args, fn_type): - def array_size_checker(arry): - if arry.size == 0: - raise ValueError("Passed Empty array") - - context.compile_internal(builder, array_size_checker, - signature(types.none, *sig.args), args) - - sycl_queue = get_sycl_queue(context, builder) - - aty = sig.args[0] - a = make_array(aty)(context, builder, args[0]) - size = a.nitems - - total_size_a = get_total_size_of_array(context, builder, aty.dtype, a) - a_usm = allocate_usm(context, builder, total_size_a, sycl_queue) - copy_usm(context, builder, a.data, a_usm, total_size_a, sycl_queue) - - out = cgutils.alloca_once(builder, context.get_value_type(sig.return_type)) - builder.store(context.get_constant(sig.return_type, 0), out) - out_usm = allocate_usm(context, builder, - context.get_constant(types.intp, context.get_abi_sizeof(context.get_value_type(sig.return_type))), sycl_queue) - - # arguments are : a ->void*, result->void*, size->int64 - param_tys = [ll_void_p, ll_void_p, ir.IntType(64)] - params = (a_usm, out_usm, size) - - type_names = [] - type_names.append(aty.dtype.name) - type_names.append(sig.return_type.name) - - call_dpnp(context, builder, fn_type, type_names, params, param_tys, ll_void) - - copy_usm(context, builder, out_usm, out, - context.get_constant(types.intp, context.get_abi_sizeof(context.get_value_type(sig.return_type))), sycl_queue) - - free_usm(context, builder, a_usm, sycl_queue) - free_usm(context, builder, out_usm, sycl_queue) - - return builder.load(out) - - - -@lower_builtin(np.argmax, types.Array) -def array_argmax(context, builder, sig, args): - ensure_dpnp("argmax") - - return common_argmax_argmin_impl(context, builder, sig, args, "dpnp_argmax") - - -@lower_builtin(np.argmin, types.Array) -def array_argmin(context, builder, sig, args): - ensure_dpnp("argmin") - - return common_argmax_argmin_impl(context, builder, sig, args, "dpnp_argmin") - - -@lower_builtin(np.argsort, types.Array, types.StringLiteral) -def array_argsort(context, builder, sig, args): - ensure_dpnp("argsort") - - def make_res(A): - return np.arange(A.size) - - def array_dim_checker(arry): - if arry.ndim > 1: - raise ValueError("Argsort is only supported for 1D array") - - context.compile_internal(builder, array_dim_checker, - signature(types.none, *sig.args[:1]), args[:1]) - - sycl_queue = get_sycl_queue(context, builder) - aty = sig.args[0] - a = make_array(aty)(context, builder, args[0]) - size, = cgutils.unpack_tuple(builder, a.shape) - - total_size_a = get_total_size_of_array(context, builder, aty.dtype, a) - a_usm = allocate_usm(context, builder, total_size_a, sycl_queue) - copy_usm(context, builder, a.data, a_usm, total_size_a, sycl_queue) - - out = context.compile_internal(builder, make_res, - signature(sig.return_type, *sig.args[:1]), args[:1]) - outary = make_array(sig.return_type)(context, builder, out) - - total_size_out = get_total_size_of_array(context, builder, sig.return_type.dtype, outary) - out_usm = allocate_usm(context, builder, total_size_out, sycl_queue) - - - # arguments are : a ->void*, result->void*, size->int64 - param_tys = [ll_void_p, ll_void_p, ir.IntType(64)] - params = (a_usm, out_usm, size) - - type_names = [] - for argty in sig.args[:1]: - type_names.append(argty.dtype.name) - type_names.append(sig.return_type.name) - - call_dpnp(context, builder, "dpnp_argsort", type_names, params, param_tys, ll_void) - - copy_usm(context, builder, out_usm, outary.data, total_size_out, sycl_queue) - - free_usm(context, builder, a_usm, sycl_queue) - free_usm(context, builder, out_usm, sycl_queue) - - return out - - -@lower_builtin(np.cov, types.Array) -def array_cov(context, builder, sig, args): - ensure_dpnp("cov") - def make_1D_res(size): - return np.empty(1, dtype=np.float64) - - def make_2D_res(size): - return np.empty((size, size), dtype=np.float64) - - sycl_queue = get_sycl_queue(context, builder) - aty = sig.args[0] - aty = sig.args[0] - a = make_array(aty)(context, builder, args[0]) - - total_size_a = get_total_size_of_array(context, builder, aty.dtype, a) - a_usm = allocate_usm(context, builder, total_size_a, sycl_queue) - copy_usm(context, builder, a.data, a_usm, total_size_a, sycl_queue) - - if aty.ndim == 2: - m, n = cgutils.unpack_tuple(builder, a.shape) - out = context.compile_internal(builder, make_2D_res, - signature(sig.return_type, types.int64), (m,)) - elif aty.ndim == 1: - m, = cgutils.unpack_tuple(builder, a.shape) - out = context.compile_internal(builder, make_1D_res, - signature(sig.return_type, types.int64), (m,)) - else: - #TODO: Throw error, cov is supported for only 1D and 2D array - pass - - outary = make_array(sig.return_type)(context, builder, out) - - total_size_out = get_total_size_of_array(context, builder, sig.return_type.dtype, outary) - out_usm = allocate_usm(context, builder, total_size_out, sycl_queue) - - nrows = cgutils.alloca_once(builder, context.get_value_type(types.int64)) - ncols = cgutils.alloca_once(builder, context.get_value_type(types.int64)) - - if aty.ndim == 2: - builder.store(m, nrows) - builder.store(n, ncols) - - elif aty.ndim == 1: - builder.store(context.get_constant(types.int64, 1), nrows) - builder.store(m, ncols) - - - # arguments are : a ->void*, result->void*, nrows->int64, ncols->int64 - param_tys = [ll_void_p, ll_void_p, ir.IntType(64), ir.IntType(64)] - params = (a_usm, out_usm, builder.load(nrows), builder.load(ncols)) - - type_names = [] - type_names.append(aty.dtype.name) - type_names.append("NONE") - - - call_dpnp(context, builder, "dpnp_cov", type_names, params, param_tys, ll_void) - - copy_usm(context, builder, out_usm, outary.data, total_size_out, sycl_queue) - - free_usm(context, builder, a_usm, sycl_queue) - free_usm(context, builder, out_usm, sycl_queue) - - return out - - -''' -@lower_builtin(np.linalg.eig, types.Array) -def array_cov(context, builder, sig, args): - pass - -@lower_builtin("np.random.sample") -def random_impl(context, builder, sig, args): - - def make_res(shape): - return np.empty(shape, dtype=np.float64) - - import pdb - pdb.set_trace() - out = context.compile_internal(builder, make_res, - signature(sig.return_type, *sig.args), args) - - outary = make_array(sig.return_type)(context, builder, out) - - # arguments are : result->void*, size->int64 - param_tys = [ll_void_p, ll_intp_p] - params = (builder.bitcast(outary.data, ll_void_p), ) - - - type_names = [] - for argty in sig.args[:1]: - type_names.append(argty.dtype.name.encode('utf-8')) - type_names.append(sig.return_type.name.encode('utf-8')) - - call_dpnp(context, builder, b"dpnp_cov", type_names, params, param_tys, ll_void) -''' From 7b2c1acbe313124b65acb472b60dfdc0b9f4e437 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Mon, 14 Dec 2020 20:54:17 -0600 Subject: [PATCH 27/34] Print cleanup --- numba_dppy/dpnp_glue/dpnp_linalgimpl.py | 5 ----- numba_dppy/dpnp_glue/dpnp_sort_search_countimpl.py | 3 --- numba_dppy/dpnp_glue/dpnp_statisticsimpl.py | 7 ------- numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py | 2 -- 4 files changed, 17 deletions(-) diff --git a/numba_dppy/dpnp_glue/dpnp_linalgimpl.py b/numba_dppy/dpnp_glue/dpnp_linalgimpl.py index 598283bc10..9146299b05 100644 --- a/numba_dppy/dpnp_glue/dpnp_linalgimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_linalgimpl.py @@ -67,7 +67,6 @@ def dpnp_eig_impl(a): free_usm(vr_usm, sycl_queue) dpnp_ext._dummy_liveness_func([wr.size, vr.size]) - print("CCCC") return (wr, vr) @@ -165,7 +164,6 @@ def dot_2_mm(a, b): free_usm(out_usm, sycl_queue) dpnp_ext._dummy_liveness_func([a.size, b.size, out.size]) - print("MM") return out @@ -200,7 +198,6 @@ def dot_2_mv(a, b): free_usm(out_usm, sycl_queue) dpnp_ext._dummy_liveness_func([a.size, b.size, out.size]) - print("MV") return out @@ -234,7 +231,6 @@ def dot_2_vm(a, b): free_usm(out_usm, sycl_queue) dpnp_ext._dummy_liveness_func([a.size, b.size, out.size]) - print("VM") return out @@ -271,7 +267,6 @@ def dot_2_vv(a, b): dpnp_ext._dummy_liveness_func([a.size, b.size, out.size]) - print("VV") return out[0] return dot_2_vv diff --git a/numba_dppy/dpnp_glue/dpnp_sort_search_countimpl.py b/numba_dppy/dpnp_glue/dpnp_sort_search_countimpl.py index f129757a29..8ec200059b 100644 --- a/numba_dppy/dpnp_glue/dpnp_sort_search_countimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_sort_search_countimpl.py @@ -52,7 +52,6 @@ def dpnp_impl(a): dpnp_ext._dummy_liveness_func([a.size, out.size]) - print("HH") return out[0] return dpnp_impl @@ -103,7 +102,6 @@ def dpnp_impl(a): dpnp_ext._dummy_liveness_func([a.size, out.size]) - print("II") return out[0] return dpnp_impl @@ -154,7 +152,6 @@ def dpnp_impl(a): dpnp_ext._dummy_liveness_func([a.size, out.size]) - print("JJ") return out return dpnp_impl diff --git a/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py b/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py index b831f4280a..cae9507902 100644 --- a/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_statisticsimpl.py @@ -59,7 +59,6 @@ def dpnp_impl(a): dpnp_ext._dummy_liveness_func([out.size]) - print("DDD") return out[0] return dpnp_impl @@ -117,7 +116,6 @@ def dpnp_impl(a): dpnp_ext._dummy_liveness_func([out.size]) - print("EEE") return out[0] return dpnp_impl @@ -177,7 +175,6 @@ def dpnp_impl(a): free_usm(out_usm, sycl_queue) dpnp_ext._dummy_liveness_func([a.size, out.size]) - print("FFFF") return out[0] return dpnp_impl @@ -238,7 +235,6 @@ def dpnp_impl(a): dpnp_ext._dummy_liveness_func([a.size, out.size]) - print("GG") return out[0] return dpnp_impl @@ -308,12 +304,9 @@ def dpnp_impl(a): dpnp_ext._dummy_liveness_func([a_copy_in_double.size, a.size, out.size]) - print("KK") if a.ndim == 2: return out elif a.ndim == 1: return out[0] return dpnp_impl - - diff --git a/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py b/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py index 161eb37e43..f7ba425206 100644 --- a/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py +++ b/numba_dppy/dpnp_glue/dpnp_transcendentalsimpl.py @@ -50,7 +50,6 @@ def dpnp_impl(a): dpnp_ext._dummy_liveness_func([out.size]) - print("AAAAA") return out[0] return dpnp_impl @@ -98,7 +97,6 @@ def dpnp_impl(a): dpnp_ext._dummy_liveness_func([out.size]) - print("BBB") return out[0] return dpnp_impl From e11a68934f5e2fa52b52b44a06da8054313b9c9a Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Tue, 15 Dec 2020 12:12:58 -0600 Subject: [PATCH 28/34] We now support np.amax, we need to update our reduction example --- numba_dppy/tests/test_dppy_fallback.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/numba_dppy/tests/test_dppy_fallback.py b/numba_dppy/tests/test_dppy_fallback.py index 3a7e668f02..dd05bbdc84 100644 --- a/numba_dppy/tests/test_dppy_fallback.py +++ b/numba_dppy/tests/test_dppy_fallback.py @@ -34,7 +34,10 @@ def inner_call_fallback(): def test_dppy_fallback_reductions(self): def reduction(a): - return np.amax(a) + b = 1 + for i in numba.prange(len(a)): + b += a[i] + return b a = np.ones(10) with captured_stderr() as msg, dpctl.device_context("opencl:gpu"): From 71dcb053b909803f165730038cf723a5c529ff59 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Tue, 15 Dec 2020 13:24:31 -0600 Subject: [PATCH 29/34] Update test to match result with tolerance --- numba_dppy/tests/test_numpy_math_functions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/numba_dppy/tests/test_numpy_math_functions.py b/numba_dppy/tests/test_numpy_math_functions.py index 0d19193cb7..cf5174ac96 100644 --- a/numba_dppy/tests/test_numpy_math_functions.py +++ b/numba_dppy/tests/test_numpy_math_functions.py @@ -218,7 +218,8 @@ def f(a): c = f(input_arr) d = np.exp(input_arr) - self.assertTrue(np.all(c == d)) + max_abs_err = c.sum() - d.sum() + self.assertTrue(max_abs_err < 1e-5) def test_log(self): @njit From c91d640480e2084d5e51a4c98f62731edafab9fd Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Wed, 16 Dec 2020 09:58:23 -0600 Subject: [PATCH 30/34] Add skipping tests --- numba_dppy/tests/test_numpy_math_functions.py | 14 ++++++++++++++ .../tests/test_numpy_trigonomteric_functions.py | 11 +++++++++++ 2 files changed, 25 insertions(+) diff --git a/numba_dppy/tests/test_numpy_math_functions.py b/numba_dppy/tests/test_numpy_math_functions.py index cf5174ac96..d030fbb5e5 100644 --- a/numba_dppy/tests/test_numpy_math_functions.py +++ b/numba_dppy/tests/test_numpy_math_functions.py @@ -4,6 +4,15 @@ import dpctl import unittest +def skip_tests(device_type): + with dpctl.device_context(device_type): + q = dpctl.get_current_queue() + device = q.get_sycl_device() + name = device.get_device_name() + if ("Gen12LP HD Graphics NEO" in name) or ("Gen12HP HD Graphics NEO" in name): + return True + + return False @unittest.skipUnless(dpctl.has_gpu_queues(), 'test only on GPU system') class TestNumpy_math_functions(unittest.TestCase): @@ -22,6 +31,7 @@ def f(a, b): d = self.a + self.b self.assertTrue(np.all(c == d)) + skip_tests("opencl:gpu") def test_subtract(self): @njit @@ -179,6 +189,7 @@ def f(a): self.assertTrue(np.all(c == -input_arr)) + @unittest.skipIf(skip_tests("opencl:gpu"), "skipping test") def test_sign(self): @njit def f(a): @@ -221,6 +232,7 @@ def f(a): max_abs_err = c.sum() - d.sum() self.assertTrue(max_abs_err < 1e-5) + @unittest.skipIf(skip_tests("opencl:gpu"), "skipping test") def test_log(self): @njit def f(a): @@ -236,6 +248,7 @@ def f(a): max_abs_err = c.sum() - d.sum() self.assertTrue(max_abs_err < 1e-5) + @unittest.skipIf(skip_tests("opencl:gpu"), "skipping test") def test_log10(self): @njit def f(a): @@ -251,6 +264,7 @@ def f(a): max_abs_err = c.sum() - d.sum() self.assertTrue(max_abs_err < 1e-5) + @unittest.skipIf(skip_tests("opencl:gpu"), "skipping test") def test_expm1(self): @njit def f(a): diff --git a/numba_dppy/tests/test_numpy_trigonomteric_functions.py b/numba_dppy/tests/test_numpy_trigonomteric_functions.py index 7c0a95d323..12fcf813e2 100644 --- a/numba_dppy/tests/test_numpy_trigonomteric_functions.py +++ b/numba_dppy/tests/test_numpy_trigonomteric_functions.py @@ -4,6 +4,16 @@ import dpctl import unittest +def skip_tests(device_type): + with dpctl.device_context(device_type): + q = dpctl.get_current_queue() + device = q.get_sycl_device() + name = device.get_device_name() + if ("Gen12LP HD Graphics NEO" in name) or ("Gen12HP HD Graphics NEO" in name): + return True + + return False + @unittest.skipUnless(dpctl.has_gpu_queues(), 'test only on GPU system') class TestNumpy_math_functions(unittest.TestCase): @@ -155,6 +165,7 @@ def f(a): max_abs_err = c.sum() - d.sum() self.assertTrue(max_abs_err < 1e-5) + @unittest.skipIf(skip_tests("opencl:gpu"), "skipping test") def test_arccosh(self): @njit def f(a): From feea9b06c83358515648e5cfb2bf543a64e7e209 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Wed, 16 Dec 2020 10:15:01 -0600 Subject: [PATCH 31/34] remove artifacts of checking --- numba_dppy/tests/test_numpy_math_functions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/numba_dppy/tests/test_numpy_math_functions.py b/numba_dppy/tests/test_numpy_math_functions.py index d030fbb5e5..979c3b886b 100644 --- a/numba_dppy/tests/test_numpy_math_functions.py +++ b/numba_dppy/tests/test_numpy_math_functions.py @@ -31,7 +31,6 @@ def f(a, b): d = self.a + self.b self.assertTrue(np.all(c == d)) - skip_tests("opencl:gpu") def test_subtract(self): @njit From 8e031db1a158ccc244e0547d4282972b6613fa69 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Wed, 16 Dec 2020 10:52:14 -0600 Subject: [PATCH 32/34] Change search string --- numba_dppy/tests/test_numpy_math_functions.py | 2 +- numba_dppy/tests/test_numpy_trigonomteric_functions.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/numba_dppy/tests/test_numpy_math_functions.py b/numba_dppy/tests/test_numpy_math_functions.py index 979c3b886b..de61e2ab40 100644 --- a/numba_dppy/tests/test_numpy_math_functions.py +++ b/numba_dppy/tests/test_numpy_math_functions.py @@ -9,7 +9,7 @@ def skip_tests(device_type): q = dpctl.get_current_queue() device = q.get_sycl_device() name = device.get_device_name() - if ("Gen12LP HD Graphics NEO" in name) or ("Gen12HP HD Graphics NEO" in name): + if "Gen12" in name: return True return False diff --git a/numba_dppy/tests/test_numpy_trigonomteric_functions.py b/numba_dppy/tests/test_numpy_trigonomteric_functions.py index 12fcf813e2..bfd2d11de3 100644 --- a/numba_dppy/tests/test_numpy_trigonomteric_functions.py +++ b/numba_dppy/tests/test_numpy_trigonomteric_functions.py @@ -9,7 +9,7 @@ def skip_tests(device_type): q = dpctl.get_current_queue() device = q.get_sycl_device() name = device.get_device_name() - if ("Gen12LP HD Graphics NEO" in name) or ("Gen12HP HD Graphics NEO" in name): + if "Gen12" in name: return True return False From 4b778bce4afe6112dca35fe024bbb3d9d5d861d8 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Wed, 16 Dec 2020 17:26:19 -0600 Subject: [PATCH 33/34] Remove duplication --- numba_dppy/tests/skip_tests.py | 11 +++++++++++ numba_dppy/tests/test_numpy_math_functions.py | 19 +++++-------------- .../test_numpy_trigonomteric_functions.py | 13 ++----------- 3 files changed, 18 insertions(+), 25 deletions(-) create mode 100644 numba_dppy/tests/skip_tests.py diff --git a/numba_dppy/tests/skip_tests.py b/numba_dppy/tests/skip_tests.py new file mode 100644 index 0000000000..fa18d36181 --- /dev/null +++ b/numba_dppy/tests/skip_tests.py @@ -0,0 +1,11 @@ +import dpctl + +def is_gen12(device_type): + with dpctl.device_context(device_type): + q = dpctl.get_current_queue() + device = q.get_sycl_device() + name = device.get_device_name() + if "Gen12" in name: + return True + + return False diff --git a/numba_dppy/tests/test_numpy_math_functions.py b/numba_dppy/tests/test_numpy_math_functions.py index de61e2ab40..1421f66d82 100644 --- a/numba_dppy/tests/test_numpy_math_functions.py +++ b/numba_dppy/tests/test_numpy_math_functions.py @@ -3,16 +3,7 @@ from numba import njit import dpctl import unittest - -def skip_tests(device_type): - with dpctl.device_context(device_type): - q = dpctl.get_current_queue() - device = q.get_sycl_device() - name = device.get_device_name() - if "Gen12" in name: - return True - - return False +from . import skip_tests @unittest.skipUnless(dpctl.has_gpu_queues(), 'test only on GPU system') class TestNumpy_math_functions(unittest.TestCase): @@ -188,7 +179,7 @@ def f(a): self.assertTrue(np.all(c == -input_arr)) - @unittest.skipIf(skip_tests("opencl:gpu"), "skipping test") + @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "skipping test") def test_sign(self): @njit def f(a): @@ -231,7 +222,7 @@ def f(a): max_abs_err = c.sum() - d.sum() self.assertTrue(max_abs_err < 1e-5) - @unittest.skipIf(skip_tests("opencl:gpu"), "skipping test") + @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "skipping test") def test_log(self): @njit def f(a): @@ -247,7 +238,7 @@ def f(a): max_abs_err = c.sum() - d.sum() self.assertTrue(max_abs_err < 1e-5) - @unittest.skipIf(skip_tests("opencl:gpu"), "skipping test") + @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "skipping test") def test_log10(self): @njit def f(a): @@ -263,7 +254,7 @@ def f(a): max_abs_err = c.sum() - d.sum() self.assertTrue(max_abs_err < 1e-5) - @unittest.skipIf(skip_tests("opencl:gpu"), "skipping test") + @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "skipping test") def test_expm1(self): @njit def f(a): diff --git a/numba_dppy/tests/test_numpy_trigonomteric_functions.py b/numba_dppy/tests/test_numpy_trigonomteric_functions.py index bfd2d11de3..7b75bdf889 100644 --- a/numba_dppy/tests/test_numpy_trigonomteric_functions.py +++ b/numba_dppy/tests/test_numpy_trigonomteric_functions.py @@ -3,16 +3,7 @@ from numba import njit import dpctl import unittest - -def skip_tests(device_type): - with dpctl.device_context(device_type): - q = dpctl.get_current_queue() - device = q.get_sycl_device() - name = device.get_device_name() - if "Gen12" in name: - return True - - return False +from . import skip_tests @unittest.skipUnless(dpctl.has_gpu_queues(), 'test only on GPU system') @@ -165,7 +156,7 @@ def f(a): max_abs_err = c.sum() - d.sum() self.assertTrue(max_abs_err < 1e-5) - @unittest.skipIf(skip_tests("opencl:gpu"), "skipping test") + @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "skipping test") def test_arccosh(self): @njit def f(a): From 23700d27044e5a1039a6ca91183962e015807758 Mon Sep 17 00:00:00 2001 From: "reazul.hoque" Date: Wed, 16 Dec 2020 17:36:52 -0600 Subject: [PATCH 34/34] Update skip message --- numba_dppy/tests/test_numpy_math_functions.py | 8 ++++---- numba_dppy/tests/test_numpy_trigonomteric_functions.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/numba_dppy/tests/test_numpy_math_functions.py b/numba_dppy/tests/test_numpy_math_functions.py index 1421f66d82..ef5dc235b8 100644 --- a/numba_dppy/tests/test_numpy_math_functions.py +++ b/numba_dppy/tests/test_numpy_math_functions.py @@ -179,7 +179,7 @@ def f(a): self.assertTrue(np.all(c == -input_arr)) - @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "skipping test") + @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "Gen12 not supported") def test_sign(self): @njit def f(a): @@ -222,7 +222,7 @@ def f(a): max_abs_err = c.sum() - d.sum() self.assertTrue(max_abs_err < 1e-5) - @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "skipping test") + @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "Gen12 not supported") def test_log(self): @njit def f(a): @@ -238,7 +238,7 @@ def f(a): max_abs_err = c.sum() - d.sum() self.assertTrue(max_abs_err < 1e-5) - @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "skipping test") + @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "Gen12 not supported") def test_log10(self): @njit def f(a): @@ -254,7 +254,7 @@ def f(a): max_abs_err = c.sum() - d.sum() self.assertTrue(max_abs_err < 1e-5) - @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "skipping test") + @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "Gen12 not supported") def test_expm1(self): @njit def f(a): diff --git a/numba_dppy/tests/test_numpy_trigonomteric_functions.py b/numba_dppy/tests/test_numpy_trigonomteric_functions.py index 7b75bdf889..812f3d060c 100644 --- a/numba_dppy/tests/test_numpy_trigonomteric_functions.py +++ b/numba_dppy/tests/test_numpy_trigonomteric_functions.py @@ -156,7 +156,7 @@ def f(a): max_abs_err = c.sum() - d.sum() self.assertTrue(max_abs_err < 1e-5) - @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "skipping test") + @unittest.skipIf(skip_tests.is_gen12("opencl:gpu"), "Gen12 not supported") def test_arccosh(self): @njit def f(a):