1 // 2 // Copyright (c) 2017 The Khronos Group Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 #ifndef TEST_CONFORMANCE_CLCPP_MATH_FUNCS_COMMON_FUNCS_HPP 17 #define TEST_CONFORMANCE_CLCPP_MATH_FUNCS_COMMON_FUNCS_HPP 18 19 #include <cmath> 20 #include <limits> 21 22 #include "../common.hpp" 23 #include "../funcs_test_utils.hpp" 24 25 #include "reference.hpp" 26 27 #ifndef MATH_FUNCS_CLASS_NAME 28 #define MATH_FUNCS_CLASS_NAME(x, y) x ## _func_ ## y 29 #endif 30 31 #define MATH_FUNCS_DEFINE_UNARY_FUNC1(GROUP_NAME, NAME, OCL_FUNC, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1) \ 32 struct MATH_FUNCS_CLASS_NAME(GROUP_NAME, NAME) : public unary_func<cl_float, cl_float> \ 33 { \ 34 MATH_FUNCS_CLASS_NAME(GROUP_NAME, NAME)(bool is_embedded) : m_is_embedded(is_embedded) \ 35 { \ 36 \ 37 } \ 38 \ 39 std::string str() \ 40 { \ 41 return #OCL_FUNC; \ 42 } \ 43 \ 44 std::string headers() \ 45 { \ 46 return "#include <opencl_math>\n"; \ 47 } \ 48 /* Reference value type is cl_double */ \ 49 cl_double operator()(const cl_float& x) \ 50 { \ 51 return (HOST_FUNC)(static_cast<cl_double>(x)); \ 52 } \ 53 \ 54 cl_float min1() \ 55 { \ 56 return MIN1; \ 57 } \ 58 \ 59 cl_float max1() \ 60 { \ 61 return MAX1; \ 62 } \ 63 \ 64 std::vector<cl_float> in1_special_cases() \ 65 { \ 66 return { \ 67 cl_float(0.0f), \ 68 cl_float(-0.0f), \ 69 cl_float(1.0f), \ 70 cl_float(-1.0f), \ 71 cl_float(2.0f), \ 72 cl_float(-2.0f), \ 73 std::numeric_limits<cl_float>::infinity(), \ 74 -std::numeric_limits<cl_float>::infinity(), \ 75 std::numeric_limits<cl_float>::quiet_NaN() \ 76 }; \ 77 } \ 78 \ 79 bool use_ulp() \ 80 { \ 81 return USE_ULP; \ 82 } \ 83 \ 84 template<class T> \ 85 typename make_vector_type<cl_double, vector_size<T>::value>::type \ 86 delta(const cl_float& in1, const T& expected) \ 87 { \ 88 typedef \ 89 typename make_vector_type<cl_double, vector_size<T>::value>::type \ 90 delta_vector_type; \ 91 (void) in1; \ 92 auto e = detail::make_value<delta_vector_type>(DELTA); \ 93 return detail::multiply<delta_vector_type>(e, expected); \ 94 } \ 95 \ 96 float ulp() \ 97 { \ 98 if(m_is_embedded) \ 99 { \ 100 return ULP_EMBEDDED; \ 101 } \ 102 return ULP; \ 103 } \ 104 private: \ 105 bool m_is_embedded; \ 106 }; 107 108 #define MATH_FUNCS_DEFINE_BINARY_FUNC1(GROUP_NAME, NAME, OCL_NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1, MIN2, MAX2) \ 109 struct MATH_FUNCS_CLASS_NAME(GROUP_NAME, NAME) : public binary_func<cl_float, cl_float, cl_float> \ 110 { \ 111 MATH_FUNCS_CLASS_NAME(GROUP_NAME, NAME)(bool is_embedded) : m_is_embedded(is_embedded) \ 112 { \ 113 \ 114 } \ 115 \ 116 std::string str() \ 117 { \ 118 return #OCL_NAME; \ 119 } \ 120 \ 121 std::string headers() \ 122 { \ 123 return "#include <opencl_math>\n"; \ 124 } \ 125 \ 126 cl_float operator()(const cl_float& x, const cl_float& y) \ 127 { \ 128 return (HOST_FUNC)(x, y); \ 129 } \ 130 \ 131 cl_float min1() \ 132 { \ 133 return MIN1; \ 134 } \ 135 \ 136 cl_float max1() \ 137 { \ 138 return MAX1; \ 139 } \ 140 \ 141 cl_float min2() \ 142 { \ 143 return MIN2; \ 144 } \ 145 \ 146 cl_float max2() \ 147 { \ 148 return MAX2; \ 149 } \ 150 \ 151 std::vector<cl_float> in1_special_cases() \ 152 { \ 153 return { \ 154 cl_float(0.0f), \ 155 cl_float(-0.0f), \ 156 cl_float(1.0f), \ 157 cl_float(-1.0f), \ 158 cl_float(2.0f), \ 159 cl_float(-2.0f), \ 160 std::numeric_limits<cl_float>::infinity(), \ 161 -std::numeric_limits<cl_float>::infinity(), \ 162 std::numeric_limits<cl_float>::quiet_NaN() \ 163 }; \ 164 } \ 165 \ 166 std::vector<cl_float> in2_special_cases() \ 167 { \ 168 return { \ 169 cl_float(0.0f), \ 170 cl_float(-0.0f), \ 171 cl_float(1.0f), \ 172 cl_float(-1.0f), \ 173 cl_float(2.0f), \ 174 cl_float(-2.0f), \ 175 std::numeric_limits<cl_float>::infinity(), \ 176 -std::numeric_limits<cl_float>::infinity(), \ 177 std::numeric_limits<cl_float>::quiet_NaN() \ 178 }; \ 179 } \ 180 \ 181 template<class T> \ 182 typename make_vector_type<cl_double, vector_size<T>::value>::type \ 183 delta(const cl_float& in1, const cl_float& in2, const T& expected) \ 184 { \ 185 typedef \ 186 typename make_vector_type<cl_double, vector_size<T>::value>::type \ 187 delta_vector_type; \ 188 (void) in1; \ 189 (void) in2; \ 190 auto e = detail::make_value<delta_vector_type>(DELTA); \ 191 return detail::multiply<delta_vector_type>(e, expected); \ 192 } \ 193 \ 194 bool use_ulp() \ 195 { \ 196 return USE_ULP; \ 197 } \ 198 \ 199 float ulp() \ 200 { \ 201 if(m_is_embedded) \ 202 { \ 203 return ULP_EMBEDDED; \ 204 } \ 205 return ULP; \ 206 } \ 207 private: \ 208 bool m_is_embedded; \ 209 }; 210 211 #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) \ 212 struct MATH_FUNCS_CLASS_NAME(GROUP_NAME, NAME) : public ternary_func<cl_float, cl_float, cl_float, cl_float> \ 213 { \ 214 MATH_FUNCS_CLASS_NAME(GROUP_NAME, NAME)(bool is_embedded) : m_is_embedded(is_embedded) \ 215 { \ 216 \ 217 } \ 218 \ 219 std::string str() \ 220 { \ 221 return #OCL_NAME; \ 222 } \ 223 \ 224 std::string headers() \ 225 { \ 226 return "#include <opencl_math>\n"; \ 227 } \ 228 \ 229 cl_double operator()(const cl_float& x, const cl_float& y, const cl_float& z) \ 230 { \ 231 return (HOST_FUNC)(static_cast<cl_double>(x), static_cast<cl_double>(y), static_cast<cl_double>(z)); \ 232 } \ 233 \ 234 cl_float min1() \ 235 { \ 236 return MIN1; \ 237 } \ 238 \ 239 cl_float max1() \ 240 { \ 241 return MAX1; \ 242 } \ 243 \ 244 cl_float min2() \ 245 { \ 246 return MIN2; \ 247 } \ 248 \ 249 cl_float max2() \ 250 { \ 251 return MAX2; \ 252 } \ 253 \ 254 cl_float min3() \ 255 { \ 256 return MIN3; \ 257 } \ 258 \ 259 cl_float max3() \ 260 { \ 261 return MAX3; \ 262 } \ 263 \ 264 std::vector<cl_float> in1_special_cases() \ 265 { \ 266 return { \ 267 cl_float(0.0f), \ 268 cl_float(-0.0f), \ 269 cl_float(1.0f), \ 270 cl_float(-1.0f), \ 271 cl_float(2.0f), \ 272 cl_float(-2.0f), \ 273 std::numeric_limits<cl_float>::infinity(), \ 274 -std::numeric_limits<cl_float>::infinity(), \ 275 std::numeric_limits<cl_float>::quiet_NaN() \ 276 }; \ 277 } \ 278 \ 279 std::vector<cl_float> in2_special_cases() \ 280 { \ 281 return { \ 282 cl_float(0.0f), \ 283 cl_float(-0.0f), \ 284 cl_float(1.0f), \ 285 cl_float(-1.0f), \ 286 cl_float(2.0f), \ 287 cl_float(-2.0f), \ 288 std::numeric_limits<cl_float>::infinity(), \ 289 -std::numeric_limits<cl_float>::infinity(), \ 290 std::numeric_limits<cl_float>::quiet_NaN() \ 291 }; \ 292 } \ 293 \ 294 std::vector<cl_float> in3_special_cases() \ 295 { \ 296 return { \ 297 cl_float(0.0f), \ 298 cl_float(-0.0f), \ 299 cl_float(1.0f), \ 300 cl_float(-1.0f), \ 301 cl_float(2.0f), \ 302 cl_float(-2.0f), \ 303 std::numeric_limits<cl_float>::infinity(), \ 304 -std::numeric_limits<cl_float>::infinity(), \ 305 std::numeric_limits<cl_float>::quiet_NaN() \ 306 }; \ 307 } \ 308 \ 309 template<class T> \ 310 typename make_vector_type<cl_double, vector_size<T>::value>::type \ 311 delta(const cl_float& in1, const cl_float& in2, const cl_float& in3, const T& expected) \ 312 { \ 313 typedef \ 314 typename make_vector_type<cl_double, vector_size<T>::value>::type \ 315 delta_vector_type; \ 316 (void) in1; \ 317 (void) in2; \ 318 (void) in3; \ 319 auto e = detail::make_value<delta_vector_type>(DELTA); \ 320 return detail::multiply<delta_vector_type>(e, expected); \ 321 } \ 322 \ 323 bool use_ulp() \ 324 { \ 325 return USE_ULP; \ 326 } \ 327 \ 328 float ulp() \ 329 { \ 330 if(m_is_embedded) \ 331 { \ 332 return ULP_EMBEDDED; \ 333 } \ 334 return ULP; \ 335 } \ 336 private: \ 337 bool m_is_embedded; \ 338 }; 339 340 #define MATH_FUNCS_DEFINE_UNARY_FUNC(GROUP_NAME, NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1) \ 341 MATH_FUNCS_DEFINE_UNARY_FUNC1(GROUP_NAME, NAME, NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1) 342 #define MATH_FUNCS_DEFINE_BINARY_FUNC(GROUP_NAME, NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1, MIN2, MAX2) \ 343 MATH_FUNCS_DEFINE_BINARY_FUNC1(GROUP_NAME, NAME, NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1, MIN2, MAX2) 344 #define MATH_FUNCS_DEFINE_TERNARY_FUNC(GROUP_NAME, NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1, MIN2, MAX2, MIN3, MAX3) \ 345 MATH_FUNCS_DEFINE_TERNARY_FUNC1(GROUP_NAME, NAME, NAME, HOST_FUNC, USE_ULP, ULP, ULP_EMBEDDED, DELTA, MIN1, MAX1, MIN2, MAX2, MIN3, MAX3) 346 347 #endif // TEST_CONFORMANCE_CLCPP_MATH_FUNCS_COMMON_FUNCS_HPP 348