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

IntelPython / dpnp / 12279662243

11 Dec 2024 03:33PM UTC coverage: 65.029% (-0.06%) from 65.09%
12279662243

Pull #2075

github

web-flow
Merge e87174e31 into c4997cc62
Pull Request #2075: Handle dpnp functions and tests to run on CUDA devices

4604 of 11552 branches covered (39.85%)

Branch coverage included in aggregate %.

49 of 89 new or added lines in 7 files covered. (55.06%)

1 existing line in 1 file now uncovered.

16996 of 21664 relevant lines covered (78.45%)

19739.07 hits per line

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

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

27
"""
28
Interface of the sorting function of the dpnp
29

30
Notes
31
-----
32
This module is a face or public interface file for the library
33
it contains:
34
 - Interface functions
35
 - documentation for the functions
36
 - The functions parameters check
37

38
"""
39

40

41
import dpctl.tensor as dpt
1✔
42
import numpy
1✔
43
from dpctl.tensor._numpy_helper import normalize_axis_index
1✔
44

45
import dpnp
1✔
46

47
# pylint: disable=no-name-in-module
48
from .dpnp_algo import (
1✔
49
    dpnp_partition,
50
)
51
from .dpnp_array import dpnp_array
1✔
52
from .dpnp_utils import (
1✔
53
    call_origin,
54
    map_dtype_to_device,
55
)
56

57
__all__ = ["argsort", "partition", "sort", "sort_complex"]
1✔
58

59

60
def _wrap_sort_argsort(
1✔
61
    a, _sorting_fn, axis=-1, kind=None, order=None, stable=True
62
):
63
    """Wrap a sorting call from dpctl.tensor interface."""
64

65
    if order is not None:
1✔
66
        raise NotImplementedError(
1✔
67
            "`order` keyword argument is only supported with its default value."
68
        )
69
    if stable is not None:
1✔
70
        if stable not in [True, False]:
1✔
71
            raise ValueError(
1✔
72
                "`stable` parameter should be None, True, or False."
73
            )
74
        if kind is not None:
1✔
75
            raise ValueError(
1✔
76
                "`kind` and `stable` parameters can't be provided at"
77
                " the same time. Use only one of them."
78
            )
79

80
    usm_a = dpnp.get_usm_ndarray(a)
1✔
81
    if axis is None:
1✔
82
        usm_a = dpt.reshape(usm_a, -1)
1✔
83
        axis = -1
1✔
84

85
    axis = normalize_axis_index(axis, ndim=usm_a.ndim)
1✔
86
    usm_res = _sorting_fn(usm_a, axis=axis, stable=stable, kind=kind)
1✔
87
    return dpnp_array._create_from_usm_ndarray(usm_res)
1✔
88

89

