|
template <typename T1, typename T2> |
|
bool |
|
is_equal_val(const T1& val1, const T2& val2) |
|
{ |
|
using T = std::common_type_t<T1, T2>; |
|
|
|
if constexpr (std::is_floating_point_v<T>) |
|
{ |
|
const auto eps = std::numeric_limits<T>::epsilon(); |
|
return std::fabs(T(val1) - T(val2)) < eps; |
|
} |
This floating point comparison approach is not correct.
Instead we should:
- Numeric algorithms: create a "stretching" margin of error.
- Rest algorithms, i.e. ones which just move and shuffle elements: compare values exactly.
There was an attempt to do (1) in #2762, but it was reverted as a non-essential change:
template <typename T>
bool
is_close(T a, T b)
{
// abs_tol is for rounding errors near zero.
// It is a multiple of an epsilon to tolerate accumulated errors.
// The larger the type, the larger the multiple to allow for more accumulations.
// rel_tol is selected intuitively.
T rel_tol = T(0.001); // 0.1%
T abs_tol = T(1e-5); // ~100x of the epsilon for float
if constexpr (sizeof(T) > sizeof(float))
{
rel_tol = T(0.0001); // 0.01%, 10x of the relative difference of any nearest number
abs_tol = T(1e-12); // ~1000x of the epsilon
}
#if TEST_DPCPP_BACKEND_PRESENT
else if constexpr (std::is_same_v<T, sycl::half>)
{
rel_tol = T(0.005); // 0.5%
abs_tol = T(1e-3); // ~10x of the epsilon
}
#if defined(SYCL_IMPLEMENTATION_INTEL)
else if constexpr (std::is_same_v<T, sycl::ext::oneapi::bfloat16>)
{
rel_tol = T(0.02); // 2%
abs_tol = T(1e-2); // ~10x of the epsilon
}
#endif
#endif
const T tol = std::max(rel_tol * std::max(std::fabs(a), std::fabs(b)), abs_tol);
return std::fabs(a - b) < tol;
}
template <typename T>
constexpr bool is_non_standard_float_v = false;
#if TEST_DPCPP_BACKEND_PRESENT
template <>
constexpr bool is_non_standard_float_v<sycl::half> = true;
#if defined(SYCL_IMPLEMENTATION_INTEL)
template <>
constexpr bool is_non_standard_float_v<sycl::ext::oneapi::bfloat16> = true;
#endif
#endif
oneDPL/test/support/utils.h
Lines 115 to 125 in 59c96c8
This floating point comparison approach is not correct.
Instead we should:
There was an attempt to do (1) in #2762, but it was reverted as a non-essential change: