diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index 5771abf7d..2bdf7dde7 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -937,6 +937,15 @@ template EIGEN_DEVICE_FUNC bool (isnan) (const T &x) { return inte template EIGEN_DEVICE_FUNC bool (isinf) (const T &x) { return internal::isinf_impl(x); } template EIGEN_DEVICE_FUNC bool (isfinite)(const T &x) { return internal::isfinite_impl(x); } +template EIGEN_DEVICE_FUNC int (fpclassify)(const T& x){ + #ifdef __CUDA_ARCH__ + return (::fpclassify)(x); + #else + using std::fpclassify; + return fpclassify(x); + #endif +} + template EIGEN_DEVICE_FUNC inline EIGEN_MATHFUNC_RETVAL(round, Scalar) round(const Scalar& x) diff --git a/Eigen/src/Core/arch/CUDA/Half.h b/Eigen/src/Core/arch/CUDA/Half.h index 9ecc4fd88..319074e4a 100644 --- a/Eigen/src/Core/arch/CUDA/Half.h +++ b/Eigen/src/Core/arch/CUDA/Half.h @@ -407,6 +407,28 @@ static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool (isnan)(const Eigen::half& a) static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool (isfinite)(const Eigen::half& a) { return !(Eigen::numext::isinf)(a) && !(Eigen::numext::isnan)(a); } +template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC int (fpclassify)(const Eigen::half& a) { + const int exponent = a.x & 0x7c00; + const int mantissa = a.x & 0x03ff; + if (exponent == 0) { + if (mantissa == 0) { + // Positive or negative zero. + return FP_ZERO; + } else { + return FP_SUBNORMAL; + } + } else if (exponent == 0x7c00) { + // Maximum possible exponent signifies either NaN or +/- inf. + if (mantissa == 0) { + return FP_INFINITE; + } else { + return FP_NAN; + } + } else { + return FP_NORMAL; + } +} + template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Eigen::half abs(const Eigen::half& a) { Eigen::half result; result.x = a.x & 0x7FFF;