From 34296a82cb48cd0e313950cf3f6de19e407ff895 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Tue, 3 Dec 2024 12:59:10 -0600 Subject: [PATCH 1/2] Updated from_dlpack docstring Closes gh-1917. The change to docstring documents that `tensor.from_dlpack` may return numpy.ndarray or tensor.usm_ndarray and stipulates when that may happen. --- dpctl/tensor/_dlpack.pyx | 65 ++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/dpctl/tensor/_dlpack.pyx b/dpctl/tensor/_dlpack.pyx index f7d2847c74..ca168b3cd7 100644 --- a/dpctl/tensor/_dlpack.pyx +++ b/dpctl/tensor/_dlpack.pyx @@ -965,41 +965,66 @@ cdef object _create_device(object device, object dl_device): def from_dlpack(x, /, *, device=None, copy=None): """from_dlpack(x, /, *, device=None, copy=None) - Constructs :class:`dpctl.tensor.usm_ndarray` instance from a Python - object ``x`` that implements ``__dlpack__`` protocol. + Constructs :class:`dpctl.tensor.usm_ndarray` or :class:`numpy.ndarray` instance + from a Python object ``x`` that implements ``__dlpack__`` protocol. Args: x (object): A Python object representing an array that supports ``__dlpack__`` protocol. device (Optional[str, :class:`dpctl.SyclDevice`, :class:`dpctl.SyclQueue`, :class:`dpctl.tensor.Device`, tuple([:class:`enum.IntEnum`, int])])): - Array API concept of a device where the output array is to be placed. - ``device`` can be ``None``, a oneAPI filter selector - string, an instance of :class:`dpctl.SyclDevice` corresponding to - a non-partitioned SYCL device, an instance of - :class:`dpctl.SyclQueue`, a :class:`dpctl.tensor.Device` object - returned by :attr:`dpctl.tensor.usm_ndarray.device`, or a - 2-tuple matching the format of the output of the ``__dlpack_device__`` - method, an integer enumerator representing the device type followed by - an integer representing the index of the device. The only supported - :class:`dpctl.tensor.DLDeviceType` types are "kDLCPU" and - "kDLOneAPI". + Device where the output array is to be placed. ``device`` keyword values can be: + + * ``None`` + The data remains on the same device. If the data backing up + input object ``x`` resides on ``"kDLCPU"`` device, the return + type would be :class:`numpy.ndarray`, otherwise the return + type would be :class:`dpctl.tensor.usm_ndarray`. + * oneAPI filter selector string + SYCL device selected by :ref:`filter selector string `. + * :class:`dpctl.SyclDevice` + explicit SYCL device that must correspond to + a non-partitioned SYCL device. + * :class:`dpctl.SyclQueue` + implies SYCL device targeted by the SYCL queue. + * :class:`dpctl.tensor.Device` + implies SYCL device `device.sycl_queue`. The `Device` object + is obtained via :attr:`dpctl.tensor.usm_ndarray.device`. + * ``(device_type, device_id)`` + 2-tuple matching the format of the output of the ``__dlpack_device__`` + method: an integer enumerator representing the device type followed by + an integer representing the index of the device. + The only supported :class:`dpctl.tensor.DLDeviceType` device types + are ``"kDLCPU"`` and ``"kDLOneAPI"``. If ``"kDLCPU"`` requested, the + output type is :class:`numpy.ndarray`, otherwise it is + :class:`dpctl.tensor.usm_ndarray`. + Default: ``None``. + + .. note:: + + If the return type if :class:`dpctl.tensor.usm_ndarray`, the associated + SYCL queue is derived from the ``device`` keyword. When ``device`` + keyword value has type :class:`dpctl.SyclQueue`, the explicit queue + instance is used, when ``device`` keyword value has type :class:`dpctl.tensor.Device`, + the ``device.sycl_queue`` is used. In all other cases, the cached + SYCL queue corresponding the implied SYCL device is used. + copy (bool, optional) Boolean indicating whether or not to copy the input. * If ``copy`` is ``True``, the input will always be - copied. + copied. * If ``False``, a ``BufferError`` will be raised if a - copy is deemed necessary. + copy is deemed necessary. * If ``None``, a copy will be made only if deemed - necessary, otherwise, the existing memory buffer will - be reused. + necessary, otherwise, the existing memory buffer will + be reused. Default: ``None``. Returns: - usm_ndarray: + Alternative[usm_ndarray, numpy.ndarray]: An array containing the data in ``x``. When ``copy`` is ``None`` or ``False``, this may be a view into the original memory. @@ -1008,7 +1033,7 @@ def from_dlpack(x, /, *, device=None, copy=None): TypeError: if ``x`` does not implement ``__dlpack__`` method ValueError: - if the input array resides on an unsupported device + if data of the input object resides on an unsupported device See https://dmlc.github.io/dlpack/latest/ for more details. @@ -1031,7 +1056,9 @@ def from_dlpack(x, /, *, device=None, copy=None): return self._array.__dlpack_device__() C = Container(dpt.linspace(0, 100, num=20, dtype="int16")) + # create usm_ndarray view X = dpt.from_dlpack(C) + # migrate content of the container to device of type kDLCPU Y = dpt.from_dlpack(C, device=(dpt.DLDeviceType.kDLCPU, 0)) """ From ef407d22c33e19321d933860461c6fac5222e143 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Tue, 3 Dec 2024 14:06:09 -0600 Subject: [PATCH 2/2] Fixed typos pointed in PR feedback Removed duplicated statements clarifying type of the return object from entries describing supported device keyword values to the paragraph describing the return type. Moved the note pertaining to the SYCL queue of the returned usm_ndarray there as well. --- dpctl/tensor/_dlpack.pyx | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/dpctl/tensor/_dlpack.pyx b/dpctl/tensor/_dlpack.pyx index ca168b3cd7..afe76885ad 100644 --- a/dpctl/tensor/_dlpack.pyx +++ b/dpctl/tensor/_dlpack.pyx @@ -976,10 +976,7 @@ def from_dlpack(x, /, *, device=None, copy=None): Device where the output array is to be placed. ``device`` keyword values can be: * ``None`` - The data remains on the same device. If the data backing up - input object ``x`` resides on ``"kDLCPU"`` device, the return - type would be :class:`numpy.ndarray`, otherwise the return - type would be :class:`dpctl.tensor.usm_ndarray`. + The data remains on the same device. * oneAPI filter selector string SYCL device selected by :ref:`filter selector string `. * :class:`dpctl.SyclDevice` @@ -995,21 +992,10 @@ def from_dlpack(x, /, *, device=None, copy=None): method: an integer enumerator representing the device type followed by an integer representing the index of the device. The only supported :class:`dpctl.tensor.DLDeviceType` device types - are ``"kDLCPU"`` and ``"kDLOneAPI"``. If ``"kDLCPU"`` requested, the - output type is :class:`numpy.ndarray`, otherwise it is - :class:`dpctl.tensor.usm_ndarray`. + are ``"kDLCPU"`` and ``"kDLOneAPI"``. Default: ``None``. - .. note:: - - If the return type if :class:`dpctl.tensor.usm_ndarray`, the associated - SYCL queue is derived from the ``device`` keyword. When ``device`` - keyword value has type :class:`dpctl.SyclQueue`, the explicit queue - instance is used, when ``device`` keyword value has type :class:`dpctl.tensor.Device`, - the ``device.sycl_queue`` is used. In all other cases, the cached - SYCL queue corresponding the implied SYCL device is used. - copy (bool, optional) Boolean indicating whether or not to copy the input. @@ -1029,6 +1015,22 @@ def from_dlpack(x, /, *, device=None, copy=None): ``None`` or ``False``, this may be a view into the original memory. + The type of the returned object + depends on where the data backing up input object ``x`` resides. + If it resides in a USM allocation on a SYCL device, the + type :class:`dpctl.tensor.usm_ndarray` is returned, otherwise if it resides + on ``"kDLCPU"`` device the type is :class:`numpy.ndarray`, and otherwise + an exception is raised. + + .. note:: + + If the return type is :class:`dpctl.tensor.usm_ndarray`, the associated + SYCL queue is derived from the ``device`` keyword. When ``device`` + keyword value has type :class:`dpctl.SyclQueue`, the explicit queue + instance is used, when ``device`` keyword value has type :class:`dpctl.tensor.Device`, + the ``device.sycl_queue`` is used. In all other cases, the cached + SYCL queue corresponding to the implied SYCL device is used. + Raises: TypeError: if ``x`` does not implement ``__dlpack__`` method