Add explicit `_Float16` cast operator to Eigen::half
Reference issue
Fixes #2835 (closed)
What does this implement/fix?
Fix compilation on AVX512FP16. An cast from or to an extended floating point type is only implicit when the conversion is non-lossy.
This affects Eigen::half which has an implicit float conversion operator but is passed to functions expecting a _Float16 or cast into that, i.e. static_cast<_Float16>(halfInstance). This is disallowed by the (proposed) C++ standard and seemingly enforced in GCC 13 where such code fails to compile.
The solution proposed here is an explicit _Float16 conversion operator such that the static_cast above works.
The explicit operator is similar to using the bit_cast at each usage but less confusing (as to why the bit_cast is allowed at that point)
It cannot be implicit because that would conflict with the float conversion operator if the is present, create ODR issues when (either) is conditionally present and ambiguous overloads when only the _Float16 conversion operator exists, because e.g. std::isnan accept either a float or a double which are both equally viable for a _Float16 instance.
Similarly float or even double constants are used as input to intrinsics expecting a _Float16 which is also not allowed. Currently this results in warnings such as
warning: ISO C++ does not allow converting to '_Float16' from 'float' with greater conversion rank [-Wnarrowing]
But that likely will be a hard error according to the wording. See https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1467r4.html#implicit and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112498
Hence use namespace scoped user defined literals for specifying half-precision constants.
I compile-tested a large number with EIGEN_TEST_AVX512DQ, EIGEN_TEST_AVX512FP16, EIGEN_TEST_F16C enabled and also with CMAKE_CXX_FLAGS=-march=sapphirerapids