Files
2026-07-13 12:40:42 +08:00

133 lines
5.3 KiB
C++

// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <math.h>
#include "paddle/phi/common/complex.h"
namespace phi {
namespace funcs {
#define COMPARE_FUNCTOR(func_name, op) \
template <typename InT, typename OutT = bool> \
struct func_name { \
HOSTDEVICE OutT operator()(const InT a, const InT b) const { \
return static_cast<OutT>(a op b); \
} \
};
#define COMPARE_COMPLEX_FUNCTOR(func_name, op) \
template <typename T> \
struct func_name<phi::dtype::complex<T>> { \
HOSTDEVICE bool operator()(const phi::dtype::complex<T> a, \
const phi::dtype::complex<T> b) const { \
if (isnan(a.real) || isnan(a.imag) || isnan(b.real) || isnan(b.imag)) \
return false; \
return (a.real op b.real) || (a.real == b.real && a.imag op b.imag); \
} \
};
#define COMPARE_COMPLEX_EQUAL_FUNCTOR(func_name, op_equal, op) \
template <typename T> \
struct func_name<phi::dtype::complex<T>> { \
HOSTDEVICE bool operator()(const phi::dtype::complex<T> a, \
const phi::dtype::complex<T> b) const { \
if (isnan(a.real) || isnan(a.imag) || isnan(b.real) || isnan(b.imag)) \
return false; \
return (a.real op b.real) || \
(a.real == b.real && a.imag op_equal b.imag); \
} \
};
COMPARE_FUNCTOR(LessThanFunctor, <)
COMPARE_FUNCTOR(LessEqualFunctor, <=)
COMPARE_FUNCTOR(GreaterThanFunctor, >)
COMPARE_FUNCTOR(GreaterEqualFunctor, >=)
COMPARE_COMPLEX_FUNCTOR(LessThanFunctor, <)
COMPARE_COMPLEX_FUNCTOR(GreaterThanFunctor, >)
COMPARE_COMPLEX_EQUAL_FUNCTOR(LessEqualFunctor, <=, <)
COMPARE_COMPLEX_EQUAL_FUNCTOR(GreaterEqualFunctor, >=, >)
#undef COMPARE_FUNCTOR
#undef COMPARE_COMPLEX_FUNCTOR
#undef COMPARE_COMPLEX_EQUAL_FUNCTOR
template <typename InT, typename OutT = bool>
struct EqualFunctor {
HOSTDEVICE OutT operator()(const InT a, const InT b) const {
if (std::is_floating_point<InT>::value) {
if (isnan(static_cast<float>(a)) || isnan(static_cast<float>(b))) {
return static_cast<OutT>(false);
}
if (isinf(static_cast<float>(a)) || isinf(static_cast<float>(b))) {
return static_cast<OutT>(a == b);
}
return static_cast<OutT>(fabs(static_cast<double>(a - b)) < 1e-15);
} else {
return static_cast<OutT>(a == b);
}
}
};
template <typename InT, typename OutT = bool>
struct NanEqualFunctor {
HOSTDEVICE OutT operator()(const InT a, const InT b) const {
if (std::is_floating_point<InT>::value) {
if (isnan(static_cast<float>(a)) && isnan(static_cast<float>(b))) {
return static_cast<OutT>(true);
}
if (isnan(static_cast<float>(a)) || isnan(static_cast<float>(b))) {
return static_cast<OutT>(false);
}
if (isinf(static_cast<float>(a)) || isinf(static_cast<float>(b))) {
return static_cast<OutT>(a == b);
}
return static_cast<OutT>(fabs(static_cast<double>(a - b)) < 1e-15);
} else {
return static_cast<OutT>(a == b);
}
}
};
template <typename T>
struct EqualFunctor<phi::dtype::complex<T>> {
HOSTDEVICE bool operator()(const phi::dtype::complex<T> a,
const phi::dtype::complex<T> b) const {
if (isnan(static_cast<float>(a.real)) ||
isnan(static_cast<float>(a.imag)) ||
isnan(static_cast<float>(b.real)) ||
isnan(static_cast<float>(b.imag))) {
return static_cast<bool>(false);
}
if (isinf(static_cast<float>(a.real)) ||
isinf(static_cast<float>(a.imag)) ||
isinf(static_cast<float>(b.real)) ||
isinf(static_cast<float>(b.imag))) {
return static_cast<bool>(a.real == b.real && a.imag == b.imag);
}
return static_cast<bool>(
fabs(static_cast<double>(a.real - b.real)) < 1e-15 &&
fabs(static_cast<double>(a.imag - b.imag)) < 1e-15);
}
};
template <typename InT, typename OutT = bool>
struct NotEqualFunctor {
HOSTDEVICE bool operator()(const InT a, const InT b) const {
return !EqualFunctor<InT, OutT>()(a, b);
}
};
} // namespace funcs
} // namespace phi