diff --git a/CHANGELOG.md b/CHANGELOG.md index fc4cf6dc32..b7fec72cad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Fixed `dpctl.lsplatform()` to work correctly when used from within Jupyter notebook [#800](https://github.com/IntelPython/dpctl/pull/800). * Fixed script to drive debug build [#835](https://github.com/IntelPython/dpctl/pull/835) and fixed code to compile in debug mode [#836](https://github.com/IntelPython/dpctl/pull/836). +* Fixed issue with slicing reported in gh-870 in [#871](https://github.com/IntelPython/dpctl/pull/871). ## [0.12.0] - 03/01/2022 diff --git a/dpctl/tensor/_slicing.pxi b/dpctl/tensor/_slicing.pxi index 9fd62e4944..b94fd60b8f 100755 --- a/dpctl/tensor/_slicing.pxi +++ b/dpctl/tensor/_slicing.pxi @@ -110,6 +110,7 @@ cdef object _basic_slice_meta(object ind, tuple shape, new_strides = list() k = 0 new_offset = offset + is_empty = False for i in range(len(ind)): ind_i = ind[i] if (ind_i is Ellipsis): @@ -127,23 +128,27 @@ cdef object _basic_slice_meta(object ind, tuple shape, str_i = (1 if sh_i == 0 else sl_step) * strides[k] new_shape.append(sh_i) new_strides.append(str_i) - if sh_i > 0: + if sh_i > 0 and not is_empty: new_offset = new_offset + sl_start * strides[k] + if sh_i == 0: + is_empty = True k = k_new elif is_integral(ind_i): ind_i = ind_i.__index__() if 0 <= ind_i < shape[k]: k_new = k + 1 - new_offset = new_offset + ind_i * strides[k] + if not is_empty: + new_offset = new_offset + ind_i * strides[k] k = k_new elif -shape[k] <= ind_i < 0: k_new = k + 1 - new_offset = new_offset + (shape[k] + ind_i) * strides[k] + if not is_empty: + new_offset = new_offset + (shape[k] + ind_i) * strides[k] k = k_new else: raise IndexError( - "Index {0} is out of range for " - "axes {1} with size {2}".format(ind_i, k, shape[k])) + ("Index {0} is out of range for " + "axes {1} with size {2}").format(ind_i, k, shape[k])) new_shape.extend(shape[k:]) new_strides.extend(strides[k:]) return (tuple(new_shape), tuple(new_strides), new_offset) diff --git a/dpctl/tensor/_usmarray.pyx b/dpctl/tensor/_usmarray.pyx index 5ad7dfe6fa..329794ebd6 100644 --- a/dpctl/tensor/_usmarray.pyx +++ b/dpctl/tensor/_usmarray.pyx @@ -234,10 +234,10 @@ cdef class usm_ndarray: else: self._cleanup() raise ValueError( - "buffer='{}' is not understood. " + ("buffer='{}' is not understood. " "Recognized values are 'device', 'shared', 'host', " "an instance of `MemoryUSM*` object, or a usm_ndarray" - "".format(buffer)) + "").format(buffer)) elif isinstance(buffer, usm_ndarray): _buffer = buffer.usm_data else: @@ -246,8 +246,8 @@ cdef class usm_ndarray: if (_offset + ary_min_displacement < 0 or (_offset + ary_max_displacement + 1) * itemsize > _buffer.nbytes): self._cleanup() - raise ValueError("buffer='{}' can not accomodate the requested " - "array.".format(buffer)) + raise ValueError(("buffer='{}' can not accomodate " + "the requested array.").format(buffer)) self.base_ = _buffer self.data_ = ( ( _buffer._pointer)) + itemsize * _offset self.shape_ = shape_ptr diff --git a/dpctl/tests/test_usm_ndarray_ctor.py b/dpctl/tests/test_usm_ndarray_ctor.py index 28180c4714..fffcf711d1 100644 --- a/dpctl/tests/test_usm_ndarray_ctor.py +++ b/dpctl/tests/test_usm_ndarray_ctor.py @@ -219,6 +219,9 @@ def test_empty_slice(): assert Y.shape == X.shape Z = X[::2] assert Z.shape == X.shape + X = dpt.empty((0, 4), dtype="u1") + assert X[:, 1].shape == (0,) + assert X[:, 1:3].shape == (0, 2) def test_slice_constructor_1d(): diff --git a/dpctl/tests/test_usm_ndarray_manipulation.py b/dpctl/tests/test_usm_ndarray_manipulation.py index 9e99372639..e020ae84e8 100644 --- a/dpctl/tests/test_usm_ndarray_manipulation.py +++ b/dpctl/tests/test_usm_ndarray_manipulation.py @@ -835,6 +835,7 @@ def test_concat_1array(data): "data", [ [(1,), (1,), 0], + [(0, 2), (0, 2), 1], [(0, 2), (2, 2), 0], [(2, 1), (2, 2), -1], [(2, 2, 2), (2, 1, 2), 1],