@@ -153,13 +153,6 @@ def mT(self):
153153
154154 return dpnp_array ._create_from_usm_ndarray (self ._array_obj .mT )
155155
156- def to_device (self , target_device ):
157- """Transfer array to target device."""
158-
159- return dpnp_array (
160- shape = self .shape , buffer = self .get_array ().to_device (target_device )
161- )
162-
163156 @property
164157 def sycl_queue (self ):
165158 return self ._array_obj .sycl_queue
@@ -199,7 +192,9 @@ def __and__(self, other):
199192 # '__array_prepare__',
200193 # '__array_priority__',
201194 # '__array_struct__',
202- # '__array_ufunc__',
195+
196+ __array_ufunc__ = None
197+
203198 # '__array_wrap__',
204199
205200 def __array_namespace__ (self , / , * , api_version = None ):
@@ -612,6 +607,25 @@ def __truediv__(self, other):
612607 """Return ``self/value``."""
613608 return dpnp .true_divide (self , other )
614609
610+ @property
611+ def __usm_ndarray__ (self ):
612+ """
613+ Property to support `__usm_ndarray__` protocol.
614+
615+ It assumes to return :class:`dpctl.tensor.usm_ndarray` instance
616+ corresponding to the content of the object.
617+
618+ This property is intended to speed-up conversion from
619+ :class:`dpnp.ndarray` to :class:`dpctl.tensor.usm_ndarray` passed
620+ into `dpctl.tensor.asarray` function. The input object that implements
621+ `__usm_ndarray__` protocol is recognized as owner of USM allocation
622+ that is managed by a smart pointer, and asynchronous deallocation
623+ will not involve GIL.
624+
625+ """
626+
627+ return self ._array_obj
628+
615629 def __xor__ (self , other ):
616630 """Return ``self^value``."""
617631 return dpnp .bitwise_xor (self , other )
@@ -1693,6 +1707,48 @@ def take(self, indices, axis=None, out=None, mode="wrap"):
16931707
16941708 return dpnp .take (self , indices , axis = axis , out = out , mode = mode )
16951709
1710+ def to_device (self , device , / , * , stream = None ):
1711+ """
1712+ Transfers this array to specified target device.
1713+
1714+ Parameters
1715+ ----------
1716+ device : {string, SyclDevice, SyclQueue}
1717+ Array API concept of target device. It can be an OneAPI filter
1718+ selector string, an instance of :class:`dpctl.SyclDevice`
1719+ corresponding to a non-partitioned SYCL device, an instance of
1720+ :class:`dpctl.SyclQueue`, or a :class:`dpctl.tensor.Device` object
1721+ returned by :obj:`dpnp.dpnp_array.dpnp_array.device` property.
1722+ stream : {SyclQueue, None}, optional
1723+ Execution queue to synchronize with. If ``None``, synchronization
1724+ is not performed.
1725+ Default: ``None``.
1726+
1727+ Returns
1728+ -------
1729+ out : dpnp.ndarray
1730+ A view if data copy is not required, and a copy otherwise.
1731+ If copying is required, it is done by copying from the original
1732+ allocation device to the host, followed by copying from host
1733+ to the target device.
1734+
1735+ Examples
1736+ --------
1737+ >>> import dpnp as np, dpctl
1738+ >>> x = np.full(100, 2, dtype=np.int64)
1739+ >>> q_prof = dpctl.SyclQueue(x.sycl_device, property="enable_profiling")
1740+ >>> # return a view with profile-enabled queue
1741+ >>> y = x.to_device(q_prof)
1742+ >>> timer = dpctl.SyclTimer()
1743+ >>> with timer(q_prof):
1744+ ... z = y * y
1745+ >>> print(timer.dt)
1746+
1747+ """
1748+
1749+ usm_res = self ._array_obj .to_device (device , stream = stream )
1750+ return dpnp_array ._create_from_usm_ndarray (usm_res )
1751+
16961752 # 'tobytes',
16971753 # 'tofile',
16981754 # 'tolist',
0 commit comments