Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
3adafe8
ENH: ArrayMethod sorting for built-in dtypes
MaanasArora Apr 20, 2026
07e6894
REF: Remove unused template variable
MaanasArora Apr 20, 2026
8a5df82
REF: Simplify output descriptor in sort_resolve_descriptors
MaanasArora Apr 20, 2026
923116f
BUG: Move builtin sort registrations after array method types are ready
MaanasArora Apr 21, 2026
241ba4b
REF: Remove set_sorts function back to set_typeinfo, move ready array…
MaanasArora Apr 21, 2026
63787e6
Descending sorting with built-in dtype implementations
MaanasArora Apr 27, 2026
ce87f1e
REF: Fix linting
MaanasArora Apr 27, 2026
5e0f399
Register new-style sorts in C++, templated compare used in sorts
MaanasArora Apr 29, 2026
7e36287
Move generic templated sorts to header files
MaanasArora Apr 29, 2026
0dadfee
Fix string/unicode sorting
MaanasArora Apr 29, 2026
83f4e76
Use ordered initialization for sort and argsort specs
MaanasArora Apr 29, 2026
71b7154
Amend sorting ArrFuncs
MaanasArora Apr 29, 2026
1c95a4e
Fix linting and stubs issues
MaanasArora Apr 29, 2026
e54fa74
Add randomization option and strings to descending sort tests
MaanasArora Apr 29, 2026
451dcb1
Add descending option to argsort function signatures
MaanasArora Apr 29, 2026
558183a
Add descending option to sort function signatures in fromnumeric and …
MaanasArora Apr 29, 2026
87a3ea1
Add missing descending args in masked array sorts
MaanasArora Apr 29, 2026
6ed868f
Add argsort descending tests
MaanasArora Apr 29, 2026
b586fdb
Refactor argsort return statement
MaanasArora Apr 29, 2026
ab43ee7
Add descending parameter to sort docs
MaanasArora Apr 30, 2026
2f203b3
Change descending parameter in argsort to be optional
MaanasArora Apr 30, 2026
6460b64
TST: Throw if stable/descending=True used with masked arrays
MaanasArora Apr 30, 2026
9e6ff64
Fix signature issue (wasm) and use greater + npy::cmp helper (not sur…
seberg Apr 30, 2026
d84a54b
Restore ascending SIMD sorts
MaanasArora Apr 30, 2026
cfcc498
Refactor sorting functions to use type aliasing for dispatch types
MaanasArora May 1, 2026
1e0a9a9
Fix quicksort dispatch to support np::half
MaanasArora May 1, 2026
f35b010
Add release note
MaanasArora May 1, 2026
5cf942d
condition half typename for simd sorts on tag
MaanasArora May 1, 2026
579c416
Apply complex bug fix suggestion
MaanasArora May 4, 2026
70b4b72
Move sorting registration for all dtypes at once to C++
MaanasArora May 4, 2026
4e85e7a
Descending sort tests for complex
MaanasArora May 4, 2026
3948bd6
Fix complex tag greater to handle NaN cases correctly
MaanasArora May 4, 2026
f09471d
Replace sort dispatch flags on tag with constexpr check in quicksort_…
MaanasArora May 4, 2026
51207b3
Swap names of quicksort and timsort generic and templated files
MaanasArora May 5, 2026
c1ec4b1
Better test for nan ordering in complex sorting (not lex ordering on …
MaanasArora May 5, 2026
a230d12
Refactor sorting tests; add lex order test for complex sorting
MaanasArora May 6, 2026
a8eed2a
Fix NaN handling in (arg)sorting tests
MaanasArora May 6, 2026
3e5a8b7
Fix linting issues
MaanasArora May 6, 2026
35e2a8f
Fix comparison of datetime and timedelta types in argsort test
MaanasArora May 7, 2026
2e44d63
Fix SIMD dispatch (tag checking was broken)
MaanasArora May 7, 2026
29890fe
Fix missing newline at end of file in npysort_methods.cpp
MaanasArora May 7, 2026
c486a18
fix heapsort dispatching in PyArray_(Arg)Sort (clear to quicksort for…
MaanasArora May 7, 2026
4b3a481
Restore radixsort for ascending sorts
MaanasArora May 7, 2026
ffbc51c
Enable SIMD path for descending sorts on highway only
MaanasArora May 7, 2026
a654904
Fix compilation errors
MaanasArora May 7, 2026
3f695ff
Fix missing argument (descending)
MaanasArora May 7, 2026
99aa4d8
EXPERIMENT: Do not fallback to generic quicksort from highway
MaanasArora May 7, 2026
ad917a4
Guard highway include with VQSORT_ENABLED
MaanasArora May 7, 2026
fe35d68
Fill sort arrfunc with radixsort trampoline if using
MaanasArora May 11, 2026
e0e8d65
Fixup radixsort templating (may be unused) and QSort fallback logic
seberg May 12, 2026
52970f7
Make error handling GIL safe (effectively unreachable anyway...)
seberg May 12, 2026
92945ce
Use constexpr rather than finline (reformats complex slightly)
seberg May 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Restore radixsort for ascending sorts
  • Loading branch information
MaanasArora committed May 7, 2026
commit 4b3a48154a42add8931208d848a47ae91b33a46a
1 change: 0 additions & 1 deletion numpy/_core/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -1234,7 +1234,6 @@ src_multiarray = multiarray_gen_headers + [
'src/npysort/mergesort.cpp',
'src/npysort/timsort_generic.cpp',
'src/npysort/heapsort.cpp',
'src/npysort/radixsort.cpp',
'src/npysort/npysort_methods.cpp',
'src/common/npy_partition.h',
'src/npysort/selection.cpp',
Expand Down
27 changes: 27 additions & 0 deletions numpy/_core/src/npysort/npysort_methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "npysort_common.h"
#include "numpy_tag.h"
#include "quicksort.hpp"
#include "radixsort.hpp"
#include "timsort.hpp"

#include <cstdlib>
Expand Down Expand Up @@ -53,13 +54,26 @@ sort_loop_(PyArrayMethod_Context *context, char *const data[],
npy_intp const dimensions[], npy_intp const strides[],
NpyAuxData *NPY_UNUSED(auxdata))
{
constexpr bool use_radixsort = (
std::is_same_v<Tag, npy::bool_tag> ||
std::is_same_v<Tag, npy::ubyte_tag> ||
std::is_same_v<Tag, npy::byte_tag> ||
std::is_same_v<Tag, npy::ushort_tag> ||
std::is_same_v<Tag, npy::short_tag>
);

PyArrayMethod_SortParameters *params =
(PyArrayMethod_SortParameters *)context->parameters;
switch ((int)params->flags) {
case NPY_SORT_DEFAULT:
return quicksort_<Tag, type, false>((type *)data[0], dimensions[0]);
case NPY_SORT_STABLE:
if constexpr (use_radixsort) {
return radixsort<type>(data[0], dimensions[0]);
}
else {
return timsort_<Tag, type, false>((type *)data[0], dimensions[0]);
}
case NPY_SORT_DEFAULT | NPY_SORT_DESCENDING:
return quicksort_<Tag, type, true>((type *)data[0], dimensions[0]);
case NPY_SORT_STABLE | NPY_SORT_DESCENDING:
Expand All @@ -77,15 +91,28 @@ argsort_loop_(PyArrayMethod_Context *context, char *const data[],
npy_intp const dimensions[], npy_intp const strides[],
NpyAuxData *NPY_UNUSED(auxdata))
{
constexpr bool use_radixsort = (
std::is_same_v<Tag, npy::bool_tag> ||
std::is_same_v<Tag, npy::ubyte_tag> ||
std::is_same_v<Tag, npy::byte_tag> ||
std::is_same_v<Tag, npy::ushort_tag> ||
std::is_same_v<Tag, npy::short_tag>
);

PyArrayMethod_SortParameters *params =
(PyArrayMethod_SortParameters *)context->parameters;
switch ((int)params->flags) {
case NPY_SORT_DEFAULT:
return aquicksort_<Tag, type, false>((type *)data[0], (npy_intp *)data[1],
dimensions[0]);
case NPY_SORT_STABLE:
if constexpr (use_radixsort) {
return aradixsort<type>(data[0], (npy_intp *)data[1], dimensions[0]);
}
else {
return atimsort_<Tag, type, false>((type *)data[0], (npy_intp *)data[1],
dimensions[0]);
}
case NPY_SORT_DEFAULT | NPY_SORT_DESCENDING:
return aquicksort_<Tag, type, true>((type *)data[0], (npy_intp *)data[1],
dimensions[0]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,122 +235,3 @@ aradixsort(void *start, npy_intp *tosort, npy_intp num)
using UT = typename std::make_unsigned<T>::type;
return aradixsort_<T>((UT *)start, tosort, num);
}

extern "C" {
NPY_NO_EXPORT int
radixsort_bool(void *vec, npy_intp cnt, void *NPY_UNUSED(null))
{
return radixsort<npy_bool>(vec, cnt);
}
NPY_NO_EXPORT int
radixsort_byte(void *vec, npy_intp cnt, void *NPY_UNUSED(null))
{
return radixsort<npy_byte>(vec, cnt);
}
NPY_NO_EXPORT int
radixsort_ubyte(void *vec, npy_intp cnt, void *NPY_UNUSED(null))
{
return radixsort<npy_ubyte>(vec, cnt);
}
NPY_NO_EXPORT int
radixsort_short(void *vec, npy_intp cnt, void *NPY_UNUSED(null))
{
return radixsort<npy_short>(vec, cnt);
}
NPY_NO_EXPORT int
radixsort_ushort(void *vec, npy_intp cnt, void *NPY_UNUSED(null))
{
return radixsort<npy_ushort>(vec, cnt);
}
NPY_NO_EXPORT int
radixsort_int(void *vec, npy_intp cnt, void *NPY_UNUSED(null))
{
return radixsort<npy_int>(vec, cnt);
}
NPY_NO_EXPORT int
radixsort_uint(void *vec, npy_intp cnt, void *NPY_UNUSED(null))
{
return radixsort<npy_uint>(vec, cnt);
}
NPY_NO_EXPORT int
radixsort_long(void *vec, npy_intp cnt, void *NPY_UNUSED(null))
{
return radixsort<npy_long>(vec, cnt);
}
NPY_NO_EXPORT int
radixsort_ulong(void *vec, npy_intp cnt, void *NPY_UNUSED(null))
{
return radixsort<npy_ulong>(vec, cnt);
}
NPY_NO_EXPORT int
radixsort_longlong(void *vec, npy_intp cnt, void *NPY_UNUSED(null))
{
return radixsort<npy_longlong>(vec, cnt);
}
NPY_NO_EXPORT int
radixsort_ulonglong(void *vec, npy_intp cnt, void *NPY_UNUSED(null))
{
return radixsort<npy_ulonglong>(vec, cnt);
}
NPY_NO_EXPORT int
aradixsort_bool(void *vec, npy_intp *ind, npy_intp cnt, void *NPY_UNUSED(null))
{
return aradixsort<npy_bool>(vec, ind, cnt);
}
NPY_NO_EXPORT int
aradixsort_byte(void *vec, npy_intp *ind, npy_intp cnt, void *NPY_UNUSED(null))
{
return aradixsort<npy_byte>(vec, ind, cnt);
}
NPY_NO_EXPORT int
aradixsort_ubyte(void *vec, npy_intp *ind, npy_intp cnt,
void *NPY_UNUSED(null))
{
return aradixsort<npy_ubyte>(vec, ind, cnt);
}
NPY_NO_EXPORT int
aradixsort_short(void *vec, npy_intp *ind, npy_intp cnt,
void *NPY_UNUSED(null))
{
return aradixsort<npy_short>(vec, ind, cnt);
}
NPY_NO_EXPORT int
aradixsort_ushort(void *vec, npy_intp *ind, npy_intp cnt,
void *NPY_UNUSED(null))
{
return aradixsort<npy_ushort>(vec, ind, cnt);
}
NPY_NO_EXPORT int
aradixsort_int(void *vec, npy_intp *ind, npy_intp cnt, void *NPY_UNUSED(null))
{
return aradixsort<npy_int>(vec, ind, cnt);
}
NPY_NO_EXPORT int
aradixsort_uint(void *vec, npy_intp *ind, npy_intp cnt, void *NPY_UNUSED(null))
{
return aradixsort<npy_uint>(vec, ind, cnt);
}
NPY_NO_EXPORT int
aradixsort_long(void *vec, npy_intp *ind, npy_intp cnt, void *NPY_UNUSED(null))
{
return aradixsort<npy_long>(vec, ind, cnt);
}
NPY_NO_EXPORT int
aradixsort_ulong(void *vec, npy_intp *ind, npy_intp cnt,
void *NPY_UNUSED(null))
{
return aradixsort<npy_ulong>(vec, ind, cnt);
}
NPY_NO_EXPORT int
aradixsort_longlong(void *vec, npy_intp *ind, npy_intp cnt,
void *NPY_UNUSED(null))
{
return aradixsort<npy_longlong>(vec, ind, cnt);
}
NPY_NO_EXPORT int
aradixsort_ulonglong(void *vec, npy_intp *ind, npy_intp cnt,
void *NPY_UNUSED(null))
{
return aradixsort<npy_ulonglong>(vec, ind, cnt);
}
}
Loading