diff options
author | Benoit Steiner <benoit.steiner.goog@gmail.com> | 2015-08-21 16:01:40 -0700 |
---|---|---|
committer | Benoit Steiner <benoit.steiner.goog@gmail.com> | 2015-08-21 16:01:40 -0700 |
commit | a09cfe650fe56b181747af04d61548800da1f72b (patch) | |
tree | 7bc08d94ce01cc2063510fcea481d7d9495a9549 /Eigen/src/Core | |
parent | e5c78d85c8d173f37dcb2b57c1540c0574e467ef (diff) |
std::numeric_limits doesn't work reliably on CUDA devices. Use our own definition of numeric_limit<T>::max() and numeric_limit<T>::min() instead of the stl ones.
Diffstat (limited to 'Eigen/src/Core')
-rw-r--r-- | Eigen/src/Core/NumTraits.h | 20 | ||||
-rw-r--r-- | Eigen/src/Core/util/Meta.h | 37 |
2 files changed, 55 insertions, 2 deletions
diff --git a/Eigen/src/Core/NumTraits.h b/Eigen/src/Core/NumTraits.h index a04227f57..4d60cf88b 100644 --- a/Eigen/src/Core/NumTraits.h +++ b/Eigen/src/Core/NumTraits.h @@ -83,8 +83,24 @@ template<typename T> struct GenericNumTraits // make sure to override this for floating-point types return Real(0); } - static inline T highest() { return (std::numeric_limits<T>::max)(); } - static inline T lowest() { return IsInteger ? (std::numeric_limits<T>::min)() : (-(std::numeric_limits<T>::max)()); } + + + EIGEN_DEVICE_FUNC + static inline T highest() { +#if defined(__CUDA_ARCH__) + return internal::device::numeric_limits<T>::max(); +#else + return (std::numeric_limits<T>::max)(); +#endif + } + + EIGEN_DEVICE_FUNC + static inline T lowest() { +#if defined(__CUDA_ARCH__) + return IsInteger ? (internal::device::numeric_limits<T>::min)() : (-(internal::device::numeric_limits<T>::max)()); +#else + return IsInteger ? (std::numeric_limits<T>::min)() : (-(std::numeric_limits<T>::max)()); +#endif }; template<typename T> struct NumTraits : GenericNumTraits<T> diff --git a/Eigen/src/Core/util/Meta.h b/Eigen/src/Core/util/Meta.h index 7c8932511..152a0fd78 100644 --- a/Eigen/src/Core/util/Meta.h +++ b/Eigen/src/Core/util/Meta.h @@ -128,16 +128,53 @@ template<typename T> struct numeric_limits { EIGEN_DEVICE_FUNC static T epsilon() { return 0; } + static T max() { assert(false && "Highest not suppoted for this type"); } + static T min() { assert(false && "Lowest not suppoted for this type"); } }; template<> struct numeric_limits<float> { EIGEN_DEVICE_FUNC static float epsilon() { return __FLT_EPSILON__; } + EIGEN_DEVICE_FUNC + static float max() { return CUDART_MAX_NORMAL_F; } + EIGEN_DEVICE_FUNC + static float min() { return __FLT_EPSILON__; } }; template<> struct numeric_limits<double> { EIGEN_DEVICE_FUNC static double epsilon() { return __DBL_EPSILON__; } + EIGEN_DEVICE_FUNC + static double max() { return CUDART_INF; } + EIGEN_DEVICE_FUNC + static double min() { return __DBL_EPSILON__; } +}; +template<> struct numeric_limits<int> +{ + EIGEN_DEVICE_FUNC + static int epsilon() { return 0; } + EIGEN_DEVICE_FUNC + static int max() { return INT_MAX; } + EIGEN_DEVICE_FUNC + static int min() { return INT_MIN; } +}; +template<> struct numeric_limits<long> +{ + EIGEN_DEVICE_FUNC + static long epsilon() { return 0; } + EIGEN_DEVICE_FUNC + static long max() { return LONG_MAX; } + EIGEN_DEVICE_FUNC + static long min() { return LONG_MIN; } +}; +template<> struct numeric_limits<long long> +{ + EIGEN_DEVICE_FUNC + static long long epsilon() { return 0; } + EIGEN_DEVICE_FUNC + static long long max() { return LLONG_MAX; } + EIGEN_DEVICE_FUNC + static long long min() { return LLONG_MIN; } }; } |