We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN 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). 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cupy/array_api/_sorting_functions.py`
Content:
```
1 # mypy: ignore-errors
2 
3 from __future__ import annotations
4 
5 from ._array_object import Array
6 
7 import cupy as np
8 
9 
10 def argsort(
11     x: Array, /, *, axis: int = -1, descending: bool = False, stable: bool = True
12 ) -> Array:
13     """
14     Array API compatible wrapper for :py:func:`np.argsort <numpy.argsort>`.
15 
16     See its docstring for more information.
17     """
18     # Note: this keyword argument is different, and the default is different.
19     kind = "stable" if stable else "quicksort"
20     if not descending:
21         res = np.argsort(x._array, axis=axis, kind=kind)
22     else:
23         # As NumPy has no native descending sort, we imitate it here. Note that
24         # simply flipping the results of np.argsort(x._array, ...) would not
25         # respect the relative order like it would in native descending sorts.
26         res = np.flip(
27             np.argsort(np.flip(x._array, axis=axis), axis=axis, kind=kind),
28             axis=axis,
29         )
30         # Rely on flip()/argsort() to validate axis
31         normalised_axis = axis if axis >= 0 else x.ndim + axis
32         max_i = x.shape[normalised_axis] - 1
33         res = max_i - res
34     return Array._new(res)
35 
36 
37 def sort(
38     x: Array, /, *, axis: int = -1, descending: bool = False, stable: bool = True
39 ) -> Array:
40     """
41     Array API compatible wrapper for :py:func:`np.sort <numpy.sort>`.
42 
43     See its docstring for more information.
44     """
45     # Note: this keyword argument is different, and the default is different.
46     kind = "stable" if stable else "quicksort"
47     res = np.sort(x._array, axis=axis, kind=kind)
48     if descending:
49         res = np.flip(res, axis=axis)
50     return Array._new(res)
51
```

Path: `cupy/_sorting/sort.py`
Content:
```
1 import cupy
2 import numpy
3 
4 from cupy.cuda import thrust
5 
6 
7 def sort(a, axis=-1):
8     """Returns a sorted copy of an array with a stable sorting algorithm.
9 
10     Args:
11         a (cupy.ndarray): Array to be sorted.
12         axis (int or None): Axis along which to sort. Default is -1, which
13             means sort along the last axis. If None is supplied, the array is
14             flattened before sorting.
15 
16     Returns:
17         cupy.ndarray: Array of the same type and shape as ``a``.
18 
19     .. note::
20        For its implementation reason, ``cupy.sort`` currently does not support
21        ``kind`` and ``order`` parameters that ``numpy.sort`` does
22        support.
23 
24     .. seealso:: :func:`numpy.sort`
25 
26     """
27     if axis is None:
28         ret = a.flatten()
29         axis = -1
30     else:
31         ret = a.copy()
32     ret.sort(axis=axis)
33     return ret
34 
35 
36 def lexsort(keys):
37     """Perform an indirect sort using an array of keys.
38 
39     Args:
40         keys (cupy.ndarray): ``(k, N)`` array containing ``k`` ``(N,)``-shaped
41             arrays. The ``k`` different "rows" to be sorted. The last row is
42             the primary sort key.
43 
44     Returns:
45         cupy.ndarray: Array of indices that sort the keys.
46 
47     .. note::
48         For its implementation reason, ``cupy.lexsort`` currently supports only
49         keys with their rank of one or two and does not support ``axis``
50         parameter that ``numpy.lexsort`` supports.
51 
52     .. seealso:: :func:`numpy.lexsort`
53 
54     """
55 
56     # TODO(takagi): Support axis argument.
57 
58     if not cupy.cuda.thrust.available:
59         raise RuntimeError('Thrust is needed to use cupy.lexsort. Please '
60                            'install CUDA Toolkit with Thrust then reinstall '
61                            'CuPy after uninstalling it.')
62 
63     if keys.ndim == ():
64         # as numpy.lexsort() raises
65         raise TypeError('need sequence of keys with len > 0 in lexsort')
66 
67     if keys.ndim == 1:
68         return 0
69 
70     # TODO(takagi): Support ranks of three or more.
71     if keys.ndim > 2:
72         raise NotImplementedError('Keys with the rank of three or more is not '
73                                   'supported in lexsort')
74 
75     # thrust.lexsort() assumes a C-contiguous array
76     if not keys.flags.c_contiguous:
77         keys = keys.copy('C')
78 
79     idx_array = cupy.ndarray(keys._shape[1:], dtype=numpy.intp)
80     k = keys._shape[0]
81     n = keys._shape[1]
82     thrust.lexsort(keys.dtype, idx_array.data.ptr, keys.data.ptr, k, n)
83 
84     return idx_array
85 
86 
87 def argsort(a, axis=-1):
88     """Returns the indices that would sort an array with a stable sorting.
89 
90     Args:
91         a (cupy.ndarray): Array to sort.
92         axis (int or None): Axis along which to sort. Default is -1, which
93             means sort along the last axis. If None is supplied, the array is
94             flattened before sorting.
95 
96     Returns:
97         cupy.ndarray: Array of indices that sort ``a``.
98 
99     .. note::
100         For its implementation reason, ``cupy.argsort`` does not support
101         ``kind`` and ``order`` parameters.
102 
103     .. seealso:: :func:`numpy.argsort`
104 
105     """
106     return a.argsort(axis=axis)
107 
108 
109 def msort(a):
110     """Returns a copy of an array sorted along the first axis.
111 
112     Args:
113         a (cupy.ndarray): Array to be sorted.
114 
115     Returns:
116         cupy.ndarray: Array of the same type and shape as ``a``.
117 
118     .. note:
119         ``cupy.msort(a)``, the CuPy counterpart of ``numpy.msort(a)``, is
120         equivalent to ``cupy.sort(a, axis=0)``.
121 
122     .. seealso:: :func:`numpy.msort`
123 
124     """
125 
126     return sort(a, axis=0)
127 
128 
129 def sort_complex(a):
130     """Sort a complex array using the real part first,
131     then the imaginary part.
132 
133     Args:
134         a (cupy.ndarray): Array to be sorted.
135 
136     Returns:
137         cupy.ndarray: sorted complex array.
138 
139     .. seealso:: :func:`numpy.sort_complex`
140 
141     """
142     if a.dtype.char in 'bhBHF':
143         a = a.astype('F')
144     else:
145         a = a.astype('D')
146     a.sort()
147     return a
148 
149 
150 def partition(a, kth, axis=-1):
151     """Returns a partitioned copy of an array.
152 
153     Creates a copy of the array whose elements are rearranged such that the
154     value of the element in k-th position would occur in that position in a
155     sorted array. All of the elements before the new k-th element are less
156     than or equal to the elements after the new k-th element.
157 
158     Args:
159         a (cupy.ndarray): Array to be sorted.
160         kth (int or sequence of ints): Element index to partition by. If
161             supplied with a sequence of k-th it will partition all elements
162             indexed by k-th of them into their sorted position at once.
163         axis (int or None): Axis along which to sort. Default is -1, which
164             means sort along the last axis. If None is supplied, the array is
165             flattened before sorting.
166 
167     Returns:
168         cupy.ndarray: Array of the same type and shape as ``a``.
169 
170     .. seealso:: :func:`numpy.partition`
171 
172     """
173     if axis is None:
174         ret = a.flatten()
175         axis = -1
176     else:
177         ret = a.copy()
178     ret.partition(kth, axis=axis)
179     return ret
180 
181 
182 def argpartition(a, kth, axis=-1):
183     """Returns the indices that would partially sort an array.
184 
185     Args:
186         a (cupy.ndarray): Array to be sorted.
187         kth (int or sequence of ints): Element index to partition by. If
188             supplied with a sequence of k-th it will partition all elements
189             indexed by k-th of them into their sorted position at once.
190         axis (int or None): Axis along which to sort. Default is -1, which
191             means sort along the last axis. If None is supplied, the array is
192             flattened before sorting.
193 
194     Returns:
195         cupy.ndarray: Array of the same type and shape as ``a``.
196 
197     .. note::
198         For its implementation reason, `cupy.argpartition` fully sorts the
199         given array as `cupy.argsort` does. It also does not support ``kind``
200         and ``order`` parameters that ``numpy.argpartition`` supports.
201 
202     .. seealso:: :func:`numpy.argpartition`
203 
204     """
205     return a.argpartition(kth, axis=axis)
206
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

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 @@
         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 @@
     .. 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 @@
     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 @@
         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 @@
     .. 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 @@
 
     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 @@
 
     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)

{"golden_diff": "diff --git a/cupy/_sorting/sort.py b/cupy/_sorting/sort.py\n--- a/cupy/_sorting/sort.py\n+++ b/cupy/_sorting/sort.py\n@@ -4,7 +4,7 @@\n from cupy.cuda import thrust\n \n \n-def sort(a, axis=-1):\n+def sort(a, axis=-1, kind=None):\n     \"\"\"Returns a sorted copy of an array with a stable sorting algorithm.\n \n     Args:\n@@ -12,6 +12,8 @@\n         axis (int or None): Axis along which to sort. Default is -1, which\n             means sort along the last axis. If None is supplied, the array is\n             flattened before sorting.\n+        kind: Default is `None`, which is equivalent to 'stable'. Unlike in\n+            NumPy any other options are not accepted here.\n \n     Returns:\n         cupy.ndarray: Array of the same type and shape as ``a``.\n@@ -24,6 +26,8 @@\n     .. seealso:: :func:`numpy.sort`\n \n     \"\"\"\n+    if kind is not None and kind != 'stable':\n+        raise ValueError(\"kind can only be None or 'stable'\")\n     if axis is None:\n         ret = a.flatten()\n         axis = -1\n@@ -84,7 +88,7 @@\n     return idx_array\n \n \n-def argsort(a, axis=-1):\n+def argsort(a, axis=-1, kind=None):\n     \"\"\"Returns the indices that would sort an array with a stable sorting.\n \n     Args:\n@@ -92,6 +96,8 @@\n         axis (int or None): Axis along which to sort. Default is -1, which\n             means sort along the last axis. If None is supplied, the array is\n             flattened before sorting.\n+        kind: Default is `None`, which is equivalent to 'stable'. Unlike in\n+            NumPy any other options are not accepted here.\n \n     Returns:\n         cupy.ndarray: Array of indices that sort ``a``.\n@@ -103,6 +109,8 @@\n     .. seealso:: :func:`numpy.argsort`\n \n     \"\"\"\n+    if kind is not None and kind != 'stable':\n+        raise ValueError(\"kind can only be None or 'stable'\")\n     return a.argsort(axis=axis)\n \n \ndiff --git a/cupy/array_api/_sorting_functions.py b/cupy/array_api/_sorting_functions.py\n--- a/cupy/array_api/_sorting_functions.py\n+++ b/cupy/array_api/_sorting_functions.py\n@@ -15,8 +15,9 @@\n \n     See its docstring for more information.\n     \"\"\"\n-    # Note: this keyword argument is different, and the default is different.\n-    kind = \"stable\" if stable else \"quicksort\"\n+    # Note: Unlike in NumPy we only support kind={None, 'stable'}, but the standard\n+    # does *not* require we need to support unstable sort.\n+    kind = None\n     if not descending:\n         res = np.argsort(x._array, axis=axis, kind=kind)\n     else:\n@@ -42,8 +43,9 @@\n \n     See its docstring for more information.\n     \"\"\"\n-    # Note: this keyword argument is different, and the default is different.\n-    kind = \"stable\" if stable else \"quicksort\"\n+    # Note: Unlike in NumPy we only support kind={None, 'stable'}, but the standard\n+    # does *not* require we need to support unstable sort.\n+    kind = None\n     res = np.sort(x._array, axis=axis, kind=kind)\n     if descending:\n         res = np.flip(res, axis=axis)\n", "issue": "array_api sort() does not work\n### Description\n\nThe array_api sort() is copied from the NumPy implementation, but passes through a `kind` keyword which doesn't exist in `cupy.sort`.\n\n### To Reproduce\n\n```py\r\n>>> a = xp.asarray([1, 0, 2])\r\n>>> xp.sort(a)\r\nTraceback (most recent call last):\r\n  File \"<stdin>\", line 1, in <module>\r\n  File \"/home/aaronmeurer/anaconda3/envs/array-api/lib/python3.10/site-packages/cupy/array_api/_sorting_functions.py\", line 45, in sort\r\n    res = np.sort(x._array, axis=axis, kind=kind)\r\nTypeError: sort() got an unexpected keyword argument 'kind'\r\n```\r\n\n\n### Installation\n\nConda-Forge (`conda install ...`)\n\n### Environment\n\n```\r\n# Paste the output here\r\n```\r\n\n\n### Additional Information\n\nThe 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). \n", "before_files": [{"content": "# mypy: ignore-errors\n\nfrom __future__ import annotations\n\nfrom ._array_object import Array\n\nimport cupy as np\n\n\ndef argsort(\n    x: Array, /, *, axis: int = -1, descending: bool = False, stable: bool = True\n) -> Array:\n    \"\"\"\n    Array API compatible wrapper for :py:func:`np.argsort <numpy.argsort>`.\n\n    See its docstring for more information.\n    \"\"\"\n    # Note: this keyword argument is different, and the default is different.\n    kind = \"stable\" if stable else \"quicksort\"\n    if not descending:\n        res = np.argsort(x._array, axis=axis, kind=kind)\n    else:\n        # As NumPy has no native descending sort, we imitate it here. Note that\n        # simply flipping the results of np.argsort(x._array, ...) would not\n        # respect the relative order like it would in native descending sorts.\n        res = np.flip(\n            np.argsort(np.flip(x._array, axis=axis), axis=axis, kind=kind),\n            axis=axis,\n        )\n        # Rely on flip()/argsort() to validate axis\n        normalised_axis = axis if axis >= 0 else x.ndim + axis\n        max_i = x.shape[normalised_axis] - 1\n        res = max_i - res\n    return Array._new(res)\n\n\ndef sort(\n    x: Array, /, *, axis: int = -1, descending: bool = False, stable: bool = True\n) -> Array:\n    \"\"\"\n    Array API compatible wrapper for :py:func:`np.sort <numpy.sort>`.\n\n    See its docstring for more information.\n    \"\"\"\n    # Note: this keyword argument is different, and the default is different.\n    kind = \"stable\" if stable else \"quicksort\"\n    res = np.sort(x._array, axis=axis, kind=kind)\n    if descending:\n        res = np.flip(res, axis=axis)\n    return Array._new(res)\n", "path": "cupy/array_api/_sorting_functions.py"}, {"content": "import cupy\nimport numpy\n\nfrom cupy.cuda import thrust\n\n\ndef sort(a, axis=-1):\n    \"\"\"Returns a sorted copy of an array with a stable sorting algorithm.\n\n    Args:\n        a (cupy.ndarray): Array to be sorted.\n        axis (int or None): Axis along which to sort. Default is -1, which\n            means sort along the last axis. If None is supplied, the array is\n            flattened before sorting.\n\n    Returns:\n        cupy.ndarray: Array of the same type and shape as ``a``.\n\n    .. note::\n       For its implementation reason, ``cupy.sort`` currently does not support\n       ``kind`` and ``order`` parameters that ``numpy.sort`` does\n       support.\n\n    .. seealso:: :func:`numpy.sort`\n\n    \"\"\"\n    if axis is None:\n        ret = a.flatten()\n        axis = -1\n    else:\n        ret = a.copy()\n    ret.sort(axis=axis)\n    return ret\n\n\ndef lexsort(keys):\n    \"\"\"Perform an indirect sort using an array of keys.\n\n    Args:\n        keys (cupy.ndarray): ``(k, N)`` array containing ``k`` ``(N,)``-shaped\n            arrays. The ``k`` different \"rows\" to be sorted. The last row is\n            the primary sort key.\n\n    Returns:\n        cupy.ndarray: Array of indices that sort the keys.\n\n    .. note::\n        For its implementation reason, ``cupy.lexsort`` currently supports only\n        keys with their rank of one or two and does not support ``axis``\n        parameter that ``numpy.lexsort`` supports.\n\n    .. seealso:: :func:`numpy.lexsort`\n\n    \"\"\"\n\n    # TODO(takagi): Support axis argument.\n\n    if not cupy.cuda.thrust.available:\n        raise RuntimeError('Thrust is needed to use cupy.lexsort. Please '\n                           'install CUDA Toolkit with Thrust then reinstall '\n                           'CuPy after uninstalling it.')\n\n    if keys.ndim == ():\n        # as numpy.lexsort() raises\n        raise TypeError('need sequence of keys with len > 0 in lexsort')\n\n    if keys.ndim == 1:\n        return 0\n\n    # TODO(takagi): Support ranks of three or more.\n    if keys.ndim > 2:\n        raise NotImplementedError('Keys with the rank of three or more is not '\n                                  'supported in lexsort')\n\n    # thrust.lexsort() assumes a C-contiguous array\n    if not keys.flags.c_contiguous:\n        keys = keys.copy('C')\n\n    idx_array = cupy.ndarray(keys._shape[1:], dtype=numpy.intp)\n    k = keys._shape[0]\n    n = keys._shape[1]\n    thrust.lexsort(keys.dtype, idx_array.data.ptr, keys.data.ptr, k, n)\n\n    return idx_array\n\n\ndef argsort(a, axis=-1):\n    \"\"\"Returns the indices that would sort an array with a stable sorting.\n\n    Args:\n        a (cupy.ndarray): Array to sort.\n        axis (int or None): Axis along which to sort. Default is -1, which\n            means sort along the last axis. If None is supplied, the array is\n            flattened before sorting.\n\n    Returns:\n        cupy.ndarray: Array of indices that sort ``a``.\n\n    .. note::\n        For its implementation reason, ``cupy.argsort`` does not support\n        ``kind`` and ``order`` parameters.\n\n    .. seealso:: :func:`numpy.argsort`\n\n    \"\"\"\n    return a.argsort(axis=axis)\n\n\ndef msort(a):\n    \"\"\"Returns a copy of an array sorted along the first axis.\n\n    Args:\n        a (cupy.ndarray): Array to be sorted.\n\n    Returns:\n        cupy.ndarray: Array of the same type and shape as ``a``.\n\n    .. note:\n        ``cupy.msort(a)``, the CuPy counterpart of ``numpy.msort(a)``, is\n        equivalent to ``cupy.sort(a, axis=0)``.\n\n    .. seealso:: :func:`numpy.msort`\n\n    \"\"\"\n\n    return sort(a, axis=0)\n\n\ndef sort_complex(a):\n    \"\"\"Sort a complex array using the real part first,\n    then the imaginary part.\n\n    Args:\n        a (cupy.ndarray): Array to be sorted.\n\n    Returns:\n        cupy.ndarray: sorted complex array.\n\n    .. seealso:: :func:`numpy.sort_complex`\n\n    \"\"\"\n    if a.dtype.char in 'bhBHF':\n        a = a.astype('F')\n    else:\n        a = a.astype('D')\n    a.sort()\n    return a\n\n\ndef partition(a, kth, axis=-1):\n    \"\"\"Returns a partitioned copy of an array.\n\n    Creates a copy of the array whose elements are rearranged such that the\n    value of the element in k-th position would occur in that position in a\n    sorted array. All of the elements before the new k-th element are less\n    than or equal to the elements after the new k-th element.\n\n    Args:\n        a (cupy.ndarray): Array to be sorted.\n        kth (int or sequence of ints): Element index to partition by. If\n            supplied with a sequence of k-th it will partition all elements\n            indexed by k-th of them into their sorted position at once.\n        axis (int or None): Axis along which to sort. Default is -1, which\n            means sort along the last axis. If None is supplied, the array is\n            flattened before sorting.\n\n    Returns:\n        cupy.ndarray: Array of the same type and shape as ``a``.\n\n    .. seealso:: :func:`numpy.partition`\n\n    \"\"\"\n    if axis is None:\n        ret = a.flatten()\n        axis = -1\n    else:\n        ret = a.copy()\n    ret.partition(kth, axis=axis)\n    return ret\n\n\ndef argpartition(a, kth, axis=-1):\n    \"\"\"Returns the indices that would partially sort an array.\n\n    Args:\n        a (cupy.ndarray): Array to be sorted.\n        kth (int or sequence of ints): Element index to partition by. If\n            supplied with a sequence of k-th it will partition all elements\n            indexed by k-th of them into their sorted position at once.\n        axis (int or None): Axis along which to sort. Default is -1, which\n            means sort along the last axis. If None is supplied, the array is\n            flattened before sorting.\n\n    Returns:\n        cupy.ndarray: Array of the same type and shape as ``a``.\n\n    .. note::\n        For its implementation reason, `cupy.argpartition` fully sorts the\n        given array as `cupy.argsort` does. It also does not support ``kind``\n        and ``order`` parameters that ``numpy.argpartition`` supports.\n\n    .. seealso:: :func:`numpy.argpartition`\n\n    \"\"\"\n    return a.argpartition(kth, axis=axis)\n", "path": "cupy/_sorting/sort.py"}], "after_files": [{"content": "# mypy: ignore-errors\n\nfrom __future__ import annotations\n\nfrom ._array_object import Array\n\nimport cupy as np\n\n\ndef argsort(\n    x: Array, /, *, axis: int = -1, descending: bool = False, stable: bool = True\n) -> Array:\n    \"\"\"\n    Array API compatible wrapper for :py:func:`np.argsort <numpy.argsort>`.\n\n    See its docstring for more information.\n    \"\"\"\n    # Note: Unlike in NumPy we only support kind={None, 'stable'}, but the standard\n    # does *not* require we need to support unstable sort.\n    kind = None\n    if not descending:\n        res = np.argsort(x._array, axis=axis, kind=kind)\n    else:\n        # As NumPy has no native descending sort, we imitate it here. Note that\n        # simply flipping the results of np.argsort(x._array, ...) would not\n        # respect the relative order like it would in native descending sorts.\n        res = np.flip(\n            np.argsort(np.flip(x._array, axis=axis), axis=axis, kind=kind),\n            axis=axis,\n        )\n        # Rely on flip()/argsort() to validate axis\n        normalised_axis = axis if axis >= 0 else x.ndim + axis\n        max_i = x.shape[normalised_axis] - 1\n        res = max_i - res\n    return Array._new(res)\n\n\ndef sort(\n    x: Array, /, *, axis: int = -1, descending: bool = False, stable: bool = True\n) -> Array:\n    \"\"\"\n    Array API compatible wrapper for :py:func:`np.sort <numpy.sort>`.\n\n    See its docstring for more information.\n    \"\"\"\n    # Note: Unlike in NumPy we only support kind={None, 'stable'}, but the standard\n    # does *not* require we need to support unstable sort.\n    kind = None\n    res = np.sort(x._array, axis=axis, kind=kind)\n    if descending:\n        res = np.flip(res, axis=axis)\n    return Array._new(res)\n", "path": "cupy/array_api/_sorting_functions.py"}, {"content": "import cupy\nimport numpy\n\nfrom cupy.cuda import thrust\n\n\ndef sort(a, axis=-1, kind=None):\n    \"\"\"Returns a sorted copy of an array with a stable sorting algorithm.\n\n    Args:\n        a (cupy.ndarray): Array to be sorted.\n        axis (int or None): Axis along which to sort. Default is -1, which\n            means sort along the last axis. If None is supplied, the array is\n            flattened before sorting.\n        kind: Default is `None`, which is equivalent to 'stable'. Unlike in\n            NumPy any other options are not accepted here.\n\n    Returns:\n        cupy.ndarray: Array of the same type and shape as ``a``.\n\n    .. note::\n       For its implementation reason, ``cupy.sort`` currently does not support\n       ``kind`` and ``order`` parameters that ``numpy.sort`` does\n       support.\n\n    .. seealso:: :func:`numpy.sort`\n\n    \"\"\"\n    if kind is not None and kind != 'stable':\n        raise ValueError(\"kind can only be None or 'stable'\")\n    if axis is None:\n        ret = a.flatten()\n        axis = -1\n    else:\n        ret = a.copy()\n    ret.sort(axis=axis)\n    return ret\n\n\ndef lexsort(keys):\n    \"\"\"Perform an indirect sort using an array of keys.\n\n    Args:\n        keys (cupy.ndarray): ``(k, N)`` array containing ``k`` ``(N,)``-shaped\n            arrays. The ``k`` different \"rows\" to be sorted. The last row is\n            the primary sort key.\n\n    Returns:\n        cupy.ndarray: Array of indices that sort the keys.\n\n    .. note::\n        For its implementation reason, ``cupy.lexsort`` currently supports only\n        keys with their rank of one or two and does not support ``axis``\n        parameter that ``numpy.lexsort`` supports.\n\n    .. seealso:: :func:`numpy.lexsort`\n\n    \"\"\"\n\n    # TODO(takagi): Support axis argument.\n\n    if not cupy.cuda.thrust.available:\n        raise RuntimeError('Thrust is needed to use cupy.lexsort. Please '\n                           'install CUDA Toolkit with Thrust then reinstall '\n                           'CuPy after uninstalling it.')\n\n    if keys.ndim == ():\n        # as numpy.lexsort() raises\n        raise TypeError('need sequence of keys with len > 0 in lexsort')\n\n    if keys.ndim == 1:\n        return 0\n\n    # TODO(takagi): Support ranks of three or more.\n    if keys.ndim > 2:\n        raise NotImplementedError('Keys with the rank of three or more is not '\n                                  'supported in lexsort')\n\n    # thrust.lexsort() assumes a C-contiguous array\n    if not keys.flags.c_contiguous:\n        keys = keys.copy('C')\n\n    idx_array = cupy.ndarray(keys._shape[1:], dtype=numpy.intp)\n    k = keys._shape[0]\n    n = keys._shape[1]\n    thrust.lexsort(keys.dtype, idx_array.data.ptr, keys.data.ptr, k, n)\n\n    return idx_array\n\n\ndef argsort(a, axis=-1, kind=None):\n    \"\"\"Returns the indices that would sort an array with a stable sorting.\n\n    Args:\n        a (cupy.ndarray): Array to sort.\n        axis (int or None): Axis along which to sort. Default is -1, which\n            means sort along the last axis. If None is supplied, the array is\n            flattened before sorting.\n        kind: Default is `None`, which is equivalent to 'stable'. Unlike in\n            NumPy any other options are not accepted here.\n\n    Returns:\n        cupy.ndarray: Array of indices that sort ``a``.\n\n    .. note::\n        For its implementation reason, ``cupy.argsort`` does not support\n        ``kind`` and ``order`` parameters.\n\n    .. seealso:: :func:`numpy.argsort`\n\n    \"\"\"\n    if kind is not None and kind != 'stable':\n        raise ValueError(\"kind can only be None or 'stable'\")\n    return a.argsort(axis=axis)\n\n\ndef msort(a):\n    \"\"\"Returns a copy of an array sorted along the first axis.\n\n    Args:\n        a (cupy.ndarray): Array to be sorted.\n\n    Returns:\n        cupy.ndarray: Array of the same type and shape as ``a``.\n\n    .. note:\n        ``cupy.msort(a)``, the CuPy counterpart of ``numpy.msort(a)``, is\n        equivalent to ``cupy.sort(a, axis=0)``.\n\n    .. seealso:: :func:`numpy.msort`\n\n    \"\"\"\n\n    return sort(a, axis=0)\n\n\ndef sort_complex(a):\n    \"\"\"Sort a complex array using the real part first,\n    then the imaginary part.\n\n    Args:\n        a (cupy.ndarray): Array to be sorted.\n\n    Returns:\n        cupy.ndarray: sorted complex array.\n\n    .. seealso:: :func:`numpy.sort_complex`\n\n    \"\"\"\n    if a.dtype.char in 'bhBHF':\n        a = a.astype('F')\n    else:\n        a = a.astype('D')\n    a.sort()\n    return a\n\n\ndef partition(a, kth, axis=-1):\n    \"\"\"Returns a partitioned copy of an array.\n\n    Creates a copy of the array whose elements are rearranged such that the\n    value of the element in k-th position would occur in that position in a\n    sorted array. All of the elements before the new k-th element are less\n    than or equal to the elements after the new k-th element.\n\n    Args:\n        a (cupy.ndarray): Array to be sorted.\n        kth (int or sequence of ints): Element index to partition by. If\n            supplied with a sequence of k-th it will partition all elements\n            indexed by k-th of them into their sorted position at once.\n        axis (int or None): Axis along which to sort. Default is -1, which\n            means sort along the last axis. If None is supplied, the array is\n            flattened before sorting.\n\n    Returns:\n        cupy.ndarray: Array of the same type and shape as ``a``.\n\n    .. seealso:: :func:`numpy.partition`\n\n    \"\"\"\n    if axis is None:\n        ret = a.flatten()\n        axis = -1\n    else:\n        ret = a.copy()\n    ret.partition(kth, axis=axis)\n    return ret\n\n\ndef argpartition(a, kth, axis=-1):\n    \"\"\"Returns the indices that would partially sort an array.\n\n    Args:\n        a (cupy.ndarray): Array to be sorted.\n        kth (int or sequence of ints): Element index to partition by. If\n            supplied with a sequence of k-th it will partition all elements\n            indexed by k-th of them into their sorted position at once.\n        axis (int or None): Axis along which to sort. Default is -1, which\n            means sort along the last axis. If None is supplied, the array is\n            flattened before sorting.\n\n    Returns:\n        cupy.ndarray: Array of the same type and shape as ``a``.\n\n    .. note::\n        For its implementation reason, `cupy.argpartition` fully sorts the\n        given array as `cupy.argsort` does. It also does not support ``kind``\n        and ``order`` parameters that ``numpy.argpartition`` supports.\n\n    .. seealso:: :func:`numpy.argpartition`\n\n    \"\"\"\n    return a.argpartition(kth, axis=axis)\n", "path": "cupy/_sorting/sort.py"}]}