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

cupy.lib.stride_tricks.as_strided(...) not consistent with Numpy? #4825

Open
Tracked by #9
kkotyk opened this issue Mar 5, 2021 · 1 comment
Open
Tracked by #9

cupy.lib.stride_tricks.as_strided(...) not consistent with Numpy? #4825

kkotyk opened this issue Mar 5, 2021 · 1 comment

Comments

@kkotyk
Copy link

kkotyk commented Mar 5, 2021

Using strides causes memory allocations to balloon in size. It looks like as_strided() is not creating a view of the array the same way that Numpy does.

import cupy as cp
import numpy as np

def windowed_view(ndarray, window_len, step, xp):

    nrows = ((ndarray.shape[-1] - window_len) // step) + 1
    last_dim_stride = ndarray.strides[-1]
    new_shape = ndarray.shape[:-1] + (nrows, window_len)
    new_strides = list(ndarray.strides + (last_dim_stride,))
    new_strides[-2] *= step

    return xp.lib.stride_tricks.as_strided(ndarray, shape=new_shape, strides=new_strides)


arr = np.ones((1,1,1000))
v = windowed_view(arr, 100, 10, np)

print(v.shape)
print(arr.nbytes, v.nbytes)
print(v.base)
print(v.base.base.nbytes)

arr = cp.ones((1,1,1000))
v = windowed_view(arr, 100, 10, cp)

print(v.shape)
print(arr.nbytes, v.nbytes)
print(v.base)

The output of this example shows:

(1, 1, 91, 100)
8000 72800
<numpy.lib.stride_tricks.DummyArray object at 0x7f74ef128b38>
8000
(1, 1, 91, 100)
8000 72800
None

So it appears that when using as_strided, Cupy using the original array as a base. Does anyone have a suggestion on how to deal with this?

@newmanwang
Copy link

newmanwang commented Jun 26, 2023

@kkotyk, Cupy's ndarray has __cuda_array_interface__ attribute that similar to numpy ndarray's __array_interface__. To avoid memory allocation as cupy's as_strided doese, as what numpy's as_strided did, make a DummyArray which has a __cuda_array_interface__, set desired strides and shape which make the sliding window view into this __cuda_array_interface__. As cp.asarray hornor strides and shape in the __cuda_array_interface__, so the new ndarray returned by cp.asarray(DummyArray(this_cuda_interface, base=original_array)) is almost the final real sliding window view that you can use in some cases(In other cases, for example, print this view lead to memory allocation ).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants