* This function executes all the standard NumPy reduction function * boilerplate code, just calling the appropriate inner loop function where * necessary. * * context : The ArrayMethod context (with ufunc, method, and descriptors). * operand : The array to be reduced. * out : NULL, or the array into which to place the result. * wheremask : Reduction mask of valid values us
| 174 | * generalized ufuncs!) |
| 175 | */ |
| 176 | NPY_NO_EXPORT PyArrayObject * |
| 177 | PyUFunc_ReduceWrapper(PyArrayMethod_Context *context, |
| 178 | PyArrayObject *operand, PyArrayObject *out, PyArrayObject *wheremask, |
| 179 | npy_bool *axis_flags, int keepdims, |
| 180 | PyObject *initial, PyArray_ReduceLoopFunc *loop, |
| 181 | npy_intp buffersize, const char *funcname, int errormask) |
| 182 | { |
| 183 | assert(loop != NULL); |
| 184 | PyArrayObject *result = NULL; |
| 185 | npy_intp skip_first_count = 0; |
| 186 | |
| 187 | /* Iterator parameters */ |
| 188 | NpyIter *iter = NULL; |
| 189 | PyArrayObject *op[3]; |
| 190 | PyArray_Descr *op_dtypes[3]; |
| 191 | npy_uint32 it_flags, op_flags[3]; |
| 192 | /* Loop auxdata (must be freed on error) */ |
| 193 | NpyAuxData *auxdata = NULL; |
| 194 | |
| 195 | /* Set up the iterator */ |
| 196 | op[0] = out; |
| 197 | op[1] = operand; |
| 198 | op_dtypes[0] = context->descriptors[0]; |
| 199 | op_dtypes[1] = context->descriptors[1]; |
| 200 | |
| 201 | /* Buffer to use when we need an initial value */ |
| 202 | char *initial_buf = NULL; |
| 203 | |
| 204 | /* More than one axis means multiple orders are possible */ |
| 205 | if (!(context->method->flags & NPY_METH_IS_REORDERABLE) |
| 206 | && count_axes(PyArray_NDIM(operand), axis_flags) > 1) { |
| 207 | PyErr_Format(PyExc_ValueError, |
| 208 | "reduction operation '%s' is not reorderable, " |
| 209 | "so at most one axis may be specified", |
| 210 | funcname); |
| 211 | goto fail; |
| 212 | } |
| 213 | |
| 214 | it_flags = NPY_ITER_BUFFERED | |
| 215 | NPY_ITER_EXTERNAL_LOOP | |
| 216 | NPY_ITER_GROWINNER | |
| 217 | NPY_ITER_ZEROSIZE_OK | |
| 218 | NPY_ITER_REFS_OK | |
| 219 | NPY_ITER_DELAY_BUFALLOC | |
| 220 | NPY_ITER_COPY_IF_OVERLAP; |
| 221 | if (!(context->method->flags & NPY_METH_IS_REORDERABLE)) { |
| 222 | it_flags |= NPY_ITER_DONT_NEGATE_STRIDES; |
| 223 | } |
| 224 | op_flags[0] = NPY_ITER_READWRITE | |
| 225 | NPY_ITER_ALIGNED | |
| 226 | NPY_ITER_ALLOCATE | |
| 227 | NPY_ITER_NO_SUBTYPE; |
| 228 | op_flags[1] = NPY_ITER_READONLY | |
| 229 | NPY_ITER_ALIGNED | |
| 230 | NPY_ITER_NO_BROADCAST; |
| 231 | |
| 232 | if (wheremask != NULL) { |
| 233 | op[2] = wheremask; |
no test coverage detected