From 54459214a1b9c67df04bc529474fca1ec9f4c84f Mon Sep 17 00:00:00 2001 From: Chip Kerchner Date: Thu, 16 Feb 2023 23:35:42 +0000 Subject: [PATCH] Fix epsilon and dummy_precision values in long double for double doubles. Prevented some algorithms from converging on PPC. --- Eigen/src/Core/NumTraits.h | 14 ++++++++++++-- Eigen/src/SparseCore/SparseMatrix.h | 6 +++--- .../Eigen/src/MatrixFunctions/MatrixPower.h | 2 +- unsupported/test/cxx11_tensor_reduction.cpp | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Eigen/src/Core/NumTraits.h b/Eigen/src/Core/NumTraits.h index 53362ef78..0a32d69c0 100644 --- a/Eigen/src/Core/NumTraits.h +++ b/Eigen/src/Core/NumTraits.h @@ -246,8 +246,18 @@ template<> struct NumTraits : GenericNumTraits template<> struct NumTraits : GenericNumTraits { - EIGEN_CONSTEXPR - static inline long double dummy_precision() { return 1e-15l; } + EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR + static inline long double dummy_precision() { return static_cast(1e-15l); } + +#if defined(EIGEN_ARCH_PPC) && (__LDBL_MANT_DIG__ == 106) + // PowerPC double double causes issues with some values + EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR + static inline long double epsilon() + { + // 2^(-(__LDBL_MANT_DIG__)+1) + return static_cast(2.4651903288156618919116517665087e-32l); + } +#endif }; template struct NumTraits > diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h index bf1d56218..0d6e11446 100644 --- a/Eigen/src/SparseCore/SparseMatrix.h +++ b/Eigen/src/SparseCore/SparseMatrix.h @@ -1109,7 +1109,7 @@ void set_from_triplets(const InputIterator& begin, const InputIterator& end, Spa IndexMap outerIndexMap(mat.outerIndexPtr(), mat.outerSize() + 1); for (InputIterator it(begin); it != end; ++it) { eigen_assert(it->row() >= 0 && it->row() < mat.rows() && it->col() >= 0 && it->col() < mat.cols()); - StorageIndex j = IsRowMajor ? it->row() : it->col(); + StorageIndex j = static_cast(IsRowMajor ? it->row() : it->col()); outerIndexMap.coeffRef(j + 1)++; } @@ -1124,8 +1124,8 @@ void set_from_triplets(const InputIterator& begin, const InputIterator& end, Spa // push triplets to back of each inner vector for (InputIterator it(begin); it != end; ++it) { - StorageIndex j = IsRowMajor ? it->row() : it->col(); - StorageIndex i = IsRowMajor ? it->col() : it->row(); + StorageIndex j = static_cast(IsRowMajor ? it->row() : it->col()); + StorageIndex i = static_cast(IsRowMajor ? it->col() : it->row()); mat.data().index(back.coeff(j)) = i; mat.data().value(back.coeff(j)) = it->value(); back.coeffRef(j)++; diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h b/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h index 4eb865190..aca717b4d 100644 --- a/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h +++ b/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h @@ -283,7 +283,7 @@ inline int MatrixPowerAtomic::getPadeDegree(long double normIminusT) #endif int degree = 3; for (; degree <= maxPadeDegree; ++degree) - if (normIminusT <= maxNormForPade[degree - 3]) + if (normIminusT <= static_cast(maxNormForPade[degree - 3])) break; return degree; } diff --git a/unsupported/test/cxx11_tensor_reduction.cpp b/unsupported/test/cxx11_tensor_reduction.cpp index a090e4a8f..ce4e53860 100644 --- a/unsupported/test/cxx11_tensor_reduction.cpp +++ b/unsupported/test/cxx11_tensor_reduction.cpp @@ -485,7 +485,7 @@ void test_sum_accuracy() { // Test against probabilistic forward error bound. In reality, the error is much smaller // when we use tree summation. double err = Eigen::numext::abs(static_cast(sum()) - expected_sum); - double tol = numext::sqrt(num_elements) * NumTraits::epsilon() * static_cast(abs_sum); + double tol = numext::sqrt(static_cast(num_elements)) * NumTraits::epsilon() * static_cast(abs_sum); VERIFY_LE(err, tol); } }