Skip to content

Fix floating point comparison in the tests #2785

Description

@dmitriy-sobolev

oneDPL/test/support/utils.h

Lines 115 to 125 in 59c96c8

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:

  1. Numeric algorithms: create a "stretching" margin of error.
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    testTest only Change

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions