Skip to content

Commit 145065b

Browse files
committed
API: Remove legacy-inner-loop-selector
Remove legacy-inner-loop-selector and clean up the masked one (This was effectivly removed a while ago, but a deprecation was added for ABI compatibility if compiling against a newer NumPy that still had the slot). Removed the `reservedX` struct member docs, seems clear enough to not have them explicitly...
1 parent 7351341 commit 145065b

File tree

6 files changed

+9
-79
lines changed

6 files changed

+9
-79
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
* The ``legacy_inner_loop_selector`` member of the ufunc struct is removed
2+
to simplify improvements to the dispatching system.
3+
There are no known users overriding or directly accessing this member.

doc/source/reference/c-api/types-and-structures.rst

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -820,8 +820,8 @@ PyUFunc_Type and PyUFuncObject
820820
int *core_offsets;
821821
char *core_signature;
822822
PyUFunc_TypeResolutionFunc *type_resolver;
823-
PyUFunc_LegacyInnerLoopSelectionFunc *legacy_inner_loop_selector;
824823
void *reserved2;
824+
void *reserved3;
825825
npy_uint32 *op_flags;
826826
npy_uint32 *iter_flags;
827827
/* new in API version 0x0000000D */
@@ -890,10 +890,6 @@ PyUFunc_Type and PyUFuncObject
890890
specifies how many different 1-d loops (of the builtin data
891891
types) are available.
892892
893-
.. c:member:: int reserved1
894-
895-
Unused.
896-
897893
.. c:member:: char *name
898894
899895
A string name for the ufunc. This is used dynamically to build
@@ -966,19 +962,6 @@ PyUFunc_Type and PyUFuncObject
966962
A function which resolves the types and fills an array with the dtypes
967963
for the inputs and outputs
968964
969-
.. c:member:: PyUFunc_LegacyInnerLoopSelectionFunc *legacy_inner_loop_selector
970-
971-
.. deprecated:: 1.22
972-
973-
Some fallback support for this slot exists, but will be removed
974-
eventually. A universal function that relied on this will
975-
have to be ported eventually.
976-
See :ref:`NEP 41 <NEP41>` and :ref:`NEP 43 <NEP43>`
977-
978-
.. c:member:: void *reserved2
979-
980-
For a possible future loop selector with a different signature.
981-
982965
.. c:member:: npy_uint32 op_flags
983966
984967
Override the default operand flags for each ufunc operand.

numpy/core/include/numpy/ufuncobject.h

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -65,30 +65,6 @@ typedef int (PyUFunc_TypeResolutionFunc)(
6565
PyObject *type_tup,
6666
PyArray_Descr **out_dtypes);
6767

68-
/*
69-
* Legacy loop selector. (This should NOT normally be used and we can expect
70-
* that only the `PyUFunc_DefaultLegacyInnerLoopSelector` is ever set).
71-
* However, unlike the masked version, it probably still works.
72-
*
73-
* ufunc: The ufunc object.
74-
* dtypes: An array which has been populated with dtypes,
75-
* in most cases by the type resolution function
76-
* for the same ufunc.
77-
* out_innerloop: Should be populated with the correct ufunc inner
78-
* loop for the given type.
79-
* out_innerloopdata: Should be populated with the void* data to
80-
* be passed into the out_innerloop function.
81-
* out_needs_api: If the inner loop needs to use the Python API,
82-
* should set the to 1, otherwise should leave
83-
* this untouched.
84-
*/
85-
typedef int (PyUFunc_LegacyInnerLoopSelectionFunc)(
86-
struct _tagPyUFuncObject *ufunc,
87-
PyArray_Descr **dtypes,
88-
PyUFuncGenericFunction *out_innerloop,
89-
void **out_innerloopdata,
90-
int *out_needs_api);
91-
9268

