-
Notifications
You must be signed in to change notification settings - Fork 94
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
Integrating generic_float struct for adding datatypes #3522
Conversation
A couple of things:
The specializations should use the template type like: template<unsigned int E, unsigned int M, unsigned int F>
class numeric_limits<migraphx::generic_float<E, M, F>>
{
...
}; |
Also, we can use the fp8 template type as well to reduce the number common_type overloads: template<unsigned int E, unsigned int M, unsigned int F, migraphx::fp8::f8_type T, bool FNUZ>
struct common_type<migraphx::generic_float<E, M, F>, migraphx::fp8::float8<T, FNUZ>> : std::common_type<float, float>
{};
template<unsigned int E, unsigned int M, unsigned int F, migraphx::fp8::f8_type T, bool FNUZ>
struct common_type<migraphx::fp8::float8<T, FNUZ>, migraphx::generic_float<E, M, F>> : std::common_type<float, float>
{}; |
For the fp16 tests, we want test similiar to the fp8, but instead of having an array lookup table, we would sample some values into a map and test that: TEST_CASE(check_half_values)
{
for(auto [x, f] : half_lut)
{
auto h = migraphx::bit_cast<migraphx::half>(x);
if(std::isnan(f))
{
CHECK(std::isnan(h));
}
else if(std::isinf(f))
{
CHECK(std::isinf(h));
CHECK((h < 0) == (f < 0));
CHECK(bit_equal(x, migraphx::half(f)));
}
else
{
CHECK(migraphx::float_equal(float(h), f));
CHECK(bit_equal(x, migraphx::half(f)));
}
}
} I have a map of a thousand or so values we can use for this test. Also we will want to test the numeric limits by checking the bits match what we would expect: TEST_CASE(check_numeric_limits)
{
CHECK(bit_equal(std::numeric_limits<migraphx::half>::min(), uint16_t{0x0400}));
CHECK(bit_equal(std::numeric_limits<migraphx::half>::lowest(), uint16_t{0xfbff}));
CHECK(bit_equal(std::numeric_limits<migraphx::half>::max(), uint16_t{0x7bff}));
CHECK(bit_equal(std::numeric_limits<migraphx::half>::epsilon(), uint16_t{0x1400}));
CHECK(bit_equal(std::numeric_limits<migraphx::half>::denorm_min(), uint16_t{0x0001}));
CHECK(bit_equal(std::numeric_limits<migraphx::half>::infinity(), uint16_t{0x7c00}));
CHECK(bit_equal(std::numeric_limits<migraphx::half>::quiet_NaN(), uint16_t{0x7fff}));
CHECK(bit_equal(std::numeric_limits<migraphx::half>::signaling_NaN(), uint16_t{0x7dff}));
} In addition, it would be good to have some tests for overflow and underflow like for |
test/half.cpp
Outdated
CHECK(bit_equal(std::numeric_limits<migraphx::half>::signaling_NaN(), uint16_t{0x7d00})); | ||
} | ||
|
||
static const std::map<uint16_t, float> half_lut = { |
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.
We probably need to wrap this in a function to fix the tidy warning:
const std::map<uint16_t, float>& half_lut()
{
static const std::map<uint16_t, float> result = { ... };
return result;
}
Overall this looks, we just need to fix the tidy warnings. |
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.
Looks good, just need to fix the CI checks.
|
||
constexpr float32_parts get_parts(float f) { return migraphx::bit_cast<float32_parts>(f); } | ||
|
||
#pragma pack(push, 1) |
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 needs to be surrounded by #ifdef _MSC_VER
.
|
||
#pragma pack(push, 1) | ||
template <unsigned int MantissaSize, unsigned int ExponentSize, unsigned int Flags = 0> | ||
struct alignas(1) __attribute__((may_alias)) generic_float |
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 need the packed attribute for gcc/clang, but this probably breaks windows though. Instead of using macros, doing [[gnu::packed, gnu::may_alias]]
may work instead.
|
||
#pragma pack(push, 1) | ||
template <unsigned int MantissaSize, unsigned int ExponentSize, unsigned int Flags = 0> | ||
struct alignas(1) __attribute__((may_alias)) generic_float |
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.
Also alignment is wrong. It should be alignas((MantissaSize+ExponentSize+1)/8)
, I dont know if that compiles.
return temp; | ||
} | ||
}; | ||
#pragma pack(pop) |
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.
Also needs a #ifdef _MSC_VER
.
This build is not recommended to merge 🔴 |
🔴bert_large_uncased_fp16: FAILED: MIGraphX is not within tolerance - check verbose output |
No description provided.