blob: 32249056d0aabee4c3f0e63d8971fc6e41fb83ef [file] [log] [blame]
//
// 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_MATH_FUNCS_COMMON_FUNCS_HPP
#define TEST_CONFORMANCE_CLCPP_MATH_FUNCS_COMMON_FUNCS_HPP
#include <cmath>
#include <limits>
#include "../common.hpp"
#include "../funcs_test_utils.hpp"
#include "reference.hpp"
#ifndef MATH_FUNCS_CLASS_NAME
#define MATH_FUNCS_CLASS_NAME(x, y) x ## _func_ ## y
#endif
#define MATH_FUNCS_DEFINE_UNARY_FUNC1(GROUP_NAME, NAME, OCL_FUNC, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1) \
struct MATH_FUNCS_CLASS_NAME(GROUP_NAME, NAME) : public unary_func<cl_float, cl_float> \
{ \
MATH_FUNCS_CLASS_NAME(GROUP_NAME, NAME)(bool is_embedded) : m_is_embedded(is_embedded) \
{ \
\
} \
\
std::string str() \
{ \
return #OCL_FUNC; \
} \
\
std::string headers() \
{ \
return "#include <opencl_math>\n"; \
} \
/* Reference value type is cl_double */ \
cl_double operator()(const cl_float& x) \
{ \
return (HOST_FUNC)(static_cast<cl_double>(x)); \
} \
\
cl_float min1() \
{ \
return MIN1; \
} \
\
cl_float max1() \
{ \
return MAX1; \
} \
\
std::vector<cl_float> in1_special_cases() \
{ \
return { \
cl_float(0.0f), \
cl_float(-0.0f), \
cl_float(1.0f), \
cl_float(-1.0f), \
cl_float(2.0f), \
cl_float(-2.0f), \
std::numeric_limits<cl_float>::infinity(), \
-std::numeric_limits<cl_float>::infinity(), \
std::numeric_limits<cl_float>::quiet_NaN() \
}; \
} \
\
bool use_ulp() \
{ \
return USE_ULP; \
} \
\
template<class T> \
typename make_vector_type<cl_double, vector_size<T>::value>::type \
delta(const cl_float& in1, const T& expected) \
{ \
typedef \
typename make_vector_type<cl_double, vector_size<T>::value>::type \
delta_vector_type; \
(void) in1; \
auto e = detail::make_value<delta_vector_type>(DELTA); \
return detail::multiply<delta_vector_type>(e, expected); \
} \
\
float ulp() \
{ \
if(m_is_embedded) \
{ \
return ULP_EMBEDDED; \
} \
return ULP; \
} \
private: \
bool m_is_embedded; \
};
#define MATH_FUNCS_DEFINE_BINARY_FUNC1(GROUP_NAME, NAME, OCL_NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1, MIN2, MAX2) \
struct MATH_FUNCS_CLASS_NAME(GROUP_NAME, NAME) : public binary_func<cl_float, cl_float, cl_float> \
{ \
MATH_FUNCS_CLASS_NAME(GROUP_NAME, NAME)(bool is_embedded) : m_is_embedded(is_embedded) \
{ \
\
} \
\
std::string str() \
{ \
return #OCL_NAME; \
} \
\
std::string headers() \
{ \
return "#include <opencl_math>\n"; \
} \
\
cl_float operator()(const cl_float& x, const cl_float& y) \
{ \
return (HOST_FUNC)(x, y); \
} \
\
cl_float min1() \
{ \
return MIN1; \
} \
\
cl_float max1() \
{ \
return MAX1; \
} \
\
cl_float min2() \
{ \
return MIN2; \
} \
\
cl_float max2() \
{ \
return MAX2; \
} \
\
std::vector<cl_float> in1_special_cases() \
{ \
return { \
cl_float(0.0f), \
cl_float(-0.0f), \
cl_float(1.0f), \
cl_float(-1.0f), \
cl_float(2.0f), \
cl_float(-2.0f), \
std::numeric_limits<cl_float>::infinity(), \
-std::numeric_limits<cl_float>::infinity(), \
std::numeric_limits<cl_float>::quiet_NaN() \
}; \
} \
\
std::vector<cl_float> in2_special_cases() \
{ \
return { \
cl_float(0.0f), \
cl_float(-0.0f), \
cl_float(1.0f), \
cl_float(-1.0f), \
cl_float(2.0f), \
cl_float(-2.0f), \
std::numeric_limits<cl_float>::infinity(), \
-std::numeric_limits<cl_float>::infinity(), \
std::numeric_limits<cl_float>::quiet_NaN() \
}; \
} \
\
template<class T> \
typename make_vector_type<cl_double, vector_size<T>::value>::type \
delta(const cl_float& in1, const cl_float& in2, const T& expected) \
{ \
typedef \
typename make_vector_type<cl_double, vector_size<T>::value>::type \
delta_vector_type; \
(void) in1; \
(void) in2; \
auto e = detail::make_value<delta_vector_type>(DELTA); \
return detail::multiply<delta_vector_type>(e, expected); \
} \
\
bool use_ulp() \
{ \
return USE_ULP; \
} \
\
float ulp() \
{ \
if(m_is_embedded) \
{ \
return ULP_EMBEDDED; \
} \
return ULP; \
} \
private: \
bool m_is_embedded; \
};
#define MATH_FUNCS_DEFINE_TERNARY_FUNC1(GROUP_NAME, NAME, OCL_NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1, MIN2, MAX2, MIN3, MAX3) \
struct MATH_FUNCS_CLASS_NAME(GROUP_NAME, NAME) : public ternary_func<cl_float, cl_float, cl_float, cl_float> \
{ \
MATH_FUNCS_CLASS_NAME(GROUP_NAME, NAME)(bool is_embedded) : m_is_embedded(is_embedded) \
{ \
\
} \
\
std::string str() \
{ \
return #OCL_NAME; \
} \
\
std::string headers() \
{ \
return "#include <opencl_math>\n"; \
} \
\
cl_double operator()(const cl_float& x, const cl_float& y, const cl_float& z) \
{ \
return (HOST_FUNC)(static_cast<cl_double>(x), static_cast<cl_double>(y), static_cast<cl_double>(z)); \
} \
\
cl_float min1() \
{ \
return MIN1; \
} \
\
cl_float max1() \
{ \
return MAX1; \
} \
\
cl_float min2() \
{ \
return MIN2; \
} \
\
cl_float max2() \
{ \
return MAX2; \
} \
\
cl_float min3() \
{ \
return MIN3; \
} \
\
cl_float max3() \
{ \
return MAX3; \
} \
\
std::vector<cl_float> in1_special_cases() \
{ \
return { \
cl_float(0.0f), \
cl_float(-0.0f), \
cl_float(1.0f), \
cl_float(-1.0f), \
cl_float(2.0f), \
cl_float(-2.0f), \
std::numeric_limits<cl_float>::infinity(), \
-std::numeric_limits<cl_float>::infinity(), \
std::numeric_limits<cl_float>::quiet_NaN() \
}; \
} \
\
std::vector<cl_float> in2_special_cases() \
{ \
return { \
cl_float(0.0f), \
cl_float(-0.0f), \
cl_float(1.0f), \
cl_float(-1.0f), \
cl_float(2.0f), \
cl_float(-2.0f), \
std::numeric_limits<cl_float>::infinity(), \
-std::numeric_limits<cl_float>::infinity(), \
std::numeric_limits<cl_float>::quiet_NaN() \
}; \
} \
\
std::vector<cl_float> in3_special_cases() \
{ \
return { \
cl_float(0.0f), \
cl_float(-0.0f), \
cl_float(1.0f), \
cl_float(-1.0f), \
cl_float(2.0f), \
cl_float(-2.0f), \
std::numeric_limits<cl_float>::infinity(), \
-std::numeric_limits<cl_float>::infinity(), \
std::numeric_limits<cl_float>::quiet_NaN() \
}; \
} \
\
template<class T> \
typename make_vector_type<cl_double, vector_size<T>::value>::type \
delta(const cl_float& in1, const cl_float& in2, const cl_float& in3, const T& expected) \
{ \
typedef \
typename make_vector_type<cl_double, vector_size<T>::value>::type \
delta_vector_type; \
(void) in1; \
(void) in2; \
(void) in3; \
auto e = detail::make_value<delta_vector_type>(DELTA); \
return detail::multiply<delta_vector_type>(e, expected); \
} \
\
bool use_ulp() \
{ \
return USE_ULP; \
} \
\
float ulp() \
{ \
if(m_is_embedded) \
{ \
return ULP_EMBEDDED; \
} \
return ULP; \
} \
private: \
bool m_is_embedded; \
};
#define MATH_FUNCS_DEFINE_UNARY_FUNC(GROUP_NAME, NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1) \
MATH_FUNCS_DEFINE_UNARY_FUNC1(GROUP_NAME, NAME, NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1)
#define MATH_FUNCS_DEFINE_BINARY_FUNC(GROUP_NAME, NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1, MIN2, MAX2) \
MATH_FUNCS_DEFINE_BINARY_FUNC1(GROUP_NAME, NAME, NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1, MIN2, MAX2)
#define MATH_FUNCS_DEFINE_TERNARY_FUNC(GROUP_NAME, NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1, MIN2, MAX2, MIN3, MAX3) \
MATH_FUNCS_DEFINE_TERNARY_FUNC1(GROUP_NAME, NAME, NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1, MIN2, MAX2, MIN3, MAX3)
#endif // TEST_CONFORMANCE_CLCPP_MATH_FUNCS_COMMON_FUNCS_HPP