mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Fix Half NaN definition and test.
The `half_float` test was failing with `-mcpu=cortex-a55` (native `__fp16`) due to a bad NaN bit-pattern comparison (in the case of casting a float to `__fp16`, the signaling `NaN` is quieted). There was also an inconsistency between `numeric_limits<half>::quiet_NaN()` and `NumTraits::quiet_NaN()`. Here we correct the inconsistency and compare NaNs according to the IEEE 754 definition. Also modified the `bfloat16_float` test to match. Tested with `cortex-a53` and `cortex-a55`.
This commit is contained in:
@@ -136,12 +136,22 @@ void test_numtraits()
|
||||
VERIFY_IS_EQUAL(
|
||||
numext::bit_cast<numext::uint16_t>(std::numeric_limits<half>::infinity()),
|
||||
numext::bit_cast<numext::uint16_t>(half(std::numeric_limits<float>::infinity())) );
|
||||
VERIFY_IS_EQUAL(
|
||||
numext::bit_cast<numext::uint16_t>(std::numeric_limits<half>::quiet_NaN()),
|
||||
numext::bit_cast<numext::uint16_t>(half(std::numeric_limits<float>::quiet_NaN())) );
|
||||
VERIFY_IS_EQUAL(
|
||||
numext::bit_cast<numext::uint16_t>(std::numeric_limits<half>::signaling_NaN()),
|
||||
numext::bit_cast<numext::uint16_t>(half(std::numeric_limits<float>::signaling_NaN())) );
|
||||
// There is no guarantee that casting a 32-bit NaN to 16-bit has a precise
|
||||
// bit pattern. We test that it is in fact a NaN, then test the signaling
|
||||
// bit (msb of significand is 1 for quiet, 0 for signaling).
|
||||
const numext::uint16_t HALF_QUIET_BIT = 0x0200;
|
||||
VERIFY(
|
||||
(numext::isnan)(std::numeric_limits<half>::quiet_NaN())
|
||||
&& (numext::isnan)(half(std::numeric_limits<float>::quiet_NaN()))
|
||||
&& ((numext::bit_cast<numext::uint16_t>(std::numeric_limits<half>::quiet_NaN()) & HALF_QUIET_BIT) > 0)
|
||||
&& ((numext::bit_cast<numext::uint16_t>(half(std::numeric_limits<float>::quiet_NaN())) & HALF_QUIET_BIT) > 0) );
|
||||
// After a cast to half, a signaling NaN may become non-signaling
|
||||
// (e.g. in the case of casting float to native __fp16). Thus, we check that
|
||||
// both are NaN, and that only the `numeric_limits` version is signaling.
|
||||
VERIFY(
|
||||
(numext::isnan)(std::numeric_limits<half>::signaling_NaN())
|
||||
&& (numext::isnan)(half(std::numeric_limits<float>::signaling_NaN()))
|
||||
&& ((numext::bit_cast<numext::uint16_t>(std::numeric_limits<half>::signaling_NaN()) & HALF_QUIET_BIT) == 0) );
|
||||
|
||||
VERIFY( (std::numeric_limits<half>::min)() > half(0.f) );
|
||||
VERIFY( (std::numeric_limits<half>::denorm_min)() > half(0.f) );
|
||||
|
||||
Reference in New Issue
Block a user