aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core
diff options
context:
space:
mode:
authorGravatar Benoit Steiner <benoit.steiner.goog@gmail.com>2015-08-21 16:01:40 -0700
committerGravatar Benoit Steiner <benoit.steiner.goog@gmail.com>2015-08-21 16:01:40 -0700
commita09cfe650fe56b181747af04d61548800da1f72b (patch)
tree7bc08d94ce01cc2063510fcea481d7d9495a9549 /Eigen/src/Core
parente5c78d85c8d173f37dcb2b57c1540c0574e467ef (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.h20
-rw-r--r--Eigen/src/Core/util/Meta.h37
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; }
};
}