Source code for dpnp.dpnp_array

# -*- coding: utf-8 -*-
# *****************************************************************************
# Copyright (c) 2016-2025, Intel Corporation
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# - Redistributions of source code must retain the above copyright notice,
#   this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
# *****************************************************************************

import dpctl.tensor as dpt
from dpctl.tensor._numpy_helper import AxisError

import dpnp


def _get_unwrapped_index_key(key):
    """
    Get an unwrapped index key.

    Return a key where each nested instance of DPNP array is unwrapped into USM ndarray
    for further processing in DPCTL advanced indexing functions.

    """

    if isinstance(key, tuple):
        if any(isinstance(x, dpnp_array) for x in key):
            # create a new tuple from the input key with unwrapped DPNP arrays
            return tuple(
                x.get_array() if isinstance(x, dpnp_array) else x for x in key
            )
    elif isinstance(key, dpnp_array):
        return key.get_array()
    return key


[docs] class dpnp_array: """ Multi-dimensional array object. This is a wrapper around dpctl.tensor.usm_ndarray that provides methods to be compliant with original NumPy. """ def __init__( self, shape, dtype=None, buffer=None, offset=0, strides=None, order="C", device=None, usm_type="device", sycl_queue=None, ): if order is None: order = "C" if buffer is not None: buffer = dpnp.get_usm_ndarray(buffer) if dtype is None: dtype = buffer.dtype else: buffer = usm_type sycl_queue_normalized = dpnp.get_normalized_queue_device( device=device, sycl_queue=sycl_queue ) self._array_obj = dpt.usm_ndarray( shape, dtype=dtype, strides=strides, buffer=buffer, offset=offset, order=order, buffer_ctor_kwargs={"queue": sycl_queue_normalized}, array_namespace=dpnp, ) @property def __sycl_usm_array_interface__(self): return self._array_obj.__sycl_usm_array_interface__
[docs] def get_array(self): """Get usm_ndarray object.""" return self._array_obj
@property def T(self): """View of the transposed array.""" return self.transpose() @property def mT(self): """ View of the matrix transposed array. The matrix transpose is the transpose of the last two dimensions, even if the array is of higher dimension. Raises ------ ValueError If the array is of dimension less than 2. Examples -------- >>> import dpnp as np >>> a = np.array([[1, 2], [3, 4]]) >>> a array([[1, 2], [3, 4]]) >>> a.mT array([[1, 3], [2, 4]]) >>> a = np.arange(8).reshape((2, 2, 2)) >>> a array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]]) >>> a.mT array([[[0, 2], [1, 3]], [[4, 6], [5, 7]]]) """ if self.ndim < 2: raise ValueError("matrix transpose with ndim < 2 is undefined") return dpnp_array._create_from_usm_ndarray(self._array_obj.mT) @property def sycl_queue(self): return self._array_obj.sycl_queue @property def sycl_device(self): return self._array_obj.sycl_device @property def sycl_context(self): return self._array_obj.sycl_context @property def device(self): return self._array_obj.device @property def usm_type(self): return self._array_obj.usm_type def __abs__(self): r"""Return ``\|self\|``.""" return dpnp.abs(self) def __add__(self, other): """Return ``self+value``.""" return dpnp.add(self, other) def __and__(self, other): """Return ``self&value``.""" return dpnp.bitwise_and(self, other) def __array__(self, dtype=None, /, *, copy=None): raise TypeError( "Implicit conversion to a NumPy array is not allowed. " "Please use `.asnumpy()` to construct a NumPy array explicitly." ) # '__array_finalize__', # '__array_function__', # '__array_interface__', # '__array_prepare__', # '__array_priority__', # '__array_struct__', __array_ufunc__ = None # '__array_wrap__', def __array_namespace__(self, /, *, api_version=None): """ Returns array namespace, member functions of which implement data API. Parameters ---------- api_version : str, optional Request namespace compliant with given version of array API. If ``None``, namespace for the most recent supported version is returned. Default: ``None``. Returns ------- out : any An object representing the array API namespace. It should have every top-level function defined in the specification as an attribute. It may contain other public names as well, but it is recommended to only include those names that are part of the specification. """ return self._array_obj.__array_namespace__(api_version=api_version) def __bool__(self): """``True`` if self else ``False``.""" return self._array_obj.__bool__() # '__class__', # `__class_getitem__`, def __complex__(self): return self._array_obj.__complex__() # '__contains__', def __copy__(self): """ Used if :func:`copy.copy` is called on an array. Returns a copy of the array. Equivalent to ``a.copy(order="K")``. """ return self.copy(order="K") # '__deepcopy__', # '__delattr__', # '__delitem__', # '__dir__', # '__divmod__', # '__doc__', def __dlpack__( self, *, stream=None, max_version=None, dl_device=None, copy=None ): """ Produces DLPack capsule. Parameters ---------- stream : {:class:`dpctl.SyclQueue`, None}, optional Execution queue to synchronize with. If ``None``, synchronization is not performed. Default: ``None``. max_version {tuple of ints, None}, optional The maximum DLPack version the consumer (caller of ``__dlpack__``) supports. As ``__dlpack__`` may not always return a DLPack capsule with version `max_version`, the consumer must verify the version even if this argument is passed. Default: ``None``. dl_device {tuple, None}, optional: The device the returned DLPack capsule will be placed on. The device must be a 2-tuple matching the format of ``__dlpack_device__`` method, an integer enumerator representing the device type followed by an integer representing the index of the device. Default: ``None``. copy {bool, None}, optional: Boolean indicating whether or not to copy the input. * If `copy` is ``True``, the input will always be copied. * If ``False``, a ``BufferError`` will be raised if a copy is deemed necessary. * If ``None``, a copy will be made only if deemed necessary, otherwise, the existing memory buffer will be reused. Default: ``None``. Raises ------ MemoryError: when host memory can not be allocated. DLPackCreationError: when array is allocated on a partitioned SYCL device, or with a non-default context. BufferError: when a copy is deemed necessary but `copy` is ``False`` or when the provided `dl_device` cannot be handled. """ return self._array_obj.__dlpack__( stream=stream, max_version=max_version, dl_device=dl_device, copy=copy, ) def __dlpack_device__(self): """ Gives a tuple (``device_type``, ``device_id``) corresponding to ``DLDevice`` entry in ``DLTensor`` in DLPack protocol. The tuple describes the non-partitioned device where the array has been allocated, or the non-partitioned parent device of the allocation device. Raises ------ DLPackCreationError: when the ``device_id`` could not be determined. """ return self._array_obj.__dlpack_device__() def __eq__(self, other): """Return ``self==value``.""" return dpnp.equal(self, other) def __float__(self): return self._array_obj.__float__() def __floordiv__(self, other): """Return ``self//value``.""" return dpnp.floor_divide(self, other) # '__format__', def __ge__(self, other): """Return ``self>=value``.""" return dpnp.greater_equal(self, other) # '__getattribute__', def __getitem__(self, key): """Return ``self[key]``.""" key = _get_unwrapped_index_key(key) item = self._array_obj.__getitem__(key) return dpnp_array._create_from_usm_ndarray(item) # '__getstate__', def __gt__(self, other): """Return ``self>value``.""" return dpnp.greater(self, other) # '__hash__', def __iadd__(self, other): """Return ``self+=value``.""" dpnp.add(self, other, out=self) return self def __iand__(self, other): """Return ``self&=value``.""" dpnp.bitwise_and(self, other, out=self) return self def __ifloordiv__(self, other): """Return ``self//=value``.""" dpnp.floor_divide(self, other, out=self) return self def __ilshift__(self, other): """Return ``self<<=value``.""" dpnp.left_shift(self, other, out=self) return self def __imatmul__(self, other): """Return ``self@=value``.""" """ Unlike `matmul(a, b, out=a)` we ensure that the result is not broadcast if the result without `out` would have less dimensions than `a`. Since the signature of matmul is '(n?,k),(k,m?)->(n?,m?)' this is the case exactly when the second operand has both core dimensions. We have to enforce this check by passing the correct `axes=`. """ if self.ndim == 1: axes = [(-1,), (-2, -1), (-1,)] else: axes = [(-2, -1), (-2, -1), (-2, -1)] try: dpnp.matmul(self, other, out=self, dtype=self.dtype, axes=axes) except AxisError: # AxisError should indicate that the axes argument didn't work out # which should mean the second operand not being 2 dimensional. raise ValueError( "inplace matrix multiplication requires the first operand to " "have at least one and the second at least two dimensions." ) return self def __imod__(self, other): """Return ``self%=value``.""" dpnp.remainder(self, other, out=self) return self def __imul__(self, other): """Return ``self*=value``.""" dpnp.multiply(self, other, out=self) return self def __index__(self): return self._array_obj.__index__() # '__init__', # '__init_subclass__', def __int__(self): return self._array_obj.__int__() def __invert__(self): """Return ``~self``.""" return dpnp.invert(self) def __ior__(self, other): """Return ``self|=value``.""" dpnp.bitwise_or(self, other, out=self) return self def __ipow__(self, other): """Return ``self**=value``.""" dpnp.power(self, other, out=self) return self def __irshift__(self, other): """Return ``self>>=value``.""" dpnp.right_shift(self, other, out=self) return self def __isub__(self, other): """Return ``self-=value``.""" dpnp.subtract(self, other, out=self) return self def __iter__(self): """Return ``iter(self)``.""" if self.ndim == 0: raise TypeError("iteration over a 0-d array") return (self[i] for i in range(self.shape[0])) def __itruediv__(self, other): """Return ``self/=value``.""" dpnp.true_divide(self, other, out=self) return self def __ixor__(self, other): """Return ``self^=value``.""" dpnp.bitwise_xor(self, other, out=self) return self def __le__(self, other): """Return ``self<=value``.""" return dpnp.less_equal(self, other) def __len__(self): """Return ``len(self)``.""" return self._array_obj.__len__() def __lshift__(self, other): """Return ``self<<value``.""" return dpnp.left_shift(self, other) def __lt__(self, other): """Return ``self<value``.""" return dpnp.less(self, other) def __matmul__(self, other): """Return ``self@value``.""" return dpnp.matmul(self, other) def __mod__(self, other): """Return ``self%value``.""" return dpnp.remainder(self, other) def __mul__(self, other): """Return ``self*value``.""" return dpnp.multiply(self, other) def __ne__(self, other): """Return ``self!=value``.""" return dpnp.not_equal(self, other) def __neg__(self): """Return ``-self``.""" return dpnp.negative(self) # '__new__', def __or__(self, other): """Return ``self|value``.""" return dpnp.bitwise_or(self, other) def __pos__(self): """Return ``+self``.""" return dpnp.positive(self) def __pow__(self, other): """Return ``self**value``.""" return dpnp.power(self, other) def __radd__(self, other): """Return ``value+self``.""" return dpnp.add(other, self) def __rand__(self, other): """Return ``value&self``.""" return dpnp.bitwise_and(other, self) # '__rdivmod__', # '__reduce__', # '__reduce_ex__', def __repr__(self): """Return ``repr(self)``.""" return dpt.usm_ndarray_repr(self._array_obj, prefix="array") def __rfloordiv__(self, other): """Return ``value//self``.""" return dpnp.floor_divide(self, other) def __rlshift__(self, other): """Return ``value<<self``.""" return dpnp.left_shift(other, self) def __rmatmul__(self, other): """Return ``value@self``.""" return dpnp.matmul(other, self) def __rmod__(self, other): """Return ``value%self``.""" return dpnp.remainder(other, self) def __rmul__(self, other): """Return ``value*self``.""" return dpnp.multiply(other, self) def __ror__(self, other): """Return ``value|self``.""" return dpnp.bitwise_or(other, self) def __rpow__(self, other): """Return ``value**self``.""" return dpnp.power(other, self) def __rrshift__(self, other): """Return ``value>>self``.""" return dpnp.right_shift(other, self) def __rshift__(self, other): """Return ``self>>value``.""" return dpnp.right_shift(self, other) def __rsub__(self, other): """Return ``value-self``.""" return dpnp.subtract(other, self) def __rtruediv__(self, other): """Return ``value/self``.""" return dpnp.true_divide(other, self) def __rxor__(self, other): """Return ``value^self``.""" return dpnp.bitwise_xor(other, self) # '__setattr__', def __setitem__(self, key, val): """Set ``self[key]`` to value.""" key = _get_unwrapped_index_key(key) if isinstance(val, dpnp_array): val = val.get_array() self._array_obj.__setitem__(key, val) # '__setstate__', # '__sizeof__', __slots__ = ("_array_obj",) def __str__(self): """Return ``str(self)``.""" return self._array_obj.__str__() def __sub__(self, other): """Return ``self-value``.""" return dpnp.subtract(self, other) # '__subclasshook__', 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) @staticmethod def _create_from_usm_ndarray(usm_ary: dpt.usm_ndarray): if not isinstance(usm_ary, dpt.usm_ndarray): raise TypeError( f"Expected dpctl.tensor.usm_ndarray, got {type(usm_ary)}" ) res = dpnp_array.__new__(dpnp_array) res._array_obj = usm_ary res._array_obj._set_namespace(dpnp) return res
[docs] def all(self, axis=None, out=None, keepdims=False, *, where=True): """ Returns True if all elements evaluate to True. Refer to :obj:`dpnp.all` for full documentation. See Also -------- :obj:`dpnp.all` : equivalent function """ return dpnp.all( self, axis=axis, out=out, keepdims=keepdims, where=where )
[docs] def any(self, axis=None, out=None, keepdims=False, *, where=True): """ Returns True if any of the elements of `a` evaluate to True. Refer to :obj:`dpnp.any` for full documentation. See Also -------- :obj:`dpnp.any` : equivalent function """ return dpnp.any( self, axis=axis, out=out, keepdims=keepdims, where=where )
[docs] def argmax(self, axis=None, out=None, *, keepdims=False): """ Returns array of indices of the maximum values along the given axis. Refer to :obj:`dpnp.argmax` for full documentation. """ return dpnp.argmax(self, axis=axis, out=out, keepdims=keepdims)
[docs] def argmin(self, axis=None, out=None, *, keepdims=False): """ Return array of indices to the minimum values along the given axis. Refer to :obj:`dpnp.argmin` for full documentation. """ return dpnp.argmin(self, axis=axis, out=out, keepdims=keepdims)
# 'argpartition',
[docs] def argsort( self, axis=-1, kind=None, order=None, *, descending=False, stable=None ): """ Return an ndarray of indices that sort the array along the specified axis. Refer to :obj:`dpnp.argsort` for full documentation. Parameters ---------- axis : {None, int}, optional Axis along which to sort. If ``None``, the array is flattened before sorting. The default is ``-1``, which sorts along the last axis. Default: ``-1``. kind : {None, "stable", "mergesort", "radixsort"}, optional Sorting algorithm. The default is ``None``, which uses parallel merge-sort or parallel radix-sort algorithms depending on the array data type. Default: ``None``. descending : bool, optional Sort order. If ``True``, the array must be sorted in descending order (by value). If ``False``, the array must be sorted in ascending order (by value). Default: ``False``. stable : {None, bool}, optional Sort stability. If ``True``, the returned array will maintain the relative order of `a` values which compare as equal. The same behavior applies when set to ``False`` or ``None``. Internally, this option selects ``kind="stable"``. Default: ``None``. See Also -------- :obj:`dpnp.sort` : Return a sorted copy of an array. :obj:`dpnp.argsort` : Return the indices that would sort an array. :obj:`dpnp.lexsort` : Indirect stable sort on multiple keys. :obj:`dpnp.searchsorted` : Find elements in a sorted array. :obj:`dpnp.partition` : Partial sort. Examples -------- >>> import dpnp as np >>> a = np.array([3, 1, 2]) >>> a.argsort() array([1, 2, 0]) >>> a = np.array([[0, 3], [2, 2]]) >>> a.argsort(axis=0) array([[0, 1], [1, 0]]) """ return dpnp.argsort( self, axis, kind, order, descending=descending, stable=stable )
[docs] def asnumpy(self): """ Copy content of the array into :class:`numpy.ndarray` instance of the same shape and data type. Returns ------- out : numpy.ndarray An instance of :class:`numpy.ndarray` populated with the array content. """ return dpt.asnumpy(self._array_obj)
[docs] def astype( self, dtype, order="K", casting="unsafe", subok=True, copy=True, device=None, ): """ Copy the array with data type casting. Refer to :obj:`dpnp.astype` for full documentation. Parameters ---------- dtype : {None, str, dtype object} Target data type. order : {None, "C", "F", "A", "K"}, optional Row-major (C-style) or column-major (Fortran-style) order. When `order` is ``"A"``, it uses ``"F"`` if `a` is column-major and uses ``"C"`` otherwise. And when `order` is ``"K"``, it keeps strides as closely as possible. Default: ``"K"``. casting : {"no", "equiv", "safe", "same_kind", "unsafe"}, optional Controls what kind of data casting may occur. Defaults to ``"unsafe"`` for backwards compatibility. - "no" means the data types should not be cast at all. - "equiv" means only byte-order changes are allowed. - "safe" means only casts which can preserve values are allowed. - "same_kind" means only safe casts or casts within a kind, like float64 to float32, are allowed. - "unsafe" means any data conversions may be done. Default: ``"unsafe"``. copy : bool, optional Specifies whether to copy an array when the specified dtype matches the data type of that array. If ``True``, a newly allocated array must always be returned. If ``False`` and the specified dtype matches the data type of that array, the self array must be returned; otherwise, a newly allocated array must be returned. Default: ``True``. device : {None, string, SyclDevice, SyclQueue, Device}, optional An array API concept of device where the output array is created. `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`, or a :class:`dpctl.tensor.Device` object returned by :attr:`dpnp.ndarray.device`. If the value is ``None``, returned array is created on the same device as that array. Default: ``None``. Returns ------- out : dpnp.ndarray An array having the specified data type. Limitations ----------- Parameter `subok` is supported with default value. Otherwise ``NotImplementedError`` exception will be raised. Examples -------- >>> import dpnp as np >>> x = np.array([1, 2, 2.5]); x array([1. , 2. , 2.5]) >>> x.astype(int) array([1, 2, 2]) """ if subok is not True: raise NotImplementedError( f"subok={subok} is currently not supported" ) return dpnp.astype( self, dtype, order=order, casting=casting, copy=copy, device=device )
# 'base', # 'byteswap',
[docs] def choose(self, /, choices, out=None, mode="wrap"): """ Use an array as index array to construct a new array from a set of choices. Refer to :obj:`dpnp.choose` for full documentation. """ return dpnp.choose(self, choices, out, mode)
[docs] def clip(self, min=None, max=None, out=None, **kwargs): """ Clip (limit) the values in an array. Refer to :obj:`dpnp.clip` for full documentation. """ return dpnp.clip(self, min, max, out=out, **kwargs)
[docs] def compress(self, condition, axis=None, out=None): """ Select slices of an array along a given axis. Refer to :obj:`dpnp.compress` for full documentation. """ return dpnp.compress(condition, self, axis=axis, out=out)
[docs] def conj(self): """ Complex-conjugate all elements. Refer to :obj:`dpnp.conjugate` for full documentation. """ if not dpnp.issubdtype(self.dtype, dpnp.complexfloating): return self else: return dpnp.conjugate(self)
[docs] def conjugate(self): """ Return the complex conjugate, element-wise. Refer to :obj:`dpnp.conjugate` for full documentation. """ if not dpnp.issubdtype(self.dtype, dpnp.complexfloating): return self else: return dpnp.conjugate(self)
[docs] def copy(self, order="C", device=None, usm_type=None, sycl_queue=None): """ Return a copy of the array. Refer to :obj:`dpnp.copy` for full documentation. Parameters ---------- order : {"C", "F", "A", "K"}, optional Memory layout of the newly output array. Default: ``"C"``. device : {None, string, SyclDevice, SyclQueue, Device}, optional An array API concept of device where the output array is created. `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`, or a :class:`dpctl.tensor.Device` object returned by :attr:`dpnp.ndarray.device`. Default: ``None``. usm_type : {None, "device", "shared", "host"}, optional The type of SYCL USM allocation for the output array. Default: ``None``. sycl_queue : {None, SyclQueue}, optional A SYCL queue to use for output array allocation and copying. The `sycl_queue` can be passed as ``None`` (the default), which means to get the SYCL queue from `device` keyword if present or to use a default queue. Default: ``None``. Returns ------- out : dpnp.ndarray A copy of the array. See also -------- :obj:`dpnp.copy` : Similar function with different default behavior :obj:`dpnp.copyto` : Copies values from one array to another. Notes ----- This function is the preferred method for creating an array copy. The function :func:`dpnp.copy` is similar, but it defaults to using order ``"K"``. Examples -------- >>> import dpnp as np >>> x = np.array([[1, 2, 3], [4, 5, 6]], order='F') >>> y = x.copy() >>> x.fill(0) >>> x array([[0, 0, 0], [0, 0, 0]]) >>> y array([[1, 2, 3], [4, 5, 6]]) >>> y.flags['C_CONTIGUOUS'] True """ return dpnp.copy( self, order=order, device=device, usm_type=usm_type, sycl_queue=sycl_queue, )
# 'ctypes',
[docs] def cumprod(self, axis=None, dtype=None, out=None): """ Return the cumulative product of the elements along the given axis. Refer to :obj:`dpnp.cumprod` for full documentation. """ return dpnp.cumprod(self, axis=axis, dtype=dtype, out=out)
[docs] def cumsum(self, axis=None, dtype=None, out=None): """ Return the cumulative sum of the elements along the given axis. Refer to :obj:`dpnp.cumsum` for full documentation. """ return dpnp.cumsum(self, axis=axis, dtype=dtype, out=out)
# 'data',
[docs] def diagonal(self, offset=0, axis1=0, axis2=1): """ Return specified diagonals. Refer to :obj:`dpnp.diagonal` for full documentation. See Also -------- :obj:`dpnp.diagonal` : Equivalent function. Examples -------- >>> import dpnp as np >>> a = np.arange(4).reshape(2,2) >>> a.diagonal() array([0, 3]) """ return dpnp.diagonal(self, offset=offset, axis1=axis1, axis2=axis2)
[docs] def dot(self, b, out=None): """ Dot product of two arrays. Refer to :obj:`dpnp.dot` for full documentation. Examples -------- >>> import dpnp as np >>> a = np.eye(2) >>> b = np.ones((2, 2)) * 2 >>> a.dot(b) array([[2., 2.], [2., 2.]]) This array method can be conveniently chained: >>> a.dot(b).dot(b) array([[8., 8.], [8., 8.]]) """ return dpnp.dot(self, b, out)
@property def dtype(self): """Returns NumPy's dtype corresponding to the type of the array elements.""" return self._array_obj.dtype # 'dump', # 'dumps',
[docs] def fill(self, value): """ Fill the array with a scalar value. For full documentation refer to :obj:`numpy.ndarray.fill`. Parameters ---------- value : {dpnp.ndarray, usm_ndarray, scalar} All elements of `a` will be assigned this value. Examples -------- >>> import dpnp as np >>> a = np.array([1, 2]) >>> a.fill(0) >>> a array([0, 0]) >>> a = np.empty(2) >>> a.fill(1) >>> a array([1., 1.]) """ # lazy import avoids circular imports from .dpnp_algo.dpnp_fill import dpnp_fill dpnp_fill(self, value)
@property def flags(self): """Return information about the memory layout of the array.""" return self._array_obj.flags @property def flat(self): """Return a flat iterator, or set a flattened version of self to value.""" return dpnp.flatiter(self)
[docs] def flatten(self, order="C"): """ Return a copy of the array collapsed into one dimension. For full documentation refer to :obj:`numpy.ndarray.flatten`. Parameters ---------- order : {"C", "F"}, optional Read the elements using this index order, and place the elements into the reshaped array using this index order. - ``"C"`` means to read / write the elements using C-like index order, with the last axis index changing fastest, back to the first axis index changing slowest. - ``"F"`` means to read / write the elements using Fortran-like index order, with the first index changing fastest, and the last index changing slowest. Default: ``"C"``. Returns ------- out : dpnp.ndarray A copy of the input array, flattened to one dimension. See Also -------- :obj:`dpnp.ravel` : Return a flattened array. :obj:`dpnp.flat` : A 1-D flat iterator over the array. Examples -------- >>> import dpnp as np >>> a = np.array([[1, 2], [3, 4]]) >>> a.flatten() array([1, 2, 3, 4]) >>> a.flatten("F") array([1, 3, 2, 4]) """ return self.reshape(-1, order=order, copy=True)
# 'getfield', @property def imag(self): """ The imaginary part of the array. For full documentation refer to :obj:`numpy.ndarray.imag`. Examples -------- >>> import dpnp as np >>> x = np.sqrt(np.array([1+0j, 0+1j])) >>> x.imag array([0. , 0.70710677]) """ return dpnp_array._create_from_usm_ndarray( dpnp.get_usm_ndarray(self).imag ) @imag.setter def imag(self, value): """ Set the imaginary part of the array. For full documentation refer to :obj:`numpy.ndarray.imag`. Examples -------- >>> import dpnp as np >>> a = np.array([1+2j, 3+4j, 5+6j]) >>> a.imag = 9 >>> a array([1.+9.j, 3.+9.j, 5.+9.j]) """ if dpnp.issubdtype(self.dtype, dpnp.complexfloating): dpnp.copyto(self._array_obj.imag, value) else: raise TypeError("array does not have imaginary part to set")
[docs] def item(self, *args): """ Copy an element of an array to a standard Python scalar and return it. For full documentation refer to :obj:`numpy.ndarray.item`. Parameters ---------- *args : {none, int, tuple of ints} - none: in this case, the method only works for arrays with one element (``a.size == 1``), which element is copied into a standard Python scalar object and returned. - int: this argument is interpreted as a flat index into the array, specifying which element to copy and return. - tuple of ints: functions as does a single int argument, except that the argument is interpreted as an nd-index into the array. Returns ------- out : Standard Python scalar object A copy of the specified element of the array as a suitable Python scalar. Examples -------- >>> import dpnp as np >>> np.random.seed(123) >>> x = np.random.randint(9, size=(3, 3)) >>> x array([[0, 0, 7], [6, 6, 6], [0, 7, 1]]) >>> x.item(3) 6 >>> x.item(7) 7 >>> x.item((0, 1)) 0 >>> x.item((2, 2)) 1 >>> x = np.array(5) >>> x.item() 5 """ # TODO: implement a more efficient way to avoid copying to host # for large arrays using `asnumpy()` return self.asnumpy().item(*args)
@property def itemsize(self): """Size of one array element in bytes.""" return self._array_obj.itemsize
[docs] def max( self, axis=None, out=None, keepdims=False, initial=None, where=True, ): """ Return the maximum along an axis. Refer to :obj:`dpnp.max` for full documentation. """ return dpnp.max( self, axis=axis, out=out, keepdims=keepdims, initial=initial, where=where, )
[docs] def mean( self, axis=None, dtype=None, out=None, keepdims=False, *, where=True ): """ Returns the average of the array elements. Refer to :obj:`dpnp.mean` for full documentation. """ return dpnp.mean(self, axis, dtype, out, keepdims, where=where)
[docs] def min( self, axis=None, out=None, keepdims=False, initial=None, where=True, ): """ Return the minimum along a given axis. Refer to :obj:`dpnp.min` for full documentation. """ return dpnp.min( self, axis=axis, out=out, keepdims=keepdims, initial=initial, where=where, )
@property def nbytes(self): """Total bytes consumed by the elements of the array.""" return self._array_obj.nbytes @property def ndim(self): """ Return the number of dimensions of an array. For full documentation refer to :obj:`numpy.ndarray.ndim`. Returns ------- number_of_dimensions : int The number of dimensions in `a`. See Also -------- :obj:`dpnp.ndim` : Equivalent method for any array-like input. :obj:`dpnp.shape` : Return the shape of an array. :obj:`dpnp.ndarray.shape` : Return the shape of an array. Examples -------- >>> import dpnp as np >>> x = np.array([1, 2, 3]) >>> x.ndim 1 >>> y = np.zeros((2, 3, 4)) >>> y.ndim 3 """ return self._array_obj.ndim
[docs] def nonzero(self): """ Return the indices of the elements that are non-zero. Refer to :obj:`dpnp.nonzero` for full documentation. """ return dpnp.nonzero(self)
[docs] def partition(self, kth, axis=-1, kind="introselect", order=None): """ Return a partitioned copy of an array. Rearranges the elements in the array in such a way that the value of the element in `kth` position is in the position it would be in a sorted array. All elements smaller than the `kth` element are moved before this element and all equal or greater are moved behind it. The ordering of the elements in the two partitions is undefined. Refer to `dpnp.partition` for full documentation. See Also -------- :obj:`dpnp.partition` : Return a partitioned copy of an array. Examples -------- >>> import dpnp as np >>> a = np.array([3, 4, 2, 1]) >>> a.partition(3) >>> a array([1, 2, 3, 4]) """ self._array_obj = dpnp.partition( self, kth, axis=axis, kind=kind, order=order ).get_array()
[docs] def prod( self, axis=None, dtype=None, out=None, keepdims=False, initial=None, where=True, ): """ Returns the prod along a given axis. Refer to :obj:`dpnp.prod` for full documentation. """ return dpnp.prod( self, axis=axis, dtype=dtype, out=out, keepdims=keepdims, initial=initial, where=where, )
[docs] def put(self, indices, vals, /, *, axis=None, mode="wrap"): """ Puts values of an array into another array along a given axis. Refer to :obj:`dpnp.put` for full documentation. """ return dpnp.put(self, indices, vals, axis=axis, mode=mode)
[docs] def ravel(self, order="C"): """ Return a contiguous flattened array. Refer to :obj:`dpnp.ravel` for full documentation. """ return dpnp.ravel(self, order=order)
@property def real(self): """ The real part of the array. For full documentation refer to :obj:`numpy.ndarray.real`. Examples -------- >>> import dpnp as np >>> x = np.sqrt(np.array([1+0j, 0+1j])) >>> x.real array([1. , 0.70710677]) """ if dpnp.issubdtype(self.dtype, dpnp.complexfloating): return dpnp_array._create_from_usm_ndarray( dpnp.get_usm_ndarray(self).real ) return self @real.setter def real(self, value): """ Set the real part of the array. For full documentation refer to :obj:`numpy.ndarray.real`. Examples -------- >>> import dpnp as np >>> a = np.array([1+2j, 3+4j, 5+6j]) >>> a.real = 9 >>> a array([9.+2.j, 9.+4.j, 9.+6.j]) """ dpnp.copyto(self._array_obj.real, value)
[docs] def repeat(self, repeats, axis=None): """ Repeat elements of an array. Refer to :obj:`dpnp.repeat` for full documentation. """ return dpnp.repeat(self, repeats, axis=axis)
[docs] def reshape(self, *shape, order="C", copy=None): """ Returns an array containing the same data with a new shape. Refer to :obj:`dpnp.reshape` for full documentation. Returns ------- y : dpnp.ndarray This will be a new view object if possible; otherwise, it will be a copy. See Also -------- :obj:`dpnp.reshape` : Equivalent function. Notes ----- Unlike the free function `dpnp.reshape`, this method on `ndarray` allows the elements of the shape parameter to be passed in as separate arguments. For example, ``a.reshape(10, 11)`` is equivalent to ``a.reshape((10, 11))``. """ if len(shape) == 1: shape = shape[0] return dpnp.reshape(self, shape, order=order, copy=copy)
# 'resize',
[docs] def round(self, decimals=0, out=None): """ Return array with each element rounded to the given number of decimals. Refer to :obj:`dpnp.round` for full documentation. """ return dpnp.around(self, decimals, out)
[docs] def searchsorted(self, v, side="left", sorter=None): """ Find indices where elements of `v` should be inserted in `a` to maintain order. Refer to :obj:`dpnp.searchsorted` for full documentation """ return dpnp.searchsorted(self, v, side=side, sorter=sorter)
# 'setfield', # 'setflags', @property def shape(self): """ Tuple of array dimensions. The shape property is usually used to get the current shape of an array, but may also be used to reshape the array in-place by assigning a tuple of array dimensions to it. Unlike :obj:`dpnp.reshape`, only non-negative values are supported to be set as new shape. Reshaping an array in-place will fail if a copy is required. For full documentation refer to :obj:`numpy.ndarray.shape`. Note ---- Using :obj:`dpnp.ndarray.reshape` or :obj:`dpnp.reshape` is the preferred approach to set new shape of an array. See Also -------- :obj:`dpnp.shape` : Equivalent getter function. :obj:`dpnp.reshape` : Function similar to setting `shape`. :obj:`dpnp.ndarray.reshape` : Method similar to setting `shape`. Examples -------- >>> import dpnp as np >>> x = np.array([1, 2, 3, 4]) >>> x.shape (4,) >>> y = np.zeros((2, 3, 4)) >>> y.shape (2, 3, 4) >>> y.shape = (3, 8) >>> y array([[ 0., 0., 0., 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0., 0., 0., 0.]]) >>> y.shape = (3, 6) ... TypeError: Can not reshape array of size 24 into (3, 6) """ return self._array_obj.shape @shape.setter def shape(self, newshape): """ Set new lengths of axes. Modifies array instance in-place by changing its metadata about the shape and the strides of the array, or raises `AttributeError` exception if in-place change is not possible. Whether the array can be reshape in-place depends on its strides. Use :obj:`dpnp.reshape` function which always succeeds to reshape the array by performing a copy if necessary. For full documentation refer to :obj:`numpy.ndarray.shape`. Parameters ---------- newshape : {tuple, int} New shape. Only non-negative values are supported. The new shape may not lead to the change in the number of elements in the array. """ self._array_obj.shape = newshape @property def size(self): """ Number of elements in the array. Returns ------- element_count : int Number of elements in the array. See Also -------- :obj:`dpnp.size` : Return the number of elements along a given axis. :obj:`dpnp.shape` : Return the shape of an array. :obj:`dpnp.ndarray.shape` : Return the shape of an array. Examples -------- >>> import dpnp as np >>> x = np.zeros((3, 5, 2), dtype=np.complex64) >>> x.size 30 """ return self._array_obj.size
[docs] def sort( self, axis=-1, kind=None, order=None, *, descending=False, stable=None ): """ Sort an array in-place. Refer to :obj:`dpnp.sort` for full documentation. Parameters ---------- axis : int, optional Axis along which to sort. The default is ``-1``, which sorts along the last axis. Default: ``-1``. kind : {None, "stable", "mergesort", "radixsort"}, optional Sorting algorithm. The default is ``None``, which uses parallel merge-sort or parallel radix-sort algorithms depending on the array data type. Default: ``None``. descending : bool, optional Sort order. If ``True``, the array must be sorted in descending order (by value). If ``False``, the array must be sorted in ascending order (by value). Default: ``False``. stable : {None, bool}, optional Sort stability. If ``True``, the returned array will maintain the relative order of `a` values which compare as equal. The same behavior applies when set to ``False`` or ``None``. Internally, this option selects ``kind="stable"``. Default: ``None``. See Also -------- :obj:`dpnp.sort` : Return a sorted copy of an array. :obj:`dpnp.argsort` : Return the indices that would sort an array. :obj:`dpnp.lexsort` : Indirect stable sort on multiple keys. :obj:`dpnp.searchsorted` : Find elements in a sorted array. :obj:`dpnp.partition` : Partial sort. Note ---- `axis` in :obj:`dpnp.sort` could be integer or ``None``. If ``None``, the array is flattened before sorting. However, `axis` in :obj:`dpnp.ndarray.sort` can only be integer since it sorts an array in-place. Examples -------- >>> import dpnp as np >>> a = np.array([[1, 4], [3, 1]]) >>> a.sort(axis=1) >>> a array([[1, 4], [1, 3]]) >>> a.sort(axis=0) >>> a array([[1, 1], [3, 4]]) """ if axis is None: raise TypeError( "'NoneType' object cannot be interpreted as an integer" ) self[...] = dpnp.sort( self, axis=axis, kind=kind, order=order, descending=descending, stable=stable, )
[docs] def squeeze(self, axis=None): """ Remove single-dimensional entries from the shape of an array. Refer to :obj:`dpnp.squeeze` for full documentation """ return dpnp.squeeze(self, axis)
[docs] def std( self, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *, where=True, mean=None, correction=None, ): """ Returns the standard deviation of the array elements, along given axis. Refer to :obj:`dpnp.std` for full documentation. """ return dpnp.std( self, axis, dtype, out, ddof, keepdims, where=where, mean=mean, correction=correction, )
@property def strides(self): """ Returns memory displacement in array elements, upon unit change of respective index. For example, for strides ``(s1, s2, s3)`` and multi-index ``(i1, i2, i3)`` position of the respective element relative to zero multi-index element is ``s1*s1 + s2*i2 + s3*i3``. """ return self._array_obj.strides
[docs] def sum( self, axis=None, dtype=None, out=None, keepdims=False, initial=None, where=True, ): """ Returns the sum along a given axis. Refer to :obj:`dpnp.sum` for full documentation. """ return dpnp.sum( self, axis=axis, dtype=dtype, out=out, keepdims=keepdims, initial=initial, where=where, )
[docs] def swapaxes(self, axis1, axis2): """ Interchange two axes of an array. Refer to :obj:`dpnp.swapaxes` for full documentation. """ return dpnp.swapaxes(self, axis1=axis1, axis2=axis2)
[docs] def take(self, indices, axis=None, out=None, mode="wrap"): """ Take elements from an array along an axis. Refer to :obj:`dpnp.take` for full documentation. """ return dpnp.take(self, indices, axis=axis, out=out, mode=mode)
[docs] def to_device(self, device, /, *, stream=None): """ Transfers this array to specified target device. Parameters ---------- device : {None, string, SyclDevice, SyclQueue, Device}, optional An array API concept of device where the output array is created. `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`, or a :class:`dpctl.tensor.Device` object returned by :attr:`dpnp.ndarray.device`. stream : {SyclQueue, None}, optional Execution queue to synchronize with. If ``None``, synchronization is not performed. Default: ``None``. Returns ------- out : dpnp.ndarray A view if data copy is not required, and a copy otherwise. If copying is required, it is done by copying from the original allocation device to the host, followed by copying from host to the target device. Examples -------- >>> import dpnp as np, dpctl >>> x = np.full(100, 2, dtype=np.int64) >>> q_prof = dpctl.SyclQueue(x.sycl_device, property="enable_profiling") >>> # return a view with profile-enabled queue >>> y = x.to_device(q_prof) >>> timer = dpctl.SyclTimer() >>> with timer(q_prof): ... z = y * y >>> print(timer.dt) """ usm_res = self._array_obj.to_device(device, stream=stream) return dpnp_array._create_from_usm_ndarray(usm_res)
# 'tobytes', # 'tofile', # 'tolist',
[docs] def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None): """ Return the sum along diagonals of the array. Refer to :obj:`dpnp.trace` for full documentation. """ return dpnp.trace( self, offset=offset, axis1=axis1, axis2=axis2, dtype=dtype, out=out )
[docs] def transpose(self, *axes): """ Returns a view of the array with axes transposed. For full documentation refer to :obj:`numpy.ndarray.transpose`. Parameters ---------- axes : None, tuple or list of ints, n ints, optional * ``None`` or no argument: reverses the order of the axes. * ``tuple or list of ints``: `i` in the `j`-th place in the tuple/list means that the array’s `i`-th axis becomes the transposed array’s `j`-th axis. * ``n ints``: same as an n-tuple/n-list of the same integers (this form is intended simply as a “convenience” alternative to the tuple form). Returns ------- out : dpnp.ndarray View of the array with its axes suitably permuted. See Also -------- :obj:`dpnp.transpose` : Equivalent function. :obj:`dpnp.ndarray.ndarray.T` : Array property returning the array transposed. :obj:`dpnp.ndarray.reshape` : Give a new shape to an array without changing its data. Examples -------- >>> import dpnp as np >>> a = np.array([[1, 2], [3, 4]]) >>> a array([[1, 2], [3, 4]]) >>> a.transpose() array([[1, 3], [2, 4]]) >>> a.transpose((1, 0)) array([[1, 3], [2, 4]]) >>> a = np.array([1, 2, 3, 4]) >>> a array([1, 2, 3, 4]) >>> a.transpose() array([1, 2, 3, 4]) """ ndim = self.ndim if ndim < 2: return self axes_len = len(axes) if axes_len == 1 and isinstance(axes[0], (tuple, list)): axes = axes[0] if ndim == 2 and axes_len == 0: usm_res = self._array_obj.T else: if len(axes) == 0 or axes[0] is None: # self.transpose().shape == self.shape[::-1] # self.transpose(None).shape == self.shape[::-1] axes = tuple((ndim - x - 1) for x in range(ndim)) usm_res = dpt.permute_dims(self._array_obj, axes) return dpnp_array._create_from_usm_ndarray(usm_res)
[docs] def var( self, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *, where=True, mean=None, correction=None, ): """ Returns the variance of the array elements, along given axis. Refer to :obj:`dpnp.var` for full documentation. """ return dpnp.var( self, axis, dtype, out, ddof, keepdims, where=where, mean=mean, correction=correction, )
# 'view'