-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
reshape for numpy arrays #984
Conversation
First impression: looks useful, filling in a blank, not doing anything substantially new or different, therefore unlikely to upset anything. @Skylion007 if you want to modernize this one (CI green here), I could run all our sanitizers, if that's clean, merge. I don't think this needs global testing. My testing turn-around could therefore be really quick. |
@@ -790,6 +795,15 @@ class array : public buffer { | |||
if (isinstance<array>(new_array)) { *this = std::move(new_array); } | |||
} | |||
|
|||
array reshape(ShapeContainer new_shape) { |
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.
while we're at it, I'd also plumb through the order
.
even if it's not actually used now (idk), it may be in future numpy versions.
easier to just do it than to explain why not.
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.
@rwgk We would need to add support for it as a function arg, which we currently don't. That can be added in a followup PR.
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.
That can be added in a followup PR.
OK
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.
There is an NORDER Enum that it takes, but I am not sure how to expose that properly. We probably should leave it as is now.
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.
sounds good, thanks for looking into it!
@@ -790,6 +795,15 @@ class array : public buffer { | |||
if (isinstance<array>(new_array)) { *this = std::move(new_array); } | |||
} | |||
|
|||
array reshape(ShapeContainer new_shape) { |
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.
sounds good, thanks for looking into it!
tests/test_numpy_array.py
Outdated
|
||
def test_reshape_tuple_empty(msg): | ||
a = np.random.randn(10 * 20 * 30).astype("float64") | ||
# FIXME: This should be a ValueError for maximum numpy compat |
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.
Yep, I just spent a couple minutes playing myself, we definitely need to make this compatible in this PR. Otherwise we'd be introducing a wrinkle of the really silly kind that can lead to surprisingly huge stumbles.
If you feel out of your comfort zone, I could help out working on it here. Please let me know.
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 get the following error back:
E TypeError: Unable to convert function return value to a Python type! The signature was
E (arg0: numpy.ndarray[numpy.float64], arg1: List[int]) -> numpy.ndarray
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.
@rwgk Aha, figured it out. Behavior matches Numpy now.
@@ -203,6 +203,8 @@ struct npy_api { | |||
// Unused. Not removed because that affects ABI of the class. | |||
int (*PyArray_SetBaseObject_)(PyObject *, PyObject *); | |||
PyObject* (*PyArray_Resize_)(PyObject*, PyArray_Dims*, int, int); | |||
PyObject* (*PyArray_Newshape_)(PyObject*, PyArray_Dims*, int); |
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 causes an ABI break?
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.
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 don't see any virtual
here. If there is no vtable, how does adding or removing member functions change the ABI? I'm having doubts about the correctness of the comment in line 203. I could imagine maybe getting into trouble removing a function, but adding? If a newer extension knows about it, the machine code for it will be in that extension for sure. No?
include/pybind11/numpy.h
Outdated
array reshape(ShapeContainer new_shape) { | ||
detail::npy_api::PyArray_Dims d | ||
= {reinterpret_cast<Py_intptr_t *>(new_shape->data()), int(new_shape->size())}; | ||
// try to reshape, set ordering param to 0 cause it's not used anyway |
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 think it's best to remove this comment, and add a comment just above the array reshape(ShapeContainer new_shape) {
line, e.g.
// Optional `order` parameter omitted here, to be added as needed.
tests/test_numpy_array.cpp
Outdated
sm.def("array_reshape1", [](py::array_t<double> a, size_t N) { | ||
return a.reshape({N, N, N}); | ||
}); |
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.
To keep the tests lean, I'd remove this function completely (and test_array_reshape
with it). The exact same interface is covered by test_array_reshape
. (I realize it takes away from PyPy coverage because of the xfail
for test_array_reshape
, but that's not enough reason in my mind to keep this one.)
If you feel differently, I'd at least change this to something like {N, N+5, N+7}
to get a little bit more value.
Hi @Skylion007, I streamlined the tests. Could you please take a look? |
Thanks Aaron for digging up this ancient PR, thanks Henry for the review. Sorry Nick this took forever, but we're getting better. Merging! |
This should be merged at same time as : #987 |
Yes, I need to run right now but back in an hour or two. If you get a chance to update it I'll take a look asap. |
These need to go into the docs, too. |
implemented reshape, since
resize
is rarely useful and often fails.Suggested changelog entry:
* Implemented ``reshape`` on arrays