Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b7412df
Implements kernels for median and partition functions
ndgrigorian Oct 31, 2026
f772a86
Report the coverage of dpnp.partition's kernel
ndgrigorian Nov 2, 2026
d6f2a49
Instrument only the host code of the radix select sources
ndgrigorian Nov 3, 2026
5f762d3
Avoid an all-NaN row in TestNanMedianSelect::test_basic
ndgrigorian Nov 3, 2026
9bc5b87
Check the shape of out in the select path of median and nanmedian
ndgrigorian Nov 4, 2026
b228094
Test the queue and USM type of partition and argpartition results
ndgrigorian Nov 4, 2026
4a4d385
Validate the inputs of _median and _partition for an empty batch
ndgrigorian Nov 4, 2026
45c205f
Add the changelog entries of argpartition and the radix select
ndgrigorian Nov 4, 2026
fd4c14a
Accept an out of the keepdims shape in median and nanmedian
ndgrigorian Nov 4, 2026
a130521
Give -0.0 the radix key of +0.0 by comparing keys
ndgrigorian Nov 4, 2026
de21311
Order the all_nan fill of the empty-batch median test after its creation
ndgrigorian Nov 4, 2026
6197e60
Instrument only the host code of the whole _statistics_impl module
ndgrigorian Nov 4, 2026
6e7c737
Average the two medians of an even row even when they are equal
ndgrigorian Nov 8, 2026
4999347
Reject src and dst sharing memory in _partition and _argpartition
ndgrigorian Nov 8, 2026
ebf1e5b
Validate kth of partition and argpartition as NumPy does
ndgrigorian Nov 8, 2026
c37e2d8
Say overwrite_input may modify the input of median and nanmedian
ndgrigorian Nov 8, 2026
c02897b
Remove dpnp_less_comp and the backend partition mentions
ndgrigorian Nov 8, 2026
8b13ff6
Ignore NumPy's intended overflow in the special-value median tests
ndgrigorian Nov 8, 2026
d4826ca
Wait for the all_nan fill of _median if the selection throws
ndgrigorian Nov 8, 2026
e710323
Reject an all_nan sharing memory with src or dst in _median
ndgrigorian Nov 8, 2026
72d1cd4
Make is_median_type_pair a variable template, which llvm-cov doesn't …
ndgrigorian Nov 8, 2026
0763597
Filter top_k only after the first pass of the multi-group radix selec…
ndgrigorian Nov 8, 2026
25e12f2
Keep the per work-group maxima of the median with the counts rather t…
ndgrigorian Nov 8, 2026
32e565c
Say sub-group rows of radix_partition_impl come out sorted
ndgrigorian Nov 8, 2026
9074bc5
Warn in the nanmedian docstring that it synchronizes
ndgrigorian Nov 8, 2026
358772b
Cast the medians to out unsafely, so complex nanmedian accepts an out…
ndgrigorian Nov 8, 2026
7d5de58
Run the out, all-NaN and usm_ndarray median tests with complex input …
ndgrigorian Nov 8, 2026
6a93a8c
Read the all-NaN flag of nanmedian in place from host USM
ndgrigorian Nov 8, 2026
22c3e4d
Fill the median of an empty array with NaN, without selecting or sorting
ndgrigorian Nov 8, 2026
7cb4b7d
Link dpnp.argpartition from dpnp.top_k and ndarray.argsort
ndgrigorian Nov 8, 2026
fa677d6
Fix the ndarray.partition docstring: a Parameters heading, a link and…
ndgrigorian Nov 8, 2026
08a32d3
Say partition selects only for a single kth in the changelog
ndgrigorian Nov 10, 2026
2f07cdc
Build partition.cpp with -fno-fast-math, as topk.cpp in the same module
ndgrigorian Nov 10, 2026
4acd8d3
Add the \file blocks to the partition and median sources
ndgrigorian Nov 10, 2026
6d970d3
Keep the all-NaN flag of nanmedian in host USM only where the device …
ndgrigorian Nov 10, 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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ This release drops support for Python 3.10, making Python 3.11 the minimum requi

