mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
Fix math tests to allow ftz in relaxed mode. (#1371)
* Fix math tests to allow ftz in relaxed mode. In recent spec clarification, it is agreed that ftz is a valid optimization in case of cl-fast-math-relaxed and doesn't require cl-denorms-are-zero to be passed explicitly to enforce ftz behavior for implementations that already support this. GitHub Spec Issue OpenCL-Docs#579 GitHub Spec Issue OpenCL-Docs#597 GitHub CTS Issue OpenCL-CTS#1267
This commit is contained in:
@@ -297,6 +297,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
float ulps = job->ulps;
|
||||
dptr func = job->f->dfunc;
|
||||
int ftz = job->ftz;
|
||||
bool relaxedMode = job->relaxedMode;
|
||||
MTdata d = tinfo->d;
|
||||
cl_int error;
|
||||
const char *name = job->f->name;
|
||||
@@ -481,7 +482,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
float err = Bruteforce_Ulp_Error_Double(test, correct);
|
||||
int fail = !(fabsf(err) <= ulps);
|
||||
|
||||
if (fail && ftz)
|
||||
if (fail && (ftz || relaxedMode))
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsDoubleResultSubnormal(correct, ulps))
|
||||
@@ -680,6 +681,7 @@ int TestFunc_Double_Double_Double(const Func *f, MTdata d, bool relaxedMode)
|
||||
test_info.f = f;
|
||||
test_info.ulps = f->double_ulps;
|
||||
test_info.ftz = f->ftz || gForceFTZ;
|
||||
test_info.relaxedMode = relaxedMode;
|
||||
|
||||
test_info.isFDim = 0 == strcmp("fdim", f->nameInCode);
|
||||
test_info.skipNanInf = 0;
|
||||
|
||||
@@ -461,7 +461,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
{
|
||||
// Calculate the correctly rounded reference result
|
||||
memset(&oldMode, 0, sizeof(oldMode));
|
||||
if (ftz) ForceFTZ(&oldMode);
|
||||
if (ftz || relaxedMode) ForceFTZ(&oldMode);
|
||||
|
||||
// Set the rounding mode to match the device
|
||||
if (gIsInRTZMode) oldRoundMode = set_round(kRoundTowardZero, kfloat);
|
||||
@@ -546,7 +546,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
float err = Ulp_Error(test, correct);
|
||||
int fail = !(fabsf(err) <= ulps);
|
||||
|
||||
if (fail && ftz)
|
||||
if (fail && (ftz || relaxedMode))
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsFloatResultSubnormal(correct, ulps))
|
||||
|
||||
@@ -164,6 +164,8 @@ struct TestInfo
|
||||
cl_uint scale; // stride between individual test values
|
||||
float ulps; // max_allowed ulps
|
||||
int ftz; // non-zero if running in flush to zero mode
|
||||
bool relaxedMode; // True if test is running in relaxed mode, false
|
||||
// otherwise.
|
||||
|
||||
// no special values
|
||||
};
|
||||
@@ -300,6 +302,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
float ulps = job->ulps;
|
||||
dptr func = job->f->dfunc;
|
||||
int ftz = job->ftz;
|
||||
bool relaxedMode = job->relaxedMode;
|
||||
MTdata d = tinfo->d;
|
||||
cl_int error;
|
||||
const char *name = job->f->name;
|
||||
@@ -482,7 +485,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
float err = Bruteforce_Ulp_Error_Double(test, correct);
|
||||
int fail = !(fabsf(err) <= ulps);
|
||||
|
||||
if (fail && ftz)
|
||||
if (fail && (ftz || relaxedMode))
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsDoubleResultSubnormal(correct, ulps))
|
||||
@@ -601,6 +604,7 @@ int TestFunc_Double_Double_Int(const Func *f, MTdata d, bool relaxedMode)
|
||||
test_info.f = f;
|
||||
test_info.ulps = f->double_ulps;
|
||||
test_info.ftz = f->ftz || gForceFTZ;
|
||||
test_info.relaxedMode = relaxedMode;
|
||||
|
||||
// cl_kernels aren't thread safe, so we make one for each vector size for
|
||||
// every thread
|
||||
|
||||
@@ -162,7 +162,8 @@ struct TestInfo
|
||||
cl_uint scale; // stride between individual test values
|
||||
float ulps; // max_allowed ulps
|
||||
int ftz; // non-zero if running in flush to zero mode
|
||||
|
||||
bool relaxedMode; // True if test is running in relaxed mode, false
|
||||
// otherwise.
|
||||
// no special values
|
||||
};
|
||||
|
||||
@@ -291,6 +292,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
ThreadInfo *tinfo = &(job->tinfo[thread_id]);
|
||||
fptr func = job->f->func;
|
||||
int ftz = job->ftz;
|
||||
bool relaxedMode = job->relaxedMode;
|
||||
float ulps = job->ulps;
|
||||
MTdata d = tinfo->d;
|
||||
cl_int error;
|
||||
@@ -473,7 +475,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
float err = Ulp_Error(test, correct);
|
||||
int fail = !(fabsf(err) <= ulps);
|
||||
|
||||
if (fail && ftz)
|
||||
if (fail && (ftz || relaxedMode))
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsFloatResultSubnormal(correct, ulps))
|
||||
@@ -595,6 +597,7 @@ int TestFunc_Float_Float_Int(const Func *f, MTdata d, bool relaxedMode)
|
||||
test_info.ulps = gIsEmbedded ? f->float_embedded_ulps : f->float_ulps;
|
||||
test_info.ftz =
|
||||
f->ftz || gForceFTZ || 0 == (CL_FP_DENORM & gFloatCapabilities);
|
||||
test_info.relaxedMode = relaxedMode;
|
||||
|
||||
// cl_kernels aren't thread safe, so we make one for each vector size for
|
||||
// every thread
|
||||
|
||||
@@ -294,6 +294,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
float ulps = job->ulps;
|
||||
dptr func = job->f->dfunc;
|
||||
int ftz = job->ftz;
|
||||
bool relaxedMode = job->relaxedMode;
|
||||
MTdata d = tinfo->d;
|
||||
cl_int error;
|
||||
const char *name = job->f->name;
|
||||
@@ -476,7 +477,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
float err = Bruteforce_Ulp_Error_Double(test, correct);
|
||||
int fail = !(fabsf(err) <= ulps);
|
||||
|
||||
if (fail && ftz)
|
||||
if (fail && (ftz || relaxedMode))
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsDoubleResultSubnormal(correct, ulps))
|
||||
|
||||
@@ -456,7 +456,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
// Calculate the correctly rounded reference result
|
||||
FPU_mode_type oldMode;
|
||||
memset(&oldMode, 0, sizeof(oldMode));
|
||||
if (ftz) ForceFTZ(&oldMode);
|
||||
if (ftz || relaxedMode) ForceFTZ(&oldMode);
|
||||
|
||||
// Set the rounding mode to match the device
|
||||
oldRoundMode = kRoundToNearestEven;
|
||||
@@ -484,7 +484,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
|
||||
if (gIsInRTZMode) (void)set_round(oldRoundMode, kfloat);
|
||||
|
||||
if (ftz) RestoreFPState(&oldMode);
|
||||
if (ftz || relaxedMode) RestoreFPState(&oldMode);
|
||||
|
||||
// Read the data back -- no need to wait for the first N-1 buffers but wait
|
||||
// for the last buffer. This is an in order queue.
|
||||
@@ -541,7 +541,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
((!(fabsf(err) <= ulps)) && (!(fabsf(errB) <= ulps)));
|
||||
if (fabsf(errB) < fabsf(err)) err = errB;
|
||||
|
||||
if (fail && ftz)
|
||||
if (fail && (ftz || relaxedMode))
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsFloatResultSubnormal(correct, ulps))
|
||||
|
||||
@@ -379,7 +379,7 @@ int TestFunc_DoubleI_Double_Double(const Func *f, MTdata d, bool relaxedMode)
|
||||
if (iptrUndefined) iErr = 0;
|
||||
|
||||
int fail = !(fabsf(err) <= f->double_ulps && iErr == 0);
|
||||
if (ftz && fail)
|
||||
if ((ftz || relaxedMode) && fail)
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsDoubleResultSubnormal(correct, f->double_ulps))
|
||||
|
||||
@@ -379,7 +379,7 @@ int TestFunc_FloatI_Float_Float(const Func *f, MTdata d, bool relaxedMode)
|
||||
if (iptrUndefined) iErr = 0;
|
||||
|
||||
int fail = !(fabsf(err) <= float_ulps && iErr == 0);
|
||||
if (ftz && fail)
|
||||
if ((ftz || relaxedMode) && fail)
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsFloatResultSubnormal(correct, float_ulps))
|
||||
|
||||
@@ -248,7 +248,7 @@ int TestFunc_Int_Double(const Func *f, MTdata d, bool relaxedMode)
|
||||
// If we aren't getting the correctly rounded result
|
||||
if (t[j] != q[j])
|
||||
{
|
||||
if (ftz && IsDoubleSubnormal(s[j]))
|
||||
if ((ftz || relaxedMode) && IsDoubleSubnormal(s[j]))
|
||||
{
|
||||
unsigned int correct0 = f->dfunc.i_f(0.0);
|
||||
unsigned int correct1 = f->dfunc.i_f(-0.0);
|
||||
|
||||
@@ -245,7 +245,7 @@ int TestFunc_Int_Float(const Func *f, MTdata d, bool relaxedMode)
|
||||
// If we aren't getting the correctly rounded result
|
||||
if (t[j] != q[j])
|
||||
{
|
||||
if (ftz && IsFloatSubnormal(s[j]))
|
||||
if ((ftz || relaxedMode) && IsFloatSubnormal(s[j]))
|
||||
{
|
||||
unsigned int correct0 = f->func.i_f(0.0);
|
||||
unsigned int correct1 = f->func.i_f(-0.0);
|
||||
|
||||
@@ -157,6 +157,8 @@ struct TestInfo
|
||||
cl_uint step; // step between each chunk and the next.
|
||||
cl_uint scale; // stride between individual test values
|
||||
int ftz; // non-zero if running in flush to zero mode
|
||||
bool relaxedMode; // True if test is running in relaxed mode, false
|
||||
// otherwise.
|
||||
};
|
||||
|
||||
// A table of more difficult cases to get right
|
||||
@@ -282,6 +284,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
ThreadInfo *tinfo = &(job->tinfo[thread_id]);
|
||||
dptr dfunc = job->f->dfunc;
|
||||
int ftz = job->ftz;
|
||||
bool relaxedMode = job->relaxedMode;
|
||||
MTdata d = tinfo->d;
|
||||
cl_int error;
|
||||
const char *name = job->f->name;
|
||||
@@ -455,7 +458,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
if (gMinVectorSizeIndex == 0 && t[j] != q[j])
|
||||
{
|
||||
// If we aren't getting the correctly rounded result
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
if (IsDoubleSubnormal(s[j]))
|
||||
{
|
||||
@@ -503,7 +506,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
// If we aren't getting the correctly rounded result
|
||||
if (-t[j] != q[j])
|
||||
{
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
if (IsDoubleSubnormal(s[j]))
|
||||
{
|
||||
@@ -607,6 +610,7 @@ int TestMacro_Int_Double_Double(const Func *f, MTdata d, bool relaxedMode)
|
||||
|
||||
test_info.f = f;
|
||||
test_info.ftz = f->ftz || gForceFTZ;
|
||||
test_info.relaxedMode = relaxedMode;
|
||||
|
||||
// cl_kernels aren't thread safe, so we make one for each vector size for
|
||||
// every thread
|
||||
|
||||
@@ -155,6 +155,8 @@ struct TestInfo
|
||||
cl_uint step; // step between each chunk and the next.
|
||||
cl_uint scale; // stride between individual test values
|
||||
int ftz; // non-zero if running in flush to zero mode
|
||||
bool relaxedMode; // True if test is running in relaxed mode, false
|
||||
// otherwise.
|
||||
};
|
||||
|
||||
// A table of more difficult cases to get right
|
||||
@@ -272,6 +274,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
ThreadInfo *tinfo = &(job->tinfo[thread_id]);
|
||||
fptr func = job->f->func;
|
||||
int ftz = job->ftz;
|
||||
bool relaxedMode = job->relaxedMode;
|
||||
MTdata d = tinfo->d;
|
||||
cl_int error;
|
||||
const char *name = job->f->name;
|
||||
@@ -445,7 +448,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
|
||||
if (gMinVectorSizeIndex == 0 && t[j] != q[j])
|
||||
{
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
if (IsFloatSubnormal(s[j]))
|
||||
{
|
||||
@@ -492,7 +495,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
// If we aren't getting the correctly rounded result
|
||||
if (-t[j] != q[j])
|
||||
{
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
if (IsFloatSubnormal(s[j]))
|
||||
{
|
||||
@@ -596,6 +599,7 @@ int TestMacro_Int_Float_Float(const Func *f, MTdata d, bool relaxedMode)
|
||||
test_info.f = f;
|
||||
test_info.ftz =
|
||||
f->ftz || gForceFTZ || 0 == (CL_FP_DENORM & gFloatCapabilities);
|
||||
test_info.relaxedMode = relaxedMode;
|
||||
|
||||
// cl_kernels aren't thread safe, so we make one for each vector size for
|
||||
// every thread
|
||||
|
||||
@@ -149,6 +149,8 @@ struct TestInfo
|
||||
cl_uint step; // step between each chunk and the next.
|
||||
cl_uint scale; // stride between individual test values
|
||||
int ftz; // non-zero if running in flush to zero mode
|
||||
bool relaxedMode; // True if test is running in relaxed mode, false
|
||||
// otherwise.
|
||||
};
|
||||
|
||||
cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
@@ -161,6 +163,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
ThreadInfo *tinfo = &(job->tinfo[thread_id]);
|
||||
dptr dfunc = job->f->dfunc;
|
||||
int ftz = job->ftz;
|
||||
bool relaxedMode = job->relaxedMode;
|
||||
cl_int error;
|
||||
const char *name = job->f->name;
|
||||
|
||||
@@ -286,7 +289,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
if (gMinVectorSizeIndex == 0 && t[j] != q[j])
|
||||
{
|
||||
// If we aren't getting the correctly rounded result
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
if (IsDoubleSubnormal(s[j]))
|
||||
{
|
||||
@@ -311,7 +314,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
// If we aren't getting the correctly rounded result
|
||||
if (-t[j] != q[j])
|
||||
{
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
if (IsDoubleSubnormal(s[j]))
|
||||
{
|
||||
@@ -392,6 +395,7 @@ int TestMacro_Int_Double(const Func *f, MTdata d, bool relaxedMode)
|
||||
|
||||
test_info.f = f;
|
||||
test_info.ftz = f->ftz || gForceFTZ;
|
||||
test_info.relaxedMode = relaxedMode;
|
||||
|
||||
// cl_kernels aren't thread safe, so we make one for each vector size for
|
||||
// every thread
|
||||
|
||||
@@ -148,6 +148,8 @@ struct TestInfo
|
||||
cl_uint step; // step between each chunk and the next.
|
||||
cl_uint scale; // stride between individual test values
|
||||
int ftz; // non-zero if running in flush to zero mode
|
||||
bool relaxedMode; // True if test is running in relaxed mode, false
|
||||
// otherwise.
|
||||
};
|
||||
|
||||
cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
@@ -160,6 +162,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
ThreadInfo *tinfo = &(job->tinfo[thread_id]);
|
||||
fptr func = job->f->func;
|
||||
int ftz = job->ftz;
|
||||
bool relaxedMode = job->relaxedMode;
|
||||
cl_int error = CL_SUCCESS;
|
||||
cl_int ret = CL_SUCCESS;
|
||||
const char *name = job->f->name;
|
||||
@@ -290,7 +293,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
if (gMinVectorSizeIndex == 0 && t[j] != q[j])
|
||||
{
|
||||
// If we aren't getting the correctly rounded result
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
if (IsFloatSubnormal(s[j]))
|
||||
{
|
||||
@@ -316,7 +319,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
// If we aren't getting the correctly rounded result
|
||||
if (-t[j] != q[j])
|
||||
{
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
if (IsFloatSubnormal(s[j]))
|
||||
{
|
||||
@@ -406,6 +409,7 @@ int TestMacro_Int_Float(const Func *f, MTdata d, bool relaxedMode)
|
||||
test_info.f = f;
|
||||
test_info.ftz =
|
||||
f->ftz || gForceFTZ || 0 == (CL_FP_DENORM & gFloatCapabilities);
|
||||
test_info.relaxedMode = relaxedMode;
|
||||
|
||||
// cl_kernels aren't thread safe, so we make one for each vector size for
|
||||
// every thread
|
||||
|
||||
@@ -391,7 +391,7 @@ int TestFunc_Double_Double_Double_Double(const Func *f, MTdata d,
|
||||
float err = Bruteforce_Ulp_Error_Double(test, correct);
|
||||
int fail = !(fabsf(err) <= f->double_ulps);
|
||||
|
||||
if (fail && ftz)
|
||||
if (fail && (ftz || relaxedMode))
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsDoubleSubnormal(correct))
|
||||
|
||||
@@ -443,7 +443,7 @@ int TestFunc_Float_Float_Float_Float(const Func *f, MTdata d, bool relaxedMode)
|
||||
err = Ulp_Error(test, correct);
|
||||
fail = !(fabsf(err) <= float_ulps);
|
||||
|
||||
if (fail && ftz)
|
||||
if (fail && (ftz || relaxedMode))
|
||||
{
|
||||
float correct2, err2;
|
||||
|
||||
|
||||
@@ -172,6 +172,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
dptr func = job->f->dfunc;
|
||||
cl_int error;
|
||||
int ftz = job->ftz;
|
||||
bool relaxedMode = job->relaxedMode;
|
||||
|
||||
Force64BitFPUPrecision();
|
||||
|
||||
@@ -305,7 +306,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
|
||||
if (fail)
|
||||
{
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsDoubleResultSubnormal(correct, ulps))
|
||||
|
||||
@@ -435,7 +435,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
|
||||
|
||||
if (fail)
|
||||
{
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
typedef int (*CheckForSubnormal)(
|
||||
double, float); // If we are in fast relaxed math,
|
||||
|
||||
@@ -291,7 +291,7 @@ int TestFunc_Double2_Double(const Func *f, MTdata d, bool relaxedMode)
|
||||
float err2 = Bruteforce_Ulp_Error_Double(test2, correct2);
|
||||
int fail = !(fabsf(err) <= f->double_ulps
|
||||
&& fabsf(err2) <= f->double_ulps);
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsDoubleResultSubnormal(correct, f->double_ulps))
|
||||
|
||||
@@ -258,7 +258,7 @@ int TestFunc_Float2_Float(const Func *f, MTdata d, bool relaxedMode)
|
||||
{
|
||||
// Calculate the correctly rounded reference result
|
||||
memset(&oldMode, 0, sizeof(oldMode));
|
||||
if (ftz) ForceFTZ(&oldMode);
|
||||
if (ftz || relaxedMode) ForceFTZ(&oldMode);
|
||||
|
||||
// Set the rounding mode to match the device
|
||||
if (gIsInRTZMode)
|
||||
@@ -385,7 +385,7 @@ int TestFunc_Float2_Float(const Func *f, MTdata d, bool relaxedMode)
|
||||
int fail = !(fabsf(err) <= float_ulps
|
||||
&& fabsf(err2) <= float_ulps);
|
||||
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if ((*isFloatResultSubnormalPtr)(correct, float_ulps))
|
||||
|
||||
@@ -294,7 +294,7 @@ int TestFunc_DoubleI_Double(const Func *f, MTdata d, bool relaxedMode)
|
||||
cl_long iErr = (long long)q2[j] - (long long)correct2;
|
||||
int fail = !(fabsf(err) <= f->double_ulps
|
||||
&& abs_cl_long(iErr) <= maxiError);
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsDoubleResultSubnormal(correct, f->double_ulps))
|
||||
|
||||
@@ -297,7 +297,7 @@ int TestFunc_FloatI_Float(const Func *f, MTdata d, bool relaxedMode)
|
||||
cl_long iErr = (int64_t)q2[j] - (int64_t)correct2;
|
||||
int fail = !(fabsf(err) <= float_ulps
|
||||
&& abs_cl_long(iErr) <= maxiError);
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsFloatResultSubnormal(correct, float_ulps))
|
||||
|
||||
@@ -249,7 +249,7 @@ int TestFunc_Double_ULong(const Func *f, MTdata d, bool relaxedMode)
|
||||
|
||||
if (fail)
|
||||
{
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsDoubleResultSubnormal(correct,
|
||||
|
||||
@@ -253,7 +253,7 @@ int TestFunc_Float_UInt(const Func *f, MTdata d, bool relaxedMode)
|
||||
|
||||
if (fail)
|
||||
{
|
||||
if (ftz)
|
||||
if (ftz || relaxedMode)
|
||||
{
|
||||
// retry per section 6.5.3.2
|
||||
if (IsFloatResultSubnormal(correct, float_ulps))
|
||||
|
||||
Reference in New Issue
Block a user