// // 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 #include #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 \ { \ 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 \n"; \ } \ /* Reference value type is cl_double */ \ cl_double operator()(const cl_float& x) \ { \ return (HOST_FUNC)(static_cast(x)); \ } \ \ cl_float min1() \ { \ return MIN1; \ } \ \ cl_float max1() \ { \ return MAX1; \ } \ \ std::vector 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::infinity(), \ -std::numeric_limits::infinity(), \ std::numeric_limits::quiet_NaN() \ }; \ } \ \ bool use_ulp() \ { \ return USE_ULP; \ } \ \ template \ typename make_vector_type::value>::type \ delta(const cl_float& in1, const T& expected) \ { \ typedef \ typename make_vector_type::value>::type \ delta_vector_type; \ (void) in1; \ auto e = detail::make_value(DELTA); \ return detail::multiply(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 \ { \ 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 \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 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::infinity(), \ -std::numeric_limits::infinity(), \ std::numeric_limits::quiet_NaN() \ }; \ } \ \ std::vector 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::infinity(), \ -std::numeric_limits::infinity(), \ std::numeric_limits::quiet_NaN() \ }; \ } \ \ template \ typename make_vector_type::value>::type \ delta(const cl_float& in1, const cl_float& in2, const T& expected) \ { \ typedef \ typename make_vector_type::value>::type \ delta_vector_type; \ (void) in1; \ (void) in2; \ auto e = detail::make_value(DELTA); \ return detail::multiply(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 \ { \ 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 \n"; \ } \ \ cl_double operator()(const cl_float& x, const cl_float& y, const cl_float& z) \ { \ return (HOST_FUNC)(static_cast(x), static_cast(y), static_cast(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 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::infinity(), \ -std::numeric_limits::infinity(), \ std::numeric_limits::quiet_NaN() \ }; \ } \ \ std::vector 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::infinity(), \ -std::numeric_limits::infinity(), \ std::numeric_limits::quiet_NaN() \ }; \ } \ \ std::vector 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::infinity(), \ -std::numeric_limits::infinity(), \ std::numeric_limits::quiet_NaN() \ }; \ } \ \ template \ typename make_vector_type::value>::type \ delta(const cl_float& in1, const cl_float& in2, const cl_float& in3, const T& expected) \ { \ typedef \ typename make_vector_type::value>::type \ delta_vector_type; \ (void) in1; \ (void) in2; \ (void) in3; \ auto e = detail::make_value(DELTA); \ return detail::multiply(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