MCPcopy Create free account
hub / github.com/numpy/numpy / execute_ufunc_loop

Function execute_ufunc_loop

numpy/core/src/umath/ufunc_object.c:1456–1669  ·  view source on GitHub ↗

* The ufunc loop implementation for both normal ufunc calls and masked calls * when the iterator has to be used. * * See `PyUFunc_GenericFunctionInternal` for more information (where this is * called from). */

Source from the content-addressed store, hash-verified

1454 * called from).
1455 */
1456static int
1457execute_ufunc_loop(PyArrayMethod_Context *context, int masked,
1458 PyArrayObject **op, NPY_ORDER order, npy_intp buffersize,
1459 NPY_CASTING casting,
1460 PyObject **arr_prep, ufunc_full_args full_args,
1461 npy_uint32 *op_flags, int errormask, PyObject *extobj)
1462{
1463 PyUFuncObject *ufunc = (PyUFuncObject *)context->caller;
1464 int nin = context->method->nin, nout = context->method->nout;
1465 int nop = nin + nout;
1466
1467 if (validate_casting(context->method,
1468 ufunc, op, context->descriptors, casting) < 0) {
1469 return -1;
1470 }
1471
1472 if (masked) {
1473 assert(PyArray_TYPE(op[nop]) == NPY_BOOL);
1474 if (ufunc->_always_null_previously_masked_innerloop_selector != NULL) {
1475 if (PyErr_WarnFormat(PyExc_UserWarning, 1,
1476 "The ufunc %s has a custom masked-inner-loop-selector."
1477 "NumPy assumes that this is NEVER used. If you do make "
1478 "use of this please notify the NumPy developers to discuss "
1479 "future solutions. (See NEP 41 and 43)\n"
1480 "NumPy will continue, but ignore the custom loop selector. "
1481 "This should only affect performance.",
1482 ufunc_get_name_cstr(ufunc)) < 0) {
1483 return -1;
1484 }
1485 }
1486
1487 /*
1488 * NOTE: In the masked version, we consider the output read-write,
1489 * this gives a best-effort of preserving the input, but does
1490 * not always work. It could allow the operand to be copied
1491 * due to copy-if-overlap, but only if it was passed in.
1492 * In that case `__array_prepare__` is called before it happens.
1493 */
1494 for (int i = nin; i < nop; ++i) {
1495 op_flags[i] |= (op[i] != NULL ? NPY_ITER_READWRITE : NPY_ITER_WRITEONLY);
1496 }
1497 op_flags[nop] = NPY_ITER_READONLY | NPY_ITER_ARRAYMASK; /* mask */
1498 }
1499
1500 NPY_UF_DBG_PRINT("Making iterator\n");
1501
1502 npy_uint32 iter_flags = ufunc->iter_flags |
1503 NPY_ITER_EXTERNAL_LOOP |
1504 NPY_ITER_REFS_OK |
1505 NPY_ITER_ZEROSIZE_OK |
1506 NPY_ITER_BUFFERED |
1507 NPY_ITER_GROWINNER |
1508 NPY_ITER_DELAY_BUFALLOC |
1509 NPY_ITER_COPY_IF_OVERLAP;
1510
1511 /*
1512 * Call the __array_prepare__ functions for already existing output arrays.
1513 * Do this before creating the iterator, as the iterator may UPDATEIFCOPY

Callers 1

Calls 15

validate_castingFunction · 0.85
PyArray_TYPEFunction · 0.85
ufunc_get_name_cstrFunction · 0.85
prepare_ufunc_outputFunction · 0.85
NpyIter_AdvancedNewFunction · 0.85
NpyIter_GetOperandArrayFunction · 0.85
NpyIter_DeallocateFunction · 0.85
PyArray_BYTESFunction · 0.85
NpyIter_GetIterSizeFunction · 0.85
NpyIter_GetDataPtrArrayFunction · 0.85

Tested by

no test coverage detected