Bruteforce - embedded, relaxed ulp requirements (#839)

* Add embedded profile ULP requiremnts for relaxed tests.

* Fixed exp relaxed ULP for embedded.

* Added a utility function, getAllowedUlpError, for determining FP32 ULP.

* Collection of requested changes from PR.

Re-named float_embedded_relaxed_ulps -> relaxed_embedded_error.

Re-ordered Func struct members.
This commit is contained in:
Jeremy Kemp
2020-08-10 13:19:26 +01:00
committed by GitHub
parent ce484988ab
commit 93001e99a4
8 changed files with 286 additions and 135 deletions

View File

@@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@@ -27,10 +27,30 @@
// Only use ulps information in spir test
#ifdef FUNCTION_LIST_ULPS_ONLY
#define ENTRY( _name, _ulp, _embedded_ulp, _rmode, _type ) { STRINGIFY(_name), STRINGIFY(_name), {NULL}, {NULL}, {NULL}, _ulp, _ulp, _embedded_ulp, INFINITY, _rmode, RELAXED_OFF, _type }
#define ENTRY_EXT( _name, _ulp, _embedded_ulp, _relaxed_ulp, _rmode, _type ) { STRINGIFY(_name), STRINGIFY(_name), {NULL}, {NULL}, {NULL}, _ulp, _ulp, _embedded_ulp, _relaxed_ulp, _rmode, RELAXED_ON, _type }
#define HALF_ENTRY( _name, _ulp, _embedded_ulp, _rmode, _type ) { "half_" STRINGIFY(_name), "half_" STRINGIFY(_name), {NULL}, {NULL}, {NULL}, _ulp, _ulp, _embedded_ulp, INFINITY, _rmode, RELAXED_OFF, _type }
#define OPERATOR_ENTRY(_name, _operator, _ulp, _embedded_ulp, _rmode, _type) { STRINGIFY(_name), _operator, {NULL}, {NULL}, {NULL}, _ulp, _ulp, _embedded_ulp, INFINITY, _rmode, RELAXED_OFF, _type }
#define ENTRY(_name, _ulp, _embedded_ulp, _rmode, _type) \
{ \
STRINGIFY(_name), STRINGIFY(_name), { NULL }, { NULL }, { NULL }, \
_ulp, _ulp, _embedded_ulp, INFINITY, INFINITY, _rmode, \
RELAXED_OFF, _type \
}
#define ENTRY_EXT(_name, _ulp, _embedded_ulp, _relaxed_ulp, _rmode, _type, \
_relaxed_embedded_ulp) \
{ \
STRINGIFY(_name), STRINGIFY(_name), { NULL }, { NULL }, { NULL }, \
_ulp, _ulp, _embedded_ulp, _relaxed_ulp, _relaxed_embedded_ulp, \
_rmode, RELAXED_ON, _type \
}
#define HALF_ENTRY(_name, _ulp, _embedded_ulp, _rmode, _type) \
{ \
"half_" STRINGIFY(_name), "half_" STRINGIFY(_name), { NULL }, \
{ NULL }, { NULL }, _ulp, _ulp, _embedded_ulp, INFINITY, INFINITY, \
_rmode, RELAXED_OFF, _type \
}
#define OPERATOR_ENTRY(_name, _operator, _ulp, _embedded_ulp, _rmode, _type) \
{ \
STRINGIFY(_name), _operator, { NULL }, { NULL }, { NULL }, _ulp, _ulp, \
_embedded_ulp, INFINITY, INFINITY, _rmode, RELAXED_OFF, _type \
}
#define unaryF NULL
#define i_unaryF NULL
#define unaryF_u NULL
@@ -54,10 +74,33 @@
#else // FUNCTION_LIST_ULPS_ONLY
#define ENTRY( _name, _ulp, _embedded_ulp, _rmode, _type ) { STRINGIFY(_name), STRINGIFY(_name), {(void*)reference_##_name}, {(void*)reference_##_name##l}, {(void*)reference_##_name}, _ulp, _ulp, _embedded_ulp, INFINITY, _rmode, RELAXED_OFF, _type }
#define ENTRY_EXT( _name, _ulp, _embedded_ulp, _relaxed_ulp, _rmode, _type ) { STRINGIFY(_name), STRINGIFY(_name), {(void*)reference_##_name}, {(void*)reference_##_name##l}, {(void*)reference_##relaxed_##_name}, _ulp, _ulp, _embedded_ulp, _relaxed_ulp, _rmode, RELAXED_ON, _type }
#define HALF_ENTRY( _name, _ulp, _embedded_ulp, _rmode, _type ) { "half_" STRINGIFY(_name), "half_" STRINGIFY(_name), {(void*)reference_##_name}, {NULL}, {NULL}, _ulp, _ulp, _embedded_ulp, INFINITY, _rmode, RELAXED_OFF, _type }
#define OPERATOR_ENTRY(_name, _operator, _ulp, _embedded_ulp, _rmode, _type) { STRINGIFY(_name), _operator, {(void*)reference_##_name}, {(void*)reference_##_name##l}, {NULL}, _ulp, _ulp, _embedded_ulp, INFINITY, _rmode, RELAXED_OFF, _type }
#define ENTRY(_name, _ulp, _embedded_ulp, _rmode, _type) \
{ \
STRINGIFY(_name), STRINGIFY(_name), { (void*)reference_##_name }, \
{ (void*)reference_##_name##l }, { (void*)reference_##_name }, \
_ulp, _ulp, _embedded_ulp, INFINITY, INFINITY, _rmode, \
RELAXED_OFF, _type \
}
#define ENTRY_EXT(_name, _ulp, _embedded_ulp, _relaxed_ulp, _rmode, _type, \
_relaxed_embedded_ulp) \
{ \
STRINGIFY(_name), STRINGIFY(_name), { (void*)reference_##_name }, \
{ (void*)reference_##_name##l }, \
{ (void*)reference_##relaxed_##_name }, _ulp, _ulp, _embedded_ulp, \
_relaxed_ulp, _relaxed_embedded_ulp, _rmode, RELAXED_ON, _type \
}
#define HALF_ENTRY(_name, _ulp, _embedded_ulp, _rmode, _type) \
{ \
"half_" STRINGIFY(_name), "half_" STRINGIFY(_name), \
{ (void*)reference_##_name }, { NULL }, { NULL }, _ulp, _ulp, \
_embedded_ulp, INFINITY, INFINITY, _rmode, RELAXED_OFF, _type \
}
#define OPERATOR_ENTRY(_name, _operator, _ulp, _embedded_ulp, _rmode, _type) \
{ \
STRINGIFY(_name), _operator, { (void*)reference_##_name }, \
{ (void*)reference_##_name##l }, { NULL }, _ulp, _ulp, \
_embedded_ulp, INFINITY, INFINITY, _rmode, RELAXED_OFF, _type \
}
extern const vtbl _unary; // float foo( float )
extern const vtbl _unary_u; // float foo( uint ), double foo( ulong )
@@ -91,115 +134,192 @@ extern const vtbl _mad_tbl; // float mad( float, float, float )
#endif // FUNCTION_LIST_ULPS_ONLY
const Func functionList[] = {
ENTRY( acos, 4.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY( acosh, 4.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY( acospi, 5.0f, 5.0f, FTZ_OFF, unaryF),
ENTRY( asin, 4.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY( asinh, 4.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY( asinpi, 5.0f, 5.0f, FTZ_OFF, unaryF),
ENTRY( atan, 5.0f, 5.0f, FTZ_OFF, unaryF),
ENTRY( atanh, 5.0f, 5.0f, FTZ_OFF, unaryF),
ENTRY( atanpi, 5.0f, 5.0f, FTZ_OFF, unaryF),
ENTRY( atan2, 6.0f, 6.0f, FTZ_OFF, binaryF),
ENTRY( atan2pi, 6.0f, 6.0f, FTZ_OFF, binaryF),
ENTRY( cbrt, 2.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY( ceil, 0.0f, 0.0f, FTZ_OFF, unaryF),
ENTRY( copysign, 0.0f, 0.0f, FTZ_OFF, binaryF),
ENTRY_EXT( cos, 4.0f, 4.0f, 0.00048828125f, FTZ_OFF, unaryF), //relaxed ulp 2^-11
ENTRY( cosh, 4.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY( cospi, 4.0f, 4.0f, FTZ_OFF, unaryF),
// ENTRY( erfc, 16.0f, 16.0f, FTZ_OFF, unaryF), //disabled for 1.0 due to lack of reference implementation
// ENTRY( erf, 16.0f, 16.0f, FTZ_OFF, unaryF), //disabled for 1.0 due to lack of reference implementation
ENTRY_EXT( exp, 3.0f, 4.0f, 3.0f, FTZ_OFF, unaryF), //relaxed error is actually overwritten in unary.c as it is 3+floor(fabs(2*x))
ENTRY_EXT( exp2, 3.0f, 4.0f, 3.0f, FTZ_OFF, unaryF), //relaxed error is actually overwritten in unary.c as it is 3+floor(fabs(2*x))
ENTRY_EXT( exp10, 3.0f, 4.0f, 8192.0f, FTZ_OFF, unaryF), //relaxed error is actually overwritten in unary.c as it is 3+floor(fabs(2*x)) in derived mode,
// in non-derived mode it uses the ulp error for half_exp10.
ENTRY( expm1, 3.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY( fabs, 0.0f, 0.0f, FTZ_OFF, unaryF),
ENTRY( fdim, 0.0f, 0.0f, FTZ_OFF, binaryF),
ENTRY( floor, 0.0f, 0.0f, FTZ_OFF, unaryF),
ENTRY( fma, 0.0f, 0.0f, FTZ_OFF, ternaryF),
ENTRY( fmax, 0.0f, 0.0f, FTZ_OFF, binaryF),
ENTRY( fmin, 0.0f, 0.0f, FTZ_OFF, binaryF),
ENTRY( fmod, 0.0f, 0.0f, FTZ_OFF, binaryF ),
ENTRY( fract, 0.0f, 0.0f, FTZ_OFF, unaryF_two_results),
ENTRY( frexp, 0.0f, 0.0f, FTZ_OFF, unaryF_two_results_i),
ENTRY( hypot, 4.0f, 4.0f, FTZ_OFF, binaryF),
ENTRY( ilogb, 0.0f, 0.0f, FTZ_OFF, i_unaryF),
ENTRY( isequal, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY( isfinite, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
ENTRY( isgreater, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY( isgreaterequal, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY( isinf, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
ENTRY( isless, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY( islessequal, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY( islessgreater, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY( isnan, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
ENTRY( isnormal, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
ENTRY( isnotequal, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY( isordered, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY( isunordered, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY( ldexp, 0.0f, 0.0f, FTZ_OFF, binaryF_i),
ENTRY( lgamma, INFINITY, INFINITY, FTZ_OFF, unaryF),
ENTRY( lgamma_r, INFINITY, INFINITY, FTZ_OFF, unaryF_two_results_i),
ENTRY_EXT( log, 3.0f, 4.0f, 4.76837158203125e-7f, FTZ_OFF, unaryF), //relaxed ulp 2^-21
ENTRY_EXT( log2, 3.0f, 4.0f, 4.76837158203125e-7f, FTZ_OFF, unaryF), //relaxed ulp 2^-21
ENTRY( log10, 3.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY( log1p, 2.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY( logb, 0.0f, 0.0f, FTZ_OFF, unaryF),
ENTRY_EXT( mad, INFINITY, INFINITY, INFINITY, FTZ_OFF, mad_function), //in fast-relaxed-math mode it has to be either exactly rounded fma or exactly rounded a*b+c
ENTRY( maxmag, 0.0f, 0.0f, FTZ_OFF, binaryF ),
ENTRY( minmag, 0.0f, 0.0f, FTZ_OFF, binaryF ),
ENTRY( modf, 0.0f, 0.0f, FTZ_OFF, unaryF_two_results ),
ENTRY( nan, 0.0f, 0.0f, FTZ_OFF, unaryF_u),
ENTRY( nextafter, 0.0f, 0.0f, FTZ_OFF, binaryF_nextafter),
ENTRY_EXT( pow, 16.0f, 16.0f, 8192.0f, FTZ_OFF, binaryF), //in derived mode the ulp error is calculated as exp2(y*log2(x)) and in non-derived it is the same as half_pow
ENTRY( pown, 16.0f, 16.0f, FTZ_OFF, binaryF_i),
ENTRY( powr, 16.0f, 16.0f, FTZ_OFF, binaryF),
// ENTRY( reciprocal, 1.0f, 1.0f, FTZ_OFF, unaryF),
ENTRY( remainder, 0.0f, 0.0f, FTZ_OFF, binaryF),
ENTRY( remquo, 0.0f, 0.0f, FTZ_OFF, binaryF_two_results_i),
ENTRY( rint, 0.0f, 0.0f, FTZ_OFF, unaryF),
ENTRY( rootn, 16.0f, 16.0f, FTZ_OFF, binaryF_i),
ENTRY( round, 0.0f, 0.0f, FTZ_OFF, unaryF),
ENTRY( rsqrt, 2.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY( signbit, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
ENTRY_EXT( sin, 4.0f, 4.0f, 0.00048828125f, FTZ_OFF, unaryF), //relaxed ulp 2^-11
ENTRY_EXT( sincos, 4.0f, 4.0f, 0.00048828125f, FTZ_OFF, unaryF_two_results), //relaxed ulp 2^-11
ENTRY( sinh, 4.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY( sinpi, 4.0f, 4.0f, FTZ_OFF, unaryF),
{ "sqrt", "sqrt", {(void*)reference_sqrt}, {(void*)reference_sqrtl}, {NULL}, 3.0f, 0.0f, 4.0f, INFINITY, FTZ_OFF, RELAXED_OFF, unaryF },
{ "sqrt_cr", "sqrt", {(void*)reference_sqrt}, {(void*)reference_sqrtl}, {NULL}, 0.0f, 0.0f, 0.0f, INFINITY, FTZ_OFF, RELAXED_OFF, unaryF },
ENTRY_EXT( tan, 5.0f, 5.0f, 8192.0f, FTZ_OFF, unaryF), //in derived mode it the ulp error is calculated as sin/cos and in non-derived mode it is the same as half_tan.
ENTRY( tanh, 5.0f, 5.0f, FTZ_OFF, unaryF),
ENTRY( tanpi, 6.0f, 6.0f, FTZ_OFF, unaryF),
// ENTRY( tgamma, 16.0f, 16.0f, FTZ_OFF, unaryF), // Commented this out until we can be sure this requirement is realistic
ENTRY( trunc, 0.0f, 0.0f, FTZ_OFF, unaryF),
const Func functionList[] = {
ENTRY(acos, 4.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY(acosh, 4.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY(acospi, 5.0f, 5.0f, FTZ_OFF, unaryF),
ENTRY(asin, 4.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY(asinh, 4.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY(asinpi, 5.0f, 5.0f, FTZ_OFF, unaryF),
ENTRY(atan, 5.0f, 5.0f, FTZ_OFF, unaryF),
ENTRY(atanh, 5.0f, 5.0f, FTZ_OFF, unaryF),
ENTRY(atanpi, 5.0f, 5.0f, FTZ_OFF, unaryF),
ENTRY(atan2, 6.0f, 6.0f, FTZ_OFF, binaryF),
ENTRY(atan2pi, 6.0f, 6.0f, FTZ_OFF, binaryF),
ENTRY(cbrt, 2.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY(ceil, 0.0f, 0.0f, FTZ_OFF, unaryF),
ENTRY(copysign, 0.0f, 0.0f, FTZ_OFF, binaryF),
ENTRY_EXT(cos, 4.0f, 4.0f, 0.00048828125f, FTZ_OFF, unaryF,
0.00048828125f), // relaxed ulp 2^-11
ENTRY(cosh, 4.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY(cospi, 4.0f, 4.0f, FTZ_OFF, unaryF),
// ENTRY( erfc, 16.0f,
// 16.0f, FTZ_OFF, unaryF),
// //disabled for 1.0 due to lack of
// reference implementation ENTRY( erf,
// 16.0f, 16.0f, FTZ_OFF,
// unaryF), //disabled for 1.0 due to lack
// of reference implementation
ENTRY_EXT(exp, 3.0f, 4.0f, 3.0f, FTZ_OFF, unaryF,
4.0f), // relaxed error is actually overwritten in unary.c as it
// is 3+floor(fabs(2*x))
ENTRY_EXT(exp2, 3.0f, 4.0f, 3.0f, FTZ_OFF, unaryF,
4.0f), // relaxed error is actually overwritten in unary.c as it
// is 3+floor(fabs(2*x))
ENTRY_EXT(exp10, 3.0f, 4.0f, 8192.0f, FTZ_OFF, unaryF,
8192.0f), // relaxed error is actually overwritten in unary.c as
// it is 3+floor(fabs(2*x)) in derived mode,
// in non-derived mode it uses the ulp error for half_exp10.
ENTRY(expm1, 3.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY(fabs, 0.0f, 0.0f, FTZ_OFF, unaryF),
ENTRY(fdim, 0.0f, 0.0f, FTZ_OFF, binaryF),
ENTRY(floor, 0.0f, 0.0f, FTZ_OFF, unaryF),
ENTRY(fma, 0.0f, 0.0f, FTZ_OFF, ternaryF),
ENTRY(fmax, 0.0f, 0.0f, FTZ_OFF, binaryF),
ENTRY(fmin, 0.0f, 0.0f, FTZ_OFF, binaryF),
ENTRY(fmod, 0.0f, 0.0f, FTZ_OFF, binaryF),
ENTRY(fract, 0.0f, 0.0f, FTZ_OFF, unaryF_two_results),
ENTRY(frexp, 0.0f, 0.0f, FTZ_OFF, unaryF_two_results_i),
ENTRY(hypot, 4.0f, 4.0f, FTZ_OFF, binaryF),
ENTRY(ilogb, 0.0f, 0.0f, FTZ_OFF, i_unaryF),
ENTRY(isequal, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY(isfinite, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
ENTRY(isgreater, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY(isgreaterequal, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY(isinf, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
ENTRY(isless, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY(islessequal, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY(islessgreater, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY(isnan, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
ENTRY(isnormal, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
ENTRY(isnotequal, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY(isordered, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY(isunordered, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
ENTRY(ldexp, 0.0f, 0.0f, FTZ_OFF, binaryF_i),
ENTRY(lgamma, INFINITY, INFINITY, FTZ_OFF, unaryF),
ENTRY(lgamma_r, INFINITY, INFINITY, FTZ_OFF, unaryF_two_results_i),
ENTRY_EXT(log, 3.0f, 4.0f, 4.76837158203125e-7f, FTZ_OFF, unaryF,
4.76837158203125e-7f), // relaxed ulp 2^-21
ENTRY_EXT(log2, 3.0f, 4.0f, 4.76837158203125e-7f, FTZ_OFF, unaryF,
4.76837158203125e-7f), // relaxed ulp 2^-21
ENTRY(log10, 3.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY(log1p, 2.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY(logb, 0.0f, 0.0f, FTZ_OFF, unaryF),
ENTRY_EXT(mad, INFINITY, INFINITY, INFINITY, FTZ_OFF, mad_function,
INFINITY), // in fast-relaxed-math mode it has to be either
// exactly rounded fma or exactly rounded a*b+c
ENTRY(maxmag, 0.0f, 0.0f, FTZ_OFF, binaryF),
ENTRY(minmag, 0.0f, 0.0f, FTZ_OFF, binaryF),
ENTRY(modf, 0.0f, 0.0f, FTZ_OFF, unaryF_two_results),
ENTRY(nan, 0.0f, 0.0f, FTZ_OFF, unaryF_u),
ENTRY(nextafter, 0.0f, 0.0f, FTZ_OFF, binaryF_nextafter),
ENTRY_EXT(pow, 16.0f, 16.0f, 8192.0f, FTZ_OFF, binaryF,
8192.0f), // in derived mode the ulp error is calculated as
// exp2(y*log2(x)) and in non-derived it is the same as
// half_pow
ENTRY(pown, 16.0f, 16.0f, FTZ_OFF, binaryF_i),
ENTRY(powr, 16.0f, 16.0f, FTZ_OFF, binaryF),
// ENTRY( reciprocal, 1.0f,
// 1.0f, FTZ_OFF, unaryF),
ENTRY(remainder, 0.0f, 0.0f, FTZ_OFF, binaryF),
ENTRY(remquo, 0.0f, 0.0f, FTZ_OFF, binaryF_two_results_i),
ENTRY(rint, 0.0f, 0.0f, FTZ_OFF, unaryF),
ENTRY(rootn, 16.0f, 16.0f, FTZ_OFF, binaryF_i),
ENTRY(round, 0.0f, 0.0f, FTZ_OFF, unaryF),
ENTRY(rsqrt, 2.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY(signbit, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
ENTRY_EXT(sin, 4.0f, 4.0f, 0.00048828125f, FTZ_OFF, unaryF,
0.00048828125f), // relaxed ulp 2^-11
ENTRY_EXT(sincos, 4.0f, 4.0f, 0.00048828125f, FTZ_OFF, unaryF_two_results,
0.00048828125f), // relaxed ulp 2^-11
ENTRY(sinh, 4.0f, 4.0f, FTZ_OFF, unaryF),
ENTRY(sinpi, 4.0f, 4.0f, FTZ_OFF, unaryF),
{ "sqrt",
"sqrt",
{ (void*)reference_sqrt },
{ (void*)reference_sqrtl },
{ NULL },
3.0f,
0.0f,
4.0f,
INFINITY,
INFINITY,
FTZ_OFF,
RELAXED_OFF,
unaryF },
{ "sqrt_cr",
"sqrt",
{ (void*)reference_sqrt },
{ (void*)reference_sqrtl },
{ NULL },
0.0f,
0.0f,
0.0f,
INFINITY,
INFINITY,
FTZ_OFF,
RELAXED_OFF,
unaryF },
ENTRY_EXT(
tan, 5.0f, 5.0f, 8192.0f, FTZ_OFF, unaryF,
8192.0f), // in derived mode it the ulp error is calculated as sin/cos
// and in non-derived mode it is the same as half_tan.
ENTRY(tanh, 5.0f, 5.0f, FTZ_OFF, unaryF),
ENTRY(tanpi, 6.0f, 6.0f, FTZ_OFF, unaryF),
// ENTRY( tgamma, 16.0f,
// 16.0f, FTZ_OFF, unaryF),
// // Commented this out until we can be
// sure this requirement is realistic
ENTRY(trunc, 0.0f, 0.0f, FTZ_OFF, unaryF),
HALF_ENTRY( cos, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY( divide, 8192.0f, 8192.0f, FTZ_ON, binaryF),
HALF_ENTRY( exp, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY( exp2, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY( exp10, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY( log, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY( log2, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY( log10, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY( powr, 8192.0f, 8192.0f, FTZ_ON, binaryF),
HALF_ENTRY( recip, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY( rsqrt, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY( sin, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY( sqrt, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY( tan, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY(cos, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY(divide, 8192.0f, 8192.0f, FTZ_ON, binaryF),
HALF_ENTRY(exp, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY(exp2, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY(exp10, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY(log, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY(log2, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY(log10, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY(powr, 8192.0f, 8192.0f, FTZ_ON, binaryF),
HALF_ENTRY(recip, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY(rsqrt, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY(sin, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY(sqrt, 8192.0f, 8192.0f, FTZ_ON, unaryF),
HALF_ENTRY(tan, 8192.0f, 8192.0f, FTZ_ON, unaryF),
// basic operations
OPERATOR_ENTRY( add, "+", 0.0f, 0.0f, FTZ_OFF, binaryOperatorF),
OPERATOR_ENTRY( subtract, "-", 0.0f, 0.0f, FTZ_OFF, binaryOperatorF),
{ "divide", "/", {(void*)reference_divide}, {(void*)reference_dividel}, {(void*)reference_relaxed_divide}, 2.5f, 0.0f, 3.0f, 2.5f, FTZ_OFF, RELAXED_ON, binaryOperatorF },
{ "divide_cr", "/", {(void*)reference_divide}, {(void*)reference_dividel}, {(void*)reference_relaxed_divide}, 0.0f, 0.0f, 0.0f, 0.f, FTZ_OFF, RELAXED_OFF, binaryOperatorF },
OPERATOR_ENTRY( multiply, "*", 0.0f, 0.0f, FTZ_OFF, binaryOperatorF),
OPERATOR_ENTRY( assignment, "", 0.0f, 0.0f, FTZ_OFF, unaryF), // A simple copy operation
OPERATOR_ENTRY( not, "!", 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
};
// basic operations
OPERATOR_ENTRY(add, "+", 0.0f, 0.0f, FTZ_OFF, binaryOperatorF),
OPERATOR_ENTRY(subtract, "-", 0.0f, 0.0f, FTZ_OFF, binaryOperatorF),
{ "divide",
"/",
{ (void*)reference_divide },
{ (void*)reference_dividel },
{ (void*)reference_relaxed_divide },
2.5f,
0.0f,
3.0f,
2.5f,
INFINITY,
FTZ_OFF,
RELAXED_ON,
binaryOperatorF },
{ "divide_cr",
"/",
{ (void*)reference_divide },
{ (void*)reference_dividel },
{ (void*)reference_relaxed_divide },
0.0f,
0.0f,
0.0f,
0.f,
INFINITY,
FTZ_OFF,
RELAXED_OFF,
binaryOperatorF },
OPERATOR_ENTRY(multiply, "*", 0.0f, 0.0f, FTZ_OFF, binaryOperatorF),
OPERATOR_ENTRY(assignment, "", 0.0f, 0.0f, FTZ_OFF,
unaryF), // A simple copy operation
OPERATOR_ENTRY(not, "!", 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
};
const size_t functionListCount = sizeof( functionList ) / sizeof( functionList[0] );

View File

@@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@@ -85,6 +85,7 @@ typedef struct Func
float double_ulps;
float float_embedded_ulps;
float relaxed_error;
float relaxed_embedded_error;
int ftz;
int relaxed;
const vtbl *vtbl_ptr;

View File

@@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@@ -14,6 +14,7 @@
// limitations under the License.
//
#include "Utility.h"
#include "FunctionList.h"
#if defined(__PPC__)
// Global varaiable used to hold the FPU control register state. The FPSCR register can not
@@ -167,3 +168,32 @@ void logFunctionInfo(const char *fname, unsigned int float_size, unsigned int is
vlog("%15s %4s %4s",fname, fpSizeStr, fpFastRelaxedStr);
}
float getAllowedUlpError(const Func *f, const bool relaxed)
{
float ulp;
if (relaxed)
{
if (gIsEmbedded)
{
ulp = f->relaxed_embedded_error;
}
else
{
ulp = f->relaxed_error;
}
}
else
{
if (gIsEmbedded)
{
ulp = f->float_embedded_ulps;
}
else
{
ulp = f->float_ulps;
}
}
return ulp;
}

View File

@@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@@ -29,6 +29,7 @@
#include "harness/testHarness.h"
#include "harness/ThreadPool.h"
#include "harness/conversions.h"
#define BUFFER_SIZE (1024*1024*2)
#if defined( __GNUC__ )
@@ -37,6 +38,8 @@
#define UNUSED
#endif
struct Func;
extern int gWimpyBufferSize;
extern int gWimpyReductionFactor;
@@ -224,6 +227,8 @@ int compareDoubles(double x, double y);
void logFunctionInfo(const char *fname, unsigned int float_size, unsigned int isFastRelaxed);
float getAllowedUlpError(const Func *f, const bool relaxed);
#endif /* UTILITY_H */

View File

@@ -500,10 +500,10 @@ static cl_int TestFloat( cl_uint job_id, cl_uint thread_id, void *data )
size_t buffer_size = buffer_elements * sizeof( cl_float );
cl_uint base = job_id * (cl_uint) job->step;
ThreadInfo *tinfo = job->tinfo + thread_id;
float ulps = job->ulps;
fptr func = job->f->func;
int ftz = job->ftz;
bool relaxedMode = job->relaxedMode;
float ulps = getAllowedUlpError(job->f, relaxedMode);
MTdata d = tinfo->d;
cl_uint j, k;
cl_int error;
@@ -528,7 +528,6 @@ static cl_int TestFloat( cl_uint job_id, cl_uint thread_id, void *data )
}else
{
func = job->f->rfunc;
ulps = job->f->relaxed_error;
}
}

View File

@@ -491,9 +491,9 @@ static cl_int TestFloat(cl_uint job_id, cl_uint thread_id, void *data)
size_t buffer_size = buffer_elements * sizeof( cl_float );
cl_uint base = job_id * (cl_uint) job->step;
ThreadInfo *tinfo = job->tinfo + thread_id;
float ulps = job->ulps;
fptr func = job->f->func;
bool relaxedMode = job->relaxedMode;
float ulps = getAllowedUlpError(job->f, relaxedMode);
if (relaxedMode)
{
func = job->f->rfunc;
@@ -731,8 +731,6 @@ static cl_int TestFloat(cl_uint job_id, cl_uint thread_id, void *data)
float err = Ulp_Error( test, correct );
float errB = Ulp_Error( test, (float) correct );
if (relaxedMode) ulps = job->f->relaxed_error;
int fail = ((!(fabsf(err) <= ulps)) && (!(fabsf(errB) <= ulps)));
if( fabsf( errB ) < fabsf(err ) )
err = errB;

View File

@@ -463,13 +463,12 @@ static cl_int TestFloat( cl_uint job_id, cl_uint thread_id, void *data )
cl_uint scale = job->scale;
cl_uint base = job_id * (cl_uint) job->step;
ThreadInfo *tinfo = job->tinfo + thread_id;
float ulps = job->ulps;
fptr func = job->f->func;
const char * fname = job->f->name;
bool relaxedMode = job->relaxedMode;
float ulps = getAllowedUlpError(job->f, relaxedMode);
if (relaxedMode)
{
ulps = job->f->relaxed_error;
func = job->f->rfunc;
}
@@ -634,8 +633,13 @@ static cl_int TestFloat( cl_uint job_id, cl_uint thread_id, void *data )
if ( strcmp(fname, "exp") == 0 || strcmp(fname, "exp2") == 0 )
{
float exp_error = ulps;
if (!gIsEmbedded)
{
exp_error += floor(fabs(2 * s[j]));
}
float exp_error = 3+floor(fabs(2*s[j]));
fail = ! (fabsf(err) <= exp_error);
ulps = exp_error;
}

View File

@@ -208,19 +208,13 @@ int TestFunc_Float2_Float(const Func *f, MTdata d, bool relaxedMode)
cl_uchar overflow[BUFFER_SIZE / sizeof( float )];
int isFract = 0 == strcmp( "fract", f->nameInCode );
int skipNanInf = isFract && ! gInfNanSupport;
float float_ulps;
float float_ulps = getAllowedUlpError(f, relaxedMode);
logFunctionInfo(f->name, sizeof(cl_float), relaxedMode);
if( gWimpyMode )
{
step = (1ULL<<32) * gWimpyReductionFactor / (512);
}
if( gIsEmbedded )
float_ulps = f->float_embedded_ulps;
else
float_ulps = f->float_ulps;
if (relaxedMode) float_ulps = f->relaxed_error;
// Init the kernels
BuildKernelInfo build_info = { gMinVectorSizeIndex, kernels, programs,