diff --git a/dpnp/backend/include/dpnp_iface_fptr.hpp b/dpnp/backend/include/dpnp_iface_fptr.hpp index 044135c1bc5..87826cc3bb9 100644 --- a/dpnp/backend/include/dpnp_iface_fptr.hpp +++ b/dpnp/backend/include/dpnp_iface_fptr.hpp @@ -78,8 +78,6 @@ enum class DPNPFuncName : size_t DPNP_FN_ARGMAX, /**< Used in numpy.argmax() impl */ DPNP_FN_ARGMIN, /**< Used in numpy.argmin() impl */ DPNP_FN_ARGSORT, /**< Used in numpy.argsort() impl */ - DPNP_FN_ARGSORT_EXT, /**< Used in numpy.argsort() impl, requires extra - parameters */ DPNP_FN_AROUND, /**< Used in numpy.around() impl */ DPNP_FN_ASTYPE, /**< Used in numpy.astype() impl */ DPNP_FN_BITWISE_AND, /**< Used in numpy.bitwise_and() impl */ @@ -357,9 +355,7 @@ enum class DPNPFuncName : size_t DPNP_FN_SIN, /**< Used in numpy.sin() impl */ DPNP_FN_SINH, /**< Used in numpy.sinh() impl */ DPNP_FN_SORT, /**< Used in numpy.sort() impl */ - DPNP_FN_SORT_EXT, /**< Used in numpy.sort() impl, requires extra parameters - */ - DPNP_FN_SQRT, /**< Used in numpy.sqrt() impl */ + DPNP_FN_SQRT, /**< Used in numpy.sqrt() impl */ DPNP_FN_SQRT_EXT, /**< Used in numpy.sqrt() impl, requires extra parameters */ DPNP_FN_SQUARE, /**< Used in numpy.square() impl */ diff --git a/dpnp/backend/kernels/dpnp_krnl_sorting.cpp b/dpnp/backend/kernels/dpnp_krnl_sorting.cpp index ac4992466e2..6f33c1af723 100644 --- a/dpnp/backend/kernels/dpnp_krnl_sorting.cpp +++ b/dpnp/backend/kernels/dpnp_krnl_sorting.cpp @@ -97,14 +97,6 @@ template void (*dpnp_argsort_default_c)(void *, void *, size_t) = dpnp_argsort_c<_DataType, _idx_DataType>; -template -DPCTLSyclEventRef (*dpnp_argsort_ext_c)(DPCTLSyclQueueRef, - void *, - void *, - size_t, - const DPCTLEventVectorRef) = - dpnp_argsort_c<_DataType, _idx_DataType>; - // template void dpnp_argsort_c(void* array1_in, void* result1, // size_t size); template void dpnp_argsort_c(void* array1_in, // void* result1, size_t size); template void dpnp_argsort_c(void* @@ -471,14 +463,6 @@ void dpnp_sort_c(void *array1_in, void *result1, size_t size) template void (*dpnp_sort_default_c)(void *, void *, size_t) = dpnp_sort_c<_DataType>; -template -DPCTLSyclEventRef (*dpnp_sort_ext_c)(DPCTLSyclQueueRef, - void *, - void *, - size_t, - const DPCTLEventVectorRef) = - dpnp_sort_c<_DataType>; - void func_map_init_sorting(func_map_t &fmap) { fmap[DPNPFuncName::DPNP_FN_ARGSORT][eft_INT][eft_INT] = { @@ -490,15 +474,6 @@ void func_map_init_sorting(func_map_t &fmap) fmap[DPNPFuncName::DPNP_FN_ARGSORT][eft_DBL][eft_DBL] = { eft_LNG, (void *)dpnp_argsort_default_c}; - fmap[DPNPFuncName::DPNP_FN_ARGSORT_EXT][eft_INT][eft_INT] = { - eft_LNG, (void *)dpnp_argsort_ext_c}; - fmap[DPNPFuncName::DPNP_FN_ARGSORT_EXT][eft_LNG][eft_LNG] = { - eft_LNG, (void *)dpnp_argsort_ext_c}; - fmap[DPNPFuncName::DPNP_FN_ARGSORT_EXT][eft_FLT][eft_FLT] = { - eft_LNG, (void *)dpnp_argsort_ext_c}; - fmap[DPNPFuncName::DPNP_FN_ARGSORT_EXT][eft_DBL][eft_DBL] = { - eft_LNG, (void *)dpnp_argsort_ext_c}; - fmap[DPNPFuncName::DPNP_FN_PARTITION][eft_INT][eft_INT] = { eft_INT, (void *)dpnp_partition_default_c}; fmap[DPNPFuncName::DPNP_FN_PARTITION][eft_LNG][eft_LNG] = { @@ -550,14 +525,5 @@ void func_map_init_sorting(func_map_t &fmap) fmap[DPNPFuncName::DPNP_FN_SORT][eft_DBL][eft_DBL] = { eft_DBL, (void *)dpnp_sort_default_c}; - fmap[DPNPFuncName::DPNP_FN_SORT_EXT][eft_INT][eft_INT] = { - eft_INT, (void *)dpnp_sort_ext_c}; - fmap[DPNPFuncName::DPNP_FN_SORT_EXT][eft_LNG][eft_LNG] = { - eft_LNG, (void *)dpnp_sort_ext_c}; - fmap[DPNPFuncName::DPNP_FN_SORT_EXT][eft_FLT][eft_FLT] = { - eft_FLT, (void *)dpnp_sort_ext_c}; - fmap[DPNPFuncName::DPNP_FN_SORT_EXT][eft_DBL][eft_DBL] = { - eft_DBL, (void *)dpnp_sort_ext_c}; - return; } diff --git a/dpnp/dpnp_algo/dpnp_algo.pxd b/dpnp/dpnp_algo/dpnp_algo.pxd index 76aee89231b..3fcb67aac9e 100644 --- a/dpnp/dpnp_algo/dpnp_algo.pxd +++ b/dpnp/dpnp_algo/dpnp_algo.pxd @@ -36,8 +36,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na DPNP_FN_ALLCLOSE DPNP_FN_ALLCLOSE_EXT DPNP_FN_ARANGE - DPNP_FN_ARGSORT - DPNP_FN_ARGSORT_EXT DPNP_FN_CHOOSE DPNP_FN_CHOOSE_EXT DPNP_FN_COPY @@ -175,8 +173,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na DPNP_FN_RNG_ZIPF_EXT DPNP_FN_SEARCHSORTED DPNP_FN_SEARCHSORTED_EXT - DPNP_FN_SORT - DPNP_FN_SORT_EXT DPNP_FN_SVD DPNP_FN_SVD_EXT DPNP_FN_TRACE @@ -309,12 +305,6 @@ cpdef dpnp_descriptor dpnp_fmin(dpnp_descriptor x1_obj, dpnp_descriptor x2_obj, dpnp_descriptor out=*, object where=*) -""" -Sorting functions -""" -cpdef dpnp_descriptor dpnp_argsort(dpnp_descriptor array1) -cpdef dpnp_descriptor dpnp_sort(dpnp_descriptor array1) - """ Trigonometric functions """ diff --git a/dpnp/dpnp_algo/dpnp_algo_sorting.pxi b/dpnp/dpnp_algo/dpnp_algo_sorting.pxi index c05ca603b0a..069b5335c1c 100644 --- a/dpnp/dpnp_algo/dpnp_algo_sorting.pxi +++ b/dpnp/dpnp_algo/dpnp_algo_sorting.pxi @@ -36,10 +36,8 @@ and the rest of the library # NO IMPORTs here. All imports must be placed into main "dpnp_algo.pyx" file __all__ += [ - "dpnp_argsort", "dpnp_partition", "dpnp_searchsorted", - "dpnp_sort" ] @@ -61,13 +59,6 @@ ctypedef c_dpctl.DPCTLSyclEventRef(*fptr_dpnp_searchsorted_t)(c_dpctl.DPCTLSyclQ const c_dpctl.DPCTLEventVectorRef) -cpdef utils.dpnp_descriptor dpnp_argsort(utils.dpnp_descriptor x1): - cdef shape_type_c result_shape = x1.shape - if result_shape == (): - result_shape = (1,) - return call_fptr_1in_1out(DPNP_FN_ARGSORT_EXT, x1, result_shape) - - cpdef utils.dpnp_descriptor dpnp_partition(utils.dpnp_descriptor arr, int kth, axis=-1, kind='introselect', order=None): cdef shape_type_c shape1 = arr.shape @@ -148,7 +139,3 @@ cpdef utils.dpnp_descriptor dpnp_searchsorted(utils.dpnp_descriptor arr, utils.d c_dpctl.DPCTLEvent_Delete(event_ref) return result - - -cpdef utils.dpnp_descriptor dpnp_sort(utils.dpnp_descriptor x1): - return call_fptr_1in_1out(DPNP_FN_SORT_EXT, x1, x1.shape) diff --git a/dpnp/dpnp_array.py b/dpnp/dpnp_array.py index ec8a93c335f..cf848b50690 100644 --- a/dpnp/dpnp_array.py +++ b/dpnp/dpnp_array.py @@ -510,39 +510,7 @@ def argsort(self, axis=-1, kind=None, order=None): """ Return an ndarray of indices that sort the array along the specified axis. - Parameters - ---------- - axis : int, optional - Axis along which to sort. If None, the default, the flattened array - is used. - .. versionchanged:: 1.13.0 - Previously, the default was documented to be -1, but that was - in error. At some future date, the default will change to -1, as - originally intended. - Until then, the axis should be given explicitly when - ``arr.ndim > 1``, to avoid a FutureWarning. - kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional - The sorting algorithm used. - order : list, optional - When `a` is an array with fields defined, this argument specifies - which fields to compare first, second, etc. Not all fields need be - specified. - - Returns - ------- - index_array : ndarray, int - Array of indices that sort `a` along the specified axis. - In other words, ``a[index_array]`` yields a sorted `a`. - - See Also - -------- - MaskedArray.sort : Describes sorting algorithms used. - :obj:`dpnp.lexsort` : Indirect stable sort with multiple keys. - :obj:`numpy.ndarray.sort` : Inplace sort. - - Notes - ----- - See `sort` for notes on the different sorting algorithms. + Refer to :obj:`dpnp.argsort` for full documentation. """ return dpnp.argsort(self, axis, kind, order) @@ -1163,14 +1131,44 @@ def size(self): return self._array_obj.size - # 'sort', + def sort(self, axis=-1, kind=None, order=None): + """ + Sort an array in-place. + + Refer to :obj:`dpnp.sort` for full documentation. + + Note + ---- + `axis` in :obj:`dpnp.sort` could be integr or ``None``. If ``None``, + the array is flattened before sorting. However, `axis` in :obj:`dpnp.ndarray.sort` + can only be integer since it sorts an array in-place. + + Examples + -------- + >>> import dpnp as np + >>> a = np.array([[1,4],[3,1]]) + >>> a.sort(axis=1) + >>> a + array([[1, 4], + [1, 3]]) + >>> a.sort(axis=0) + >>> a + array([[1, 1], + [3, 4]]) + + """ + + if axis is None: + raise TypeError( + "'NoneType' object cannot be interpreted as an integer" + ) + self[...] = dpnp.sort(self, axis=axis, kind=kind, order=order) def squeeze(self, axis=None): """ Remove single-dimensional entries from the shape of an array. - .. seealso:: - :obj:`dpnp.squeeze` for full documentation + Refer to :obj:`dpnp.squeeze` for full documentation """ diff --git a/dpnp/dpnp_iface_indexing.py b/dpnp/dpnp_iface_indexing.py index 20a4a60a5bc..8f973ed1f1a 100644 --- a/dpnp/dpnp_iface_indexing.py +++ b/dpnp/dpnp_iface_indexing.py @@ -851,6 +851,7 @@ def take_along_axis(a, indices, axis): -------- :obj:`dpnp.take` : Take along an axis, using the same indices for every 1d slice. :obj:`dpnp.put_along_axis` : Put values into the destination array by matching 1d index and data slices. + :obj:`dpnp.argsort` : Return the indices that would sort an array. Examples -------- diff --git a/dpnp/dpnp_iface_mathematical.py b/dpnp/dpnp_iface_mathematical.py index 7ed945ee6c2..91a8a2569d5 100644 --- a/dpnp/dpnp_iface_mathematical.py +++ b/dpnp/dpnp_iface_mathematical.py @@ -2709,7 +2709,7 @@ def sum( Parameters ---------- - a : {dpnp.ndarray, usm_ndarray}: + a : {dpnp.ndarray, usm_ndarray} Input array. axis : int or tuple of ints, optional Axis or axes along which sums must be computed. If a tuple @@ -2762,7 +2762,7 @@ def sum( Limitations ----------- - Parameters `initial` and `where` are supported with their default values. + Parameters `initial` and `where` are only supported with their default values. Otherwise ``NotImplementedError`` exception will be raised. See Also diff --git a/dpnp/dpnp_iface_nanfunctions.py b/dpnp/dpnp_iface_nanfunctions.py index dda0e0bd2c7..fbaa06603d5 100644 --- a/dpnp/dpnp_iface_nanfunctions.py +++ b/dpnp/dpnp_iface_nanfunctions.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # ***************************************************************************** -# Copyright (c) 2016-2024, Intel Corporation +# Copyright (c) 2023-2024, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -415,7 +415,7 @@ def nanmean(a, axis=None, dtype=None, out=None, keepdims=False, *, where=True): Parameters ---------- - a : {dpnp.ndarray, usm_ndarray}: + a : {dpnp.ndarray, usm_ndarray} Input array. axis : int or tuple of ints, optional Axis or axes along which the arithmetic means must be computed. If @@ -696,7 +696,7 @@ def nansum( Parameters ---------- - a : {dpnp.ndarray, usm_ndarray}: + a : {dpnp.ndarray, usm_ndarray} Input array. axis : int or tuple of ints, optional Axis or axes along which sums must be computed. If a tuple @@ -806,7 +806,7 @@ def nanstd( Parameters ---------- - a : {dpnp.ndarray, usm_ndarray}: + a : {dpnp.ndarray, usm_ndarray} Input array. axis : int or tuple of ints, optional Axis or axes along which the standard deviations must be computed. @@ -908,7 +908,7 @@ def nanvar( Parameters ---------- - a : {dpnp.ndarray, usm_ndarray}: + a : {dpnp_array, usm_ndarray} Input array. axis : int or tuple of ints, optional axis or axes along which the variances must be computed. If a tuple diff --git a/dpnp/dpnp_iface_sorting.py b/dpnp/dpnp_iface_sorting.py index c34b97ac21c..6a3db20e74c 100644 --- a/dpnp/dpnp_iface_sorting.py +++ b/dpnp/dpnp_iface_sorting.py @@ -40,33 +40,60 @@ """ +import dpctl.tensor as dpt import numpy +from numpy.core.numeric import normalize_axis_index import dpnp from dpnp.dpnp_algo import * +from dpnp.dpnp_array import dpnp_array from dpnp.dpnp_utils import * __all__ = ["argsort", "partition", "searchsorted", "sort"] -def argsort(in_array1, axis=-1, kind=None, order=None): +def argsort(a, axis=-1, kind=None, order=None): """ Returns the indices that would sort an array. For full documentation refer to :obj:`numpy.argsort`. + Parameters + ---------- + a : {dpnp.ndarray, usm_ndarray} + Array to be sorted. + axis : int or None, optional + Axis along which to sort. If ``None``, the array is flattened before + sorting. The default is -1, which sorts along the last axis. + kind : {None, "stable"}, optional + Default is ``None``, which is equivalent to `"stable"`. + Unlike in NumPy any other options are not accepted here. + + Returns + ------- + out : dpnp.ndarray + Array of indices that sort `a` along the specified `axis`. + If `a` is one-dimensional, ``a[index_array]`` yields a sorted `a`. + More generally, ``dpnp.take_along_axis(a, index_array, axis=axis)`` + always yields the sorted `a`, irrespective of dimensionality. + The return array has default array index data type. + + Notes + ----- + For zero-dimensional arrays, if `axis=None`, output is a one-dimensional + array with a single zero element. Otherwise, an ``AxisError`` is raised. + Limitations ----------- - Input array is supported as :obj:`dpnp.ndarray`. - Otherwise the function will be executed sequentially on CPU. - Parameter `axis` is supported only with default value ``-1``. - Parameter `kind` is supported only with default value ``None``. - Parameter `order` is supported only with default value ``None``. - Input array data types are limited by supported DPNP :ref:`Data types`. + Parameters `order` is only supported with its default value. + Parameters `kind` can only be ``None`` or ``"stable"`` which + are equivalent. + Otherwise ``NotImplementedError`` exception will be raised. See Also -------- - :obj:`dpnp.sort` : Describes sorting algorithms used. + :obj:`dpnp.ndarray.argsort` : Equivalent method. + :obj:`dpnp.sort` : Return a sorted copy of an array. :obj:`dpnp.lexsort` : Indirect stable sort with multiple keys. :obj:`dpnp.argpartition` : Indirect partial sort. :obj:`dpnp.take_along_axis` : Apply ``index_array`` from argsort to @@ -76,26 +103,50 @@ def argsort(in_array1, axis=-1, kind=None, order=None): -------- >>> import dpnp as np >>> x = np.array([3, 1, 2]) - >>> out = np.argsort(x) - >>> [i for i in out] - [1, 2, 0] + >>> np.argsort(x) + array([1, 2, 0]) + + >>> x = np.array([[0, 3], [2, 2]]) + >>> x + array([[0, 3], + [2, 2]]) + + >>> ind = np.argsort(x, axis=0) # sorts along first axis + >>> ind + array([[0, 1], + [1, 0]]) + >>> np.take_along_axis(x, ind, axis=0) # same as np.sort(x, axis=0) + array([[0, 2], + [2, 3]]) + + >>> ind = np.argsort(x, axis=1) # sorts along last axis + >>> ind + array([[0, 1], + [0, 1]]) + >>> np.take_along_axis(x, ind, axis=1) # same as np.sort(x, axis=1) + array([[0, 3], + [2, 2]]) """ - x1_desc = dpnp.get_dpnp_descriptor( - in_array1, copy_when_nondefault_queue=False - ) - if x1_desc: - if axis != -1: - pass - elif kind is not None: - pass - elif order is not None: - pass - else: - return dpnp_argsort(x1_desc).get_pyobj() - - return call_origin(numpy.argsort, in_array1, axis, kind, order) + if order is not None: + raise NotImplementedError( + "order keyword argument is only supported with its default value." + ) + elif kind is not None and kind != "stable": + raise NotImplementedError( + "kind keyword argument can only be None or 'stable'." + ) + else: + dpnp.check_supported_arrays_type(a) + if axis is None: + a = a.flatten() + axis = -1 + + axis = normalize_axis_index(axis, ndim=a.ndim) + return dpnp_array._create_from_usm_ndarray( + dpt.argsort(dpnp.get_usm_ndarray(a), axis=axis) + ) def partition(x1, kth, axis=-1, kind="introselect", order=None): @@ -166,23 +217,44 @@ def searchsorted(x1, x2, side="left", sorter=None): return call_origin(numpy.searchsorted, x1, x2, side=side, sorter=sorter) -def sort(x1, **kwargs): +def sort(a, axis=-1, kind=None, order=None): """ Return a sorted copy of an array. For full documentation refer to :obj:`numpy.sort`. + Parameters + ---------- + a : {dpnp.ndarray, usm_ndarray} + Array to be sorted. + axis : int or None, optional + Axis along which to sort. If ``None``, the array is flattened before + sorting. The default is -1, which sorts along the last axis. + kind : {None, "stable"}, optional + Default is ``None``, which is equivalent to `"stable"`. + Unlike in NumPy any other options are not accepted here. + + Returns + ------- + out : dpnp.ndarray + Sorted array with the same type and shape as `a`. + + Notes + ----- + For zero-dimensional arrays, if `axis=None`, output is the input array + returned as a one-dimensional array. Otherwise, an ``AxisError`` is raised. + Limitations ----------- - Input array is supported as :obj:`dpnp.ndarray`. - Keyword arguments ``kwargs`` are currently unsupported. - Dimension of input array is supported to be equal to ``1``. - Otherwise the function will be executed sequentially on CPU. - Input array data types are limited by supported DPNP :ref:`Data types`. + Parameters `order` is only supported with its default value. + Parameters `kind` can only be ``None`` or ``"stable"`` which + are equivalent. + Otherwise ``NotImplementedError`` exception will be raised. See Also -------- - :obj:`dpnp.argsort` : Indirect sort. + :obj:`dpnp.ndarray.sort` : Sort an array in-place. + :obj:`dpnp.argsort` : Return the indices that would sort an array. :obj:`dpnp.lexsort` : Indirect stable sort on multiple keys. :obj:`dpnp.searchsorted` : Find elements in a sorted array. :obj:`dpnp.partition` : Partial sort. @@ -190,18 +262,33 @@ def sort(x1, **kwargs): Examples -------- >>> import dpnp as np - >>> a = np.array([1, 4, 3, 1]) - >>> out = np.sort(a) - >>> [i for i in out] - [1, 1, 3, 4] + >>> a = np.array([[1,4],[3,1]]) + >>> np.sort(a) # sort along the last axis + array([[1, 4], + [1, 3]]) + >>> np.sort(a, axis=None) # sort the flattened array + array([1, 1, 3, 4]) + >>> np.sort(a, axis=0) # sort along the first axis + array([[1, 1], + [3, 4]]) """ - x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_nondefault_queue=False) - if x1_desc and not kwargs: - if x1_desc.ndim != 1: - pass - else: - return dpnp_sort(x1_desc).get_pyobj() - - return call_origin(numpy.sort, x1, **kwargs) + if order is not None: + raise NotImplementedError( + "order keyword argument is only supported with its default value." + ) + elif kind is not None and kind != "stable": + raise NotImplementedError( + "kind keyword argument can only be None or 'stable'." + ) + else: + dpnp.check_supported_arrays_type(a) + if axis is None: + a = a.flatten() + axis = -1 + + axis = normalize_axis_index(axis, ndim=a.ndim) + return dpnp_array._create_from_usm_ndarray( + dpt.sort(dpnp.get_usm_ndarray(a), axis=axis) + ) diff --git a/dpnp/dpnp_iface_statistics.py b/dpnp/dpnp_iface_statistics.py index 2568acd71f1..903de2d69e9 100644 --- a/dpnp/dpnp_iface_statistics.py +++ b/dpnp/dpnp_iface_statistics.py @@ -151,7 +151,7 @@ def average(a, axis=None, weights=None, returned=False, *, keepdims=False): Parameters ---------- - a : {dpnp.ndarray, usm_ndarray}: + a : {dpnp.ndarray, usm_ndarray} Input array. axis : int or tuple of ints, optional Axis or axes along which the averages must be computed. If @@ -573,7 +573,7 @@ def mean(a, /, axis=None, dtype=None, out=None, keepdims=False, *, where=True): Parameters ---------- - a : {dpnp.ndarray, usm_ndarray}: + a : {dpnp.ndarray, usm_ndarray} Input array. axis : int or tuple of ints, optional Axis or axes along which the arithmetic means must be computed. If @@ -839,7 +839,7 @@ def std( Parameters ---------- - a : {dpnp_array, usm_ndarray}: + a : {dpnp_array, usm_ndarray} Input array. axis : int or tuple of ints, optional Axis or axes along which the standard deviations must be computed. @@ -958,7 +958,7 @@ def var( Parameters ---------- - a : {dpnp.ndarray, usm_ndarray}: + a : {dpnp_array, usm_ndarray} Input array. axis : int or tuple of ints, optional axis or axes along which the variances must be computed. If a tuple diff --git a/tests/skipped_tests.tbl b/tests/skipped_tests.tbl index bc79f538a5e..8eb46d3c983 100644 --- a/tests/skipped_tests.tbl +++ b/tests/skipped_tests.tbl @@ -755,6 +755,7 @@ tests/third_party/cupy/sorting_tests/test_search.py::TestFlatNonzero_param_3_{ar tests/third_party/cupy/sorting_tests/test_search.py::TestFlatNonzero_param_4_{array=array([], shape=(0, 2, 0), dtype=float64)}::test_flatnonzero tests/third_party/cupy/sorting_tests/test_search.py::TestNonzeroZeroDimension_param_0_{array=array(0)}::test_nonzero tests/third_party/cupy/sorting_tests/test_search.py::TestNonzeroZeroDimension_param_1_{array=array(1)}::test_nonzero + tests/third_party/cupy/sorting_tests/test_sort.py::TestArgpartition_param_0_{external=False}::test_argpartition_axis tests/third_party/cupy/sorting_tests/test_sort.py::TestArgpartition_param_0_{external=False}::test_argpartition_invalid_axis1 tests/third_party/cupy/sorting_tests/test_sort.py::TestArgpartition_param_0_{external=False}::test_argpartition_invalid_axis2 @@ -785,36 +786,6 @@ tests/third_party/cupy/sorting_tests/test_sort.py::TestArgpartition_param_1_{ext tests/third_party/cupy/sorting_tests/test_sort.py::TestArgpartition_param_1_{external=True}::test_argpartition_one_dim tests/third_party/cupy/sorting_tests/test_sort.py::TestArgpartition_param_1_{external=True}::test_argpartition_sequence_kth tests/third_party/cupy/sorting_tests/test_sort.py::TestArgpartition_param_1_{external=True}::test_argpartition_zero_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_invalid_axis1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_invalid_axis2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_invalid_negative_axis1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_invalid_negative_axis2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_multi_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_negative_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_none_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_zero_dim_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_zero_dim_invalid_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_nan1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_nan2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_invalid_axis1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_invalid_axis2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_invalid_negative_axis1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_invalid_negative_axis2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_multi_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_negative_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_none_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_zero_dim_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_zero_dim_invalid_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_nan1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_nan2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_non_contiguous -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_one_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_original_array_not_modified_multi_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_original_array_not_modified_one_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_zero_dim - tests/third_party/cupy/sorting_tests/test_sort.py::TestLexsort::test_F_order tests/third_party/cupy/sorting_tests/test_sort.py::TestLexsort::test_lexsort_dtype tests/third_party/cupy/sorting_tests/test_sort.py::TestLexsort::test_lexsort_three_or_more_dim @@ -824,29 +795,11 @@ tests/third_party/cupy/sorting_tests/test_sort.py::TestLexsort::test_nan3 tests/third_party/cupy/sorting_tests/test_sort.py::TestLexsort::test_view tests/third_party/cupy/sorting_tests/test_sort.py::TestMsort::test_msort_multi_dim tests/third_party/cupy/sorting_tests/test_sort.py::TestMsort::test_msort_one_dim - tests/third_party/cupy/sorting_tests/test_sort.py::TestSort_complex::test_sort_complex_1dim tests/third_party/cupy/sorting_tests/test_sort.py::TestSort_complex::test_sort_complex_nan tests/third_party/cupy/sorting_tests/test_sort.py::TestSort_complex::test_sort_complex_ndim tests/third_party/cupy/sorting_tests/test_sort.py::TestSort_complex::test_sort_complex_zero_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_external_sort_zero_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_nan1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_nan2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_nan3 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_nan4 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_axis1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_axis2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_axis3 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_contiguous -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_dtype -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_invalid_axis1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_invalid_axis2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_invalid_negative_axis1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_invalid_negative_axis2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_negative_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_non_contiguous -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_two_or_more_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_zero_dim + tests/third_party/cupy/statistics_tests/test_correlation.py::TestCorrcoef::test_corrcoef tests/third_party/cupy/statistics_tests/test_correlation.py::TestCorrcoef::test_corrcoef_diag_exception tests/third_party/cupy/statistics_tests/test_correlation.py::TestCorrcoef::test_corrcoef_rowvar diff --git a/tests/skipped_tests_gpu.tbl b/tests/skipped_tests_gpu.tbl index 3770c0fa9b9..b8c195b9861 100644 --- a/tests/skipped_tests_gpu.tbl +++ b/tests/skipped_tests_gpu.tbl @@ -817,6 +817,7 @@ tests/third_party/cupy/sorting_tests/test_search.py::TestFlatNonzero_param_3_{ar tests/third_party/cupy/sorting_tests/test_search.py::TestFlatNonzero_param_4_{array=array([], shape=(0, 2, 0), dtype=float64)}::test_flatnonzero tests/third_party/cupy/sorting_tests/test_search.py::TestNonzeroZeroDimension_param_0_{array=array(0)}::test_nonzero tests/third_party/cupy/sorting_tests/test_search.py::TestNonzeroZeroDimension_param_1_{array=array(1)}::test_nonzero + tests/third_party/cupy/sorting_tests/test_sort.py::TestArgpartition_param_0_{external=False}::test_argpartition_axis tests/third_party/cupy/sorting_tests/test_sort.py::TestArgpartition_param_0_{external=False}::test_argpartition_invalid_axis1 tests/third_party/cupy/sorting_tests/test_sort.py::TestArgpartition_param_0_{external=False}::test_argpartition_invalid_axis2 @@ -847,36 +848,6 @@ tests/third_party/cupy/sorting_tests/test_sort.py::TestArgpartition_param_1_{ext tests/third_party/cupy/sorting_tests/test_sort.py::TestArgpartition_param_1_{external=True}::test_argpartition_one_dim tests/third_party/cupy/sorting_tests/test_sort.py::TestArgpartition_param_1_{external=True}::test_argpartition_sequence_kth tests/third_party/cupy/sorting_tests/test_sort.py::TestArgpartition_param_1_{external=True}::test_argpartition_zero_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_invalid_axis1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_invalid_axis2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_invalid_negative_axis1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_invalid_negative_axis2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_multi_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_negative_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_none_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_zero_dim_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_zero_dim_invalid_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_nan1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_nan2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_invalid_axis1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_invalid_axis2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_invalid_negative_axis1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_invalid_negative_axis2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_multi_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_negative_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_none_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_zero_dim_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_argsort_zero_dim_invalid_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_nan1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_1_{external=True}::test_nan2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_non_contiguous -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_one_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_original_array_not_modified_multi_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_original_array_not_modified_one_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestArgsort_param_0_{external=False}::test_argsort_zero_dim - tests/third_party/cupy/sorting_tests/test_sort.py::TestLexsort::test_F_order tests/third_party/cupy/sorting_tests/test_sort.py::TestLexsort::test_lexsort_dtype tests/third_party/cupy/sorting_tests/test_sort.py::TestLexsort::test_lexsort_three_or_more_dim @@ -886,29 +857,11 @@ tests/third_party/cupy/sorting_tests/test_sort.py::TestLexsort::test_nan3 tests/third_party/cupy/sorting_tests/test_sort.py::TestLexsort::test_view tests/third_party/cupy/sorting_tests/test_sort.py::TestMsort::test_msort_multi_dim tests/third_party/cupy/sorting_tests/test_sort.py::TestMsort::test_msort_one_dim - tests/third_party/cupy/sorting_tests/test_sort.py::TestSort_complex::test_sort_complex_1dim tests/third_party/cupy/sorting_tests/test_sort.py::TestSort_complex::test_sort_complex_nan tests/third_party/cupy/sorting_tests/test_sort.py::TestSort_complex::test_sort_complex_ndim tests/third_party/cupy/sorting_tests/test_sort.py::TestSort_complex::test_sort_complex_zero_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_external_sort_zero_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_nan1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_nan2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_nan3 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_nan4 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_axis1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_axis2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_axis3 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_contiguous -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_dtype -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_invalid_axis1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_invalid_axis2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_invalid_negative_axis1 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_invalid_negative_axis2 -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_negative_axis -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_non_contiguous -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_two_or_more_dim -tests/third_party/cupy/sorting_tests/test_sort.py::TestSort::test_sort_zero_dim + tests/third_party/cupy/statistics_tests/test_correlation.py::TestCorrcoef::test_corrcoef tests/third_party/cupy/statistics_tests/test_correlation.py::TestCorrcoef::test_corrcoef_diag_exception tests/third_party/cupy/statistics_tests/test_correlation.py::TestCorrcoef::test_corrcoef_rowvar diff --git a/tests/test_indexing.py b/tests/test_indexing.py index 01e5c33f8ef..2640eb64c49 100644 --- a/tests/test_indexing.py +++ b/tests/test_indexing.py @@ -154,8 +154,6 @@ def test_broadcast(self, arr_dt, idx_dt): class TestTakeAlongAxis: - # TODO: remove fixture once `dpnp.sort` is fully implemented - @pytest.mark.usefixtures("allow_fall_back_on_numpy") @pytest.mark.parametrize( "func, argfunc, kwargs", [ diff --git a/tests/test_sort.py b/tests/test_sort.py index 7ef6c23f734..768870f1632 100644 --- a/tests/test_sort.py +++ b/tests/test_sort.py @@ -4,7 +4,161 @@ import dpnp -from .helper import get_all_dtypes +from .helper import assert_dtype_allclose, get_all_dtypes, get_complex_dtypes + + +class TestSort: + @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) + def test_sort_dtype(self, dtype): + a = numpy.random.uniform(-5, 5, 10) + np_array = numpy.array(a, dtype=dtype) + dp_array = dpnp.array(np_array) + + result = dpnp.sort(dp_array) + expected = numpy.sort(np_array) + assert_dtype_allclose(result, expected) + + @pytest.mark.parametrize("dtype", get_complex_dtypes()) + def test_sort_complex(self, dtype): + a = numpy.random.uniform(-5, 5, 10) + b = numpy.random.uniform(-5, 5, 10) + np_array = numpy.array(a + b * 1j, dtype=dtype) + dp_array = dpnp.array(np_array) + + result = dpnp.sort(dp_array) + expected = numpy.sort(np_array) + assert_dtype_allclose(result, expected) + + @pytest.mark.parametrize("axis", [None, -2, -1, 0, 1, 2]) + def test_sort_axis(self, axis): + a = numpy.random.uniform(-10, 10, 36) + np_array = numpy.array(a).reshape(3, 4, 3) + dp_array = dpnp.array(np_array) + + result = dpnp.sort(dp_array, axis=axis) + expected = numpy.sort(np_array, axis=axis) + assert_dtype_allclose(result, expected) + + @pytest.mark.parametrize("dtype", get_all_dtypes()) + @pytest.mark.parametrize("axis", [-2, -1, 0, 1]) + def test_sort_ndarray(self, dtype, axis): + a = numpy.random.uniform(-10, 10, 12) + np_array = numpy.array(a, dtype=dtype).reshape(6, 2) + dp_array = dpnp.array(np_array) + + dp_array.sort(axis=axis) + np_array.sort(axis=axis) + assert_dtype_allclose(dp_array, np_array) + + def test_sort_stable(self): + np_array = numpy.repeat(numpy.arange(10), 10) + dp_array = dpnp.array(np_array) + + result = dpnp.sort(dp_array, kind="stable") + expected = numpy.sort(np_array, kind="stable") + assert_dtype_allclose(result, expected) + + def test_sort_ndarray_axis_none(self): + a = numpy.random.uniform(-10, 10, 12) + dp_array = dpnp.array(a).reshape(6, 2) + with pytest.raises(TypeError): + dp_array.sort(axis=None) + + def test_sort_zero_dim(self): + np_array = numpy.array(2.5) + dp_array = dpnp.array(np_array) + + # with default axis=-1 + with pytest.raises(numpy.AxisError): + dpnp.sort(dp_array) + + # with axis = None + result = dpnp.sort(dp_array, axis=None) + expected = numpy.sort(np_array, axis=None) + assert_dtype_allclose(result, expected) + + def test_sort_notimplemented(self): + dp_array = dpnp.arange(10) + + with pytest.raises(NotImplementedError): + dpnp.sort(dp_array, kind="quicksort") + + with pytest.raises(NotImplementedError): + dpnp.sort(dp_array, order=["age"]) + + +class TestArgsort: + @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) + def test_argsort_dtype(self, dtype): + a = numpy.random.uniform(-5, 5, 10) + np_array = numpy.array(a, dtype=dtype) + dp_array = dpnp.array(np_array) + + result = dpnp.argsort(dp_array) + expected = numpy.argsort(np_array) + assert_dtype_allclose(result, expected) + + @pytest.mark.parametrize("dtype", get_complex_dtypes()) + def test_argsort_complex(self, dtype): + a = numpy.random.uniform(-5, 5, 10) + b = numpy.random.uniform(-5, 5, 10) + np_array = numpy.array(a + b * 1j, dtype=dtype) + dp_array = dpnp.array(np_array) + + result = dpnp.argsort(dp_array) + expected = numpy.argsort(np_array) + assert_dtype_allclose(result, expected) + + @pytest.mark.parametrize("axis", [None, -2, -1, 0, 1, 2]) + def test_argsort_axis(self, axis): + a = numpy.random.uniform(-10, 10, 36) + np_array = numpy.array(a).reshape(3, 4, 3) + dp_array = dpnp.array(np_array) + + result = dpnp.argsort(dp_array, axis=axis) + expected = numpy.argsort(np_array, axis=axis) + assert_dtype_allclose(result, expected) + + @pytest.mark.parametrize("dtype", get_all_dtypes()) + @pytest.mark.parametrize("axis", [None, -2, -1, 0, 1]) + def test_argsort_ndarray(self, dtype, axis): + a = numpy.random.uniform(-10, 10, 12) + np_array = numpy.array(a, dtype=dtype).reshape(6, 2) + dp_array = dpnp.array(np_array) + + result = dp_array.argsort(axis=axis) + expected = np_array.argsort(axis=axis) + assert_dtype_allclose(result, expected) + + def test_argsort_stable(self): + np_array = numpy.repeat(numpy.arange(10), 10) + dp_array = dpnp.array(np_array) + + result = dpnp.argsort(dp_array, kind="stable") + expected = numpy.argsort(np_array, kind="stable") + assert_dtype_allclose(result, expected) + + def test_argsort_zero_dim(self): + np_array = numpy.array(2.5) + dp_array = dpnp.array(np_array) + + # with default axis=-1 + with pytest.raises(numpy.AxisError): + dpnp.argsort(dp_array) + + # with axis = None + result = dpnp.argsort(dp_array, axis=None) + expected = numpy.argsort(np_array, axis=None) + assert_dtype_allclose(result, expected) + + def test_sort_notimplemented(self): + dp_array = dpnp.arange(10) + + with pytest.raises(NotImplementedError): + dpnp.argsort(dp_array, kind="quicksort") + + with pytest.raises(NotImplementedError): + dpnp.argsort(dp_array, order=["age"]) @pytest.mark.parametrize("kth", [0, 1], ids=["0", "1"]) diff --git a/tests/test_strides.py b/tests/test_strides.py index eb8a89698ec..6fe28281fc6 100644 --- a/tests/test_strides.py +++ b/tests/test_strides.py @@ -55,6 +55,7 @@ def test_strides(func_name, dtype): "arcsinh", "arctan", "arctanh", + "argsort", "cbrt", "ceil", "copy", @@ -78,6 +79,7 @@ def test_strides(func_name, dtype): "sign", "sin", "sinh", + "sort", "sqrt", "square", "tan", diff --git a/tests/test_sycl_queue.py b/tests/test_sycl_queue.py index 273b9685678..ee247aa5414 100644 --- a/tests/test_sycl_queue.py +++ b/tests/test_sycl_queue.py @@ -342,6 +342,7 @@ def test_meshgrid(device_x, device_y): pytest.param("arctanh", [-0.5, 0.0, 0.5]), pytest.param("argmax", [1.0, 2.0, 4.0, 7.0]), pytest.param("argmin", [1.0, 2.0, 4.0, 7.0]), + pytest.param("argsort", [2.0, 1.0, 7.0, 4.0]), pytest.param("cbrt", [1.0, 8.0, 27.0]), pytest.param("ceil", [-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]), pytest.param("conjugate", [[1.0 + 1.0j, 0.0], [0.0, 1.0 + 1.0j]]), @@ -396,7 +397,9 @@ def test_meshgrid(device_x, device_y): "sin", [-dpnp.pi / 2, -dpnp.pi / 4, 0.0, dpnp.pi / 4, dpnp.pi / 2] ), pytest.param("sinh", [-5.0, -3.5, 0.0, 3.5, 5.0]), + pytest.param("sort", [2.0, 1.0, 7.0, 4.0]), pytest.param("sqrt", [1.0, 3.0, 9.0]), + pytest.param("square", [1.0, 3.0, 9.0]), pytest.param("std", [1.0, 2.0, 4.0, 7.0]), pytest.param("sum", [1.0, 2.0]), pytest.param( diff --git a/tests/test_usm_type.py b/tests/test_usm_type.py index 37f9c2f27b3..554f939b208 100644 --- a/tests/test_usm_type.py +++ b/tests/test_usm_type.py @@ -409,6 +409,7 @@ def test_meshgrid(usm_type_x, usm_type_y): pytest.param("arctanh", [-0.5, 0.0, 0.5]), pytest.param("argmax", [1.0, 2.0, 4.0, 7.0]), pytest.param("argmin", [1.0, 2.0, 4.0, 7.0]), + pytest.param("argsort", [2.0, 1.0, 7.0, 4.0]), pytest.param("cbrt", [1, 8, 27]), pytest.param("ceil", [-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]), pytest.param("conjugate", [[1.0 + 1.0j, 0.0], [0.0, 1.0 + 1.0j]]), @@ -459,8 +460,11 @@ def test_meshgrid(usm_type_x, usm_type_y): "sin", [-dp.pi / 2, -dp.pi / 4, 0.0, dp.pi / 4, dp.pi / 2] ), pytest.param("sinh", [-5.0, -3.5, 0.0, 3.5, 5.0]), + pytest.param("sort", [2.0, 1.0, 7.0, 4.0]), pytest.param("sqrt", [1.0, 3.0, 9.0]), + pytest.param("square", [1.0, 3.0, 9.0]), pytest.param("std", [1.0, 2.0, 4.0, 7.0]), + pytest.param("sum", [1.0, 2.0]), pytest.param( "tan", [-dp.pi / 2, -dp.pi / 4, 0.0, dp.pi / 4, dp.pi / 2] ), diff --git a/tests/third_party/cupy/sorting_tests/test_sort.py b/tests/third_party/cupy/sorting_tests/test_sort.py index 7ae7911f90e..bef8859ba7b 100644 --- a/tests/third_party/cupy/sorting_tests/test_sort.py +++ b/tests/third_party/cupy/sorting_tests/test_sort.py @@ -17,7 +17,6 @@ def get_array_module(*args): cupy.get_array_module = get_array_module -@testing.gpu class TestSort(unittest.TestCase): # Test ranks @@ -33,14 +32,12 @@ def test_external_sort_zero_dim(self): with pytest.raises(numpy.AxisError): xp.sort(a) - @pytest.mark.usefixtures("allow_fall_back_on_numpy") @testing.numpy_cupy_array_equal() def test_sort_two_or_more_dim(self, xp): a = testing.shaped_random((2, 3, 3), xp) a.sort() return a - @pytest.mark.usefixtures("allow_fall_back_on_numpy") @testing.numpy_cupy_array_equal() def test_external_sort_two_or_more_dim(self, xp): a = testing.shaped_random((2, 3, 3), xp) @@ -69,10 +66,11 @@ def test_sort_contiguous(self, xp): a.sort() return a - def test_sort_non_contiguous(self): - a = testing.shaped_random((10,), cupy)[::2] # Non contiguous view - with self.assertRaises(NotImplementedError): - a.sort() + @testing.numpy_cupy_array_equal() + def test_sort_non_contiguous(self, xp): + a = testing.shaped_random((10,), xp)[::2] # Non contiguous view + a.sort() + return a @testing.numpy_cupy_array_equal() def test_external_sort_contiguous(self, xp): @@ -104,7 +102,6 @@ def test_sort_axis3(self, xp): a.sort(axis=2) return a - @pytest.mark.usefixtures("allow_fall_back_on_numpy") @testing.numpy_cupy_array_equal() def test_external_sort_axis(self, xp): a = testing.shaped_random((2, 3, 3), xp) @@ -116,13 +113,11 @@ def test_sort_negative_axis(self, xp): a.sort(axis=-2) return a - @pytest.mark.usefixtures("allow_fall_back_on_numpy") @testing.numpy_cupy_array_equal() def test_external_sort_negative_axis(self, xp): a = testing.shaped_random((2, 3, 3), xp) return xp.sort(a, axis=-2) - @pytest.mark.usefixtures("allow_fall_back_on_numpy") @testing.numpy_cupy_array_equal() def test_external_sort_none_axis(self, xp): a = testing.shaped_random((2, 3, 3), xp) @@ -139,14 +134,12 @@ def test_sort_invalid_axis2(self): with self.assertRaises(numpy.AxisError): a.sort(axis=3) - @pytest.mark.usefixtures("allow_fall_back_on_numpy") def test_external_sort_invalid_axis1(self): for xp in (numpy, cupy): a = testing.shaped_random((2, 3, 3), xp) with pytest.raises(numpy.AxisError): xp.sort(a, axis=3) - @pytest.mark.usefixtures("allow_fall_back_on_numpy") def test_external_sort_invalid_axis2(self): a = testing.shaped_random((2, 3, 3), cupy) with self.assertRaises(numpy.AxisError): @@ -163,14 +156,12 @@ def test_sort_invalid_negative_axis2(self): with self.assertRaises(numpy.AxisError): a.sort(axis=-4) - @pytest.mark.usefixtures("allow_fall_back_on_numpy") def test_external_sort_invalid_negative_axis1(self): for xp in (numpy, cupy): a = testing.shaped_random((2, 3, 3), xp) with pytest.raises(numpy.AxisError): xp.sort(a, axis=-4) - @pytest.mark.usefixtures("allow_fall_back_on_numpy") def test_external_sort_invalid_negative_axis2(self): a = testing.shaped_random((2, 3, 3), cupy) with self.assertRaises(numpy.AxisError): @@ -210,6 +201,14 @@ def test_nan4(self, xp, dtype): out = xp.sort(a, axis=2) return out + # Large case + + @testing.slow + @testing.numpy_cupy_array_equal() + def test_large(self, xp): + a = testing.shaped_random((17, 1023, 1023), xp) + return xp.sort(a, axis=-1) + @testing.gpu class TestLexsort(unittest.TestCase): @@ -296,7 +295,6 @@ def test_F_order(self, xp): } ) ) -@testing.gpu class TestArgsort(unittest.TestCase): def argsort(self, a, axis=-1): if self.external: @@ -311,14 +309,15 @@ def argsort(self, a, axis=-1): @testing.numpy_cupy_array_equal() def test_argsort_zero_dim(self, xp, dtype): a = testing.shaped_random((), xp, dtype) - return self.argsort(a) + # only numpy allows 0d array without axis=None + kwargs = {} if xp == numpy else {"axis": None} + return self.argsort(a, **kwargs) @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_argsort_one_dim(self, xp, dtype): a = testing.shaped_random((10,), xp, dtype) - res = self.argsort(a) - return a[res] + return self.argsort(a) @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() @@ -362,7 +361,8 @@ def test_argsort_invalid_axis2(self): @testing.numpy_cupy_array_equal() def test_argsort_zero_dim_axis(self, xp): a = testing.shaped_random((), xp) - return self.argsort(a, axis=0) + # only numpy allows 0d array without axis=None + return self.argsort(a, axis=None) def test_argsort_zero_dim_invalid_axis(self): for xp in (numpy, cupy):