90
def argsort(a, axis=-1, kind=None, order=None, *, stable=None):
1✔
91
    """
92
    Returns the indices that would sort an array.
93

94
    For full documentation refer to :obj:`numpy.argsort`.
95

96
    Parameters
97
    ----------
98
    a : {dpnp.ndarray, usm_ndarray}
99
        Array to be sorted.
100
    axis : {None, int}, optional
101
        Axis along which to sort. If ``None``, the array is flattened before
102
        sorting. The default is ``-1``, which sorts along the last axis.
103
    kind : {None, "stable", "mergesort", "radixsort"}, optional
104
        Sorting algorithm. Default is ``None``, which is equivalent to
105
         ``"stable"``.
106
    stable : {None, bool}, optional
107
        Sort stability. If ``True``, the returned array will maintain
108
        the relative order of ``a`` values which compare as equal.
109
        The same behavior applies when set to ``False`` or ``None``.
110
        Internally, this option selects ``kind="stable"``.
111
        Default: ``None``.
112

113
    Returns
114
    -------
115
    out : dpnp.ndarray
116
        Array of indices that sort `a` along the specified `axis`.
117
        If `a` is one-dimensional, ``a[index_array]`` yields a sorted `a`.
118
        More generally, ``dpnp.take_along_axis(a, index_array, axis=axis)``
119
        always yields the sorted `a`, irrespective of dimensionality.
120
        The return array has default array index data type.
121

122
    Notes
123
    -----
124
    For zero-dimensional arrays, if ``axis=None``, output is a one-dimensional
125
    array with a single zero element. Otherwise, an ``AxisError`` is raised.
126

127
    Limitations
128
    -----------
129
    Parameters `order` is only supported with its default value.
130
    Otherwise ``NotImplementedError`` exception will be raised.
131
    Sorting algorithms ``"quicksort"`` and ``"heapsort"`` are not supported.
132

133

134
    See Also
135
    --------
136
    :obj:`dpnp.ndarray.argsort` : Equivalent method.
137
    :obj:`dpnp.sort` : Return a sorted copy of an array.
138
    :obj:`dpnp.lexsort` : Indirect stable sort with multiple keys.
139
    :obj:`dpnp.argpartition` : Indirect partial sort.
140
    :obj:`dpnp.take_along_axis` : Apply ``index_array`` from obj:`dpnp.argsort`
141
                                  to an array as if by calling sort.
142

143
    Examples
144
    --------
145
    >>> import dpnp as np
146
    >>> x = np.array([3, 1, 2])
147
    >>> np.argsort(x)
148
    array([1, 2, 0])
149

150
    >>> x = np.array([[0, 3], [2, 2]])
151
    >>> x
152
    array([[0, 3],
153
           [2, 2]])
154

155
    >>> ind = np.argsort(x, axis=0)  # sorts along first axis
156
    >>> ind
157
    array([[0, 1],
158
           [1, 0]])
159
    >>> np.take_along_axis(x, ind, axis=0)  # same as np.sort(x, axis=0)
160
    array([[0, 2],
161
           [2, 3]])
162

163
    >>> ind = np.argsort(x, axis=1)  # sorts along last axis
164
    >>> ind
165
    array([[0, 1],
166
           [0, 1]])
167
    >>> np.take_along_axis(x, ind, axis=1)  # same as np.sort(x, axis=1)
168
    array([[0, 3],
169
           [2, 2]])
170

171
    """
172

173
    return _wrap_sort_argsort(
1✔
174
        a, dpt.argsort, axis=axis, kind=kind, order=order, stable=stable
175
    )
176

177

178
def partition(x1, kth, axis=-1, kind="introselect", order=None):
1✔
179
    """
180
    Return a partitioned copy of an array.
181

182
    For full documentation refer to :obj:`numpy.partition`.
183

184
    Limitations
185
    -----------
186
    Input array is supported as :obj:`dpnp.ndarray`.
187
    Input `kth` is supported as :obj:`int`.
188
    Parameters `axis`, `kind` and `order` are supported only with default
189
    values.
190

191
    """
192

193
    x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_nondefault_queue=False)
1✔
194
    if x1_desc:
1!
195
        if dpnp.is_cuda_backend(x1_desc.get_array()):
1!
NEW
196
            raise NotImplementedError(
×
197
                "Running on CUDA is currently not supported"
198
            )
199

200
        if not isinstance(kth, int):
1✔
201
            pass
1✔
202
        elif x1_desc.ndim == 0:
1✔
203
            pass
1✔
204
        elif kth >= x1_desc.shape[x1_desc.ndim - 1] or x1_desc.ndim + kth < 0:
1✔
205
            pass
1✔
206
        elif axis != -1:
1✔
207
            pass
1✔
208
        elif kind != "introselect":
1!
209
            pass
×
210
        elif order is not None:
1!
211
            pass
×
212
        else:
213
            return dpnp_partition(x1_desc, kth, axis, kind, order).get_pyobj()
1✔
214

215
    return call_origin(numpy.partition, x1, kth, axis, kind, order)
1✔
216

217

