diff --git a/dpnp/dpnp_array.py b/dpnp/dpnp_array.py index ff28b0c42568..8b5b12fa8651 100644 --- a/dpnp/dpnp_array.py +++ b/dpnp/dpnp_array.py @@ -605,6 +605,25 @@ def __truediv__(self, other): """Return ``self/value``.""" return dpnp.true_divide(self, other) + @property + def __usm_ndarray__(self): + """ + Property to support `__usm_ndarray__` protocol. + + It assumes to return :class:`dpctl.tensor.usm_ndarray` instance + corresponding to the content of the object. + + This property is intended to speed-up conversion from + :class:`dpnp.ndarray` to :class:`dpctl.tensor.usm_ndarray` passed + into `dpctl.tensor.asarray` function. The input object that implements + `__usm_ndarray__` protocol is recognized as owner of USM allocation + that is managed by a smart pointer, and asynchronous deallocation + will not involve GIL. + + """ + + return self._array_obj + def __xor__(self, other): """Return ``self^value``.""" return dpnp.bitwise_xor(self, other) diff --git a/dpnp/tests/test_ndarray.py b/dpnp/tests/test_ndarray.py index a184af6ba225..0dfbf6c1e1c7 100644 --- a/dpnp/tests/test_ndarray.py +++ b/dpnp/tests/test_ndarray.py @@ -176,6 +176,18 @@ def test_error(self): ia.item() +class TestUsmNdarrayProtocol: + def test_basic(self): + a = dpnp.arange(256, dtype=dpnp.int64) + usm_a = dpt.asarray(a) + + assert a.sycl_queue == usm_a.sycl_queue + assert a.usm_type == usm_a.usm_type + assert a.dtype == usm_a.dtype + assert usm_a.usm_data.reference_obj is None + assert (a == usm_a).all() + + def test_print_dpnp_int(): result = repr(dpnp.array([1, 0, 2, -3, -1, 2, 21, -9], dtype="i4")) expected = "array([ 1, 0, 2, -3, -1, 2, 21, -9], dtype=int32)"