* Added support for boolean input in `dpnp.positive` and the `+` operator of `dpnp.ndarray` [#3128](https://github.com/IntelPython/dpnp/pull/3128)
* Added `dpnp.top_k` to return the `k` largest or smallest elements and their indices along an axis, with a `sorted` keyword to return them in sorted order [#3133](https://github.com/IntelPython/dpnp/pull/3133)
* Added `dpnp.argpartition` and `dpnp.ndarray.argpartition` to return the indices that would partition an array [#3138](https://github.com/IntelPython/dpnp/pull/3138)

### Changed

Expand All @@ -23,6 +24,7 @@ This release drops support for Python 3.10, making Python 3.11 the minimum requi
* Improved performance of `dpnp.scipy.sparse.csr_matrix.sort_indices` by sorting once on a combined row and column key instead of in two passes [#3134](https://github.com/IntelPython/dpnp/pull/3134)
* Reduced the overhead of `dpnp.ndarray.flags` and `dpnp.tensor.usm_ndarray.flags` [#3168](https://github.com/IntelPython/dpnp/pull/3168)
* Changed `dpnp.linalg.LinAlgError` to derive from `numpy.linalg.LinAlgError`, so `except numpy.linalg.LinAlgError` also catches errors raised by dpnp linear algebra functions [#3184](https://github.com/IntelPython/dpnp/pull/3184)
* Changed `dpnp.median`, `dpnp.nanmedian` and `dpnp.partition` with a single `kth` to use a radix select instead of a full sort for all but complex data types [#3138](https://github.com/IntelPython/dpnp/pull/3138)

### Deprecated

Expand All @@ -36,6 +38,7 @@ This release drops support for Python 3.10, making Python 3.11 the minimum requi
* Removed the unused `FourZeroOffsets_Indexer`, `FixedDimStridedIndexer` and `ThreeOffsets_FixedDimStridedIndexer` from the libtensor header `utils/offset_utils.hpp` [#3131](https://github.com/IntelPython/dpnp/pull/3131)
* Dropped support for Python 3.10 [#3173](https://github.com/IntelPython/dpnp/pull/3173)
* Removed the `USE_GROUP_LOAD_STORE` macro from the libtensor header `utils/sycl_utils.hpp`, so `sub_group_load` and `sub_group_store` always use the `sycl_ext_oneapi_group_load_store` extension; the `sycl::sub_group` member load/store fallback it selected does not compile with DPC++ 2026.0, the minimum supported compiler [#3174](https://github.com/IntelPython/dpnp/pull/3174)
* Removed the legacy implementation of `dpnp.partition` from the backend [#3138](https://github.com/IntelPython/dpnp/pull/3138)

### Fixed

Expand All @@ -44,6 +47,9 @@ This release drops support for Python 3.10, making Python 3.11 the minimum requi
* Fixed `dpnp.place` and `dpnp.tensor.place` to order the write after the cast of `vals` to the array's data type, which could put wrong values into the array on an out-of-order queue [#3164](https://github.com/IntelPython/dpnp/pull/3164)
* Fixed the example of handling duplicate indices in the `dpnp.tensor.put` docstring, which imported `dpctl.tensor`, did not parse and lost writes when `x` is longer than `indices` [#3165](https://github.com/IntelPython/dpnp/pull/3165)
* Fixed a segfault when setting `writable` on a `Flags` object created without an array [#3168](https://github.com/IntelPython/dpnp/pull/3168)
* Fixed `dpnp.median` and `dpnp.nanmedian` raising `ValueError` for an `out` array of the result shape with `keepdims=True` [#3138](https://github.com/IntelPython/dpnp/pull/3138)
* Fixed `dpnp.partition` to accept NumPy integers and integer arrays as `kth`, and to raise as NumPy does for a boolean or an empty `kth` [#3138](https://github.com/IntelPython/dpnp/pull/3138)
* Fixed `dpnp.nanmedian` raising `TypeError` for an `out` array of a lower precision data type instead of casting to it as `dpnp.median` does [#3138](https://github.com/IntelPython/dpnp/pull/3138)

### Security

Expand Down
2 changes: 1 addition & 1 deletion dpnp/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
- `dpnp_algo/dpnp_elementwise_common.py`: ufunc wrapper classes (`DPNPUnaryFunc`, `DPNPBinaryFunc`, two-output and specialised variants)
- `dpnp_utils/`: shared helpers (`get_usm_allocations`, `map_dtype_to_device`, reduction wrappers)
- `linalg/`, `fft/`, `random/`, `scipy/`, `lib/`: subpackages, each exporting through its own `__init__.py`
- Legacy, don't extend: the Cython `dpnp_algo` path and `dpnp_backend_c` (still used by `dpnp.partition` and `dpnp.random`), and the NumPy fallback `call_origin`. New kernels go into `dpnp/libtensor` (see `dpnp/libtensor/AGENTS.md`).
- Legacy, don't extend: the Cython `dpnp_algo` path and `dpnp_backend_c` (still used by `dpnp.random`), and the NumPy fallback `call_origin`. New kernels go into `dpnp/libtensor` (see `dpnp/libtensor/AGENTS.md`).

## Adding a Public Function
1. Implement it in the matching `dpnp_iface_*.py` or subpackage module. Iface modules have no `__all__`.
Expand Down
2 changes: 2 additions & 0 deletions dpnp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@
where,
)
from .dpnp_iface_sorting import (
argpartition,
argsort,
partition,
sort,
Expand Down Expand Up @@ -988,6 +989,7 @@
__all__ += [
"argmax",
"argmin",
"argpartition",
"argwhere",
"argsort",
"count_nonzero",
Expand Down
2 changes: 1 addition & 1 deletion dpnp/backend/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
Legacy, don't extend: new kernels and bindings go into `dpnp/libtensor` (see `dpnp/libtensor/AGENTS.md`, which also holds the C++ rules and build options).

## Layout
- `src/`, `include/` and `kernels/dpnp_krnl_*.cpp` build `dpnp_backend_c` (still used by `dpnp.partition` and `dpnp.random`); `tests/` (GTest, `-DDPNP_BACKEND_TESTS=ON`) and `examples/` are not built in CI
- `src/`, `include/` and `kernels/dpnp_krnl_*.cpp` build `dpnp_backend_c` (still used by `dpnp.random`); `tests/` (GTest, `-DDPNP_BACKEND_TESTS=ON`) and `examples/` are not built in CI
- `cmake/Modules/`: vendored `IntelSYCL`, `MKL`, `TBB` and `oneDPL` config modules, used by the whole build
1 change: 0 additions & 1 deletion dpnp/backend/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ set(DPNP_SRC
kernels/dpnp_krnl_arraycreation.cpp
kernels/dpnp_krnl_common.cpp
kernels/dpnp_krnl_random.cpp
kernels/dpnp_krnl_sorting.cpp
src/dpnp_iface_fptr.cpp
src/memory_sycl.cpp
src/queue_sycl.cpp
Expand Down
32 changes: 0 additions & 32 deletions dpnp/backend/include/dpnp_iface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,38 +103,6 @@ INP_DLLEXPORT void dpnp_memory_memcpy_c(DPCTLSyclQueueRef q_ref,
INP_DLLEXPORT void
dpnp_memory_memcpy_c(void *dst, const void *src, size_t size_in_bytes);

/**
* @ingroup BACKEND_API
* @brief Return a partitioned copy of an array.
*
* @param [in] q_ref Reference to SYCL queue.
* @param [in] array Input array.
* @param [in] array2 Copy input array.
* @param [out] result Result array.
* @param [in] kth Element index to partition by.
* @param [in] shape Shape of input array.
* @param [in] ndim Number of elements in shape.
* @param [in] dep_event_vec_ref Reference to vector of SYCL events.
*/
template <typename _DataType>
INP_DLLEXPORT DPCTLSyclEventRef
dpnp_partition_c(DPCTLSyclQueueRef q_ref,
void *array,
void *array2,
void *result,
const size_t kth,
const shape_elem_type *shape,
const size_t ndim,
const DPCTLEventVectorRef dep_event_vec_ref);

template <typename _DataType>
INP_DLLEXPORT void dpnp_partition_c(void *array,
void *array2,
void *result,
const size_t kth,
const shape_elem_type *shape,
const size_t ndim);

/**
* @ingroup BACKEND_API
* @brief implementation of creating filled with value array function
Expand Down
19 changes: 8 additions & 11 deletions dpnp/backend/include/dpnp_iface_fptr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,14 @@ enum class DPNPFuncName : size_t
DPNP_FN_NONE, /**< Very first element of the enumeration */
DPNP_FN_INITVAL, /**< Used in numpy ones, ones_like, zeros, zeros_like impls
*/
DPNP_FN_INITVAL_EXT, /**< Used in numpy ones, ones_like, zeros, zeros_like
impls */
DPNP_FN_ONES, /**< Used in numpy.ones() impl */
DPNP_FN_ONES_LIKE, /**< Used in numpy.ones_like() impl */
DPNP_FN_PARTITION, /**< Used in numpy.partition() impl */
DPNP_FN_PARTITION_EXT, /**< Used in numpy.partition() impl, requires extra
parameters */
DPNP_FN_RNG_BETA, /**< Used in numpy.random.beta() impl */
DPNP_FN_RNG_BETA_EXT, /**< Used in numpy.random.beta() impl, requires extra
parameters */
DPNP_FN_RNG_BINOMIAL, /**< Used in numpy.random.binomial() impl */
DPNP_FN_INITVAL_EXT, /**< Used in numpy ones, ones_like, zeros, zeros_like
impls */
DPNP_FN_ONES, /**< Used in numpy.ones() impl */
DPNP_FN_ONES_LIKE, /**< Used in numpy.ones_like() impl */
DPNP_FN_RNG_BETA, /**< Used in numpy.random.beta() impl */
DPNP_FN_RNG_BETA_EXT, /**< Used in numpy.random.beta() impl, requires extra
parameters */
DPNP_FN_RNG_BINOMIAL, /**< Used in numpy.random.binomial() impl */
DPNP_FN_RNG_BINOMIAL_EXT, /**< Used in numpy.random.binomial() impl,
requires extra parameters */
DPNP_FN_RNG_CHISQUARE, /**< Used in numpy.random.chisquare() impl */
Expand Down
160 changes: 0 additions & 160 deletions dpnp/backend/kernels/dpnp_krnl_sorting.cpp

This file was deleted.

84 changes: 0 additions & 84 deletions dpnp/backend/src/dpnp_fptr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,95 +72,11 @@ const DPNPFuncType eft_C64 = DPNPFuncType::DPNP_FT_CMPLX64;
const DPNPFuncType eft_C128 = DPNPFuncType::DPNP_FT_CMPLX128;
const DPNPFuncType eft_BLN = DPNPFuncType::DPNP_FT_BOOL;

/**
* Implements std::is_same<> with variadic number of types to compare with
* and when type T has to match only one of types Ts.
*/
template <typename T, typename... Ts>
struct is_any : std::disjunction<std::is_same<T, Ts>...>
{
};

/**
* Implements std::is_same<> with variadic number of types to compare with
* and when type T has to match every type from Ts sequence.
*/
template <typename T, typename... Ts>
struct are_same : std::conjunction<std::is_same<T, Ts>...>
{
};

/**
* A template constant to check if type T matches any type from Ts.
*/
template <typename T, typename... Ts>
constexpr auto is_any_v = is_any<T, Ts...>::value;

/**
* A template constat to check if both types T1 and T2 match every type from Ts
* sequence.
*/
template <typename T1, typename T2, typename... Ts>
constexpr auto both_types_are_same =
std::conjunction_v<is_any<T1, Ts...>, are_same<T1, T2>>;

/**
* @brief If the type _Tp is a reference type, provides the member typedef type
* which is the type referred to by _Tp with its topmost cv-qualifiers removed.
* Otherwise type is _Tp with its topmost cv-qualifiers removed.
*
* @note std::remove_cvref is only available since c++20
*/
template <typename _Tp>
using dpnp_remove_cvref_t =
typename std::remove_cv_t<typename std::remove_reference_t<_Tp>>;

/**
* @brief "<" comparison with complex types support.
*
* @note return a result of lexicographical "<" comparison for complex types.
*/
class dpnp_less_comp
{
public:
template <typename _Xp, typename _Yp>
bool operator()(_Xp &&__x, _Yp &&__y) const
{
if constexpr (both_types_are_same<
dpnp_remove_cvref_t<_Xp>, dpnp_remove_cvref_t<_Yp>,
std::complex<float>, std::complex<double>>) {
bool ret = false;
_Xp a = std::forward<_Xp>(__x);
_Yp b = std::forward<_Yp>(__y);

if (a.real() < b.real()) {
ret = (a.imag() == a.imag() || b.imag() != b.imag());
}
else if (a.real() > b.real()) {
ret = (b.imag() != b.imag() && a.imag() == a.imag());
}
else if (a.real() == b.real() ||
(a.real() != a.real() && b.real() != b.real())) {
ret = (a.imag() < b.imag() ||
(b.imag() != b.imag() && a.imag() == a.imag()));
}
else {
ret = (b.real() != b.real());
}
return ret;
}
else {
return std::forward<_Xp>(__x) < std::forward<_Yp>(__y);
}
}
};

/**
* FPTR interface initialization functions
*/
void func_map_init_arraycreation(func_map_t &fmap);
void func_map_init_linalg(func_map_t &fmap);
void func_map_init_random(func_map_t &fmap);
Comment thread
ndgrigorian marked this conversation as resolved.
Resolved
void func_map_init_sorting(func_map_t &fmap);

#endif // BACKEND_FPTR_H
Loading
Loading