218
def sort(a, axis=-1, kind=None, order=None, *, stable=None):
1✔
219
    """
220
    Return a sorted copy of an array.
221

222
    For full documentation refer to :obj:`numpy.sort`.
223

224
    Parameters
225
    ----------
226
    a : {dpnp.ndarray, usm_ndarray}
227
        Array to be sorted.
228
    axis : {None, int}, optional
229
        Axis along which to sort. If ``None``, the array is flattened before
230
        sorting. The default is ``-1``, which sorts along the last axis.
231
    kind : {None, "stable", "mergesort", "radixsort"}, optional
232
        Sorting algorithm. Default is ``None``, which is equivalent to
233
        ``"stable"``.
234
    stable : {None, bool}, optional
235
        Sort stability. If ``True``, the returned array will maintain
236
        the relative order of ``a`` values which compare as equal.
237
        The same behavior applies when set to ``False`` or ``None``.
238
        Internally, this option selects ``kind="stable"``.
239
        Default: ``None``.
240

241
    Returns
242
    -------
243
    out : dpnp.ndarray
244
        Sorted array with the same type and shape as `a`.
245

246
    Notes
247
    -----
248
    For zero-dimensional arrays, if ``axis=None``, output is the input array
249
    returned as a one-dimensional array. Otherwise, an ``AxisError`` is raised.
250

251
    Limitations
252
    -----------
253
    Parameters `order` is only supported with its default value.
254
    Otherwise ``NotImplementedError`` exception will be raised.
255
    Sorting algorithms ``"quicksort"`` and ``"heapsort"`` are not supported.
256

257
    See Also
258
    --------
259
    :obj:`dpnp.ndarray.sort` : Sort an array in-place.
260
    :obj:`dpnp.argsort` : Return the indices that would sort an array.
261
    :obj:`dpnp.lexsort` : Indirect stable sort on multiple keys.
262
    :obj:`dpnp.searchsorted` : Find elements in a sorted array.
263
    :obj:`dpnp.partition` : Partial sort.
264

265
    Examples
266
    --------
267
    >>> import dpnp as np
268
    >>> a = np.array([[1,4],[3,1]])
269
    >>> np.sort(a)                # sort along the last axis
270
    array([[1, 4],
271
           [1, 3]])
272
    >>> np.sort(a, axis=None)     # sort the flattened array
273
    array([1, 1, 3, 4])
274
    >>> np.sort(a, axis=0)        # sort along the first axis
275
    array([[1, 1],
276
           [3, 4]])
277

278
    """
279

280
    return _wrap_sort_argsort(
1✔
281
        a, dpt.sort, axis=axis, kind=kind, order=order, stable=stable
282
    )
283

284

285
def sort_complex(a):
1✔
286
    """
287
    Sort a complex array using the real part first, then the imaginary part.
288

289
    For full documentation refer to :obj:`numpy.sort_complex`.
290

291
    Parameters
292
    ----------
293
    a : {dpnp.ndarray, usm_ndarray}
294
        Input array.
295

296
    Returns
297
    -------
298
    out : dpnp.ndarray of complex dtype
299
        Always returns a sorted complex array.
300

301
    Examples
302
    --------
303
    >>> import dpnp as np
304
    >>> a = np.array([5, 3, 6, 2, 1])
305
    >>> np.sort_complex(a)
306
    array([1.+0.j, 2.+0.j, 3.+0.j, 5.+0.j, 6.+0.j])
307

308
    >>> a = np.array([1 + 2j, 2 - 1j, 3 - 2j, 3 - 3j, 3 + 5j])
309
    >>> np.sort_complex(a)
310
    array([1.+2.j, 2.-1.j, 3.-3.j, 3.-2.j, 3.+5.j])
311

312
    """
313

314
    b = dpnp.sort(a)
1✔
315
    if not dpnp.issubdtype(b.dtype, dpnp.complexfloating):
1✔
316
        if b.dtype.char in "bhBH":
1✔
317
            b_dt = dpnp.complex64
1✔
318
        else:
319
            b_dt = map_dtype_to_device(dpnp.complex128, b.sycl_device)
1✔
320
        return b.astype(b_dt)
1✔
321
    return b
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

© 2025 Coveralls, Inc