You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The upcoming C++23 standard adds support for the std::float16_t and std::bfloat16_t types, and the upcoming GCC 13 release will have support for the std::float16_t and std::bfloat16_t types with the -std=c++23 option.
The hwy::bfloat16_t type should also be updated to allow for implicit conversions to/from std::bfloat16_t in C++23 or later mode on platforms that support the std::bfloat16_t type.
Here is how support for conversions between std::bfloat16_t and hwy::bfloat16_t could be implemented:
The updated implementation of hwy::bfloat16_t above will compile in C++11 or later mode, including with older C++11 compilers such as g++ 4.7.1 or clang 3.4.1.
The updated implementation of hwy::bfloat16_t also adds a hwy::bfloat16_t(SpecialFloatFromBitsTag, uint16_t) constructor to distinguish between constructing a hwy::bfloat16_t from its bit representation and a conversion to hwy::bfloat16_t from floating-point types.
The behavior of code such as the function below will change with the updated hwy::bfloat16 implementation above:
SomeFuncThatReturnsABF16 will return a hwy::bfloat16_t with the value of 2.75 with the current implementation (which initializes a hwy::bfloat16_t from the BF16 bitwise representation of 2.75), whereas SomeFuncThatReturnsABF16 will return a hwy::bfloat16_t with the value of 16432.0 with the updated implementation of hwy::bfloat16_t (which converts the integer value of 16432.0 to a floating point).
The updated hwy::bfloat16_t implementation above will allow code such as the following in C++23 mode with GCC 13 or later (with updates to the Set function):
namespace example {
namespace HWY_NAMESPACE {
using namespace hwy;
using namespace hwy::HWY_NAMESPACE;
template<class V>
static HWY_INLINE auto InvertNonSignBitsIfNegative(V v) {
const DFromV<decltype(v)> d;
const RebindToSigned<decltype(d)> di;
const RebindToUnsigned<decltype(d)> du;
const auto vi = BitCast(di, v);
const auto invert_mask = BitCast(di, ShiftRight<1>(
BitCast(du, BroadcastSignBit(vi))));
return Xor(vi, invert_mask);
}
template<class V>
static HWY_INLINE V FloatMinUsingIntCompare(V a, V b) {
const DFromV<decltype(a)> d;
return BitCast(d, InvertNonSignBitsIfNegative(Min(
InvertNonSignBitsIfNegative(a),
InvertNonSignBitsIfNegative(b))));
}
template<class V>
static HWY_INLINE V FloatMaxUsingIntCompare(V a, V b) {
const DFromV<decltype(a)> d;
return BitCast(d, InvertNonSignBitsIfNegative(Max(
InvertNonSignBitsIfNegative(a),
InvertNonSignBitsIfNegative(b))));
}
void SomeFuncThatProcessesBFloat16(hwy::bfloat16_t* result_ptr,
const hwy::bfloat16_t* src_ptr) {
ScalableTag<hwy::bfloat16_t> d;
const RebindToUnsigned<decltype(d)> du;
const auto v = Load(d, src_ptr);
const auto clamped = FloatMaxUsingIntCompare(
FloatMinUsingIntCompare(v, Set(du, 2.75bf16)),
Set(du, -5.375bf16));
}
}
}
The text was updated successfully, but these errors were encountered:
Interesting, thanks for proposing this. I agree it would be useful to have support for Set() of bfloat16_t. Currently tests use float constants that we then DemoteTo, which is not very convenient.
It's great that your proposal still works in C++11, that is important for us.
Should we change hwy::bfloat16_t to a typedef to std::bfloat16_t (where available) instead of using a wrapper?
That is also the approach we take with float16_t, though last I checked that only worked reliably on Arm and RVV.
If you'd like to start preparing a pull request, let's first change the constexpr+#if to a HWY_CONSTEXPR_BIT_CAST and HWY_CONSTEXPR2 (or some better name), which either expands to constexpr or nothing depending on compiler capabilities. This would shorten the spots where it is used, and also help with code folding in IDEs because they might not be able to fold past an #if.
For the record, my suggestion to change hwy::bfloat16_t to a typedef will break ABI compatibility, so let's not do that :)
But I like your idea of adding a ctor that takes std::bfloat16_t.
The upcoming C++23 standard adds support for the std::float16_t and std::bfloat16_t types, and the upcoming GCC 13 release will have support for the std::float16_t and std::bfloat16_t types with the
-std=c++23
option.The hwy::bfloat16_t type should also be updated to allow for implicit conversions to/from std::bfloat16_t in C++23 or later mode on platforms that support the std::bfloat16_t type.
Here is how support for conversions between std::bfloat16_t and hwy::bfloat16_t could be implemented:
The updated implementation of hwy::bfloat16_t above will compile in C++11 or later mode, including with older C++11 compilers such as g++ 4.7.1 or clang 3.4.1.
The updated implementation of hwy::bfloat16_t also adds a
hwy::bfloat16_t(SpecialFloatFromBitsTag, uint16_t)
constructor to distinguish between constructing a hwy::bfloat16_t from its bit representation and a conversion to hwy::bfloat16_t from floating-point types.The behavior of code such as the function below will change with the updated hwy::bfloat16 implementation above:
SomeFuncThatReturnsABF16 will return a hwy::bfloat16_t with the value of 2.75 with the current implementation (which initializes a hwy::bfloat16_t from the BF16 bitwise representation of 2.75), whereas SomeFuncThatReturnsABF16 will return a hwy::bfloat16_t with the value of 16432.0 with the updated implementation of hwy::bfloat16_t (which converts the integer value of 16432.0 to a floating point).
The updated hwy::bfloat16_t implementation above will allow code such as the following in C++23 mode with GCC 13 or later (with updates to the Set function):
The text was updated successfully, but these errors were encountered: