I was wondering if anybody sees any glaring problems with doing the following:
template <>
struct numeric_limits<float> {
__host__ __device__ __forceinline__
static constexpr float quiet_NaN() {
#if defined(__CUDA_ARCH__)
return __builtin_nanf("");// <<< this line
#else
return std::numeric_limits<float>::quiet_NaN();
#endif
};
// ... some other methods ...
};
I only found out about __builtin_nanf by looking at the STL headers to see how they were creating a constexpr quiet NaN, so I don’t really know if I should use it or if I should go find the macro itself and expand it directly.
I saw some posts online showing that you could do return __int_as_float(0x7fffffff); for the device code, but then you cannot be a constexpr function.
Local tests indicate this works as expected, but I’m wondering if there is a time this could be a problem. I saw this article: https://software.intel.com/en-us/articles/limits1120-error-identifier-builtin-nanf-is-undefined
I’m only supporting VS 2015 and higher, and honestly don’t really care too much if the intel compilers work or not.
I tried to find a way to do some kind of static union with a float and int32_t but couldn’t find a way to actually get it to compile. You can’t static_cast in this scenario, and you can’t do reinterpret_cast either, since it’s constexpr.
Clearly, I can just not do constexpr, but I became rather intrigued by the difficulty of creating NaN and thought it was kind of cool.
Thanks for any thoughts :)