Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ Also, that release drops support for Python 3.9, making Python 3.10 the minimum
* Resolved an issue causing `dpnp.linspace` to return an incorrect output shape when inputs were passed as arrays [#2712](https://github.com/IntelPython/dpnp/pull/2712)
* Resolved an issue where `dpnp` always returns the base allocation pointer, when the view start is expected [#2651](https://github.com/IntelPython/dpnp/pull/2651)
* Fixed an issue causing an exception in `dpnp.geomspace` and `dpnp.logspace` when called with explicit `device` keyword but any input array is allocated on another device [#2723](https://github.com/IntelPython/dpnp/pull/2723)
* Fixed `.data.ptr` property on array views to correctly return the pointer to the view's data location instead of the base allocation pointer [#2812](https://github.com/IntelPython/dpnp/pull/2812)

### Security

Expand Down
25 changes: 15 additions & 10 deletions dpnp/memory/_memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,18 @@ def create_data(x):
usm_data = x.usm_data

if isinstance(usm_data, tuple(dispatch.values())):
return usm_data

cls = dispatch.get(type(usm_data), None)
if cls:
data = cls(usm_data)
# `ptr` is expecting to point at the start of the array's data,
# while `usm_data._pointer` is a pointer at the start of memory buffer
data.ptr = x._pointer
return data
raise TypeError(f"Expected USM memory, but got {type(usm_data)}")
# usm_data is already an instance of MemoryUSM<type> class
cls = usm_data.__class__
elif (cls := dispatch.get(type(usm_data))) is not None:
pass # cls is set
else:
raise TypeError(f"Expected USM memory, but got {type(usm_data)}")

# create a new instance each time since usm_data might be a view
# of another array
data = cls(usm_data)

# `ptr` is expecting to point at the start of the array's data,
# while `usm_data._pointer` is a pointer at the start of memory buffer
data.ptr = x._pointer
return data
59 changes: 59 additions & 0 deletions dpnp/tests/test_memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,62 @@ def test_view_non_zero_offset(self):
pl = dpnp.ndarray((n, m), dtype=a.dtype, buffer=sl)
assert pl.data.ptr == sl.data.ptr
assert a.data.ptr != sl.data.ptr

def test_slices_2d(self):
# Create 2D array and verify slices have different pointers
a = dpnp.arange(12, dtype=dpnp.float32).reshape(3, 4)

# Each row should have a different pointer
row0_ptr = a[0].data.ptr
row1_ptr = a[1].data.ptr
row2_ptr = a[2].data.ptr

assert (
row0_ptr != row1_ptr
), "a[0] and a[1] should have different pointers"
assert (
row1_ptr != row2_ptr
), "a[1] and a[2] should have different pointers"

# Check byte offsets match expected stride
stride = a.strides[0] # stride between rows in bytes
assert row1_ptr - row0_ptr == stride
assert row2_ptr - row1_ptr == stride

def test_slices_multidimensional(self):
# 3D array
a = dpnp.zeros((5, 10, 20), dtype=dpnp.int32)

# Different slices along first axis should have different pointers
slice0_ptr = a[0].data.ptr
slice1_ptr = a[1].data.ptr

assert slice0_ptr != slice1_ptr
assert slice1_ptr - slice0_ptr == a.strides[0]

def test_repeated_access(self):
a = dpnp.arange(20).reshape(4, 5)

# Multiple accesses to same slice should give same ptr value
ptr1 = a[2].data.ptr
ptr2 = a[2].data.ptr

assert ptr1 == ptr2, "Same slice should have consistent ptr value"

# But different slices should have different ptrs
assert a[0].data.ptr != a[2].data.ptr

def test_array_on_view_with_slicing(self):
# Original array
a = dpnp.arange(24, dtype=dpnp.float32).reshape(6, 4)

# Create view using slicing
view = a[2:5]

# Construct new array from view
new_arr = dpnp.ndarray(view.shape, dtype=view.dtype, buffer=view)

# Pointers should match
assert new_arr.data.ptr == view.data.ptr
# And should be different from base array
assert new_arr.data.ptr != a.data.ptr
Loading