diff options
| author | mattip <matti.picus@gmail.com> | 2023-01-23 21:18:05 +0200 |
|---|---|---|
| committer | mattip <matti.picus@gmail.com> | 2023-01-30 21:32:35 +0200 |
| commit | 7910e2bf14b8bef95c3180fbf667458e29426a0e (patch) | |
| tree | b2442cad1940633758dabb9b2113dc101dfb7de9 /numpy/core/src | |
| parent | 3ba259d20ec57052ee8df915eab308370e4a7bae (diff) | |
| download | numpy-7910e2bf14b8bef95c3180fbf667458e29426a0e.tar.gz | |
ENH: add indexed lower loops and connect them to ufuncs
Diffstat (limited to 'numpy/core/src')
| -rw-r--r-- | numpy/core/src/multiarray/argfunc.dispatch.c.src | 4 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/array_method.c | 5 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/array_method.h | 4 | ||||
| -rw-r--r-- | numpy/core/src/umath/loops.c.src | 49 | ||||
| -rw-r--r-- | numpy/core/src/umath/loops.h.src | 21 | ||||
| -rw-r--r-- | numpy/core/src/umath/loops_arithm_fp.dispatch.c.src | 14 | ||||
| -rw-r--r-- | numpy/core/src/umath/loops_arithmetic.dispatch.c.src | 42 |
7 files changed, 126 insertions, 13 deletions
diff --git a/numpy/core/src/multiarray/argfunc.dispatch.c.src b/numpy/core/src/multiarray/argfunc.dispatch.c.src index 1d7753275..88c1028dc 100644 --- a/numpy/core/src/multiarray/argfunc.dispatch.c.src +++ b/numpy/core/src/multiarray/argfunc.dispatch.c.src @@ -194,7 +194,7 @@ simd_@func@_@sfx@(npyv_lanetype_@sfx@ *ip, npy_intp len) npyv_@bsfx@ nnan_ab = npyv_and_@bsfx@(nnan_a, nnan_b); npyv_@bsfx@ nnan_cd = npyv_and_@bsfx@(nnan_c, nnan_d); npy_uint64 nnan = npyv_tobits_@bsfx@(npyv_and_@bsfx@(nnan_ab, nnan_cd)); - if (nnan != ((1LL << vstep) - 1)) { + if ((long long int)nnan != ((1LL << vstep) - 1)) { npy_uint64 nnan_4[4]; nnan_4[0] = npyv_tobits_@bsfx@(nnan_a); nnan_4[1] = npyv_tobits_@bsfx@(nnan_b); @@ -219,7 +219,7 @@ simd_@func@_@sfx@(npyv_lanetype_@sfx@ *ip, npy_intp len) #if @is_fp@ npyv_@bsfx@ nnan_a = npyv_notnan_@sfx@(a); npy_uint64 nnan = npyv_tobits_@bsfx@(nnan_a); - if (nnan != ((1LL << vstep) - 1)) { + if ((long long int)nnan != ((1LL << vstep) - 1)) { for (int vi = 0; vi < vstep; ++vi) { if (!((nnan >> vi) & 1)) { return i + vi; diff --git a/numpy/core/src/multiarray/array_method.c b/numpy/core/src/multiarray/array_method.c index eeebf2d9b..5001a67e9 100644 --- a/numpy/core/src/multiarray/array_method.c +++ b/numpy/core/src/multiarray/array_method.c @@ -291,6 +291,9 @@ fill_arraymethod_from_slots( case NPY_METH_get_reduction_initial: meth->get_reduction_initial = slot->pfunc; continue; + case NPY_METH_contiguous_indexed_loop: + meth->contiguous_indexed_loop = slot->pfunc; + continue; default: break; } @@ -891,7 +894,7 @@ generic_masked_strided_loop(PyArrayMethod_Context *context, /* * Fetches a strided-loop function that supports a boolean mask as additional * (last) operand to the strided-loop. It is otherwise largely identical to - * the `get_loop` method which it wraps. + * the `get_strided_loop` method which it wraps. * This is the core implementation for the ufunc `where=...` keyword argument. * * NOTE: This function does not support `move_references` or inner dimensions. diff --git a/numpy/core/src/multiarray/array_method.h b/numpy/core/src/multiarray/array_method.h index ef4648443..138df69fa 100644 --- a/numpy/core/src/multiarray/array_method.h +++ b/numpy/core/src/multiarray/array_method.h @@ -73,7 +73,7 @@ struct PyArrayMethodObject_tag; * TODO: Before making this public, we should review which information should * be stored on the Context/BoundArrayMethod vs. the ArrayMethod. */ -typedef struct { +typedef struct PyArrayMethod_Context_tag { PyObject *caller; /* E.g. the original ufunc, may be NULL */ struct PyArrayMethodObject_tag *method; @@ -223,6 +223,7 @@ typedef struct PyArrayMethodObject_tag { PyArrayMethod_StridedLoop *contiguous_loop; PyArrayMethod_StridedLoop *unaligned_strided_loop; PyArrayMethod_StridedLoop *unaligned_contiguous_loop; + PyArrayMethod_StridedLoop *contiguous_indexed_loop; /* Chunk only used for wrapping array method defined in umath */ struct PyArrayMethodObject_tag *wrapped_meth; PyArray_DTypeMeta **wrapped_dtypes; @@ -266,6 +267,7 @@ extern NPY_NO_EXPORT PyTypeObject PyBoundArrayMethod_Type; #define NPY_METH_contiguous_loop 5 #define NPY_METH_unaligned_strided_loop 6 #define NPY_METH_unaligned_contiguous_loop 7 +#define NPY_METH_contiguous_indexed_loop 8 /* diff --git a/numpy/core/src/umath/loops.c.src b/numpy/core/src/umath/loops.c.src index 085712f38..d4e246783 100644 --- a/numpy/core/src/umath/loops.c.src +++ b/numpy/core/src/umath/loops.c.src @@ -541,15 +541,21 @@ NPY_NO_EXPORT NPY_GCC_OPT_3 @ATTR@ void } } -NPY_NO_EXPORT NPY_GCC_OPT_3 @ATTR@ void -@TYPE@_@kind@@isa@_indexed(char const *ip1, npy_intp const *indx, char *value, - npy_intp const *dimensions, npy_intp const *steps) { +NPY_NO_EXPORT NPY_GCC_OPT_3 @ATTR@ int +@TYPE@_@kind@@isa@_indexed(PyArrayMethod_Context *NPY_UNUSED(context), char * const*args, npy_intp const *dimensions, npy_intp const *steps, NpyAuxData *NPY_UNUSED(func)) +{ + char *ip1 = args[0]; + npy_intp *indx = (npy_intp *)args[1]; + char *value = args[2]; npy_intp is1 = steps[0], is2 = steps[1], os1 = steps[2]; npy_intp n = dimensions[0]; npy_intp i; + @type@ *indexed; for(i = 0; i < n; i++, indx += is2, value += os1) { - @type@ op1 = *(@type@ *)(ip1 + is1 * indx[0]) + value[0]; + indexed = (@type@ *)(ip1 + is1 * indx[0]); + indexed[0] = indexed[0] @OP@ *(@type@ *)value; } + return 0; } #endif @@ -1546,6 +1552,23 @@ LONGDOUBLE_@kind@(char **args, npy_intp const *dimensions, npy_intp const *steps } } } + +NPY_NO_EXPORT void +LONGDOUBLE_@kind@_indexed(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func)) +{ + char *ip1 = args[0]; + npy_intp *indx = (npy_intp *)args[1]; + char *value = args[2]; + npy_intp is1 = steps[0], is2 = steps[1], os1 = steps[2]; + npy_intp n = dimensions[0]; + npy_intp i; + npy_longdouble *indexed; + for(i = 0; i < n; i++, indx += is2, value += os1) { + indexed = (npy_longdouble *)(ip1 + is1 * indx[0]); + indexed[0] = indexed[0] @OP@ *(npy_longdouble *)value; + } +} + /**end repeat**/ /**begin repeat @@ -1651,6 +1674,24 @@ HALF_@kind@(char **args, npy_intp const *dimensions, npy_intp const *steps, void } } } + +NPY_NO_EXPORT int +HALF_@kind@_indexed(void *NPY_UNUSED(context), char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func)) +{ + char *ip1 = args[0]; + npy_intp *indx = (npy_intp *)args[1]; + char *value = args[2]; + npy_intp is1 = steps[0], is2 = steps[1], os1 = steps[2]; + npy_intp n = dimensions[0]; + npy_intp i; + npy_half *indexed; + for(i = 0; i < n; i++, indx += is2, value += os1) { + indexed = (npy_half *)(ip1 + is1 * indx[0]); + const float v = npy_half_to_float(*(npy_half *)value); + indexed[0] = npy_float_to_half(npy_half_to_float(indexed[0]) @OP@ v); + } + return 0; +} /**end repeat**/ #define _HALF_LOGICAL_AND(a,b) (!npy_half_iszero(a) && !npy_half_iszero(b)) diff --git a/numpy/core/src/umath/loops.h.src b/numpy/core/src/umath/loops.h.src index 26742946f..ee69330dd 100644 --- a/numpy/core/src/umath/loops.h.src +++ b/numpy/core/src/umath/loops.h.src @@ -33,6 +33,9 @@ // #define BOOL_fmax BOOL_maximum // #define BOOL_fmin BOOL_minimum +typedef struct PyArrayMethod_Context_tag PyArrayMethod_Context; +typedef struct NpyAuxData_tag NpyAuxData; + #ifndef NPY_DISABLE_OPTIMIZATION #include "loops_comparison.dispatch.h" #endif @@ -81,6 +84,11 @@ BOOL_@kind@(char **args, npy_intp const *dimensions, npy_intp const *steps, void */ NPY_CPU_DISPATCH_DECLARE(NPY_NO_EXPORT void @TYPE@_divide, (char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))) + +NPY_NO_EXPORT int +@TYPE@_divide_indexed(PyArrayMethod_Context *NPY_UNUSED(context), char *const *args, npy_intp const *dimensions, npy_intp const *steps, NpyAuxData *NPY_UNUSED(func)); + +/**end repeat3**/ /**end repeat**/ #ifndef NPY_DISABLE_OPTIMIZATION @@ -163,6 +171,9 @@ NPY_NO_EXPORT void NPY_NO_EXPORT void @S@@TYPE@_@kind@@isa@(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func)); +NPY_NO_EXPORT int +@S@@TYPE@_@kind@@isa@_indexed(PyArrayMethod_Context *NPY_UNUSED(context), char *const *args, npy_intp const *dimensions, npy_intp const *steps, NpyAuxData *NPY_UNUSED(func)); + /**end repeat3**/ /**begin repeat3 @@ -285,10 +296,13 @@ NPY_CPU_DISPATCH_DECLARE(NPY_NO_EXPORT void @TYPE@_@kind@, /**begin repeat1 * Arithmetic * # kind = add, subtract, multiply, divide# - * # OP = +, -, *, /# */ NPY_CPU_DISPATCH_DECLARE(NPY_NO_EXPORT void @TYPE@_@kind@, (char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))) + +NPY_NO_EXPORT int +@TYPE@_@kind@_indexed(PyArrayMethod_Context *NPY_UNUSED(context), char *const *args, npy_intp const *dimensions, npy_intp const *steps, NpyAuxData *NPY_UNUSED(func)); + /**end repeat1**/ /**end repeat**/ @@ -424,6 +438,11 @@ NPY_CPU_DISPATCH_DECLARE(NPY_NO_EXPORT void @TYPE@_@kind@, ( */ NPY_NO_EXPORT void @TYPE@_@kind@(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func)); + +NPY_NO_EXPORT int +@TYPE@_@kind@_indexed(PyArrayMethod_Context *NPY_UNUSED(context), char *const *args, npy_intp const *dimensions, npy_intp const *steps, NpyAuxData *NPY_UNUSED(func)); + +/**end repeat1**/ /**end repeat1**/ /**begin repeat1 diff --git a/numpy/core/src/umath/loops_arithm_fp.dispatch.c.src b/numpy/core/src/umath/loops_arithm_fp.dispatch.c.src index 1436c46f4..1874573ce 100644 --- a/numpy/core/src/umath/loops_arithm_fp.dispatch.c.src +++ b/numpy/core/src/umath/loops_arithm_fp.dispatch.c.src @@ -547,15 +547,21 @@ NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(@TYPE@_@kind@) } } -NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(@TYPE@_@kind@_indexed) -(char const *ip1, npy_intp const *indx, char *value, - npy_intp const *dimensions, npy_intp const *steps) { +NPY_NO_EXPORT int NPY_CPU_DISPATCH_CURFX(@TYPE@_@kind@_indexed) +(PyArrayMethod_Context *NPY_UNUSED(context), char * const*args, npy_intp const *dimensions, npy_intp const *steps, NpyAuxData *NPY_UNUSED(func)) +{ + char *ip1 = args[0]; + npy_intp *indx = (npy_intp *)args[1]; + char *value = args[2]; npy_intp is1 = steps[0], is2 = steps[1], os1 = steps[2]; npy_intp n = dimensions[0]; npy_intp i; + @type@ *indexed; for(i = 0; i < n; i++, indx += is2, value += os1) { - @type@ op1 = *(@type@ *)(ip1 + is1 * indx[0]) + value[0]; + indexed = (@type@ *)(ip1 + is1 * indx[0]); + indexed[0] = indexed[0] @OP@ *(@type@ *)value; } + return 0; } /**end repeat1**/ diff --git a/numpy/core/src/umath/loops_arithmetic.dispatch.c.src b/numpy/core/src/umath/loops_arithmetic.dispatch.c.src index ea8685002..573590b1f 100644 --- a/numpy/core/src/umath/loops_arithmetic.dispatch.c.src +++ b/numpy/core/src/umath/loops_arithmetic.dispatch.c.src @@ -395,6 +395,24 @@ NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(@TYPE@_divide) } } } + +NPY_NO_EXPORT int NPY_CPU_DISPATCH_CURFX(@TYPE@_divide_indexed) +(PyArrayMethod_Context *NPY_UNUSED(context), char * const*args, npy_intp const *dimensions, npy_intp const *steps, NpyAuxData *NPY_UNUSED(func)) +{ + char *ip1 = args[0]; + npy_intp *indx = (npy_intp *)args[1]; + char *value = args[2]; + npy_intp is1 = steps[0], is2 = steps[1], os1 = steps[2]; + npy_intp n = dimensions[0]; + npy_intp i; + @type@ *indexed; + for(i = 0; i < n; i++, indx += is2, value += os1) { + indexed = (@type@ *)(ip1 + is1 * indx[0]); + indexed[0] = floor_div_@TYPE@(indexed[0], *(@type@ *)value); + } + return 0; +} + /**end repeat**/ /**begin repeat @@ -463,4 +481,28 @@ NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(@TYPE@_divide) } } } + +NPY_NO_EXPORT int NPY_CPU_DISPATCH_CURFX(@TYPE@_divide_indexed) +(PyArrayMethod_Context *NPY_UNUSED(context), char * const*args, npy_intp const *dimensions, npy_intp const *steps, NpyAuxData *NPY_UNUSED(func)) +{ + char *ip1 = args[0]; + npy_intp *indx = (npy_intp *)args[1]; + char *value = args[2]; + npy_intp is1 = steps[0], is2 = steps[1], os1 = steps[2]; + npy_intp n = dimensions[0]; + npy_intp i; + @type@ *indexed; + for(i = 0; i < n; i++, indx += is2, value += os1) { + indexed = (@type@ *)(ip1 + is1 * indx[0]); + @type@ in2 = *(@type@ *)value; + if (NPY_UNLIKELY(in2 == 0)) { + npy_set_floatstatus_divbyzero(); + indexed[0] = 0; + } else { + indexed[0] = indexed[0] / in2; + } + } + return 0; +} + /**end repeat**/ |
