Skip to content
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

Merged
merged 24 commits into from
Aug 26, 2021
Merged

reshape for numpy arrays #984

merged 24 commits into from
Aug 26, 2021

Conversation

ncullen93
Copy link
Contributor

@ncullen93 ncullen93 commented Aug 6, 2017

implemented reshape, since resize is rarely useful and often fails.

Suggested changelog entry:

* Implemented ``reshape`` on arrays

@rwgk
Copy link
Collaborator

rwgk commented Jul 15, 2021

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.

@Skylion007 Skylion007 requested a review from henryiii July 15, 2021 18:38
@Skylion007 Skylion007 self-requested a review July 28, 2021 18:31
@Skylion007
Copy link
Collaborator

@rwgk @henryiii , I fixed this PR.

tests/test_numpy_array.cpp Outdated Show resolved Hide resolved
tests/test_numpy_array.py Outdated Show resolved Hide resolved
@@ -790,6 +795,15 @@ class array : public buffer {
if (isinstance<array>(new_array)) { *this = std::move(new_array); }
}

array reshape(ShapeContainer new_shape) {
Copy link
Collaborator

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.

Copy link
Collaborator

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.

Copy link
Collaborator

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

Copy link
Collaborator

@Skylion007 Skylion007 Aug 8, 2021

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.

Copy link
Collaborator

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!

include/pybind11/numpy.h Outdated Show resolved Hide resolved
@@ -790,6 +795,15 @@ class array : public buffer {
if (isinstance<array>(new_array)) { *this = std::move(new_array); }
}

array reshape(ShapeContainer new_shape) {
Copy link
Collaborator

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!


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
Copy link
Collaborator

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.

Copy link
Collaborator

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

Copy link
Collaborator

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);
Copy link
Collaborator

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?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@henryiii shrugs @rwgk thoughts?

Copy link
Collaborator

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?

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
Copy link
Collaborator

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.

Comment on lines 408 to 410
sm.def("array_reshape1", [](py::array_t<double> a, size_t N) {
return a.reshape({N, N, N});
});
Copy link
Collaborator

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.

@rwgk
Copy link
Collaborator

rwgk commented Aug 24, 2021

Hi @Skylion007, I streamlined the tests. Could you please take a look?
(PyPy doesn't need an xfail anymore.)

@rwgk
Copy link
Collaborator

rwgk commented Aug 26, 2021

Thanks Aaron for digging up this ancient PR, thanks Henry for the review. Sorry Nick this took forever, but we're getting better. Merging!

@rwgk rwgk merged commit 59ad1e7 into pybind:master Aug 26, 2021
@Skylion007
Copy link
Collaborator

This should be merged at same time as : #987

@github-actions github-actions bot added the needs changelog Possibly needs a changelog entry label Aug 26, 2021
@rwgk
Copy link
Collaborator

rwgk commented Aug 26, 2021

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.

@henryiii
Copy link
Collaborator

These need to go into the docs, too.

@henryiii henryiii removed the needs changelog Possibly needs a changelog entry label Sep 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants