-
Notifications
You must be signed in to change notification settings - Fork 436
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes constexpr errors with frounding-math on gcc < 10. #4278
Conversation
Use std::numeric_limits digits10 instead of bespoke version trilinos/Trilinos/issues/9056 kokkos/issues/4267
Can one of the admins verify this patch? |
core/src/Kokkos_NumericTraits.hpp
Outdated
#define DIGITS10_HELPER_INTEGRAL(TYPE) \ | ||
template <> struct digits10_helper<TYPE> { static constexpr int value = digits_helper<TYPE>::value * log10_2; }; | ||
template <> struct digits10_helper<TYPE> { static constexpr int value = std::numeric_limits<TYPE>::digits10; }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't use std::numeric_limits
. This is not available in all backends and for all relevant configurations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I've fixed that. Was not aware sorry.
…ackends and follow gcc's constexpr-valid approximation of log10(2)
hi @masterleinad, oh ok. I've amended this PR to use This follows the log10_2 approximation in gcc. It is not clear to me why the 8bit is baked into the |
That might be a bug. I am seeing
for std::cout << Kokkos::Experimental::digits10<bool>::value << std::endl;
std::cout << Kokkos::Experimental::digits10<char>::value << std::endl;
std::cout << Kokkos::Experimental::digits10<signed char>::value << std::endl;
std::cout << Kokkos::Experimental::digits10<unsigned char>::value << std::endl;
std::cout << Kokkos::Experimental::digits10<short>::value << std::endl;
std::cout << Kokkos::Experimental::digits10<unsigned short>::value << std::endl;
std::cout << Kokkos::Experimental::digits10<int>::value << std::endl;
std::cout << Kokkos::Experimental::digits10<unsigned int>::value << std::endl;
std::cout << Kokkos::Experimental::digits10<long int>::value << std::endl;
std::cout << Kokkos::Experimental::digits10<unsigned long int>::value << std::endl;
std::cout << Kokkos::Experimental::digits10<long long int>::value << std::endl;
std::cout << Kokkos::Experimental::digits10<unsigned long long int>::value << std::endl;
std::cout << Kokkos::Experimental::digits10<float>::value << std::endl;
std::cout << Kokkos::Experimental::digits10<double>::value << std::endl;
std::cout << Kokkos::Experimental::digits10<long double>::value << std::endl; but std::numeric_limits<>::digits10 gives me
|
The compiler bug is described at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96862. I am wondering whether the workaround here really covers all situations or it just fails for another value. Would you mind checking if you can compile all |
core/src/Kokkos_NumericTraits.hpp
Outdated
@@ -141,7 +141,7 @@ template <> struct digits_helper<double> { static constexpr int value = DBL_MANT | |||
template <> struct digits_helper<long double> { static constexpr int value = LDBL_MANT_DIG; }; | |||
template <class> struct digits10_helper {}; | |||
template <> struct digits10_helper<bool> { static constexpr int value = 0; }; | |||
constexpr double log10_2 = 2.41; | |||
constexpr double log10_2 = 8*643L/2136; // The fraction 643/2136 approximates log10(2) to 7 significant digits. Follows gcc impl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be
constexpr double log10_2 = 8*643L/2136; // The fraction 643/2136 approximates log10(2) to 7 significant digits. Follows gcc impl | |
constexpr double log10_2 = 643./2136; // The fraction 643/2136 approximates log10(2) to 7 significant digits. Follows gcc impl |
? Note both the multiplication with 8
here and making sure the fraction is computed as a floating-point number.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe so.
a) It appears that any floating point in constexpr under -frounding-math
will trigger that bug, so constexpr double log10_2 = 643./2136;
puts us back to where we started.
b) The result needs to be rounded down, as having 2.41 digits makes no sense. AFAIK int/int
rounds to 0, which is correct and desired. Indeed I think this log10_2
should actually be a constexpr int
, not double
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, your code in the godbolt link shows that what you are proposing is equivalent to double log10_2=2
which gives wrong results when compared to std::numeric_limits<>::digits10
. I think I would in the end be OK with just hardcoding the values for digits10
instead of computing them at compile-time as workaround.
For reference https://godbolt.org/z/Kh6v4Ezs3 |
OK to test |
This is with this PR -- is that what you wanted? Or did it want it pre-PR changes? |
core/src/Kokkos_NumericTraits.hpp
Outdated
@@ -141,7 +141,7 @@ template <> struct digits_helper<double> { static constexpr int value = DBL_MANT | |||
template <> struct digits_helper<long double> { static constexpr int value = LDBL_MANT_DIG; }; | |||
template <class> struct digits10_helper {}; | |||
template <> struct digits10_helper<bool> { static constexpr int value = 0; }; | |||
constexpr double log10_2 = 2.41; | |||
constexpr int log10_2 = 8*643L/2136; // The fraction 643/2136 approximates log10(2) to 7 significant digits. Follows gcc impl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This yields I missed the 8. As Daniel pointed out it yields 0
2
That should be fine. |
#4281 supercedes this including a test and it is NOT passing tests on all compilers . |
Given this PR is addressing two problems and half of it is, seemingly, quite fiddly and better dealt with in #4281 as a separate PR, I think this should be amended to only address the |
Yeah we could just get the tuner thing through separately. |
Co-authored-by: Damien L-G <dalg24+github@gmail.com>
ok you can't make it const ... because then the copy constructor and assignment doesn't work (which ignores constexpr stuff I guess). |
Yes I'm seeing the same thing on a macos version I don't have locally. I'll remove it. |
Retest this please. |
Use std::numeric_limits digits10 instead of bespoke version
trilinos/Trilinos#9056
#4267