* The implementation of the reduction operators with the new iterator * turned into a bit of a long function here, but I think the design * of this part needs to be changed to be more like einsum, so it may * not be worth refactoring it too much. Consider this timing: * * >>> a = arange(10000) * * >>> timeit sum(a) * 10000 loops, best of 3: 17 us per loop * * >>> timeit einsum("i->",a)
| 3032 | * this function does not validate them. |
| 3033 | */ |
| 3034 | static PyArrayObject * |
| 3035 | PyUFunc_Reduce(PyUFuncObject *ufunc, |
| 3036 | PyArrayObject *arr, PyArrayObject *out, |
| 3037 | int naxes, int *axes, PyArray_DTypeMeta *signature[3], int keepdims, |
| 3038 | PyObject *initial, PyArrayObject *wheremask) |
| 3039 | { |
| 3040 | int iaxes, ndim; |
| 3041 | npy_bool axis_flags[NPY_MAXDIMS]; |
| 3042 | |
| 3043 | const char *ufunc_name = ufunc_get_name_cstr(ufunc); |
| 3044 | /* These parameters come from a TLS global */ |
| 3045 | int buffersize = 0, errormask = 0; |
| 3046 | |
| 3047 | NPY_UF_DBG_PRINT1("\nEvaluating ufunc %s.reduce\n", ufunc_name); |
| 3048 | |
| 3049 | ndim = PyArray_NDIM(arr); |
| 3050 | |
| 3051 | /* Create an array of flags for reduction */ |
| 3052 | memset(axis_flags, 0, ndim); |
| 3053 | for (iaxes = 0; iaxes < naxes; ++iaxes) { |
| 3054 | int axis = axes[iaxes]; |
| 3055 | if (axis_flags[axis]) { |
| 3056 | PyErr_SetString(PyExc_ValueError, |
| 3057 | "duplicate value in 'axis'"); |
| 3058 | return NULL; |
| 3059 | } |
| 3060 | axis_flags[axis] = 1; |
| 3061 | } |
| 3062 | |
| 3063 | if (_get_bufsize_errmask(NULL, "reduce", &buffersize, &errormask) < 0) { |
| 3064 | return NULL; |
| 3065 | } |
| 3066 | |
| 3067 | PyArray_Descr *descrs[3]; |
| 3068 | PyArrayMethodObject *ufuncimpl = reducelike_promote_and_resolve(ufunc, |
| 3069 | arr, out, signature, NPY_FALSE, descrs, NPY_UNSAFE_CASTING, "reduce"); |
| 3070 | if (ufuncimpl == NULL) { |
| 3071 | return NULL; |
| 3072 | } |
| 3073 | |
| 3074 | PyArrayMethod_Context context = { |
| 3075 | .caller = (PyObject *)ufunc, |
| 3076 | .method = ufuncimpl, |
| 3077 | .descriptors = descrs, |
| 3078 | }; |
| 3079 | |
| 3080 | PyArrayObject *result = PyUFunc_ReduceWrapper(&context, |
| 3081 | arr, out, wheremask, axis_flags, keepdims, |
| 3082 | initial, reduce_loop, buffersize, ufunc_name, errormask); |
| 3083 | |
| 3084 | for (int i = 0; i < 3; i++) { |
| 3085 | Py_DECREF(descrs[i]); |
| 3086 | } |
| 3087 | return result; |
| 3088 | } |
| 3089 | |
| 3090 | |
| 3091 | static PyObject * |
no test coverage detected