-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
API: bump MAXDIMS/MAXARGS to 64 introduce NPY_AXIS_RAVEL #25149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
OK, I think this is now ready (but relying on the other PR). I had not done it here, but I would be happy to follow up with:
|
Link? |
Oops, thought it was in the first post, just opened: #25138 |
"(Deprecated NumPy 1.23)") < 0) { | ||
return NPY_FAIL; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is very niche, but, mentioned it in the release notes.
@@ -692,7 +692,7 @@ PyArray_ConcatenateInto(PyObject *op, | |||
Py_DECREF(item); | |||
} | |||
|
|||
if (axis >= NPY_MAXDIMS) { | |||
if (axis == NPY_RAVEL_AXIS) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also a subtle oddity, mentioned in the release note (any huge axes was interpreted as raveling)
"this function only supports up to 32 dimensions but " | ||
"the array has %d.", PyArray_NDIM(mp)); | ||
return -1; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't us this internally, might remove the function, but not sure yet. In principle, anyone running into it should catch the error and not leak anything (normal array cleanup doesn't have this problem).
@@ -182,9 +182,8 @@ cdef extern from "numpy/arrayobject.h": | |||
NPY_ARRAY_UPDATE_ALL | |||
|
|||
cdef enum: | |||
NPY_MAXDIMS | |||
|
|||
npy_intp NPY_MAX_ELSIZE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a bit random, but NPY_MAX_ELSIZE
doesn't exist (it sure did at some point).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this removal need a release note? Just to say that if someone was using and relying on it, it wasn't doing what they thought it did.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤷 I doubt anyone will notice, but sure, added.
Bumping these two has three main caveats: 1. We cannot break ABI for the iterator macros, which means the iterators now need to use 32/their own macro. 2. We used axis=MAXDIMS to mean axis=None, introduce NPY_AXIS_RAVEL to replace this, it will be run-time outside NumPy. 3. The old style iterators cannot deal with high dimensions, meaning that some functions just won't work (because they use them).
Memoryview actually also only supports 65 dimensions currently, so skip the test when the memoryview creation fails. If it were to work, the test should kick in and work fine.
@ngoldbaum maybe you have some time to review this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few language suggestions and some questions. Overall looks fine though.
used in stack allocation, where the increase should be safe. | ||
However, we do encourage generally to remove any use of ``NPY_MAXDIMS`` and | ||
``NPY_MAXARGS`` to eventually allow removing the constraint completely. | ||
In some cases, ``NPY_MAXDIMS`` was passed (and returned) to mean ``axis=None`` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you make "In some cases" a little more specific? Does this only impact things that interact with numpy via the C API, or could you trigger this behavior from the python API too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The python side places are already mentioned in the other one, but made it a bit more concrete.
----------------------------------------------- | ||
In some cases ``axis=32`` or for concatenate any large value | ||
was the same as ``axis=None``. | ||
Except for ``concatenate`` this was deprecate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Except for ``concatenate`` this was deprecate. | |
Except for ``concatenate`` this was deprecated in Numpy 1.23. |
Was the deprecation noisy for other functions? Just wondering if we might want to merely deprecate this usage for concatenate
since that was missed in 2022.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It gave a deprecation warning. I briefly considered that, and think that this is ridiculously niche. IIRC, we were close to not do the deprecation warning in the other path also.
We are talking about np.concatenate(..., axis=32)
or higher. Where the axis value cannot relate to any actual axis.
This is undocumented and unless you do it accidentally (and it happens to do what you want?!) nobody should have reason to even realize it works (at least for ~15 years), I would say.
``NPY_MAXDIMS`` was also used to signal ``axis=None`` in the C-API, including | ||
the ``PyArray_AxisConverter``. | ||
If you run into this problem, you will see ``-2147483648`` | ||
(the minimum integer value) or ``64`` being used as an invalid axis. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might help to include the exact text of the error they'd see, so if they google the error message they'll find the migration guide
is the largest number of dimensions for any array. | ||
``ndarraytypes.h`` points to this data member. | ||
Although most operations may be limited in dimensionality, we do not | ||
advertise a maximum dimension. Anyone explicitly relying on one |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a remnant of an earlier version that completely removed NPY_MAXDIMS
from the public API? Maybe rephrase this to say NPY_MAXDIMS
is there but not to rely on it because it might change or be removed in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It wasn't a remnant, but rephrased a bit.
@@ -182,9 +182,8 @@ cdef extern from "numpy/arrayobject.h": | |||
NPY_ARRAY_UPDATE_ALL | |||
|
|||
cdef enum: | |||
NPY_MAXDIMS | |||
|
|||
npy_intp NPY_MAX_ELSIZE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this removal need a release note? Just to say that if someone was using and relying on it, it wasn't doing what they thought it did.
Co-authored-by: Nathan Goldbaum <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm on vacation but will merge this next week if no one else does it before me. This is mostly very straightforward and it's hard to know the impact of the ABI break or possible breakage of questionable C code using the macro without making the change.
I'm going to merge this now and immediately trigger a new nightly wheel upload. Thanks @seberg! If you are reading this because of new CI breakage, make sure any nightly builds or tests you're running against NumPy dev (future 2.0 release) use a stack that is built against Numpy dev as well, with build isolation disabled. |
Bumping these two has three main caveats:
iterators now need to use 32/their own macro.
to replace this, it will be run-time outside NumPy.
that some functions just won't work (because they use them).
Draft, as based on the mapiter removal.
Needs to document the above points, butshould be good for an initial review(the doc changes here may be a bit random). But,I don't expect the code to change really.There are two plausible follow-ups that I would prefer not to include here:
alloca()
or similar for some allocations (or malloc for big ones). We don't have to do go all the way there, but at least the stack arrays in the ufunc setup are worth shrinking. (definitely want to do that)choose
andarr.flat
I added test for here. As well asnp.random
since it relies on the old-style iterator a lot.I had mentioned before to just delete
NPY_MAXDIMS
as a public symbol rather than deleting it. After seeing that it is used in a few places in SciPy, etc. I decided that maybe it is best to defer that to NumPy 3. I doubt we are ready to force that churn on downstream.Addresses gh-5744, although some paths remain of course.