Repository: cupy/cupy

Issue:
array_api sort() does not work
### Description

The array_api sort() is copied from the NumPy implementation, but passes through a `kind` keyword which doesn't exist in `cupy.sort`.

### To Reproduce

```py
>>> a = xp.asarray([1, 0, 2])
>>> xp.sort(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/aaronmeurer/anaconda3/envs/array-api/lib/python3.10/site-packages/cupy/array_api/_sorting_functions.py", line 45, in sort
    res = np.sort(x._array, axis=axis, kind=kind)
TypeError: sort() got an unexpected keyword argument 'kind'
```


### Installation

Conda-Forge (`conda install ...`)

### Environment

```
# Paste the output here
```


### Additional Information

The array API does require support for a `stable` keyword. If `cupy.sort` is always stable, it can just ignore this flag, as `stable=False` is allowed to be stable (see https://data-apis.org/array-api/latest/API_specification/generated/signatures.sorting_functions.sort.html). Otherwise, I would suggest raising NotImplementedError for `stable=True` (which is unfortunately the default). 


Discussion:
Looks like this is a dup of #5701. @kmaehashi plz assign to me.
btw IIRC CuPy always performs stable sort (@takagi can correct me).
> btw IIRC CuPy always performs stable sort

Yes.

Resolving patch:
diff --git a/cupy/_sorting/sort.py b/cupy/_sorting/sort.py
--- a/cupy/_sorting/sort.py
+++ b/cupy/_sorting/sort.py
@@ -4,7 +4,7 @@
 from cupy.cuda import thrust
 
 
-def sort(a, axis=-1):
+def sort(a, axis=-1, kind=None):
     """Returns a sorted copy of an array with a stable sorting algorithm.
 
     Args:
@@ -12,6 +12,8 @@ def sort(a, axis=-1):
         axis (int or None): Axis along which to sort. Default is -1, which
             means sort along the last axis. If None is supplied, the array is
             flattened before sorting.
+        kind: Default is `None`, which is equivalent to 'stable'. Unlike in
+            NumPy any other options are not accepted here.
 
     Returns:
         cupy.ndarray: Array of the same type and shape as ``a``.
@@ -24,6 +26,8 @@ def sort(a, axis=-1):
     .. seealso:: :func:`numpy.sort`
 
     """
+    if kind is not None and kind != 'stable':
+        raise ValueError("kind can only be None or 'stable'")
     if axis is None:
         ret = a.flatten()
         axis = -1
@@ -84,7 +88,7 @@ def lexsort(keys):
     return idx_array
 
 
-def argsort(a, axis=-1):
+def argsort(a, axis=-1, kind=None):
     """Returns the indices that would sort an array with a stable sorting.
 
     Args:
@@ -92,6 +96,8 @@ def argsort(a, axis=-1):
         axis (int or None): Axis along which to sort. Default is -1, which
             means sort along the last axis. If None is supplied, the array is
             flattened before sorting.
+        kind: Default is `None`, which is equivalent to 'stable'. Unlike in
+            NumPy any other options are not accepted here.
 
     Returns:
         cupy.ndarray: Array of indices that sort ``a``.
@@ -103,6 +109,8 @@ def argsort(a, axis=-1):
     .. seealso:: :func:`numpy.argsort`
 
     """
+    if kind is not None and kind != 'stable':
+        raise ValueError("kind can only be None or 'stable'")
     return a.argsort(axis=axis)
 
 
diff --git a/cupy/array_api/_sorting_functions.py b/cupy/array_api/_sorting_functions.py
--- a/cupy/array_api/_sorting_functions.py
+++ b/cupy/array_api/_sorting_functions.py
@@ -15,8 +15,9 @@ def argsort(
 
     See its docstring for more information.
     """
-    # Note: this keyword argument is different, and the default is different.
-    kind = "stable" if stable else "quicksort"
+    # Note: Unlike in NumPy we only support kind={None, 'stable'}, but the standard
+    # does *not* require we need to support unstable sort.
+    kind = None
     if not descending:
         res = np.argsort(x._array, axis=axis, kind=kind)
     else:
@@ -42,8 +43,9 @@ def sort(
 
     See its docstring for more information.
     """
-    # Note: this keyword argument is different, and the default is different.
-    kind = "stable" if stable else "quicksort"
+    # Note: Unlike in NumPy we only support kind={None, 'stable'}, but the standard
+    # does *not* require we need to support unstable sort.
+    kind = None
     res = np.sort(x._array, axis=axis, kind=kind)
     if descending:
         res = np.flip(res, axis=axis)


Test patch:
diff --git a/tests/cupy_tests/array_api_tests/test_sorting_functions.py b/tests/cupy_tests/array_api_tests/test_sorting_functions.py
--- a/tests/cupy_tests/array_api_tests/test_sorting_functions.py
+++ b/tests/cupy_tests/array_api_tests/test_sorting_functions.py
@@ -12,9 +12,6 @@
         ([[0, 1], [1, 1]], 1, [[1, 0], [0, 1]]),
     ],
 )
-@pytest.mark.skipif(
-    # https://github.com/cupy/cupy/issues/5701
-    True, reason="Sorting functions miss arguments kind and order")
 def test_stable_desc_argsort(obj, axis, expected):
     """
     Indices respect relative order of a descending stable-sort