fix error utils to work on architectures where std::is_normal is not …#637
fix error utils to work on architectures where std::is_normal is not …#637
Conversation
| return violates_condition(std::forward<valT>(value), is_strictly_positive{}, | ||
| return violates_condition(std::forward<valT>(value), is_non_negative{}, |
There was a problem hiding this comment.
this is just a typo. this condition was identical to the one above.
|
One thing to note, the code // Checks whether a value obeys some sort of provided condition. If not, returns true and
// prints the provided error message, variable name, and value (but does not abort!)
template <typename valT, typename condT, typename nameT>
PORTABLE_FORCEINLINE_FUNCTION bool violates_condition(valT &&value, condT &&condition,
nameT &&var_name) {
const bool good = condition(std::forward<valT>(value));
if (!good) {
printf("### ERROR: Bad singularity-eos value\n Var: %s\n Value: %.15e\n",
var_name, value);
}
return !good;
}is what actually calls the is_normal condition. I am torn about the print statement not being behind a |
adamdempsey90
left a comment
There was a problem hiding this comment.
Might be something worth putting in ports of call since it's a portable std:: function?
| constexpr double NORMAL_FACTOR = 1.0e10; | ||
|
|
||
| struct is_normal_or_zero { | ||
| template <typename valT> | ||
| constexpr bool PORTABLE_FORCEINLINE_FUNCTION operator()(valT value) const { | ||
| static_assert(std::is_floating_point<valT>::value); | ||
| using limits = std::numeric_limits<valT>; | ||
| const valT abs_value = (value < valT{0}) ? -value : value; | ||
| return (value == valT{0}) || | ||
| (std::isnormal(_NORMAL_FACTOR * value) && std::isnormal(value)); | ||
| ((abs_value >= limits::min()) && | ||
| (abs_value * static_cast<valT>(NORMAL_FACTOR) <= limits::max())); |
There was a problem hiding this comment.
| constexpr double NORMAL_FACTOR = 1.0e10; | |
| struct is_normal_or_zero { | |
| template <typename valT> | |
| constexpr bool PORTABLE_FORCEINLINE_FUNCTION operator()(valT value) const { | |
| static_assert(std::is_floating_point<valT>::value); | |
| using limits = std::numeric_limits<valT>; | |
| const valT abs_value = (value < valT{0}) ? -value : value; | |
| return (value == valT{0}) || | |
| (std::isnormal(_NORMAL_FACTOR * value) && std::isnormal(value)); | |
| ((abs_value >= limits::min()) && | |
| (abs_value * static_cast<valT>(NORMAL_FACTOR) <= limits::max())); | |
| constexpr double PORTABLE_FORCEINLINE_FUNCTION NORMAL_FACTOR() { return 1.0e10;} | |
| struct is_normal_or_zero { | |
| template <typename valT> | |
| constexpr bool PORTABLE_FORCEINLINE_FUNCTION operator()(valT value) const { | |
| static_assert(std::is_floating_point<valT>::value); | |
| using limits = std::numeric_limits<valT>; | |
| const valT abs_value = (value < valT{0}) ? -value : value; | |
| return (value == valT{0}) || | |
| ((abs_value >= limits::min()) && | |
| (abs_value * static_cast<valT>(NORMAL_FACTOR()) <= limits::max())); |
Can't use globals on device with nvcc
There was a problem hiding this comment.
constexpr scalars (and static arrays, insanely) are an exception:
https://godbolt.org/z/dWMP9or8q
There was a problem hiding this comment.
Huh, I've definitely tried to do this across multiple code bases and it never would compile
Needs to be behind debug because it's a performance hit |
The alternative is to remove the printing of the name and value so that there are no arguments passed to it. |
|
Now uses the ports-of-call method To support that, I also bumped us to C++20. |
| -DSINGULARITY_PLUGINS=$(pwd)/../example/plugin \ | ||
| -DCMAKE_LINKER=ld.gold \ | ||
| -DCMAKE_BUILD_TYPE=Release \ | ||
| -DCMAKE_CXX_STANDARD=20 \ |
There was a problem hiding this comment.
no longer needed as we're now just on C++20
| PORTABLE_FORCEINLINE_FUNCTION bool violates_condition(valT &&value, condT &&condition, | ||
| nameT &&var_name) { | ||
| const bool good = condition(std::forward<valT>(value)); | ||
| #ifndef NDEBUG |
There was a problem hiding this comment.
now added for performance and convenience
|
In the bump to C++20, I also bump the kokkos and kokkos-kernels submodules to 5.1.0. Note that this does not (yet) impact the spack builds. When we do our next release, we need to note the updated kokkos dependency. |
…supported
PR Summary
On a V100 architecture, @swjones discovered that$10^6$ . This is apparently because
bad_valuewas triggering on perfectly normal numbers, likestd::is_normalis not guaranteed to be available or functional on all GPU architectures. This MR (hopefully!) remedies the situation by (a) implementing the constexpr version ofis_normalourselves and (b) testing it to make sure that sticks.PR Checklist
make formatcommand after configuring withcmake.plan_historiesfolder, with a filename the same as the MR number.If preparing for a new release, in addition please check the following: