Fix testing of half-precision fma. (#1882)

Half-precision functions are generally tested against the
single-precision reference. This causes double rounding: first to single
precision, then from there to half precision. For the most part, it is
good enough, but specifically in the case of fma, a correctly rounded
result is required and is not obtained, for instance for arguments
0x1.eacp+7, 0x1.3f4p+4, 0x1.c04p+14, which produce an exact result of
0x1.065fffp+15 which should be rounded to half-prefcision 0x1.064p+15,
but was previously first rounded to single-precision 0x1.066p+15, and
from there to half-precision 0x1.068p+15. Testing against reference_fmal
gives us sufficient precision that double rounding does not cause
issues.

The f_fma(..., FLUSHED) calls for FTZ testing cannot be updated the same
way but do not need to be: these calls all have at least one constant
operand of zero. If one operand is zero, double rounding cannot be an
issue.
This commit is contained in:
Harald van Dijk
2024-02-06 17:25:31 +00:00
committed by GitHub
parent 79fc236e4a
commit d338b42e8f
4 changed files with 10 additions and 9 deletions

View File

@@ -369,7 +369,7 @@ static float Ulp_Error_Half_Float(float test, double reference)
return (float)scalbn(testVal - reference, ulp_exp);
}
float Ulp_Error_Half(cl_half test, float reference)
float Ulp_Error_Half(cl_half test, double reference)
{
return Ulp_Error_Half_Float(cl_half_to_float(test), reference);
}

View File

@@ -185,7 +185,7 @@ static int vlog_win32(const char *format, ...);
extern const char *IGetErrorString(int clErrorCode);
extern float Ulp_Error_Half(cl_half test, float reference);
extern float Ulp_Error_Half(cl_half test, double reference);
extern float Ulp_Error(float test, double reference);
extern float Ulp_Error_Double(double test, long double reference);