• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_RELATIONAL_FUNCS_TEST_FUNCS_HPP
17 #define TEST_CONFORMANCE_CLCPP_RELATIONAL_FUNCS_TEST_FUNCS_HPP
18 
19 #include "common.hpp"
20 
21 // This marco creates a class wrapper for unary test function we want to test.
22 #define DEF_UNARY_TEST_FUNC(CLASS_NAME, FUNC_NAME, HOST_FUNC_EXPRESSION) \
23 template <cl_int N /* Vector size */> \
24 struct CLASS_NAME : public unary_func< \
25                                     typename make_vector_type<cl_float, N>::type, /* create cl_floatN type */ \
26                                     typename make_vector_type<cl_int, N>::type /* create cl_intN type */ \
27                                  > \
28 { \
29     typedef typename make_vector_type<cl_float, N>::type input_type; \
30     typedef typename make_vector_type<cl_int, N>::type result_type; \
31     \
32     std::string str() \
33     { \
34         return #FUNC_NAME; \
35     } \
36     \
37     std::string headers() \
38     { \
39         return "#include <opencl_relational>\n"; \
40     } \
41     \
42     result_type operator()(const input_type& x) \
43     {    \
44         typedef typename scalar_type<input_type>::type SCALAR; \
45         return perform_function<input_type, result_type>( \
46             x, \
47             [](const SCALAR& a) \
48             { \
49                 if(HOST_FUNC_EXPRESSION) \
50                 { \
51                     return cl_int(1); \
52                 } \
53                 return cl_int(0); \
54             } \
55         ); \
56     } \
57     \
58     bool is_out_bool() \
59     { \
60         return true; \
61     } \
62     \
63     input_type min1() \
64     { \
65         return detail::def_limit<input_type>(-10000.0f); \
66     } \
67     \
68     input_type max1() \
69     { \
70         return detail::def_limit<input_type>(10000.0f); \
71     } \
72     \
73     std::vector<input_type> in1_special_cases() \
74     { \
75         typedef typename scalar_type<input_type>::type SCALAR; \
76         return {  \
77             detail::make_value<input_type>(std::numeric_limits<SCALAR>::infinity()), \
78             detail::make_value<input_type>(-std::numeric_limits<SCALAR>::infinity()), \
79             detail::make_value<input_type>(std::numeric_limits<SCALAR>::quiet_NaN()), \
80             detail::make_value<input_type>(std::numeric_limits<SCALAR>::signaling_NaN()), \
81             detail::make_value<input_type>(std::numeric_limits<SCALAR>::denorm_min()), \
82             detail::make_value<input_type>(0.0f), \
83             detail::make_value<input_type>(-0.0f) \
84         }; \
85     } \
86 };
87 
88 // This marco creates a class wrapper for binary test function we want to test.
89 #define DEF_BINARY_TEST_FUNC(CLASS_NAME, FUNC_NAME, HOST_FUNC_EXPRESSION) \
90 template <cl_int N /* Vector size */> \
91 struct CLASS_NAME : public binary_func< \
92                                     typename make_vector_type<cl_float, N>::type, /* create cl_floatN type */ \
93                                     typename make_vector_type<cl_float, N>::type, /* create cl_floatN type */ \
94                                     typename make_vector_type<cl_int, N>::type /* create cl_intN type */ \
95                                  > \
96 { \
97     typedef typename make_vector_type<cl_float, N>::type input_type; \
98     typedef typename make_vector_type<cl_int, N>::type result_type; \
99     \
100     std::string str() \
101     { \
102         return #FUNC_NAME; \
103     } \
104     \
105     std::string headers() \
106     { \
107         return "#include <opencl_relational>\n"; \
108     } \
109     \
110     result_type operator()(const input_type& x, const input_type& y) \
111     {    \
112         typedef typename scalar_type<input_type>::type SCALAR; \
113         return perform_function<input_type, input_type, result_type>( \
114             x, y, \
115             [](const SCALAR& a, const SCALAR& b) \
116             { \
117                 if(HOST_FUNC_EXPRESSION) \
118                 { \
119                     return cl_int(1); \
120                 } \
121                 return cl_int(0); \
122             } \
123         ); \
124     } \
125     \
126     bool is_out_bool() \
127     { \
128         return true; \
129     } \
130     \
131     input_type min1() \
132     { \
133         return detail::def_limit<input_type>(-10000.0f); \
134     } \
135     \
136     input_type max1() \
137     { \
138         return detail::def_limit<input_type>(10000.0f); \
139     } \
140     \
141     input_type min2() \
142     { \
143         return detail::def_limit<input_type>(-10000.0f); \
144     } \
145     \
146     input_type max2() \
147     { \
148         return detail::def_limit<input_type>(10000.0f); \
149     } \
150     \
151     std::vector<input_type> in1_special_cases() \
152     { \
153         typedef typename scalar_type<input_type>::type SCALAR; \
154         return {  \
155             detail::make_value<input_type>(std::numeric_limits<SCALAR>::infinity()), \
156             detail::make_value<input_type>(-std::numeric_limits<SCALAR>::infinity()), \
157             detail::make_value<input_type>(std::numeric_limits<SCALAR>::quiet_NaN()), \
158             detail::make_value<input_type>(std::numeric_limits<SCALAR>::signaling_NaN()), \
159             detail::make_value<input_type>(std::numeric_limits<SCALAR>::denorm_min()), \
160             detail::make_value<input_type>(0.0f), \
161             detail::make_value<input_type>(-0.0f) \
162         }; \
163     } \
164     \
165     std::vector<input_type> in2_special_cases() \
166     { \
167         typedef typename scalar_type<input_type>::type SCALAR; \
168         return {  \
169             detail::make_value<input_type>(std::numeric_limits<SCALAR>::infinity()), \
170             detail::make_value<input_type>(-std::numeric_limits<SCALAR>::infinity()), \
171             detail::make_value<input_type>(std::numeric_limits<SCALAR>::quiet_NaN()), \
172             detail::make_value<input_type>(std::numeric_limits<SCALAR>::signaling_NaN()), \
173             detail::make_value<input_type>(std::numeric_limits<SCALAR>::denorm_min()), \
174             detail::make_value<input_type>(0.0f), \
175             detail::make_value<input_type>(-0.0f) \
176         }; \
177     } \
178 };
179 
180 DEF_UNARY_TEST_FUNC(test_func_isfinite, isfinite, (std::isfinite)(a))
181 DEF_UNARY_TEST_FUNC(test_func_isinf, isinf, (std::isinf)(a))
182 DEF_UNARY_TEST_FUNC(test_func_isnan, isnan, (std::isnan)(a))
183 DEF_UNARY_TEST_FUNC(test_func_isnormal, isnormal, (std::isnormal)(a))
184 DEF_UNARY_TEST_FUNC(test_func_signbit, signbit , (std::signbit)(a))
185 
186 DEF_BINARY_TEST_FUNC(test_func_isordered, isordered, !(std::isunordered)(a, b))
187 DEF_BINARY_TEST_FUNC(test_func_isunordered, isunordered, (std::isunordered)(a, b))
188 
189 #undef DEF_UNARY_TEST_FUNC
190 #undef DEF_BINARY_TEST_FUNC
191 
192 template <cl_int N /* Vector size */>
193 struct test_func_all : public unary_func<
194                                     typename make_vector_type<cl_int, N>::type, /* create cl_intN type */
195                                     cl_int /* create cl_intN type */
196                                  >
197 {
198     typedef typename make_vector_type<cl_int, N>::type input_type;
199     typedef cl_int result_type;
200 
strtest_func_all201     std::string str()
202     {
203         return "all";
204     }
205 
headerstest_func_all206     std::string headers()
207     {
208         return "#include <opencl_relational>\n";
209     }
210 
operator ()test_func_all211     result_type operator()(const input_type& x)
212     {
213         return perform_all_function(x);
214     }
215 
is_out_booltest_func_all216     bool is_out_bool()
217     {
218         return true;
219     }
220 
is_in1_booltest_func_all221     bool is_in1_bool()
222     {
223         return true;
224     }
225 
in1_special_casestest_func_all226     std::vector<input_type> in1_special_cases()
227     {
228         return {
229             detail::make_value<input_type>(0),
230             detail::make_value<input_type>(1),
231             detail::make_value<input_type>(12),
232             detail::make_value<input_type>(-12)
233         };
234     }
235 };
236 
237 template <cl_int N /* Vector size */>
238 struct test_func_any : public unary_func<
239                                     typename make_vector_type<cl_int, N>::type, /* create cl_intN type */
240                                     cl_int /* create cl_intN type */
241                                  >
242 {
243     typedef typename make_vector_type<cl_int, N>::type input_type;
244     typedef cl_int result_type;
245 
strtest_func_any246     std::string str()
247     {
248         return "any";
249     }
250 
headerstest_func_any251     std::string headers()
252     {
253         return "#include <opencl_relational>\n";
254     }
255 
operator ()test_func_any256     result_type operator()(const input_type& x)
257     {
258         return perform_any_function(x);
259     }
260 
is_out_booltest_func_any261     bool is_out_bool()
262     {
263         return true;
264     }
265 
is_in1_booltest_func_any266     bool is_in1_bool()
267     {
268         return true;
269     }
270 
in1_special_casestest_func_any271     std::vector<input_type> in1_special_cases()
272     {
273         return {
274             detail::make_value<input_type>(0),
275             detail::make_value<input_type>(1),
276             detail::make_value<input_type>(12),
277             detail::make_value<input_type>(-12)
278         };
279     }
280 };
281 
AUTO_TEST_CASE(test_relational_test_funcs)282 AUTO_TEST_CASE(test_relational_test_funcs)
283 (cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
284 {
285     int error = CL_SUCCESS;
286     int last_error = CL_SUCCESS;
287 
288 // Helper macro, so we don't have to repreat the same code.
289 #define TEST_UNARY_REL_FUNC_MACRO(CLASS_NAME) \
290     TEST_UNARY_FUNC_MACRO(CLASS_NAME<1>()) \
291     TEST_UNARY_FUNC_MACRO(CLASS_NAME<2>()) \
292     TEST_UNARY_FUNC_MACRO(CLASS_NAME<4>()) \
293     TEST_UNARY_FUNC_MACRO(CLASS_NAME<8>()) \
294     TEST_UNARY_FUNC_MACRO(CLASS_NAME<16>())
295 
296     TEST_UNARY_REL_FUNC_MACRO(test_func_isfinite)
297     TEST_UNARY_REL_FUNC_MACRO(test_func_isinf)
298     TEST_UNARY_REL_FUNC_MACRO(test_func_isnan)
299     TEST_UNARY_REL_FUNC_MACRO(test_func_isnormal)
300     TEST_UNARY_REL_FUNC_MACRO(test_func_signbit)
301 
302 // Tests for all(booln x) and any(booln x) are not run in USE_OPENCLC_KERNELS mode,
303 // because those functions in OpenCL C require different reference functions on host
304 // compared to their equivalents from OpenCL C++.
305 // (In OpenCL C those functions returns true/false based on the most significant bits
306 // in any/all component/s of x)
307 #ifndef USE_OPENCLC_KERNELS
308     TEST_UNARY_REL_FUNC_MACRO(test_func_all)
309     TEST_UNARY_REL_FUNC_MACRO(test_func_any)
310 #else
311     log_info("WARNING:\n\tTests for bool all(booln x) are not run in USE_OPENCLC_KERNELS mode\n");
312     log_info("WARNING:\n\tTests for bool any(booln x) are not run in USE_OPENCLC_KERNELS mode\n");
313 #endif
314 
315 #undef TEST_UNARY_REL_FUNC_MACRO
316 
317 #define TEST_BINARY_REL_FUNC_MACRO(CLASS_NAME) \
318     TEST_BINARY_FUNC_MACRO(CLASS_NAME<1>()) \
319     TEST_BINARY_FUNC_MACRO(CLASS_NAME<2>()) \
320     TEST_BINARY_FUNC_MACRO(CLASS_NAME<4>()) \
321     TEST_BINARY_FUNC_MACRO(CLASS_NAME<8>()) \
322     TEST_BINARY_FUNC_MACRO(CLASS_NAME<16>())
323 
324     TEST_BINARY_REL_FUNC_MACRO(test_func_isordered)
325     TEST_BINARY_REL_FUNC_MACRO(test_func_isunordered)
326 
327 #undef TEST_BINARY_REL_FUNC_MACRO
328 
329     if(error != CL_SUCCESS)
330     {
331         return -1;
332     }
333     return error;
334 }
335 
336 #endif // TEST_CONFORMANCE_CLCPP_RELATIONAL_FUNCS_TEST_FUNCS_HPP
337