• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IntelPython / dpnp / 25528825989

08 May 2026 12:02AM UTC coverage: 78.444% (+0.01%) from 78.432%
25528825989

push

github

web-flow
Pin Intel OneAPI to 2025.3 in CI workflows for coverage (#2887)

This PR proposes using OneAPI 2025.3 for `build-sphinx` and
`generate_coverage` workflows to match the compiler version used to
build dpctl packages since dpctl is waiting for the latest compiler to
become available on conda-forge
[dpctl#2300](https://github.com/IntelPython/dpctl/pull/2300/changes#diff-a88e46d7b31a87dc2241c3e8e3acf8eeeL575)

1573 of 2908 branches covered (54.09%)

Branch coverage included in aggregate %.

26273 of 32590 relevant lines covered (80.62%)

7636.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.78
/dpnp/dpnp_array.py
1
# *****************************************************************************
2
# Copyright (c) 2016, Intel Corporation
3
# All rights reserved.
4
#
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions are met:
7
# - Redistributions of source code must retain the above copyright notice,
8
#   this list of conditions and the following disclaimer.
9
# - Redistributions in binary form must reproduce the above copyright notice,
10
#   this list of conditions and the following disclaimer in the documentation
11
#   and/or other materials provided with the distribution.
12
# - Neither the name of the copyright holder nor the names of its contributors
13
#   may be used to endorse or promote products derived from this software
14
#   without specific prior written permission.
15
#
16
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26
# THE POSSIBILITY OF SUCH DAMAGE.
27
# *****************************************************************************
28

29
"""
30
Interface of an ndarray representing a multidimensional tensor of numeric
31
elements stored in a USM allocation on a SYCL device.
32

33
"""
34

35
# pylint: disable=duplicate-code
36
# pylint: disable=invalid-name
37
# pylint: disable=protected-access
38

39
import warnings
1✔
40

41
import numpy
1✔
42

43
import dpnp
1✔
44
import dpnp.tensor as dpt
1✔
45
import dpnp.tensor._type_utils as dtu
1✔
46

47
from . import memory as dpm
1✔
48
from .exceptions import AxisError
1✔
49

50

51
def _unwrap_index_element(x):
1✔
52
    """
53
    Unwrap a single index element for the tensor indexing layer.
54

55
    Converts dpnp arrays to usm_ndarray and array-like objects (range, list)
56
    to numpy arrays with intp dtype for NumPy-compatible advanced indexing.
57

58
    """
59

60
    if isinstance(x, dpt.usm_ndarray):
1✔
61
        return x
×
62
    if isinstance(x, dpnp_array):
1✔
63
        return x.get_array()
1✔
64
    if isinstance(x, range):
1✔
65
        return numpy.asarray(x, dtype=numpy.intp)
1✔
66
    if isinstance(x, list):
1✔
67
        # keep boolean lists as boolean
68
        arr = numpy.asarray(x)
1✔
69
        # cast empty lists (float64 in NumPy) to intp
70
        # for correct tensor indexing
71
        if arr.size == 0:
1✔
72
            arr = arr.astype(numpy.intp)
1✔
73
        return arr
1✔
74
    return x
1✔
75

76

77
def _get_unwrapped_index_key(key):
1✔
78
    """
79
    Get an unwrapped index key.
80

81
    Return a key where each nested instance of DPNP array is unwrapped into
82
    USM ndarray, and array-like objects (range, list) are converted to numpy
83
    arrays for further processing in advanced indexing functions.
84

85
    """
86

87
    if isinstance(key, tuple):
1✔
88
        return tuple(_unwrap_index_element(x) for x in key)
1✔
89
    return _unwrap_index_element(key)
1✔
90

91

92
# pylint: disable=too-many-public-methods
93
class dpnp_array:
1✔
94
    """
95
    An array object represents a multidimensional tensor of numeric elements
96
    stored in a USM allocation on a SYCL device.
97

98
    This is a wrapper around :class:`dpnp.tensor.usm_ndarray` that provides
99
    methods to be compliant with original NumPy.
100

101
    """
102

103
    # pylint: disable=too-many-positional-arguments
104
    def __init__(
1✔
105
        self,
106
        shape,
107
        dtype=None,
108
        buffer=None,
109
        offset=0,
110
        strides=None,
111
        order="C",
112
        device=None,
113
        usm_type="device",
114
        sycl_queue=None,
115
    ):
116
        if order is None:
1✔
117
            order = "C"
1✔
118

119
        if buffer is not None:
1✔
120
            # expecting to have buffer as dpnp.ndarray and usm_ndarray,
121
            # or as USM memory allocation
122
            if isinstance(buffer, dpnp_array):
1✔
123
                buffer = buffer.get_array()
1✔
124
                offset += buffer._element_offset
1✔
125

126
            if dtype is None and hasattr(buffer, "dtype"):
1✔
127
                dtype = buffer.dtype
1✔
128
        else:
129
            buffer = usm_type
1✔
130

131
        if strides is not None:
1✔
132
            # dpctl expects strides as elements displacement in memory,
133
            # while dpnp (and numpy as well) relies on bytes displacement
134
            if dtype is None:
1✔
135
                dtype = dpnp.default_float_type(
1✔
136
                    device=device, sycl_queue=sycl_queue
137
                )
138
            it_sz = dpnp.dtype(dtype).itemsize
1✔
139
            strides = tuple(el // it_sz for el in strides)
1✔
140

141
        sycl_queue_normalized = dpnp.get_normalized_queue_device(
1✔
142
            device=device, sycl_queue=sycl_queue
143
        )
144

145
        self._array_obj = dpt.usm_ndarray(
1✔
146
            shape,
147
            dtype=dtype,
148
            strides=strides,
149
            buffer=buffer,
150
            offset=offset,
151
            order=order,
152
            buffer_ctor_kwargs={"queue": sycl_queue_normalized},
153
            array_namespace=dpnp,
154
        )
155

156
    def __abs__(self, /):
1✔
157
        r"""Return :math:`|\text{self}|`."""
158
        return dpnp.abs(self)
1✔
159

160
    def __add__(self, other, /):
1✔
161
        r"""Return :math:`\text{self + value}`."""
162
        return dpnp.add(self, other)
1✔
163

164
    def __and__(self, other, /):
1✔
165
        r"""Return :math:`\text{self & value}`."""
166
        return dpnp.bitwise_and(self, other)
1✔
167

168
    def __array__(self, dtype=None, /, *, copy=None):
1✔
169
        """
170
        NumPy's array protocol method to disallow implicit conversion.
171

172
        Without this definition, ``numpy.asarray(dpnp_arr)`` converts
173
        :class:`dpnp.ndarray` instance into NumPy array with data type `object`
174
        and every element being zero-dimensional :class:`dpnp.ndarray`.
175

176
        """  # noqa: D403
177

178
        raise TypeError(
1✔
179
            "Implicit conversion to a NumPy array is not allowed. "
180
            "Please use `.asnumpy()` to construct a NumPy array explicitly."
181
        )
182

183
    # '__array_finalize__',
184
    # '__array_function__',
185
    # '__array_interface__',
186

187
    def __array_namespace__(self, /, *, api_version=None):
1✔
188
        """
189
        Return array namespace, member functions of which implement data API.
190

191
        Parameters
192
        ----------
193
        api_version : {None, str}, optional
194
            Request namespace compliant with given version of array API. If
195
            ``None``, namespace for the most recent supported version is
196
            returned.
197

198
            Default: ``None``.
199

200
        Returns
201
        -------
202
        out : any
203
            An object representing the array API namespace. It should have
204
            every top-level function defined in the specification as
205
            an attribute. It may contain other public names as well, but it is
206
            recommended to only include those names that are part of the
207
            specification.
208

209
        """
210

211
        return self._array_obj.__array_namespace__(api_version=api_version)
1✔
212

213
    # '__array_priority__',
214
    # '__array_struct__',
215

216
    __array_ufunc__ = None
1✔
217

218
    # '__array_wrap__',
219

220
    def __bool__(self, /):
1✔
221
        """``True`` if `self` else ``False``."""
222
        return self._array_obj.__bool__()
1✔
223

224
    def __bytes__(self):
1✔
225
        r"""Return :math:`\text{bytes(self)}`."""
226
        return bytes(self.asnumpy())
1✔
227

228
    # '__class__',
229
    # `__class_getitem__`,
230

231
    def __complex__(self, /):
1✔
232
        """Convert a zero-dimensional array to a Python complex object."""
233
        return self._array_obj.__complex__()
1✔
234

235
    def __contains__(self, value, /):
1✔
236
        r"""Return :math:`\text{value in self}`."""
237
        return (self == value).any()
1✔
238

239
    def __copy__(self):
1✔
240
        """
241
        Used if :func:`copy.copy` is called on an array. Return a copy of the
242
        array.
243

244
        Equivalent to ``a.copy(order="K")``.
245

246
        """
247
        return self.copy(order="K")
1✔
248

249
    # '__deepcopy__',
250
    # '__dir__',
251

252
    def __divmod__(self, other, /):
1✔
253
        r"""Return :math:`\text{divmod(self, value)}`."""
254
        return dpnp.divmod(self, other)
1✔
255

256
    def __dlpack__(
1✔
257
        self, /, *, stream=None, max_version=None, dl_device=None, copy=None
258
    ):
259
        """
260
        Produce DLPack capsule.
261

262
        Parameters
263
        ----------
264
        stream : {:class:`dpctl.SyclQueue`, None}, optional
265
            Execution queue to synchronize with. If ``None``, synchronization
266
            is not performed.
267

268
            Default: ``None``.
269
        max_version : {tuple of ints, None}, optional
270
            The maximum DLPack version the consumer (caller of ``__dlpack__``)
271
            supports. As ``__dlpack__`` may not always return a DLPack capsule
272
            with version `max_version`, the consumer must verify the version
273
            even if this argument is passed.
274

275
            Default: ``None``.
276
        dl_device : {tuple, None}, optional:
277
            The device the returned DLPack capsule will be placed on. The
278
            device must be a 2-tuple matching the format of
279
            :meth:`dpnp.ndarray.__dlpack_device__`, an integer enumerator
280
            representing the device type followed by an integer representing
281
            the index of the device.
282

283
            Default: ``None``.
284
        copy : {bool, None}, optional:
285
            Boolean indicating whether or not to copy the input.
286

287
            * If `copy` is ``True``, the input will always be copied.
288
            * If ``False``, a ``BufferError`` will be raised if a copy is
289
              deemed necessary.
290
            * If ``None``, a copy will be made only if deemed necessary,
291
              otherwise, the existing memory buffer will be reused.
292

293
            Default: ``None``.
294

295
        Raises
296
        ------
297
        MemoryError
298
            when host memory can not be allocated.
299
        DLPackCreationError
300
            when array is allocated on a partitioned SYCL device, or with
301
            a non-default context.
302
        BufferError
303
            when a copy is deemed necessary but `copy` is ``False`` or when
304
            the provided `dl_device` cannot be handled.
305

306
        """
307

308
        return self._array_obj.__dlpack__(
1✔
309
            stream=stream,
310
            max_version=max_version,
311
            dl_device=dl_device,
312
            copy=copy,
313
        )
314

315
    def __dlpack_device__(self, /):
1✔
316
        """
317
        Give a tuple (``device_type``, ``device_id``) corresponding to
318
        ``DLDevice`` entry in ``DLTensor`` in DLPack protocol.
319

320
        The tuple describes the non-partitioned device where the array has been
321
        allocated, or the non-partitioned parent device of the allocation
322
        device.
323

324
        See :class:`dpnp.DLDeviceType` for a list of devices supported by the
325
        DLPack protocol.
326

327
        Raises
328
        ------
329
        DLPackCreationError
330
            when the ``device_id`` could not be determined.
331

332
        """
333

334
        return self._array_obj.__dlpack_device__()
1✔
335

336
    def __eq__(self, other, /):
1✔
337
        r"""Return :math:`\text{self == value}`."""
338
        return dpnp.equal(self, other)
1✔
339

340
    def __float__(self, /):
1✔
341
        """Convert a zero-dimensional array to a Python float object."""
342
        return self._array_obj.__float__()
1✔
343

344
    def __floordiv__(self, other, /):
1✔
345
        r"""Return :math:`\text{self // value}`."""
346
        return dpnp.floor_divide(self, other)
1✔
347

348
    def __format__(self, format_spec):
1✔
349
        r"""Return :math:`\text{format(self, format_spec)}`."""
350
        return format(self.asnumpy(), format_spec)
1✔
351

352
    def __ge__(self, other, /):
1✔
353
        r"""Return :math:`\text{self >= value}`."""
354
        return dpnp.greater_equal(self, other)
1✔
355

356
    def __getitem__(self, key, /):
1✔
357
        r"""Return :math:`\text{self[key]}`."""
358
        key = _get_unwrapped_index_key(key)
1✔
359

360
        item = self._array_obj.__getitem__(key)
1✔
361
        return dpnp_array._create_from_usm_ndarray(item)
1✔
362

363
    # '__getstate__',
364

365
    def __gt__(self, other, /):
1✔
366
        r"""Return :math:`\text{self > value}`."""
367
        return dpnp.greater(self, other)
1✔
368

369
    # '__hash__',
370

371
    def __iadd__(self, other, /):
1✔
372
        r"""Return :math:`\text{self += value}`."""
373
        dpnp.add(self, other, out=self)
1✔
374
        return self
1✔
375

376
    def __iand__(self, other, /):
1✔
377
        r"""Return :math:`\text{self &= value}`."""
378
        dpnp.bitwise_and(self, other, out=self)
1✔
379
        return self
1✔
380

381
    def __ifloordiv__(self, other, /):
1✔
382
        r"""Return :math:`\text{self //= value}`."""
383
        dpnp.floor_divide(self, other, out=self)
1✔
384
        return self
1✔
385

386
    def __ilshift__(self, other, /):
1✔
387
        r"""Return :math:`\text{self <<= value}`."""
388
        dpnp.left_shift(self, other, out=self)
1✔
389
        return self
1✔
390

391
    def __imatmul__(self, other, /):
1✔
392
        r"""Return :math:`\text{self @= value}`."""
393

394
        # Unlike `matmul(a, b, out=a)` we ensure that the result isn't broadcast
395
        # if the result without `out` would have less dimensions than `a`.
396
        # Since the signature of matmul is '(n?,k),(k,m?)->(n?,m?)' this is the
397
        # case exactly when the second operand has both core dimensions.
398
        # We have to enforce this check by passing the correct `axes=`.
399
        if self.ndim == 1:
1✔
400
            axes = [(-1,), (-2, -1), (-1,)]
1✔
401
        else:
402
            axes = [(-2, -1), (-2, -1), (-2, -1)]
1✔
403

404
        try:
1✔
405
            dpnp.matmul(self, other, out=self, dtype=self.dtype, axes=axes)
1✔
406
        except AxisError as e:
1✔
407
            # AxisError should indicate that the axes argument didn't work out
408
            # which should mean the second operand not being 2 dimensional.
409
            raise ValueError(
1✔
410
                "inplace matrix multiplication requires the first operand to "
411
                "have at least one and the second at least two dimensions."
412
            ) from e
413
        return self
1✔
414

415
    def __imod__(self, other, /):
1✔
416
        r"""Return :math:`\text{self %= value}`."""
417
        dpnp.remainder(self, other, out=self)
1✔
418
        return self
1✔
419

420
    def __imul__(self, other, /):
1✔
421
        r"""Return :math:`\text{self *= value}`."""
422
        dpnp.multiply(self, other, out=self)
1✔
423
        return self
1✔
424

425
    def __index__(self, /):
1✔
426
        """Convert a zero-dimensional array to a Python int object."""
427
        return self._array_obj.__index__()
1✔
428

429
    # '__init_subclass__',
430

431
    def __int__(self, /):
1✔
432
        """Convert a zero-dimensional array to a Python int object."""
433
        return self._array_obj.__int__()
1✔
434

435
    def __invert__(self, /):
1✔
436
        r"""Return :math:`\text{~self}`."""
437
        return dpnp.invert(self)
1✔
438

439
    def __ior__(self, other, /):
1✔
440
        r"""Return :math:`\text{self |= value}`."""
441
        dpnp.bitwise_or(self, other, out=self)
1✔
442
        return self
1✔
443

444
    def __ipow__(self, other, /):
1✔
445
        r"""Return :math:`\text{self **= value}`."""
446
        dpnp.power(self, other, out=self)
1✔
447
        return self
1✔
448

449
    def __irshift__(self, other, /):
1✔
450
        r"""Return :math:`\text{self >>= value}`."""
451
        dpnp.right_shift(self, other, out=self)
1✔
452
        return self
1✔
453

454
    def __isub__(self, other, /):
1✔
455
        r"""Return :math:`\text{self -= value}`."""
456
        dpnp.subtract(self, other, out=self)
1✔
457
        return self
1✔
458

459
    def __iter__(self, /):
1✔
460
        r"""Return :math:`\text{iter(self)}`."""
461
        if self.ndim == 0:
1✔
462
            raise TypeError("iteration over a 0-d array")
1✔
463
        return (self[i] for i in range(self.shape[0]))
1✔
464

465
    def __itruediv__(self, other, /):
1✔
466
        r"""Return :math:`\text{self /= value}`."""
467
        dpnp.true_divide(self, other, out=self)
1✔
468
        return self
1✔
469

470
    def __ixor__(self, other, /):
1✔
471
        r"""Return :math:`\text{self ^= value}`."""
472
        dpnp.bitwise_xor(self, other, out=self)
1✔
473
        return self
1✔
474

475
    def __le__(self, other, /):
1✔
476
        r"""Return :math:`\text{self <= value}`."""
477
        return dpnp.less_equal(self, other)
1✔
478

479
    def __len__(self):
1✔
480
        r"""Return :math:`\text{len(self)}`."""
481
        return self._array_obj.__len__()
1✔
482

483
    def __lshift__(self, other, /):
1✔
484
        r"""Return :math:`\text{self << value}`."""
485
        return dpnp.left_shift(self, other)
1✔
486

487
    def __lt__(self, other, /):
1✔
488
        r"""Return :math:`\text{self < value}`."""
489
        return dpnp.less(self, other)
1✔
490

491
    def __matmul__(self, other, /):
1✔
492
        r"""Return :math:`\text{self @ value}`."""
493
        return dpnp.matmul(self, other)
1✔
494

495
    def __mod__(self, other, /):
1✔
496
        r"""Return :math:`\text{self % value}`."""
497
        return dpnp.remainder(self, other)
1✔
498

499
    def __mul__(self, other, /):
1✔
500
        r"""Return :math:`\text{self * value}`."""
501
        return dpnp.multiply(self, other)
1✔
502

503
    def __ne__(self, other, /):
1✔
504
        r"""Return :math:`\text{self != value}`."""
505
        return dpnp.not_equal(self, other)
1✔
506

507
    def __neg__(self, /):
1✔
508
        r"""Return :math:`\text{-self}`."""
509
        return dpnp.negative(self)
1✔
510

511
    # '__new__',
512

513
    def __or__(self, other, /):
1✔
514
        r"""Return :math:`\text{self | value}`."""
515
        return dpnp.bitwise_or(self, other)
1✔
516

517
    def __pos__(self, /):
1✔
518
        r"""Return :math:`\text{+self}`."""
519
        return dpnp.positive(self)
1✔
520

521
    def __pow__(self, other, mod=None, /):
1✔
522
        r"""Return :math:`\text{self ** value}`."""
523
        if mod is not None:
1✔
524
            return NotImplemented
1✔
525
        return dpnp.power(self, other)
1✔
526

527
    def __radd__(self, other, /):
1✔
528
        r"""Return :math:`\text{value + self}`."""
529
        return dpnp.add(other, self)
1✔
530

531
    def __rand__(self, other, /):
1✔
532
        r"""Return :math:`\text{value & self}`."""
533
        return dpnp.bitwise_and(other, self)
1✔
534

535
    def __rdivmod__(self, other, /):
1✔
536
        r"""Return :math:`\text{divmod(value, self)}`."""
537
        return dpnp.divmod(other, self)
1✔
538

539
    # '__reduce__',
540
    # '__reduce_ex__',
541

542
    def __repr__(self):
1✔
543
        r"""Return :math:`\text{repr(self)}`."""
544
        return dpt.usm_ndarray_repr(self._array_obj, prefix="array")
1✔
545

546
    def __rfloordiv__(self, other, /):
1✔
547
        r"""Return :math:`\text{value // self}`."""
548
        return dpnp.floor_divide(other, self)
1✔
549

550
    def __rlshift__(self, other, /):
1✔
551
        r"""Return :math:`\text{value << self}`."""
552
        return dpnp.left_shift(other, self)
1✔
553

554
    def __rmatmul__(self, other, /):
1✔
555
        r"""Return :math:`\text{value @ self}`."""
556
        return dpnp.matmul(other, self)
1✔
557

558
    def __rmod__(self, other, /):
1✔
559
        r"""Return :math:`\text{value % self}`."""
560
        return dpnp.remainder(other, self)
1✔
561

562
    def __rmul__(self, other, /):
1✔
563
        r"""Return :math:`\text{value * self}`."""
564
        return dpnp.multiply(other, self)
1✔
565

566
    def __ror__(self, other, /):
1✔
567
        r"""Return :math:`\text{value | self}`."""
568
        return dpnp.bitwise_or(other, self)
1✔
569

570
    def __rpow__(self, other, mod=None, /):
1✔
571
        r"""Return :math:`\text{value ** self}`."""
572
        if mod is not None:
1✔
573
            return NotImplemented
1✔
574
        return dpnp.power(other, self)
1✔
575

576
    def __rrshift__(self, other, /):
1✔
577
        r"""Return :math:`\text{value >> self}`."""
578
        return dpnp.right_shift(other, self)
1✔
579

580
    def __rshift__(self, other, /):
1✔
581
        r"""Return :math:`\text{self >> value}`."""
582
        return dpnp.right_shift(self, other)
1✔
583

584
    def __rsub__(self, other, /):
1✔
585
        r"""Return :math:`\text{value - self}`."""
586
        return dpnp.subtract(other, self)
1✔
587

588
    def __rtruediv__(self, other, /):
1✔
589
        r"""Return :math:`\text{value / self}`."""
590
        return dpnp.true_divide(other, self)
1✔
591

592
    def __rxor__(self, other, /):
1✔
593
        r"""Return :math:`\text{value ^ self}`."""
594
        return dpnp.bitwise_xor(other, self)
1✔
595

596
    def __setitem__(self, key, value, /):
1✔
597
        r"""Set :math:`\text{self[key]}` to a value."""
598
        key = _get_unwrapped_index_key(key)
1✔
599

600
        if isinstance(value, dpnp_array):
1✔
601
            value = value.get_array()
1✔
602

603
        self._array_obj.__setitem__(key, value)
1✔
604

605
    # '__setstate__',
606
    # '__sizeof__',
607

608
    __slots__ = ("_array_obj",)
1✔
609

610
    def __str__(self):
1✔
611
        r"""Return :math:`\text{str(self)}`."""
612
        return self._array_obj.__str__()
1✔
613

614
    def __sub__(self, other, /):
1✔
615
        r"""Return :math:`\text{self - value}`."""
616
        return dpnp.subtract(self, other)
1✔
617

618
    @property
1✔
619
    def __sycl_usm_array_interface__(self):
1✔
620
        """
621
        Give ``__sycl_usm_array_interface__`` dictionary describing the array.
622

623
        """  # noqa: D200
624
        return self._array_obj.__sycl_usm_array_interface__
1✔
625

626
    def __truediv__(self, other, /):
1✔
627
        r"""Return :math:`\text{self / value}`."""
628
        return dpnp.true_divide(self, other)
1✔
629

630
    @property
1✔
631
    def __usm_ndarray__(self):
1✔
632
        """
633
        Property to support ``__usm_ndarray__`` protocol.
634

635
        It assumes to return :class:`dpnp.tensor.usm_ndarray` instance
636
        corresponding to the content of the object.
637

638
        This property is intended to speed-up conversion from
639
        :class:`dpnp.ndarray` to :class:`dpnp.tensor.usm_ndarray` passed into
640
        :func:`dpnp.tensor.asarray` function. The input object that implements
641
        ``__usm_ndarray__`` protocol is recognized as owner of USM allocation
642
        that is managed by a smart pointer, and asynchronous deallocation
643
        will not involve GIL.
644

645
        """
646

647
        return self._array_obj
1✔
648

649
    def __xor__(self, other, /):
1✔
650
        r"""Return :math:`\text{self ^ value}`."""
651
        return dpnp.bitwise_xor(self, other)
1✔
652

653
    @staticmethod
1✔
654
    def _create_from_usm_ndarray(usm_ary: dpt.usm_ndarray):
1✔
655
        """
656
        Return :class:`dpnp.ndarray` instance from USM allocation providing
657
        by an instance of :class:`dpnp.tensor.usm_ndarray`.
658

659
        """
660

661
        if not isinstance(usm_ary, dpt.usm_ndarray):
1✔
662
            raise TypeError(
1✔
663
                f"Expected dpnp.tensor.usm_ndarray, got {type(usm_ary)}"
664
            )
665
        res = dpnp_array.__new__(dpnp_array)
1✔
666
        res._array_obj = usm_ary
1✔
667
        res._array_obj._set_namespace(dpnp)
1✔
668
        return res
1✔
669

670
    def _create_view(self, array_class, shape, dtype, strides):
1✔
671
        """
672
        Create a view of an array with the specified class.
673

674
        The method handles subclass instantiation by creating a usm_ndarray
675
        view and then wrapping it in the appropriate class.
676

677
        Parameters
678
        ----------
679
        array_class : type
680
            The class to instantiate (dpnp_array or a subclass).
681
        shape : tuple
682
            Shape of the view.
683
        dtype : dtype
684
            Data type of the view (can be None to keep source's dtype).
685
        strides : tuple
686
            Strides of the view.
687

688
        Returns
689
        -------
690
        view : array_class instance
691
            A view of the array as the specified class.
692

693
        """
694

695
        if dtype is None:
1✔
696
            dtype = self.dtype
1✔
697

698
        # create the underlying usm_ndarray view
699
        usm_view = dpt.usm_ndarray(
1✔
700
            shape,
701
            dtype=dtype,
702
            buffer=self._array_obj,
703
            strides=tuple(s // dpnp.dtype(dtype).itemsize for s in strides),
704
        )
705

706
        # wrap the view into the appropriate class
707
        if array_class is dpnp_array:
1✔
708
            res = dpnp_array._create_from_usm_ndarray(usm_view)
1✔
709
        else:
710
            # for subclasses, create using __new__ and set up manually
711
            res = array_class.__new__(array_class)
1✔
712
            res._array_obj = usm_view
1✔
713
            res._array_obj._set_namespace(dpnp)
1✔
714

715
            if hasattr(res, "__array_finalize__"):
1✔
716
                res.__array_finalize__(self)
1✔
717

718
        return res
1✔
719

720
    def _view_impl(self, dtype=None, array_class=None):
1✔
721
        """
722
        Internal implementation of view method to avoid an issue where
723
        `type` parameter in ndarray.view method shadowing builtin type.
724

725
        """
726

727
        # check if dtype is actually a type
728
        if dtype is not None:
1✔
729
            if isinstance(dtype, type) and issubclass(dtype, dpnp_array):
1✔
730
                if array_class is not None:
1✔
731
                    raise ValueError("Cannot specify output type twice")
1✔
732
                array_class = dtype
1✔
733
                dtype = None
1✔
734

735
        # validate array_class parameter
736
        if not (
1✔
737
            array_class is None
738
            or isinstance(array_class, type)
739
            and issubclass(array_class, dpnp_array)
740
        ):
741
            raise ValueError("Type must be a sub-type of ndarray type")
1✔
742

743
        if array_class is None:
1✔
744
            # it's a view on dpnp.ndarray
745
            array_class = self.__class__
1✔
746

747
        old_sh = self.shape
1✔
748
        old_strides = self.strides
1✔
749

750
        if dtype is None:
1✔
751
            return self._create_view(array_class, old_sh, None, old_strides)
1✔
752

753
        new_dt = dpnp.dtype(dtype)
1✔
754
        new_dt = dtu._to_device_supported_dtype(new_dt, self.sycl_device)
1✔
755

756
        new_itemsz = new_dt.itemsize
1✔
757
        old_itemsz = self.dtype.itemsize
1✔
758
        if new_itemsz == old_itemsz:
1✔
759
            return self._create_view(array_class, old_sh, new_dt, old_strides)
1✔
760

761
        ndim = self.ndim
1✔
762
        if ndim == 0:
1✔
763
            raise ValueError(
1✔
764
                "Changing the dtype of a 0d array is only supported "
765
                "if the itemsize is unchanged"
766
            )
767

768
        # resize on last axis only
769
        axis = ndim - 1
1✔
770
        if (
1✔
771
            old_sh[axis] != 1
772
            and self.size != 0
773
            and old_strides[axis] != old_itemsz
774
        ):
775
            raise ValueError(
1✔
776
                "To change to a dtype of a different size, "
777
                "the last axis must be contiguous"
778
            )
779

780
        # normalize strides whenever itemsize changes
781
        new_strides = tuple(
1✔
782
            old_strides[i] if i != axis else new_itemsz for i in range(ndim)
783
        )
784

785
        new_dim = old_sh[axis] * old_itemsz
1✔
786
        if new_dim % new_itemsz != 0:
1✔
787
            raise ValueError(
1✔
788
                "When changing to a larger dtype, its size must be a divisor "
789
                "of the total size in bytes of the last axis of the array"
790
            )
791

792
        # normalize shape whenever itemsize changes
793
        new_sh = tuple(
1✔
794
            old_sh[i] if i != axis else new_dim // new_itemsz
795
            for i in range(ndim)
796
        )
797

798
        return self._create_view(array_class, new_sh, new_dt, new_strides)
1✔
799

800
    def all(self, axis=None, *, out=None, keepdims=False, where=True):
1✔
801
        """
802
        Return ``True`` if all elements evaluate to ``True``.
803

804
        Refer to :obj:`dpnp.all` for full documentation.
805

806
        See Also
807
        --------
808
        :obj:`dpnp.all` : equivalent function
809

810
        """
811

812
        return dpnp.all(
1✔
813
            self, axis=axis, out=out, keepdims=keepdims, where=where
814
        )
815

816
    def any(self, axis=None, *, out=None, keepdims=False, where=True):
1✔
817
        """
818
        Return ``True`` if any of the elements of `a` evaluate to ``True``.
819

820
        Refer to :obj:`dpnp.any` for full documentation.
821

822
        See Also
823
        --------
824
        :obj:`dpnp.any` : equivalent function
825

826
        """
827

828
        return dpnp.any(
1✔
829
            self, axis=axis, out=out, keepdims=keepdims, where=where
830
        )
831

832
    def argmax(self, /, axis=None, out=None, *, keepdims=False):
1✔
833
        """
834
        Return array of indices of the maximum values along the given axis.
835

836
        Refer to :obj:`dpnp.argmax` for full documentation.
837

838
        """
839

840
        return dpnp.argmax(self, axis=axis, out=out, keepdims=keepdims)
1✔
841

842
    def argmin(self, /, axis=None, out=None, *, keepdims=False):
1✔
843
        """
844
        Return array of indices to the minimum values along the given axis.
845

846
        Refer to :obj:`dpnp.argmin` for full documentation.
847

848
        """
849

850
        return dpnp.argmin(self, axis=axis, out=out, keepdims=keepdims)
1✔
851

852
    # 'argpartition',
853

854
    def argsort(
1✔
855
        self, axis=-1, kind=None, order=None, *, descending=False, stable=None
856
    ):
857
        """
858
        Return an ndarray of indices that sort the array along the specified
859
        axis.
860

861
        Refer to :obj:`dpnp.argsort` for full documentation.
862

863
        Parameters
864
        ----------
865
        axis : {None, int}, optional
866
            Axis along which to sort. If ``None``, the array is flattened
867
            before sorting. The default is ``-1``, which sorts along the last
868
            axis.
869

870
            Default: ``-1``.
871
        kind : {None, "stable", "mergesort", "radixsort"}, optional
872
            Sorting algorithm. The default is ``None``, which uses parallel
873
            merge-sort or parallel radix-sort algorithms depending on the array
874
            data type.
875

876
            Default: ``None``.
877
        descending : bool, optional
878
            Sort order. If ``True``, the array must be sorted in descending
879
            order (by value). If ``False``, the array must be sorted in
880
            ascending order (by value).
881

882
            Default: ``False``.
883
        stable : {None, bool}, optional
884
            Sort stability. If ``True``, the returned array will maintain the
885
            relative order of `a` values which compare as equal. The same
886
            behavior applies when set to ``False`` or ``None``.
887
            Internally, this option selects ``kind="stable"``.
888

889
            Default: ``None``.
890

891
        See Also
892
        --------
893
        :obj:`dpnp.sort` : Return a sorted copy of an array.
894
        :obj:`dpnp.argsort` : Return the indices that would sort an array.
895
        :obj:`dpnp.lexsort` : Indirect stable sort on multiple keys.
896
        :obj:`dpnp.searchsorted` : Find elements in a sorted array.
897
        :obj:`dpnp.partition` : Partial sort.
898

899
        Examples
900
        --------
901
        >>> import dpnp as np
902
        >>> a = np.array([3, 1, 2])
903
        >>> a.argsort()
904
        array([1, 2, 0])
905

906
        >>> a = np.array([[0, 3], [2, 2]])
907
        >>> a.argsort(axis=0)
908
        array([[0, 1],
909
               [1, 0]])
910

911
        """
912

913
        return dpnp.argsort(
1✔
914
            self, axis, kind, order, descending=descending, stable=stable
915
        )
916

917
    def asnumpy(self):
1✔
918
        """
919
        Copy content of the array into :class:`numpy.ndarray` instance of
920
        the same shape and data type.
921

922
        Returns
923
        -------
924
        out : numpy.ndarray
925
            An instance of :class:`numpy.ndarray` populated with the array
926
            content.
927

928
        """
929

930
        return dpt.asnumpy(self._array_obj)
1✔
931

932
    def astype(
1✔
933
        self,
934
        dtype,
935
        order="K",
936
        casting="unsafe",
937
        subok=True,
938
        copy=True,
939
        device=None,
940
    ):
941
        """
942
        Copy the array with data type casting.
943

944
        Refer to :obj:`dpnp.astype` for full documentation.
945

946
        Parameters
947
        ----------
948
        dtype : {None, str, dtype object}
949
            Target data type.
950
        order : {None, "C", "F", "A", "K"}, optional
951
            Row-major (C-style) or column-major (Fortran-style) order.
952
            When `order` is ``"A"``, it uses ``"F"`` if `a` is column-major and
953
            uses ``"C"`` otherwise. And when `order` is ``"K"``, it keeps
954
            strides as closely as possible.
955

956
            Default: ``"K"``.
957
        casting : {"no", "equiv", "safe", "same_kind", "unsafe"}, optional
958
            Controls what kind of data casting may occur. Defaults to
959
            ``"unsafe"`` for backwards compatibility.
960

961
                - "no" means the data types should not be cast at all.
962
                - "equiv" means only byte-order changes are allowed.
963
                - "safe" means only casts which can preserve values are allowed.
964
                - "same_kind" means only safe casts or casts within a kind,
965
                  like float64 to float32, are allowed.
966
                - "unsafe" means any data conversions may be done.
967

968
            Default: ``"unsafe"``.
969
        copy : bool, optional
970
            Specifies whether to copy an array when the specified dtype matches
971
            the data type of that array. If ``True``, a newly allocated array
972
            must always be returned. If ``False`` and the specified dtype
973
            matches the data type of that array, the self array must be
974
            returned; otherwise, a newly allocated array must be returned.
975

976
            Default: ``True``.
977
        device : {None, string, SyclDevice, SyclQueue, Device}, optional
978
            An array API concept of device where the output array is created.
979
            `device` can be ``None``, a oneAPI filter selector string,
980
            an instance of :class:`dpctl.SyclDevice` corresponding to
981
            a non-partitioned SYCL device, an instance of
982
            :class:`dpctl.SyclQueue`, or a :class:`dpnp.tensor.Device` object
983
            returned by :attr:`dpnp.ndarray.device`.
984
            If the value is ``None``, returned array is created on the same
985
            device as that array.
986

987
            Default: ``None``.
988

989
        Returns
990
        -------
991
        out : dpnp.ndarray
992
            An array having the specified data type.
993

994
        Limitations
995
        -----------
996
        Parameter `subok` is supported with default value.
997
        Otherwise ``NotImplementedError`` exception will be raised.
998

999
        Examples
1000
        --------
1001
        >>> import dpnp as np
1002
        >>> x = np.array([1, 2, 2.5]); x
1003
        array([1. , 2. , 2.5])
1004

1005
        >>> x.astype(int)
1006
        array([1, 2, 2])
1007

1008
        """
1009

1010
        if subok is not True:
1✔
1011
            raise NotImplementedError(
1✔
1012
                f"subok={subok} is currently not supported"
1013
            )
1014

1015
        return dpnp.astype(
1✔
1016
            self, dtype, order=order, casting=casting, copy=copy, device=device
1017
        )
1018

1019
    # 'base',
1020
    # 'byteswap',
1021

1022
    def choose(self, /, choices, out=None, mode="wrap"):
1✔
1023
        """
1024
        Use an array as index array to construct a new array from a set of
1025
        choices.
1026

1027
        Refer to :obj:`dpnp.choose` for full documentation.
1028

1029
        """
1030

1031
        return dpnp.choose(self, choices, out, mode)
1✔
1032

1033
    def clip(self, /, min=None, max=None, out=None, **kwargs):
1✔
1034
        """
1035
        Clip (limit) the values in an array.
1036

1037
        Refer to :obj:`dpnp.clip` for full documentation.
1038

1039
        """
1040

1041
        return dpnp.clip(self, min, max, out=out, **kwargs)
1✔
1042

1043
    def compress(self, /, condition, axis=None, *, out=None):
1✔
1044
        """
1045
        Select slices of an array along a given axis.
1046

1047
        Refer to :obj:`dpnp.compress` for full documentation.
1048
        """
1049

1050
        return dpnp.compress(condition, self, axis=axis, out=out)
1✔
1051

1052
    def conj(self):
1✔
1053
        """
1054
        Complex-conjugate all elements.
1055

1056
        Refer to :obj:`dpnp.conjugate` for full documentation.
1057

1058
        """
1059

1060
        return self.conjugate()
1✔
1061

1062
    def conjugate(self):
1✔
1063
        """
1064
        Return the complex conjugate, element-wise.
1065

1066
        Refer to :obj:`dpnp.conjugate` for full documentation.
1067

1068
        """
1069

1070
        if not dpnp.issubdtype(self.dtype, dpnp.complexfloating):
1✔
1071
            return self
1✔
1072
        return dpnp.conjugate(self)
1✔
1073

1074
    def copy(
1✔
1075
        self, /, order="C", *, device=None, usm_type=None, sycl_queue=None
1076
    ):
1077
        """
1078
        Return a copy of the array.
1079

1080
        Refer to :obj:`dpnp.copy` for full documentation.
1081

1082
        Parameters
1083
        ----------
1084
        order : {None, "C", "F", "A", "K"}, optional
1085
            Memory layout of the newly output array.
1086

1087
            Default: ``"C"``.
1088
        device : {None, string, SyclDevice, SyclQueue, Device}, optional
1089
            An array API concept of device where the output array is created.
1090
            `device` can be ``None``, a oneAPI filter selector string,
1091
            an instance of :class:`dpctl.SyclDevice` corresponding to
1092
            a non-partitioned SYCL device, an instance of
1093
            :class:`dpctl.SyclQueue`, or a :class:`dpnp.tensor.Device` object
1094
            returned by :attr:`dpnp.ndarray.device`.
1095

1096
            Default: ``None``.
1097
        usm_type : {None, "device", "shared", "host"}, optional
1098
            The type of SYCL USM allocation for the output array.
1099

1100
            Default: ``None``.
1101
        sycl_queue : {None, SyclQueue}, optional
1102
            A SYCL queue to use for output array allocation and copying. The
1103
            `sycl_queue` can be passed as ``None`` (the default), which means
1104
            to get the SYCL queue from `device` keyword if present or to use
1105
            a default queue.
1106

1107
            Default: ``None``.
1108

1109
        Returns
1110
        -------
1111
        out : dpnp.ndarray
1112
            A copy of the array.
1113

1114
        See also
1115
        --------
1116
        :obj:`dpnp.copy` : Similar function with different default behavior
1117
        :obj:`dpnp.copyto` : Copies values from one array to another.
1118

1119
        Notes
1120
        -----
1121
        This function is the preferred method for creating an array copy.
1122
        The function :func:`dpnp.copy` is similar, but it defaults to using
1123
        order ``"K"``.
1124

1125
        Examples
1126
        --------
1127
        >>> import dpnp as np
1128
        >>> x = np.array([[1, 2, 3], [4, 5, 6]], order='F')
1129
        >>> y = x.copy()
1130
        >>> x.fill(0)
1131

1132
        >>> x
1133
        array([[0, 0, 0],
1134
               [0, 0, 0]])
1135

1136
        >>> y
1137
        array([[1, 2, 3],
1138
               [4, 5, 6]])
1139

1140
        >>> y.flags['C_CONTIGUOUS']
1141
        True
1142

1143
        """
1144

1145
        return dpnp.copy(
1✔
1146
            self,
1147
            order=order,
1148
            device=device,
1149
            usm_type=usm_type,
1150
            sycl_queue=sycl_queue,
1151
        )
1152

1153
    # 'ctypes',
1154

1155
    def cumprod(self, /, axis=None, dtype=None, *, out=None):
1✔
1156
        """
1157
        Return the cumulative product of the elements along the given axis.
1158

1159
        Refer to :obj:`dpnp.cumprod` for full documentation.
1160

1161
        """
1162

1163
        return dpnp.cumprod(self, axis=axis, dtype=dtype, out=out)
1✔
1164

1165
    def cumsum(self, /, axis=None, dtype=None, *, out=None):
1✔
1166
        """
1167
        Return the cumulative sum of the elements along the given axis.
1168

1169
        Refer to :obj:`dpnp.cumsum` for full documentation.
1170

1171
        """
1172

1173
        return dpnp.cumsum(self, axis=axis, dtype=dtype, out=out)
1✔
1174

1175
    @property
1✔
1176
    def data(self):
1✔
1177
        """
1178
        Python object pointing to the start of USM memory allocation with the
1179
        array's data.
1180

1181
        """
1182

1183
        return dpm.create_data(self._array_obj)
1✔
1184

1185
    @property
1✔
1186
    def device(self):
1✔
1187
        """
1188
        Return :class:`dpnp.tensor.Device` object representing residence of
1189
        the array data.
1190

1191
        The ``Device`` object represents Array API notion of the device, and
1192
        contains :class:`dpctl.SyclQueue` associated with this array. Hence,
1193
        ``.device`` property provides information distinct from ``.sycl_device``
1194
        property.
1195

1196
        Examples
1197
        --------
1198
        >>> import dpnp as np
1199
        >>> x = np.ones(10)
1200
        >>> x.device
1201
        Device(level_zero:gpu:0)
1202

1203
        """
1204

1205
        return self._array_obj.device
1✔
1206

1207
    def diagonal(self, offset=0, axis1=0, axis2=1):
1✔
1208
        """
1209
        Return specified diagonals.
1210

1211
        Refer to :obj:`dpnp.diagonal` for full documentation.
1212

1213
        See Also
1214
        --------
1215
        :obj:`dpnp.diagonal` : Equivalent function.
1216

1217
        Examples
1218
        --------
1219
        >>> import dpnp as np
1220
        >>> a = np.arange(4).reshape(2, 2)
1221
        >>> a.diagonal()
1222
        array([0, 3])
1223

1224
        """
1225

1226
        return dpnp.diagonal(self, offset=offset, axis1=axis1, axis2=axis2)
1✔
1227

1228
    def dot(self, b, out=None):
1✔
1229
        """
1230
        Dot product of two arrays.
1231

1232
        Refer to :obj:`dpnp.dot` for full documentation.
1233

1234
        Examples
1235
        --------
1236
        >>> import dpnp as np
1237
        >>> a = np.eye(2)
1238
        >>> b = np.ones((2, 2)) * 2
1239
        >>> a.dot(b)
1240
        array([[2., 2.],
1241
               [2., 2.]])
1242

1243
        This array method can be conveniently chained:
1244

1245
        >>> a.dot(b).dot(b)
1246
        array([[8., 8.],
1247
               [8., 8.]])
1248
        """
1249

1250
        return dpnp.dot(self, b, out)
1✔
1251

1252
    @property
1✔
1253
    def dtype(self):
1✔
1254
        """
1255
        Return NumPy's dtype corresponding to the type of the array elements.
1256

1257
        """  # noqa: D200
1258

1259
        return self._array_obj.dtype
1✔
1260

1261
    # 'dump',
1262
    # 'dumps',
1263

1264
    def fill(self, value):
1✔
1265
        """
1266
        Fill the array with a scalar value.
1267

1268
        For full documentation refer to :obj:`numpy.ndarray.fill`.
1269

1270
        Parameters
1271
        ----------
1272
        value : {dpnp.ndarray, usm_ndarray, scalar}
1273
            All elements of `a` will be assigned this value.
1274

1275
        Examples
1276
        --------
1277
        >>> import dpnp as np
1278
        >>> a = np.array([1, 2])
1279
        >>> a.fill(0)
1280
        >>> a
1281
        array([0, 0])
1282
        >>> a = np.empty(2)
1283
        >>> a.fill(1)
1284
        >>> a
1285
        array([1.,  1.])
1286

1287
        """
1288

1289
        # lazy import avoids circular imports
1290
        # pylint: disable=import-outside-toplevel
1291
        from .dpnp_algo.dpnp_fill import dpnp_fill
1✔
1292

1293
        dpnp_fill(self, value)
1✔
1294

1295
    @property
1✔
1296
    def flags(self):
1✔
1297
        """Return information about the memory layout of the array."""
1298

1299
        return self._array_obj.flags
1✔
1300

1301
    @property
1✔
1302
    def flat(self):
1✔
1303
        """
1304
        Return a flat iterator, or set a flattened version of self to value.
1305

1306
        """  # noqa: D200
1307

1308
        return dpnp.flatiter(self)
1✔
1309

1310
    def flatten(self, /, order="C"):
1✔
1311
        """
1312
        Return a copy of the array collapsed into one dimension.
1313

1314
        For full documentation refer to :obj:`numpy.ndarray.flatten`.
1315

1316
        Parameters
1317
        ----------
1318
        order : {"C", "F"}, optional
1319
            Read the elements using this index order, and place the elements
1320
            into the reshaped array using this index order.
1321

1322
                - ``"C"`` means to read / write the elements using C-like index
1323
                  order, with the last axis index changing fastest, back to the
1324
                  first axis index changing slowest.
1325
                - ``"F"`` means to read / write the elements using Fortran-like
1326
                  index order, with the first index changing fastest, and the
1327
                  last index changing slowest.
1328

1329
            Default: ``"C"``.
1330

1331
        Returns
1332
        -------
1333
        out : dpnp.ndarray
1334
            A copy of the input array, flattened to one dimension.
1335

1336
        See Also
1337
        --------
1338
        :obj:`dpnp.ravel` : Return a flattened array.
1339
        :obj:`dpnp.flat` : A 1-D flat iterator over the array.
1340

1341
        Examples
1342
        --------
1343
        >>> import dpnp as np
1344
        >>> a = np.array([[1, 2], [3, 4]])
1345
        >>> a.flatten()
1346
        array([1, 2, 3, 4])
1347
        >>> a.flatten("F")
1348
        array([1, 3, 2, 4])
1349

1350
        """
1351

1352
        return self.reshape(-1, order=order, copy=True)
1✔
1353

1354
    def get_array(self):
1✔
1355
        """Get :class:`dpnp.tensor.usm_ndarray` object."""
1356
        return self._array_obj
1✔
1357

1358
    # 'getfield',
1359

1360
    @property
1✔
1361
    def imag(self, /):
1✔
1362
        """
1363
        The imaginary part of the array.
1364

1365
        For full documentation refer to :obj:`numpy.ndarray.imag`.
1366

1367
        Examples
1368
        --------
1369
        >>> import dpnp as np
1370
        >>> x = np.sqrt(np.array([1+0j, 0+1j]))
1371
        >>> x.imag
1372
        array([0.        , 0.70710677])
1373

1374
        """
1375
        return dpnp_array._create_from_usm_ndarray(
1✔
1376
            dpnp.get_usm_ndarray(self).imag
1377
        )
1378

1379
    @imag.setter
1✔
1380
    def imag(self, value, /):
1✔
1381
        """
1382
        Set the imaginary part of the array.
1383

1384
        For full documentation refer to :obj:`numpy.ndarray.imag`.
1385

1386
        Examples
1387
        --------
1388
        >>> import dpnp as np
1389
        >>> a = np.array([1+2j, 3+4j, 5+6j])
1390
        >>> a.imag = 9
1391
        >>> a
1392
        array([1.+9.j, 3.+9.j, 5.+9.j])
1393

1394
        """
1395

1396
        if dpnp.issubdtype(self.dtype, dpnp.complexfloating):
1✔
1397
            dpnp.copyto(self._array_obj.imag, value)
1✔
1398
        else:
1399
            raise TypeError("array does not have imaginary part to set")
1✔
1400

1401
    def item(self, /, *args):
1✔
1402
        """
1403
        Copy an element of an array to a standard Python scalar and return it.
1404

1405
        For full documentation refer to :obj:`numpy.ndarray.item`.
1406

1407
        Parameters
1408
        ----------
1409
        *args : {none, int, tuple of ints}
1410
            - none: in this case, the method only works for arrays with
1411
              one element (``a.size == 1``), which element is copied into a
1412
              standard Python scalar object and returned.
1413
            - int: this argument is interpreted as a flat index into the array,
1414
              specifying which element to copy and return.
1415
            - tuple of ints: functions as does a single int argument, except
1416
              that the argument is interpreted as an nd-index into the array.
1417

1418
        Returns
1419
        -------
1420
        out : Standard Python scalar object
1421
            A copy of the specified element of the array as a suitable Python
1422
            scalar.
1423

1424
        Examples
1425
        --------
1426
        >>> import dpnp as np
1427
        >>> np.random.seed(123)
1428
        >>> x = np.random.randint(9, size=(3, 3))
1429
        >>> x
1430
        array([[0, 0, 7],
1431
               [6, 6, 6],
1432
               [0, 7, 1]])
1433
        >>> x.item(3)
1434
        6
1435
        >>> x.item(7)
1436
        7
1437
        >>> x.item((0, 1))
1438
        0
1439
        >>> x.item((2, 2))
1440
        1
1441

1442
        >>> x = np.array(5)
1443
        >>> x.item()
1444
        5
1445

1446
        """
1447

1448
        # TODO: implement a more efficient way to avoid copying to host
1449
        # for large arrays using `asnumpy()`
1450
        return self.asnumpy().item(*args)
1✔
1451

1452
    @property
1✔
1453
    def itemsize(self):
1✔
1454
        """Size of one array element in bytes."""
1455

1456
        return self._array_obj.itemsize
1✔
1457

1458
    def max(
1✔
1459
        self,
1460
        /,
1461
        axis=None,
1462
        *,
1463
        out=None,
1464
        keepdims=False,
1465
        initial=None,
1466
        where=True,
1467
    ):
1468
        """
1469
        Return the maximum along an axis.
1470

1471
        Refer to :obj:`dpnp.max` for full documentation.
1472

1473
        """
1474

1475
        return dpnp.max(
1✔
1476
            self,
1477
            axis=axis,
1478
            out=out,
1479
            keepdims=keepdims,
1480
            initial=initial,
1481
            where=where,
1482
        )
1483

1484
    def mean(
1✔
1485
        self, /, axis=None, dtype=None, *, out=None, keepdims=False, where=True
1486
    ):
1487
        """
1488
        Return the average of the array elements.
1489

1490
        Refer to :obj:`dpnp.mean` for full documentation.
1491

1492
        """
1493

1494
        return dpnp.mean(self, axis, dtype, out, keepdims, where=where)
1✔
1495

1496
    def min(
1✔
1497
        self,
1498
        /,
1499
        axis=None,
1500
        *,
1501
        out=None,
1502
        keepdims=False,
1503
        initial=None,
1504
        where=True,
1505
    ):
1506
        """
1507
        Return the minimum along a given axis.
1508

1509
        Refer to :obj:`dpnp.min` for full documentation.
1510

1511
        """
1512

1513
        return dpnp.min(
1✔
1514
            self,
1515
            axis=axis,
1516
            out=out,
1517
            keepdims=keepdims,
1518
            initial=initial,
1519
            where=where,
1520
        )
1521

1522
    @property
1✔
1523
    def mT(self):
1✔
1524
        """
1525
        View of the matrix transposed array.
1526

1527
        The matrix transpose is the transpose of the last two dimensions, even
1528
        if the array is of higher dimension.
1529

1530
        Raises
1531
        ------
1532
        ValueError
1533
            If the array is of dimension less than ``2``.
1534

1535
        Examples
1536
        --------
1537
        >>> import dpnp as np
1538
        >>> a = np.array([[1, 2], [3, 4]])
1539
        >>> a
1540
        array([[1, 2],
1541
               [3, 4]])
1542
        >>> a.mT
1543
        array([[1, 3],
1544
               [2, 4]])
1545

1546
        >>> a = np.arange(8).reshape((2, 2, 2))
1547
        >>> a
1548
        array([[[0, 1],
1549
                [2, 3]],
1550
               [[4, 5],
1551
                [6, 7]]])
1552
        >>> a.mT
1553
        array([[[0, 2],
1554
                [1, 3]],
1555
               [[4, 6],
1556
                [5, 7]]])
1557

1558
        """
1559

1560
        if self.ndim < 2:
1✔
1561
            raise ValueError("matrix transpose with ndim < 2 is undefined")
1✔
1562

1563
        return dpnp_array._create_from_usm_ndarray(self._array_obj.mT)
1✔
1564

1565
    @property
1✔
1566
    def nbytes(self):
1✔
1567
        """Total bytes consumed by the elements of the array."""
1568

1569
        return self._array_obj.nbytes
1✔
1570

1571
    @property
1✔
1572
    def ndim(self):
1✔
1573
        """
1574
        Return the number of dimensions of an array.
1575

1576
        For full documentation refer to :obj:`numpy.ndarray.ndim`.
1577

1578
        Returns
1579
        -------
1580
        number_of_dimensions : int
1581
            The number of dimensions in `a`.
1582

1583
        See Also
1584
        --------
1585
        :obj:`dpnp.ndim` : Equivalent method for any array-like input.
1586
        :obj:`dpnp.shape` : Return the shape of an array.
1587
        :obj:`dpnp.ndarray.shape` : Return the shape of an array.
1588

1589
        Examples
1590
        --------
1591
        >>> import dpnp as np
1592
        >>> x = np.array([1, 2, 3])
1593
        >>> x.ndim
1594
        1
1595
        >>> y = np.zeros((2, 3, 4))
1596
        >>> y.ndim
1597
        3
1598

1599
        """
1600

1601
        return self._array_obj.ndim
1✔
1602

1603
    def nonzero(self):
1✔
1604
        """
1605
        Return the indices of the elements that are non-zero.
1606

1607
        Refer to :obj:`dpnp.nonzero` for full documentation.
1608

1609
        """
1610

1611
        return dpnp.nonzero(self)
1✔
1612

1613
    def partition(self, /, kth, axis=-1, kind="introselect", order=None):
1✔
1614
        """
1615
        Partially sorts the elements in the array in such a way that the value
1616
        of the element in k-th position is in the position it would be in a
1617
        sorted array. In the output array, all elements smaller than the k-th
1618
        element are located to the left of this element and all equal or
1619
        greater are located to its right. The ordering of the elements in the
1620
        two partitions on the either side of the k-th element in the output
1621
        array is undefined.
1622

1623
        Refer to `dpnp.partition` for full documentation.
1624

1625
        kth : {int, sequence of ints}
1626
            Element index to partition by. The kth element value will be in its
1627
            final sorted position and all smaller elements will be moved before
1628
            it and all equal or greater elements behind it.
1629
            The order of all elements in the partitions is undefined. If
1630
            provided with a sequence of kth it will partition all elements
1631
            indexed by kth of them into their sorted position at once.
1632
        axis : int, optional
1633
            Axis along which to sort. The default is ``-1``, which means sort
1634
            along the the last axis.
1635

1636
            Default: ``-1``.
1637

1638
        See Also
1639
        --------
1640
        :obj:`dpnp.partition` : Return a partitioned copy of an array.
1641
        :obj:`dpnp.argpartition` : Indirect partition.
1642
        :obj:`dpnp.sort` : Full sort.
1643

1644
        Examples
1645
        --------
1646
        >>> import dpnp as np
1647
        >>> a = np.array([3, 4, 2, 1])
1648
        >>> a.partition(3)
1649
        >>> a
1650
        array([1, 2, 3, 4]) # may vary
1651

1652
        >>> a.partition((1, 3))
1653
        >>> a
1654
        array([1, 2, 3, 4])
1655

1656
        """
1657

1658
        if axis is None:
1✔
1659
            raise TypeError(
1✔
1660
                "'NoneType' object cannot be interpreted as an integer"
1661
            )
1662
        self[...] = dpnp.partition(self, kth, axis=axis, kind=kind, order=order)
1✔
1663

1664
    def prod(
1✔
1665
        self,
1666
        /,
1667
        axis=None,
1668
        dtype=None,
1669
        *,
1670
        out=None,
1671
        keepdims=False,
1672
        initial=None,
1673
        where=True,
1674
    ):
1675
        """
1676
        Return the prod along a given axis.
1677

1678
        Refer to :obj:`dpnp.prod` for full documentation.
1679

1680
        """
1681

1682
        return dpnp.prod(
1✔
1683
            self,
1684
            axis=axis,
1685
            dtype=dtype,
1686
            out=out,
1687
            keepdims=keepdims,
1688
            initial=initial,
1689
            where=where,
1690
        )
1691

1692
    def put(self, /, indices, vals, axis=None, mode="wrap"):
1✔
1693
        """
1694
        Put values of an array into another array along a given axis.
1695

1696
        Refer to :obj:`dpnp.put` for full documentation.
1697

1698
        """
1699

1700
        return dpnp.put(self, indices, vals, axis=axis, mode=mode)
1✔
1701

1702
    def ravel(self, /, order="C"):
1✔
1703
        """
1704
        Return a contiguous flattened array.
1705

1706
        Refer to :obj:`dpnp.ravel` for full documentation.
1707

1708
        """
1709

1710
        return dpnp.ravel(self, order=order)
1✔
1711

1712
    @property
1✔
1713
    def real(self, /):
1✔
1714
        """
1715
        The real part of the array.
1716

1717
        For full documentation refer to :obj:`numpy.ndarray.real`.
1718

1719
        Examples
1720
        --------
1721
        >>> import dpnp as np
1722
        >>> x = np.sqrt(np.array([1+0j, 0+1j]))
1723
        >>> x.real
1724
        array([1.        , 0.70710677])
1725

1726
        """
1727

1728
        if dpnp.issubdtype(self.dtype, dpnp.complexfloating):
1✔
1729
            return dpnp_array._create_from_usm_ndarray(
1✔
1730
                dpnp.get_usm_ndarray(self).real
1731
            )
1732
        return self
1✔
1733

1734
    @real.setter
1✔
1735
    def real(self, value, /):
1✔
1736
        """
1737
        Set the real part of the array.
1738

1739
        For full documentation refer to :obj:`numpy.ndarray.real`.
1740

1741
        Examples
1742
        --------
1743
        >>> import dpnp as np
1744
        >>> a = np.array([1+2j, 3+4j, 5+6j])
1745
        >>> a.real = 9
1746
        >>> a
1747
        array([9.+2.j, 9.+4.j, 9.+6.j])
1748

1749
        """
1750

1751
        dpnp.copyto(self._array_obj.real, value)
1✔
1752

1753
    def repeat(self, repeats, axis=None):
1✔
1754
        """
1755
        Repeat elements of an array.
1756

1757
        Refer to :obj:`dpnp.repeat` for full documentation.
1758

1759
        """
1760

1761
        return dpnp.repeat(self, repeats, axis=axis)
1✔
1762

1763
    def reshape(self, /, *shape, order="C", copy=None):
1✔
1764
        """
1765
        Return an array containing the same data with a new shape.
1766

1767
        Refer to :obj:`dpnp.reshape` for full documentation.
1768

1769
        Returns
1770
        -------
1771
        y : dpnp.ndarray
1772
            This will be a new view object if possible;
1773
            otherwise, it will be a copy.
1774

1775
        See Also
1776
        --------
1777
        :obj:`dpnp.reshape` : Equivalent function.
1778

1779
        Notes
1780
        -----
1781
        Unlike the free function `dpnp.reshape`, this method on `ndarray` allows
1782
        the elements of the shape parameter to be passed in as separate
1783
        arguments.
1784
        For example, ``a.reshape(10, 11)`` is equivalent to
1785
        ``a.reshape((10, 11))``.
1786

1787
        """
1788

1789
        if len(shape) == 1:
1✔
1790
            shape = shape[0]
1✔
1791
        return dpnp.reshape(self, shape, order=order, copy=copy)
1✔
1792

1793
    # 'resize',
1794

1795
    def round(self, /, decimals=0, *, out=None):
1✔
1796
        """
1797
        Return array with each element rounded to the given number of decimals.
1798

1799
        Refer to :obj:`dpnp.round` for full documentation.
1800

1801
        """
1802

1803
        return dpnp.around(self, decimals, out)
1✔
1804

1805
    def searchsorted(self, v, side="left", sorter=None):
1✔
1806
        """
1807
        Find indices where elements of `v` should be inserted in `a`
1808
        to maintain order.
1809

1810
        Refer to :obj:`dpnp.searchsorted` for full documentation
1811

1812
        """
1813

1814
        return dpnp.searchsorted(self, v, side=side, sorter=sorter)
1✔
1815

1816
    # 'setfield',
1817
    # 'setflags',
1818

1819
    @property
1✔
1820
    def shape(self):
1✔
1821
        """
1822
        Tuple of array dimensions.
1823

1824
        The shape property is usually used to get the current shape of an array,
1825
        but may also be used to reshape the array in-place by assigning a tuple
1826
        of array dimensions to it. Unlike :obj:`dpnp.reshape`, only non-negative
1827
        values are supported to be set as new shape. Reshaping an array in-place
1828
        will fail if a copy is required.
1829

1830
        For full documentation refer to :obj:`numpy.ndarray.shape`.
1831

1832
        Note
1833
        ----
1834
        Using :obj:`dpnp.ndarray.reshape` or :obj:`dpnp.reshape` is the
1835
        preferred approach to set new shape of an array.
1836

1837
        See Also
1838
        --------
1839
        :obj:`dpnp.shape` : Equivalent getter function.
1840
        :obj:`dpnp.reshape` : Function similar to setting `shape`.
1841
        :obj:`dpnp.ndarray.reshape` : Method similar to setting `shape`.
1842

1843
        Examples
1844
        --------
1845
        >>> import dpnp as np
1846
        >>> x = np.array([1, 2, 3, 4])
1847
        >>> x.shape
1848
        (4,)
1849
        >>> y = np.zeros((2, 3, 4))
1850
        >>> y.shape
1851
        (2, 3, 4)
1852

1853
        >>> y.shape = (3, 8)
1854
        >>> y
1855
        array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
1856
               [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
1857
               [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])
1858
        >>> y.shape = (3, 6)
1859
        ...
1860
        TypeError: Can not reshape array of size 24 into (3, 6)
1861

1862
        """
1863

1864
        return self._array_obj.shape
1✔
1865

1866
    @shape.setter
1✔
1867
    def shape(self, newshape):
1✔
1868
        """
1869
        Set new lengths of axes.
1870

1871
        Modifies array instance in-place by changing its metadata about the
1872
        shape and the strides of the array, or raises `AttributeError`
1873
        exception if in-place change is not possible.
1874

1875
        Whether the array can be reshape in-place depends on its strides. Use
1876
        :obj:`dpnp.reshape` function which always succeeds to reshape the array
1877
        by performing a copy if necessary.
1878

1879
        For full documentation refer to :obj:`numpy.ndarray.shape`.
1880

1881
        Parameters
1882
        ----------
1883
        newshape : {tuple, int}
1884
            New shape. Only non-negative values are supported. The new shape
1885
            may not lead to the change in the number of elements in the array.
1886

1887
        """
1888

1889
        self._array_obj.shape = newshape
1✔
1890

1891
    @property
1✔
1892
    def size(self):
1✔
1893
        """
1894
        Number of elements in the array.
1895

1896
        Returns
1897
        -------
1898
        element_count : int
1899
            Number of elements in the array.
1900

1901
        See Also
1902
        --------
1903
        :obj:`dpnp.size` : Return the number of elements along a given axis.
1904
        :obj:`dpnp.shape` : Return the shape of an array.
1905
        :obj:`dpnp.ndarray.shape` : Return the shape of an array.
1906

1907
        Examples
1908
        --------
1909
        >>> import dpnp as np
1910
        >>> x = np.zeros((3, 5, 2), dtype=np.complex64)
1911
        >>> x.size
1912
        30
1913

1914
        """
1915

1916
        return self._array_obj.size
1✔
1917

1918
    def sort(
1✔
1919
        self, axis=-1, kind=None, order=None, *, descending=False, stable=None
1920
    ):
1921
        """
1922
        Sort an array in-place.
1923

1924
        Refer to :obj:`dpnp.sort` for full documentation.
1925

1926
        Parameters
1927
        ----------
1928
        axis : int, optional
1929
            Axis along which to sort. The default is ``-1``, which sorts along
1930
            the last axis.
1931

1932
            Default: ``-1``.
1933
        kind : {None, "stable", "mergesort", "radixsort"}, optional
1934
            Sorting algorithm. The default is ``None``, which uses parallel
1935
            merge-sort or parallel radix-sort algorithms depending on the array
1936
            data type.
1937

1938
            Default: ``None``.
1939
        descending : bool, optional
1940
            Sort order. If ``True``, the array must be sorted in descending
1941
            order (by value). If ``False``, the array must be sorted in
1942
            ascending order (by value).
1943

1944
            Default: ``False``.
1945
        stable : {None, bool}, optional
1946
            Sort stability. If ``True``, the returned array will maintain the
1947
            relative order of `a` values which compare as equal. The same
1948
            behavior applies when set to ``False`` or ``None``.
1949
            Internally, this option selects ``kind="stable"``.
1950

1951
            Default: ``None``.
1952

1953
        See Also
1954
        --------
1955
        :obj:`dpnp.sort` : Return a sorted copy of an array.
1956
        :obj:`dpnp.argsort` : Return the indices that would sort an array.
1957
        :obj:`dpnp.lexsort` : Indirect stable sort on multiple keys.
1958
        :obj:`dpnp.searchsorted` : Find elements in a sorted array.
1959
        :obj:`dpnp.partition` : Partial sort.
1960

1961
        Note
1962
        ----
1963
        `axis` in :obj:`dpnp.sort` could be integer or ``None``. If ``None``,
1964
        the array is flattened before sorting. However, `axis` in
1965
        :obj:`dpnp.ndarray.sort` can only be integer since it sorts an array
1966
        in-place.
1967

1968
        Examples
1969
        --------
1970
        >>> import dpnp as np
1971
        >>> a = np.array([[1, 4], [3, 1]])
1972
        >>> a.sort(axis=1)
1973
        >>> a
1974
        array([[1, 4],
1975
              [1, 3]])
1976
        >>> a.sort(axis=0)
1977
        >>> a
1978
        array([[1, 1],
1979
              [3, 4]])
1980

1981
        """
1982

1983
        if axis is None:
1✔
1984
            raise TypeError(
1✔
1985
                "'NoneType' object cannot be interpreted as an integer"
1986
            )
1987
        self[...] = dpnp.sort(
1✔
1988
            self,
1989
            axis=axis,
1990
            kind=kind,
1991
            order=order,
1992
            descending=descending,
1993
            stable=stable,
1994
        )
1995

1996
    def squeeze(self, axis=None):
1✔
1997
        """
1998
        Remove single-dimensional entries from the shape of an array.
1999

2000
        Refer to :obj:`dpnp.squeeze` for full documentation
2001

2002
        """
2003

2004
        return dpnp.squeeze(self, axis)
1✔
2005

2006
    def std(
1✔
2007
        self,
2008
        axis=None,
2009
        dtype=None,
2010
        *,
2011
        out=None,
2012
        ddof=0,
2013
        keepdims=False,
2014
        where=True,
2015
        mean=None,
2016
        correction=None,
2017
    ):
2018
        """
2019
        Return the standard deviation of the array elements, along given axis.
2020

2021
        Refer to :obj:`dpnp.std` for full documentation.
2022

2023
        """
2024

2025
        return dpnp.std(
1✔
2026
            self,
2027
            axis,
2028
            dtype,
2029
            out,
2030
            ddof,
2031
            keepdims,
2032
            where=where,
2033
            mean=mean,
2034
            correction=correction,
2035
        )
2036

2037
    @property
1✔
2038
    def strides(self):
1✔
2039
        """
2040
        Tuple of bytes to step in each dimension when traversing an array.
2041

2042
        The byte offset of element ``(i[0], i[1], ..., i[n])`` in an array `a`
2043
        is::
2044

2045
            offset = sum(dpnp.array(i) * a.strides)
2046

2047
        For full documentation refer to :obj:`numpy.ndarray.strides`.
2048

2049
        See Also
2050
        --------
2051
        :obj:`dpnp.lib.stride_tricks.as_strided` : Return a view into the array
2052
            with given shape and strides.
2053

2054
        Examples
2055
        --------
2056
        >>> import dpnp as np
2057
        >>> y = np.reshape(np.arange(2 * 3 * 4, dtype=np.int32), (2, 3, 4))
2058
        >>> y
2059
        array([[[ 0,  1,  2,  3],
2060
                [ 4,  5,  6,  7],
2061
                [ 8,  9, 10, 11]],
2062
               [[12, 13, 14, 15],
2063
                [16, 17, 18, 19],
2064
                [20, 21, 22, 23]]], dtype=np.int32)
2065
        >>> y.strides
2066
        (48, 16, 4)
2067
        >>> y[1, 1, 1]
2068
        array(17, dtype=int32)
2069
        >>> offset = sum(i * s for i, s in zip((1, 1, 1), y.strides))
2070
        >>> offset // y.itemsize
2071
        17
2072

2073
        >>> x = np.reshape(np.arange(5*6*7*8, dtype=np.int32), (5, 6, 7, 8))
2074
        >>> x = x.transpose(2, 3, 1, 0)
2075
        >>> x.strides
2076
        (32, 4, 224, 1344)
2077
        >>> offset = sum(i * s for i, s in zip((3, 5, 2, 2), x.strides))
2078
        >>> x[3, 5, 2, 2]
2079
        array(813, dtype=int32)
2080
        >>> offset // x.itemsize
2081
        813
2082

2083
        """
2084

2085
        it_sz = self.itemsize
1✔
2086
        return tuple(el * it_sz for el in self._array_obj.strides)
1✔
2087

2088
    def sum(
1✔
2089
        self,
2090
        /,
2091
        axis=None,
2092
        dtype=None,
2093
        *,
2094
        out=None,
2095
        keepdims=False,
2096
        initial=None,
2097
        where=True,
2098
    ):
2099
        """
2100
        Return the sum along a given axis.
2101

2102
        Refer to :obj:`dpnp.sum` for full documentation.
2103

2104
        """
2105

2106
        return dpnp.sum(
1✔
2107
            self,
2108
            axis=axis,
2109
            dtype=dtype,
2110
            out=out,
2111
            keepdims=keepdims,
2112
            initial=initial,
2113
            where=where,
2114
        )
2115

2116
    def swapaxes(self, axis1, axis2):
1✔
2117
        """
2118
        Interchange two axes of an array.
2119

2120
        Refer to :obj:`dpnp.swapaxes` for full documentation.
2121

2122
        """
2123

2124
        return dpnp.swapaxes(self, axis1=axis1, axis2=axis2)
1✔
2125

2126
    @property
1✔
2127
    def sycl_context(self):
1✔
2128
        """
2129
        Return :class:`dpctl.SyclContext` object to which USM data is bound.
2130

2131
        """  # noqa: D200
2132
        return self._array_obj.sycl_context
1✔
2133

2134
    @property
1✔
2135
    def sycl_device(self):
1✔
2136
        """
2137
        Return :class:`dpctl.SyclDevice` object on which USM data was
2138
        allocated.
2139

2140
        """
2141
        return self._array_obj.sycl_device
1✔
2142

2143
    @property
1✔
2144
    def sycl_queue(self):
1✔
2145
        """
2146
        Return :class:`dpctl.SyclQueue` object associated with USM data.
2147

2148
        """  # noqa: D200
2149
        return self._array_obj.sycl_queue
1✔
2150

2151
    @property
1✔
2152
    def T(self):
1✔
2153
        """
2154
        View of the transposed array.
2155

2156
        Same as ``self.transpose()`` except that it requires
2157
        the array to be 2-dimensional.
2158

2159
        See Also
2160
        --------
2161
        :obj:`dpnp.transpose` : Equivalent function.
2162

2163
        Examples
2164
        --------
2165
        >>> import dpnp as np
2166
        >>> a = np.array([[1, 2], [3, 4]])
2167
        >>> a
2168
        array([[1, 2],
2169
            [3, 4]])
2170
        >>> a.T
2171
        array([[1, 3],
2172
            [2, 4]])
2173

2174
        """
2175

2176
        if self.ndim != 2:
1✔
2177
            warnings.warn(
1✔
2178
                "`.T` is deprecated for non-2D dpnp.ndarray "
2179
                "and will raise an error in a future release. "
2180
                "Either `self.transpose()` or `self.mT` (which swaps "
2181
                "the last two axes only) should be used instead.",
2182
                DeprecationWarning,
2183
                stacklevel=2,
2184
            )
2185
        return self.transpose()
1✔
2186

2187
    def take(self, indices, axis=None, *, out=None, mode="wrap"):
1✔
2188
        """
2189
        Take elements from an array along an axis.
2190

2191
        Refer to :obj:`dpnp.take` for full documentation.
2192

2193
        """
2194

2195
        return dpnp.take(self, indices, axis=axis, out=out, mode=mode)
1✔
2196

2197
    def to_device(self, device, /, *, stream=None):
1✔
2198
        """
2199
        Transfer this array to specified target device.
2200

2201
        Parameters
2202
        ----------
2203
        device : {None, string, SyclDevice, SyclQueue, Device}, optional
2204
            An array API concept of device where the output array is created.
2205
            `device` can be ``None``, a oneAPI filter selector string,
2206
            an instance of :class:`dpctl.SyclDevice` corresponding to
2207
            a non-partitioned SYCL device, an instance of
2208
            :class:`dpctl.SyclQueue`, or a :class:`dpnp.tensor.Device` object
2209
            returned by :attr:`dpnp.ndarray.device`.
2210
        stream : {SyclQueue, None}, optional
2211
            Execution queue to synchronize with. If ``None``, synchronization
2212
            is not performed.
2213

2214
            Default: ``None``.
2215

2216
        Returns
2217
        -------
2218
        out : dpnp.ndarray
2219
            A view if data copy is not required, and a copy otherwise.
2220
            If copying is required, it is done by copying from the original
2221
            allocation device to the host, followed by copying from host
2222
            to the target device.
2223

2224
        Examples
2225
        --------
2226
        >>> import dpnp as np, dpctl
2227
        >>> x = np.full(100, 2, dtype=np.int64)
2228
        >>> q_prof = dpctl.SyclQueue(x.sycl_device, property="enable_profiling")
2229
        >>> # return a view with profile-enabled queue
2230
        >>> y = x.to_device(q_prof)
2231
        >>> timer = dpctl.SyclTimer()
2232
        >>> with timer(q_prof):
2233
        ...     z = y * y
2234
        >>> print(timer.dt)
2235

2236
        """
2237

2238
        usm_res = self._array_obj.to_device(device, stream=stream)
1✔
2239
        return dpnp_array._create_from_usm_ndarray(usm_res)
1✔
2240

2241
    def tobytes(self, order="C"):
1✔
2242
        r"""
2243
        Constructs Python bytes containing the raw data bytes in the array.
2244

2245
        For full documentation refer to :obj:`numpy.ndarray.tobytes`.
2246

2247
        Parameters
2248
        ----------
2249
        order : {None, "C", "F", "A", "K"}, optional
2250
            Controls the memory layout of the bytes object.
2251

2252
            Default: ``"C"``.
2253

2254
        Returns
2255
        -------
2256
        out : bytes
2257
            Python bytes exhibiting a copy of array's raw data.
2258

2259
        See Also
2260
        --------
2261
        :obj:`dpnp.frombuffer` : Construct a 1D array from Python bytes.
2262

2263
        Examples
2264
        --------
2265
        >>> import dpnp as np
2266
        >>> x = np.array([[0, 1], [2, 3]], dtype='i2')
2267
        >>> x.tobytes()
2268
        b'\x00\x00\x01\x00\x02\x00\x03\x00'
2269
        >>> x.tobytes("C") == x.tobytes()
2270
        True
2271
        >>> x.tobytes("F")
2272
        b'\x00\x00\x02\x00\x01\x00\x03\x00'
2273

2274
        """
2275

2276
        return self.asnumpy().tobytes(order=order)
1✔
2277

2278
    def tofile(self, fid, sep="", format=""):
1✔
2279
        """
2280
        Writes the array to a file as text or binary (default).
2281

2282
        For full documentation refer to :obj:`numpy.ndarray.tofile`.
2283

2284
        Parameters
2285
        ----------
2286
        fid : {file. str, path}
2287
            An open file object, or a string containing a filename.
2288
        sep : str, optional
2289
            Separator between array items for text output. If ``""`` (empty),
2290
            a binary file is written.
2291

2292
            Default: ``""``.
2293
        format : str, optional
2294
            Format string for text file output (when non-empty `sep` is passed).
2295
            Each entry in the array is formatted to text by first converting it
2296
            to the closest Python type, and then using ``format % item``. If
2297
            ``""`` (empty), no formatting is used while converting to the
2298
            string.
2299

2300
            Default: ``""``.
2301

2302
        See Also
2303
        --------
2304
        :obj:`dpnp.fromfile` : Construct an array from data in a text or binary
2305
            file.
2306

2307
        """
2308

2309
        self.asnumpy().tofile(fid, sep=sep, format=format)
1✔
2310

2311
    def tolist(self):
1✔
2312
        """
2313
        Converts the array to a (possibly nested) Python list.
2314

2315
        For full documentation refer to :obj:`numpy.ndarray.tolist`.
2316

2317
        Returns
2318
        -------
2319
        out : list
2320
            The possibly nested Python list of array elements.
2321

2322
        Examples
2323
        --------
2324
        For a 1D array, ``a.tolist()`` is almost the same as ``list(a)``,
2325
        except that ``tolist`` changes 0D arrays to Python scalars:
2326

2327
        >>> import dpnp as np
2328
        >>> a = np.array([1, 2])
2329
        >>> list(a)
2330
        [array(1), array(2)]
2331
        >>> a.tolist()
2332
        [1, 2]
2333

2334
        Additionally, for a 2D array, ``tolist`` applies recursively:
2335

2336
        >>> a = np.array([[1, 2], [3, 4]])
2337
        >>> list(a)
2338
        [array([1, 2]), array([3, 4])]
2339
        >>> a.tolist()
2340
        [[1, 2], [3, 4]]
2341

2342
        The base case for this recursion is a 0D array:
2343

2344
        >>> a = np.array(1)
2345
        >>> list(a)
2346
        Traceback (most recent call last):
2347
        ...
2348
        TypeError: iteration over a 0-d array
2349
        >>> a.tolist()
2350
        1
2351

2352
        """
2353

2354
        return self.asnumpy().tolist()
1✔
2355

2356
    def trace(self, offset=0, axis1=0, axis2=1, dtype=None, *, out=None):
1✔
2357
        """
2358
        Return the sum along diagonals of the array.
2359

2360
        Refer to :obj:`dpnp.trace` for full documentation.
2361

2362
        """
2363

2364
        return dpnp.trace(
1✔
2365
            self, offset=offset, axis1=axis1, axis2=axis2, dtype=dtype, out=out
2366
        )
2367

2368
    def transpose(self, *axes):
1✔
2369
        """
2370
        Return a view of the array with axes transposed.
2371

2372
        For full documentation refer to :obj:`numpy.ndarray.transpose`.
2373

2374
        Parameters
2375
        ----------
2376
        axes : None, tuple or list of ints, n ints, optional
2377
            * ``None`` or no argument: reverses the order of the axes.
2378
            * ``tuple or list of ints``: `i` in the `j`-th place in the
2379
              tuple/list means that the array’s `i`-th axis becomes the
2380
              transposed array’s `j`-th axis.
2381
            * ``n ints``: same as an n-tuple/n-list of the same integers (this
2382
              form is intended simply as a “convenience” alternative to the
2383
              tuple form).
2384

2385
        Returns
2386
        -------
2387
        out : dpnp.ndarray
2388
            View of the array with its axes suitably permuted.
2389

2390
        See Also
2391
        --------
2392
        :obj:`dpnp.transpose` : Equivalent function.
2393
        :obj:`dpnp.ndarray.ndarray.T` : Array property returning the array
2394
            transposed.
2395
        :obj:`dpnp.ndarray.reshape` : Give a new shape to an array without
2396
            changing its data.
2397

2398
        Examples
2399
        --------
2400
        >>> import dpnp as np
2401
        >>> a = np.array([[1, 2], [3, 4]])
2402
        >>> a
2403
        array([[1, 2],
2404
               [3, 4]])
2405
        >>> a.transpose()
2406
        array([[1, 3],
2407
               [2, 4]])
2408
        >>> a.transpose((1, 0))
2409
        array([[1, 3],
2410
               [2, 4]])
2411

2412
        >>> a = np.array([1, 2, 3, 4])
2413
        >>> a
2414
        array([1, 2, 3, 4])
2415
        >>> a.transpose()
2416
        array([1, 2, 3, 4])
2417

2418
        """
2419

2420
        ndim = self.ndim
1✔
2421
        if ndim < 2:
1✔
2422
            return self
1✔
2423

2424
        axes_len = len(axes)
1✔
2425
        if axes_len == 1 and isinstance(axes[0], (tuple, list)):
1✔
2426
            axes = axes[0]
1✔
2427

2428
        if ndim == 2 and axes_len == 0:
1✔
2429
            usm_res = self._array_obj.T
1✔
2430
        else:
2431
            if len(axes) == 0 or axes[0] is None:
1✔
2432
                # self.transpose().shape == self.shape[::-1]
2433
                # self.transpose(None).shape == self.shape[::-1]
2434
                axes = tuple((ndim - x - 1) for x in range(ndim))
1✔
2435

2436
            usm_res = dpt.permute_dims(self._array_obj, axes)
1✔
2437
        return dpnp_array._create_from_usm_ndarray(usm_res)
1✔
2438

2439
    def var(
1✔
2440
        self,
2441
        axis=None,
2442
        dtype=None,
2443
        *,
2444
        out=None,
2445
        ddof=0,
2446
        keepdims=False,
2447
        where=True,
2448
        mean=None,
2449
        correction=None,
2450
    ):
2451
        """
2452
        Return the variance of the array elements, along given axis.
2453

2454
        Refer to :obj:`dpnp.var` for full documentation.
2455

2456
        """
2457

2458
        return dpnp.var(
1✔
2459
            self,
2460
            axis,
2461
            dtype,
2462
            out,
2463
            ddof,
2464
            keepdims,
2465
            where=where,
2466
            mean=mean,
2467
            correction=correction,
2468
        )
2469

2470
    def view(self, /, dtype=None, *, type=None):
1✔
2471
        """
2472
        New view of array with the same data.
2473

2474
        For full documentation refer to :obj:`numpy.ndarray.view`.
2475

2476
        Parameters
2477
        ----------
2478
        dtype : {None, str, dtype object, type}, optional
2479
            The desired data type of the returned view, e.g. :obj:`dpnp.float32`
2480
            or :obj:`dpnp.int16`. Omitting it results in the view having the
2481
            same data type. Can also be a subclass of :class:`dpnp.ndarray` to
2482
            create a view of that type (this is equivalent to setting the `type`
2483
            parameter).
2484

2485
            Default: ``None``.
2486
        type : {None, type}, optional
2487
            Type of the returned view, e.g. a subclass of :class:`dpnp.ndarray`.
2488
            If specified, the returned array will be an instance of `type`.
2489
            Omitting it results in type preservation.
2490

2491
            Default: ``None``.
2492

2493
        Notes
2494
        -----
2495
        Passing ``None`` for `dtype` is the same as omitting the parameter,
2496
        opposite to NumPy where they have different meaning.
2497

2498
        ``view(some_dtype)`` or ``view(dtype=some_dtype)`` constructs a view of
2499
        the array's memory with a different data type. This can cause a
2500
        reinterpretation of the bytes of memory.
2501

2502
        Only the last axis has to be contiguous.
2503

2504
        Examples
2505
        --------
2506
        >>> import dpnp as np
2507
        >>> x = np.ones((4,), dtype=np.float32)
2508
        >>> xv = x.view(dtype=np.int32)
2509
        >>> xv[:] = 0
2510
        >>> xv
2511
        array([0, 0, 0, 0], dtype=int32)
2512

2513
        However, views that change dtype are totally fine for arrays with a
2514
        contiguous last axis, even if the rest of the axes are not C-contiguous:
2515

2516
        >>> x = np.arange(2 * 3 * 4, dtype=np.int8).reshape(2, 3, 4)
2517
        >>> x.transpose(1, 0, 2).view(np.int16)
2518
        array([[[ 256,  770],
2519
                [3340, 3854]],
2520
        <BLANKLINE>
2521
            [[1284, 1798],
2522
                [4368, 4882]],
2523
        <BLANKLINE>
2524
            [[2312, 2826],
2525
                [5396, 5910]]], dtype=int16)
2526

2527
        Creating a view with a custom ndarray subclass:
2528

2529
        >>> class MyArray(np.ndarray):
2530
        ...     pass
2531
        >>> x = np.array([1, 2, 3])
2532
        >>> y = x.view(MyArray)
2533
        >>> type(y)
2534
        <class 'MyArray'>
2535

2536
        """
2537
        return self._view_impl(dtype=dtype, array_class=type)
1✔
2538

2539
    @property
1✔
2540
    def usm_type(self):
1✔
2541
        """
2542
        USM type of underlying memory. Possible values are:
2543

2544
        * ``"device"``
2545
            USM-device allocation in device memory, only accessible to kernels
2546
            executed on the device
2547
        * ``"shared"``
2548
            USM-shared allocation in device memory, accessible both from the
2549
            device and from the host
2550
        * ``"host"``
2551
            USM-host allocation in host memory, accessible both from the device
2552
            and from the host
2553

2554
        """
2555

2556
        return self._array_obj.usm_type
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc