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

Function PyUFunc_AddLoop

numpy/core/src/umath/dispatching.c:79–147  ·  view source on GitHub ↗

* Function to add a new loop to the ufunc. This mainly appends it to the * list (as it currently is just a list). * * @param ufunc The universal function to add the loop to. * @param info The tuple (dtype_tuple, ArrayMethod/promoter). * @param ignore_duplicate If 1 and a loop with the same `dtype_tuple` is * found, the function does nothing. */

Source from the content-addressed store, hash-verified

77 * found, the function does nothing.
78 */
79NPY_NO_EXPORT int
80PyUFunc_AddLoop(PyUFuncObject *ufunc, PyObject *info, int ignore_duplicate)
81{
82 /*
83 * Validate the info object, this should likely move to a different
84 * entry-point in the future (and is mostly unnecessary currently).
85 */
86 if (!PyTuple_CheckExact(info) || PyTuple_GET_SIZE(info) != 2) {
87 PyErr_SetString(PyExc_TypeError,
88 "Info must be a tuple: "
89 "(tuple of DTypes or None, ArrayMethod or promoter)");
90 return -1;
91 }
92 PyObject *DType_tuple = PyTuple_GetItem(info, 0);
93 if (PyTuple_GET_SIZE(DType_tuple) != ufunc->nargs) {
94 PyErr_SetString(PyExc_TypeError,
95 "DType tuple length does not match ufunc number of operands");
96 return -1;
97 }
98 for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(DType_tuple); i++) {
99 PyObject *item = PyTuple_GET_ITEM(DType_tuple, i);
100 if (item != Py_None
101 && !PyObject_TypeCheck(item, &PyArrayDTypeMeta_Type)) {
102 PyErr_SetString(PyExc_TypeError,
103 "DType tuple may only contain None and DType classes");
104 return -1;
105 }
106 }
107 PyObject *meth_or_promoter = PyTuple_GET_ITEM(info, 1);
108 if (!PyObject_TypeCheck(meth_or_promoter, &PyArrayMethod_Type)
109 && !PyCapsule_IsValid(meth_or_promoter, "numpy._ufunc_promoter")) {
110 PyErr_SetString(PyExc_TypeError,
111 "Second argument to info must be an ArrayMethod or promoter");
112 return -1;
113 }
114
115 if (ufunc->_loops == NULL) {
116 ufunc->_loops = PyList_New(0);
117 if (ufunc->_loops == NULL) {
118 return -1;
119 }
120 }
121
122 PyObject *loops = ufunc->_loops;
123 Py_ssize_t length = PyList_Size(loops);
124 for (Py_ssize_t i = 0; i < length; i++) {
125 PyObject *item = PyList_GetItem(loops, i);
126 PyObject *cur_DType_tuple = PyTuple_GetItem(item, 0);
127 int cmp = PyObject_RichCompareBool(cur_DType_tuple, DType_tuple, Py_EQ);
128 if (cmp < 0) {
129 return -1;
130 }
131 if (cmp == 0) {
132 continue;
133 }
134 if (ignore_duplicate) {
135 return 0;
136 }

Callers 6

PyUFunc_AddPromoterFunction · 0.85
PyUFunc_AddWrappingLoopFunction · 0.85
sfloat_add_loopFunction · 0.85
PyUFunc_AddLoopFromSpecFunction · 0.85

Calls 1

ufunc_get_name_cstrFunction · 0.85

Tested by

no test coverage detected