162 lines
4.6 KiB
C++
162 lines
4.6 KiB
C++
//
|
|
// 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
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
#ifndef TEST_CONFORMANCE_CLCPP_UTILS_TEST_COMPARE_HPP
|
|
#define TEST_CONFORMANCE_CLCPP_UTILS_TEST_COMPARE_HPP
|
|
|
|
#include <random>
|
|
#include <limits>
|
|
#include <type_traits>
|
|
#include <algorithm>
|
|
|
|
#include <cmath>
|
|
|
|
#include "../common.hpp"
|
|
|
|
// Checks if x is equal to y.
|
|
template<class type, class delta_type, class op_type>
|
|
inline bool are_equal(const type& x,
|
|
const type& y,
|
|
const delta_type& delta,
|
|
op_type op,
|
|
typename std::enable_if<
|
|
is_vector_type<type>::value
|
|
&& std::is_integral<typename scalar_type<type>::type>::value
|
|
>::type* = 0)
|
|
{
|
|
(void) delta;
|
|
for(size_t i = 0; i < vector_size<type>::value; i++)
|
|
{
|
|
if(op.is_out_bool())
|
|
{
|
|
if(!((x.s[i] != 0) == (y.s[i] != 0)))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if(!(x.s[i] == y.s[i]))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template<class type, class delta_type, class op_type>
|
|
inline bool are_equal(const type& x,
|
|
const type& y,
|
|
const delta_type& delta,
|
|
op_type op,
|
|
typename std::enable_if<
|
|
!is_vector_type<type>::value
|
|
&& std::is_integral<type>::value
|
|
>::type* = 0)
|
|
{
|
|
(void) delta;
|
|
if(op.is_out_bool())
|
|
{
|
|
if(!((x != 0) == (y != 0)))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return x == y;
|
|
}
|
|
|
|
template<class type, class type1, class type2, class op_type>
|
|
inline bool are_equal(const type& x,
|
|
const type1& y,
|
|
const type2& delta,
|
|
op_type op,
|
|
typename std::enable_if<
|
|
!is_vector_type<type>::value
|
|
&& std::is_floating_point<type>::value
|
|
>::type* = 0)
|
|
{
|
|
// x - expected
|
|
// y - result
|
|
|
|
// INFO:
|
|
// Whe don't care about subnormal values in OpenCL C++ tests
|
|
if(std::fpclassify(static_cast<type1>(x)) == FP_SUBNORMAL || std::fpclassify(y) == FP_SUBNORMAL)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// both are NaN
|
|
if((std::isnan)(static_cast<type1>(x)) && (std::isnan)(y))
|
|
{
|
|
return true;
|
|
}
|
|
// one is NaN
|
|
else if((std::isnan)(static_cast<type1>(x)) || (std::isnan)(y))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Check for perfect match, it also covers inf, -inf
|
|
if(static_cast<type1>(x) != y)
|
|
{
|
|
// Check if values are close
|
|
if(std::abs(static_cast<type1>(x) - y) > (std::max)(std::numeric_limits<type2>::epsilon(), std::abs(delta)))
|
|
{
|
|
return false;
|
|
}
|
|
// Check ulp
|
|
if(op.use_ulp())
|
|
{
|
|
return !(std::abs(Ulp_Error(x, y)) > op.ulp());
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template<class type, class type1, class type2, class op_type>
|
|
inline bool are_equal(const type& x,
|
|
const type1& y,
|
|
const type2& delta,
|
|
op_type op,
|
|
typename std::enable_if<
|
|
is_vector_type<type>::value
|
|
&& std::is_floating_point<typename scalar_type<type>::type>::value
|
|
>::type* = 0)
|
|
{
|
|
// x - expected
|
|
// y - result
|
|
for(size_t i = 0; i < vector_size<type>::value; i++)
|
|
{
|
|
if(!are_equal(x.s[i], y.s[i], delta.s[i], op))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template<class type, class type1, class func>
|
|
inline void print_error_msg(const type& expected, const type1& result, size_t i, func op)
|
|
{
|
|
log_error(
|
|
"ERROR: test_%s %s failed. Error at %lu: Expected: %s, got: %s\n",
|
|
op.str().c_str(),
|
|
op.decl_str().c_str(),
|
|
i,
|
|
format_value(expected).c_str(),
|
|
format_value(result).c_str()
|
|
);
|
|
}
|
|
|
|
#endif // TEST_CONFORMANCE_CLCPP_UTILS_TEST_COMPARE_HPP
|