Replace shape assignment with reshape calls#1106
Conversation
NumPy is deprecating direct `shape` assignment. The underlying code path simply goes through `reshape`. So just switch to `reshape` to eliminate the deprecation warning and future proof the code. ref: https://github.com/numpy/numpy/blob/2a674fc909ef47631e4f6550e25817731534987f/numpy/_core/src/multiarray/getset.c#L64
| if not hasattr(data, "__cuda_array_interface__"): | ||
| data = np.frombuffer(data, np.uint8) | ||
| data.shape = tile_shape | ||
| data = data.reshape(tile_shape, copy=False) |
There was a problem hiding this comment.
The current behavior of .shape assignment is to call reshape and error if a copy occurs. Equivalent behavior can be implemented by calling .reshape(...) with the copy keyword argument as False
There was a problem hiding this comment.
Based on the discussion below, all of these were dropped because CuPy's reshape doesn't support the copy keyword argument and they were either unneeded in that context or the intended behavior could be captured other ways.
grlee77
left a comment
There was a problem hiding this comment.
Thanks, @jakirkham this changes to avoid shape assignment look good to me
seberg
left a comment
There was a problem hiding this comment.
Thanks, looks all better and safe. Not sure if the last can see NumPy arrays but it hardly matters.
(The first feels like it might be a latent fix, but probably not in practice.)
| x_view = x.reshape((ndim, 2), copy=False) | ||
| return x_view.tolist() |
There was a problem hiding this comment.
Given we call .tolist(...) here, avoiding a copy probably doesn't matter much. After all this is an array that is already created as C-contiguous above, so the copy shouldn't happen anyways.
This would better match the same upstream change: cupy/cupy#10037
| x_view = x.reshape((ndim, 2), copy=False) | |
| return x_view.tolist() | |
| x_view = x.reshape((ndim, 2)) | |
| return x_view.tolist() |
There was a problem hiding this comment.
Yeah. Reshapes are always no-copy by default if possible, so unless any of these could error it doesn't matter.
(But yes, it adds the guarantee, which may makes sense for the other cases)
This array is constructed so that copying shouldn't happen and it is a small array (extents). Plus `the `.tolist()` call will copy it in the end anyways. So drop the `copy=False` keyword argument. Co-authored-by: jakirkham <jakirkham@gmail.com>
| if not hasattr(data, "__cuda_array_interface__"): | ||
| data = np.frombuffer(data, np.uint8) | ||
| data.shape = tile_shape | ||
| data = data.reshape(tile_shape, copy=False) |
There was a problem hiding this comment.
Hmmm, this one could be a problem, though? Because cupy doesn't have copy=False (should probably add that).
And the hasattr() above looks like the input may or may not be a CuPy array?
There was a problem hiding this comment.
Good point. Looking at CuPy's reshape logic it appears to behave similar to NumPy's copy=None. Besides the NumPy case is already starting from a 1-D contiguous array so shouldn't copy anyways. So perhaps we can just drop this keyword argument
| data = data.reshape(tile_shape, copy=False) | |
| data = data.reshape(tile_shape) |
| # https://github.com/cupy/cupy/blob/v14.1.1/cupy/_padding/pad.py#L408 | ||
| "ignore:Setting the shape on a NumPy array:DeprecationWarning:cupy", | ||
| # https://github.com/scikit-image/scikit-image/blob/v0.26.0/skimage/measure/_marching_cubes_lewiner.py#L237 | ||
| "ignore:Setting the shape on a NumPy array:DeprecationWarning:skimage", |
There was a problem hiding this comment.
Also the warnings in CuPy are being fixed by @seberg in PR: cupy/cupy#10037
The warnings in scikit-image will be fixed in 0.27 with PR: scikit-image/scikit-image#8020
Co-authored-by: jakirkham <jakirkham@gmail.com>
| out_view = out.view() | ||
| out_view.shape = (-1,) # no-copy reshape/ravel |
There was a problem hiding this comment.
Have reverted to the original syntax here as CuPy's reshape doesn't support the copy keyword argument and we really must avoid a copy here. So the best way to do this with CuPy is to assign to .shape. This is unfortunate, but it should work as intended.
Edit - Filed an upstream request to add the copy keyword argument to reshape: cupy/cupy#10039
|
Thanks all! 🙏 |
|
/merge |
NumPy is deprecating direct
shapeassignment. The underlying code path simply goes throughreshape. So just switch toreshapeto eliminate the deprecation warning and future proof the code.ref: https://github.com/numpy/numpy/blob/2a674fc909ef47631e4f6550e25817731534987f/numpy/_core/src/multiarray/getset.c#L64