From 2e7458353f50e77386a87053aed2ba8cdbbe2eda Mon Sep 17 00:00:00 2001 From: David Wells Date: Sun, 28 Feb 2016 16:08:06 -0500 Subject: [PATCH] Avoid boost functions that don't work on BSDs. As was noted in issue #2261, the function boost::math::iround cannot be used on some BSD variants due to the following compilation error: In file included from /root/workspace/dealii/source/lac/lapack_full_matrix.cc:25: In file included from /usr/local/include/boost/math/special_functions/round.hpp:15: In file included from /usr/local/include/boost/math/special_functions/fpclassify.hpp:19: In file included from /usr/local/include/boost/math/special_functions/math_fwd.hpp:26: In file included from /usr/local/include/boost/math/special_functions/detail/round_fwd.hpp:12: /usr/local/include/boost/math/tools/promotion.hpp:141:10: error: static_assert failed "Sorry, but this platform does not have sufficient long double support for the special functions to be reliably implemented." BOOST_STATIC_ASSERT_MSG((0 == ::boost::is_same::value), "Sorry, but this platform does not have sufficient long double support for the special functions to be reliably implement ed."); /usr/local/include/boost/static_assert.hpp:31:45: note: expanded from macro 'BOOST_STATIC_ASSERT_MSG' Since we only use iround for clarity this is not hard to work around. A note on the implementation: LAPACK functions can usually be run in two different modes. In the first, they compute the optimal size of the work array. In the second they actually execute the function. Therefore all we need to do is make the work arrays one longer and we should still get the same performance out of LAPACK without needing to worry about any unforeseen roundoff issues. --- source/lac/lapack_full_matrix.cc | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/source/lac/lapack_full_matrix.cc b/source/lac/lapack_full_matrix.cc index 52faaca150..c6f79ba36c 100644 --- a/source/lac/lapack_full_matrix.cc +++ b/source/lac/lapack_full_matrix.cc @@ -22,8 +22,6 @@ #include #include -#include - #include #include @@ -504,8 +502,9 @@ LAPACKFullMatrix::compute_svd() &wr[0], mu, &mm, mvt, &nn, &work[0], &lwork, &ipiv[0], &info); AssertThrow (info==0, LAPACKSupport::ExcErrorCode("gesdd", info)); - // Now resize work array and - lwork = boost::math::iround(work[0]); + // Resize the work array. Add one to the size computed by LAPACK to be on + // the safe side. + lwork = static_cast(work[0] + 1); work.resize(lwork); // Do the actual SVD. @@ -656,8 +655,9 @@ LAPACKFullMatrix::compute_eigenvalues(const bool right, // geev returns info=0 on success. Since we only queried the optimal size // for work, everything else would not be acceptable. Assert (info == 0, ExcInternalError()); - // Allocate working array according to suggestion. - lwork = boost::math::iround(work[0]); + // Allocate working array according to suggestion (same strategy as was + // noted in compute_svd). + lwork = static_cast(work[0] + 1); // resize workspace array work.resize((size_type ) lwork); @@ -728,8 +728,9 @@ LAPACKFullMatrix::compute_eigenvalues_symmetric(const number lowe // syevx returns info=0 on success. Since we only queried the optimal size // for work, everything else would not be acceptable. Assert (info == 0, ExcInternalError()); - // Allocate working array according to suggestion. - lwork = boost::math::iround(work[0]); + // Allocate working array according to suggestion (same strategy as was noted in + // compute_svd). + lwork = static_cast(work[0] + 1); work.resize(static_cast (lwork)); // Finally compute the eigenvalues. @@ -818,8 +819,9 @@ LAPACKFullMatrix::compute_generalized_eigenvalues_symmetric( // sygvx returns info=0 on success. Since we only queried the optimal size // for work, everything else would not be acceptable. Assert (info == 0, ExcInternalError()); - // Allocate working array according to suggestion. - lwork = boost::math::iround(work[0]); + // Allocate working array according to suggestion (same strategy as was + // noted in compute_svd). + lwork = static_cast(work[0] + 1); // resize workspace arrays work.resize(static_cast (lwork)); @@ -899,8 +901,9 @@ LAPACKFullMatrix::compute_generalized_eigenvalues_symmetric ( // sygv returns info=0 on success. Since we only queried the optimal size // for work, everything else would not be acceptable. Assert (info == 0, ExcInternalError()); - // Allocate working array according to suggestion. - lwork = boost::math::iround(work[0]); + // Allocate working array according to suggestion (same strategy as was + // noted in compute_svd). + lwork = static_cast(work[0] + 1); // resize workspace array work.resize((size_type) lwork); -- 2.39.5