Skip to content

Commit 004e3d9

Browse files
Merge pull request #1199 from IntelPython/qol-usm-ndarray-changes
Implement QOL properties of usm_ndarray
2 parents 25a7f42 + 4eb94f4 commit 004e3d9

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

dpctl/tensor/_usmarray.pyx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,43 @@ cdef class usm_ndarray:
355355
"byte_offset is not a multiple of item_size.")
356356
return byte_offset // item_size
357357

358+
@property
359+
def _element_offset(self):
360+
"""Returns the offset of the zero-index element of the array, in elements,
361+
relative to the start of memory allocation"""
362+
return self.get_offset()
363+
364+
@property
365+
def _byte_bounds(self):
366+
"""Returns a 2-tuple with pointers to the end-points of the array"""
367+
cdef Py_ssize_t min_disp = 0
368+
cdef Py_ssize_t max_disp = 0
369+
cdef Py_ssize_t step_ = 0
370+
cdef Py_ssize_t dim_ = 0
371+
cdef int it = 0
372+
cdef Py_ssize_t _itemsize = self.get_itemsize()
373+
374+
if ((self.flags_ & USM_ARRAY_C_CONTIGUOUS) or (self.flags_ & USM_ARRAY_F_CONTIGUOUS)):
375+
return (
376+
self._pointer,
377+
self._pointer + shape_to_elem_count(self.nd_, self.shape_) * _itemsize
378+
)
379+
380+
for it in range(self.nd_):
381+
dim_ = self.shape[it]
382+
if dim_ > 0:
383+
step_ = self.strides[it]
384+
if step_ > 0:
385+
max_disp += step_ * (dim_ - 1)
386+
else:
387+
min_disp += step_ * (dim_ - 1)
388+
389+
return (
390+
self._pointer + min_disp * _itemsize,
391+
self._pointer + (max_disp + 1) * _itemsize
392+
)
393+
394+
358395
cdef char* get_data(self):
359396
"""Returns the USM pointer for this array."""
360397
return self.data_

dpctl/tests/test_usm_ndarray_ctor.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,3 +2032,30 @@ def test_Device():
20322032
assert dict[d2] == 1
20332033
assert d1 == d2.sycl_queue
20342034
assert not d1 == Ellipsis
2035+
2036+
2037+
def test_element_offset():
2038+
n0, n1 = 3, 8
2039+
try:
2040+
x = dpt.empty((n0, n1), dtype="i4")
2041+
except dpctl.SyclDeviceCreationError:
2042+
pytest.skip("No SYCL devices available")
2043+
assert isinstance(x._element_offset, int)
2044+
assert x._element_offset == 0
2045+
y = x[::-1, ::2]
2046+
assert y._element_offset == (n0 - 1) * n1
2047+
2048+
2049+
def test_byte_bounds():
2050+
n0, n1 = 3, 8
2051+
try:
2052+
x = dpt.empty((n0, n1), dtype="i4")
2053+
except dpctl.SyclDeviceCreationError:
2054+
pytest.skip("No SYCL devices available")
2055+
assert isinstance(x._byte_bounds, tuple)
2056+
assert len(x._byte_bounds) == 2
2057+
lo, hi = x._byte_bounds
2058+
assert hi - lo == n0 * n1 * x.itemsize
2059+
y = x[::-1, ::2]
2060+
lo, hi = y._byte_bounds
2061+
assert hi - lo == (n0 * n1 - 1) * x.itemsize

0 commit comments

Comments
 (0)