Skip to content

Commit 8a87fea

Browse files
Move utils rich_comparisons.hpp file
1 parent a1d9b0a commit 8a87fea

1 file changed

Lines changed: 149 additions & 0 deletions

File tree

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
//*****************************************************************************
2+
// Copyright (c) 2026, Intel Corporation
3+
// All rights reserved.
4+
//
5+
// Redistribution and use in source and binary forms, with or without
6+
// modification, are permitted provided that the following conditions are met:
7+
// - Redistributions of source code must retain the above copyright notice,
8+
// this list of conditions and the following disclaimer.
9+
// - Redistributions in binary form must reproduce the above copyright notice,
10+
// this list of conditions and the following disclaimer in the documentation
11+
// and/or other materials provided with the distribution.
12+
// - Neither the name of the copyright holder nor the names of its contributors
13+
// may be used to endorse or promote products derived from this software
14+
// without specific prior written permission.
15+
//
16+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20+
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26+
// THE POSSIBILITY OF SUCH DAMAGE.
27+
//*****************************************************************************
28+
///
29+
/// \file
30+
/// This file defines functions of dpctl.tensor._tensor_sorting_impl
31+
/// extension.
32+
//===---------------------------------------------------------------------===//
33+
34+
#pragma once
35+
36+
#include <cmath>
37+
#include <complex>
38+
#include <functional>
39+
#include <type_traits>
40+
41+
#include "sycl/sycl.hpp"
42+
43+
namespace dpctl::tensor::rich_comparisons
44+
{
45+
46+
namespace detail
47+
{
48+
template <typename fpT>
49+
struct ExtendedRealFPLess
50+
{
51+
/* [R, nan] */
52+
bool operator()(const fpT v1, const fpT v2) const
53+
{
54+
return (!std::isnan(v1) && (std::isnan(v2) || (v1 < v2)));
55+
}
56+
};
57+
58+
template <typename fpT>
59+
struct ExtendedRealFPGreater
60+
{
61+
bool operator()(const fpT v1, const fpT v2) const
62+
{
63+
return (!std::isnan(v2) && (std::isnan(v1) || (v2 < v1)));
64+
}
65+
};
66+
67+
template <typename cT>
68+
struct ExtendedComplexFPLess
69+
{
70+
/* [(R, R), (R, nan), (nan, R), (nan, nan)] */
71+
72+
bool operator()(const cT &v1, const cT &v2) const
73+
{
74+
using realT = typename cT::value_type;
75+
76+
const realT real1 = std::real(v1);
77+
const realT real2 = std::real(v2);
78+
79+
const bool r1_nan = std::isnan(real1);
80+
const bool r2_nan = std::isnan(real2);
81+
82+
const realT imag1 = std::imag(v1);
83+
const realT imag2 = std::imag(v2);
84+
85+
const bool i1_nan = std::isnan(imag1);
86+
const bool i2_nan = std::isnan(imag2);
87+
88+
const int idx1 = ((r1_nan) ? 2 : 0) + ((i1_nan) ? 1 : 0);
89+
const int idx2 = ((r2_nan) ? 2 : 0) + ((i2_nan) ? 1 : 0);
90+
91+
const bool res =
92+
!(r1_nan && i1_nan) &&
93+
((idx1 < idx2) ||
94+
((idx1 == idx2) &&
95+
((r1_nan && !i1_nan && (imag1 < imag2)) ||
96+
(!r1_nan && i1_nan && (real1 < real2)) ||
97+
(!r1_nan && !i1_nan &&
98+
((real1 < real2) || (!(real2 < real1) && (imag1 < imag2)))))));
99+
100+
return res;
101+
}
102+
};
103+
104+
template <typename cT>
105+
struct ExtendedComplexFPGreater
106+
{
107+
bool operator()(const cT &v1, const cT &v2) const
108+
{
109+
auto less_ = ExtendedComplexFPLess<cT>{};
110+
return less_(v2, v1);
111+
}
112+
};
113+
114+
template <typename T>
115+
inline constexpr bool is_fp_v = (std::is_same_v<T, sycl::half> ||
116+
std::is_same_v<T, float> ||
117+
std::is_same_v<T, double>);
118+
119+
} // namespace detail
120+
121+
template <typename argTy>
122+
struct AscendingSorter
123+
{
124+
using type = std::conditional_t<detail::is_fp_v<argTy>,
125+
detail::ExtendedRealFPLess<argTy>,
126+
std::less<argTy>>;
127+
};
128+
129+
template <typename T>
130+
struct AscendingSorter<std::complex<T>>
131+
{
132+
using type = detail::ExtendedComplexFPLess<std::complex<T>>;
133+
};
134+
135+
template <typename argTy>
136+
struct DescendingSorter
137+
{
138+
using type = std::conditional_t<detail::is_fp_v<argTy>,
139+
detail::ExtendedRealFPGreater<argTy>,
140+
std::greater<argTy>>;
141+
};
142+
143+
template <typename T>
144+
struct DescendingSorter<std::complex<T>>
145+
{
146+
using type = detail::ExtendedComplexFPGreater<std::complex<T>>;
147+
};
148+
149+
} // namespace dpctl::tensor::rich_comparisons

0 commit comments

Comments
 (0)