9369
typedef struct _tagPyUFuncObject {
9470
PyObject_HEAD
@@ -161,13 +137,8 @@ typedef struct _tagPyUFuncObject {
161137
* with the dtypes for the inputs and outputs.
162138
*/
163139
PyUFunc_TypeResolutionFunc *type_resolver;
164-
/*
165-
* A function which returns an inner loop written for
166-
* NumPy 1.6 and earlier ufuncs. This is for backwards
167-
* compatibility, and may be NULL if inner_loop_selector
168-
* is specified.
169-
*/
170-
PyUFunc_LegacyInnerLoopSelectionFunc *legacy_inner_loop_selector;
140+
/* Was the legacy loop resolver */
141+
void *reserved2;
171142
/*
172143
* This was blocked off to be the "new" inner loop selector in 1.7,
173144
* but this was never implemented. (This is also why the above
@@ -180,7 +151,7 @@ typedef struct _tagPyUFuncObject {
180151
#endif
181152

182153
/* Was previously the `PyUFunc_MaskedInnerLoopSelectionFunc` */
183-
void *_always_null_previously_masked_innerloop_selector;
154+
void *reserved3;
184155

185156
/*
186157
* List of flags for each operand when ufunc is called by nditer object.

numpy/core/src/umath/legacy_array_method.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "dtypemeta.h"
2020

2121
#include "ufunc_object.h"
22+
#include "ufunc_type_resolution.h"
2223

2324

2425
typedef struct {
@@ -216,7 +217,7 @@ get_wrapped_legacy_ufunc_loop(PyArrayMethod_Context *context,
216217

217218
PyUFuncGenericFunction loop = NULL;
218219
/* Note that `needs_api` is not reliable (it was in fact unused normally) */
219-
if (ufunc->legacy_inner_loop_selector(ufunc,
220+
if (PyUFunc_DefaultLegacyInnerLoopSelector(ufunc,
220221
context->descriptors, &loop, &user_data, &needs_api) < 0) {
221222
return -1;
222223
}

numpy/core/src/umath/ufunc_object.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,18 +1422,6 @@ execute_ufunc_loop(PyArrayMethod_Context *context, int masked,
14221422

14231423
if (masked) {
14241424
assert(PyArray_TYPE(op[nop]) == NPY_BOOL);
1425-
if (ufunc->_always_null_previously_masked_innerloop_selector != NULL) {
1426-
if (PyErr_WarnFormat(PyExc_UserWarning, 1,
1427-
"The ufunc %s has a custom masked-inner-loop-selector."
1428-
"NumPy assumes that this is NEVER used. If you do make "
1429-
"use of this please notify the NumPy developers to discuss "
1430-
"future solutions. (See NEP 41 and 43)\n"
1431-
"NumPy will continue, but ignore the custom loop selector. "
1432-
"This should only affect performance.",
1433-
ufunc_get_name_cstr(ufunc)) < 0) {
1434-
return -1;
1435-
}
1436-
}
14371425

14381426
/*
14391427
* NOTE: In the masked version, we consider the output read-write,
@@ -5109,8 +5097,6 @@ PyUFunc_FromFuncAndDataAndSignatureAndIdentity(PyUFuncGenericFunction *func, voi
51095097

51105098
/* Type resolution and inner loop selection functions */
51115099
ufunc->type_resolver = &PyUFunc_DefaultTypeResolver;
5112-
ufunc->legacy_inner_loop_selector = &PyUFunc_DefaultLegacyInnerLoopSelector;
5113-
ufunc->_always_null_previously_masked_innerloop_selector = NULL;
51145100

51155101
ufunc->op_flags = NULL;
51165102
ufunc->_loops = NULL;

numpy/core/src/umath/umathmodule.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,6 @@ object_ufunc_type_resolver(PyUFuncObject *ufunc,
5858
return 0;
5959
}
6060

61-
static int
62-
object_ufunc_loop_selector(PyUFuncObject *ufunc,
63-
PyArray_Descr **NPY_UNUSED(dtypes),
64-
PyUFuncGenericFunction *out_innerloop,
65-
void **out_innerloopdata,
66-
int *out_needs_api)
67-
{
68-
*out_innerloop = ufunc->functions[0];
69-
*out_innerloopdata = (ufunc->data == NULL) ? NULL : ufunc->data[0];
70-
*out_needs_api = 1;
71-
72-
return 0;
73-
}
7461

7562
PyObject *
7663
ufunc_frompyfunc(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds) {
@@ -166,7 +153,6 @@ ufunc_frompyfunc(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds) {
166153
self->ptr = ptr;
167154

168155
self->type_resolver = &object_ufunc_type_resolver;
169-
self->legacy_inner_loop_selector = &object_ufunc_loop_selector;
170156
PyObject_GC_Track(self);
171157

172158
return (PyObject *)self;

0 commit comments

Comments
 (0)