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_COMPARISON_FUNCS_HPP
17 #define TEST_CONFORMANCE_CLCPP_RELATIONAL_FUNCS_COMPARISON_FUNCS_HPP
18
19 #include "common.hpp"
20
21 // This marco creates a class wrapper for comparision function we want to test.
22 #define DEF_COMPARISION_FUNC(CLASS_NAME, FUNC_NAME, HOST_FUNC_EXPRESSION) \
23 template <cl_int N /* Vector size */> \
24 struct CLASS_NAME : public binary_func< \
25 typename make_vector_type<cl_float, N>::type, /* create cl_floatN type */ \
26 typename make_vector_type<cl_float, N>::type, /* create cl_floatN type */ \
27 typename make_vector_type<cl_int, N>::type /* create cl_intN type */ \
28 > \
29 { \
30 typedef typename make_vector_type<cl_float, N>::type input_type; \
31 typedef typename make_vector_type<cl_int, N>::type result_type; \
32 \
33 std::string str() \
34 { \
35 return #FUNC_NAME; \
36 } \
37 \
38 std::string headers() \
39 { \
40 return "#include <opencl_relational>\n"; \
41 } \
42 \
43 result_type operator()(const input_type& x, const input_type& y) \
44 { \
45 typedef typename scalar_type<input_type>::type SCALAR; \
46 return perform_function<input_type, input_type, result_type>( \
47 x, y, \
48 [](const SCALAR& a, const SCALAR& b) \
49 { \
50 if(HOST_FUNC_EXPRESSION) \
51 { \
52 return cl_int(1); \
53 } \
54 return cl_int(0); \
55 } \
56 ); \
57 } \
58 \
59 bool is_out_bool() \
60 { \
61 return true; \
62 } \
63 \
64 input_type min1() \
65 { \
66 return detail::def_limit<input_type>(-10000.0f); \
67 } \
68 \
69 input_type max1() \
70 { \
71 return detail::def_limit<input_type>(10000.0f); \
72 } \
73 \
74 input_type min2() \
75 { \
76 return detail::def_limit<input_type>(-10000.0f); \
77 } \
78 \
79 input_type max2() \
80 { \
81 return detail::def_limit<input_type>(10000.0f); \
82 } \
83 \
84 std::vector<input_type> in1_special_cases() \
85 { \
86 typedef typename scalar_type<input_type>::type SCALAR; \
87 return { \
88 detail::make_value<input_type>(std::numeric_limits<SCALAR>::infinity()), \
89 detail::make_value<input_type>(-std::numeric_limits<SCALAR>::infinity()), \
90 detail::make_value<input_type>(std::numeric_limits<SCALAR>::quiet_NaN()), \
91 detail::make_value<input_type>(0.0f), \
92 detail::make_value<input_type>(-0.0f) \
93 }; \
94 } \
95 \
96 std::vector<input_type> in2_special_cases() \
97 { \
98 typedef typename scalar_type<input_type>::type SCALAR; \
99 return { \
100 detail::make_value<input_type>(std::numeric_limits<SCALAR>::infinity()), \
101 detail::make_value<input_type>(-std::numeric_limits<SCALAR>::infinity()), \
102 detail::make_value<input_type>(std::numeric_limits<SCALAR>::quiet_NaN()), \
103 detail::make_value<input_type>(0.0f), \
104 detail::make_value<input_type>(-0.0f) \
105 }; \
106 } \
107 };
108
109 DEF_COMPARISION_FUNC(comparison_func_isequal, isequal, (a == b))
110 DEF_COMPARISION_FUNC(comparison_func_isnotequal, isnotequal, !(a == b))
111 DEF_COMPARISION_FUNC(comparison_func_isgreater, isgreater, (std::isgreater)(a, b))
112 DEF_COMPARISION_FUNC(comparison_func_isgreaterequal, isgreaterequal, ((std::isgreater)(a, b) || a == b))
113 DEF_COMPARISION_FUNC(comparison_func_isless, isless, (std::isless)(a, b))
114 DEF_COMPARISION_FUNC(comparison_func_islessequal, islessequal, ((std::isless)(a, b) || a == b))
115 DEF_COMPARISION_FUNC(comparison_func_islessgreater, islessgreater, ((a < b) || (a > b)))
116
117 #undef DEF_COMPARISION_FUNC
118
AUTO_TEST_CASE(test_relational_comparison_funcs)119 AUTO_TEST_CASE(test_relational_comparison_funcs)
120 (cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
121 {
122 int error = CL_SUCCESS;
123 int last_error = CL_SUCCESS;
124
125 // Helper macro, so we don't have to repreat the same code.
126 #define TEST_BINARY_REL_FUNC_MACRO(CLASS_NAME) \
127 TEST_BINARY_FUNC_MACRO(CLASS_NAME<1>()) \
128 TEST_BINARY_FUNC_MACRO(CLASS_NAME<2>()) \
129 TEST_BINARY_FUNC_MACRO(CLASS_NAME<4>()) \
130 TEST_BINARY_FUNC_MACRO(CLASS_NAME<8>()) \
131 TEST_BINARY_FUNC_MACRO(CLASS_NAME<16>())
132
133 TEST_BINARY_REL_FUNC_MACRO(comparison_func_isequal)
134 TEST_BINARY_REL_FUNC_MACRO(comparison_func_isnotequal)
135 TEST_BINARY_REL_FUNC_MACRO(comparison_func_isgreater)
136 TEST_BINARY_REL_FUNC_MACRO(comparison_func_isgreaterequal)
137 TEST_BINARY_REL_FUNC_MACRO(comparison_func_isless)
138 TEST_BINARY_REL_FUNC_MACRO(comparison_func_islessequal)
139 TEST_BINARY_REL_FUNC_MACRO(comparison_func_islessgreater)
140
141 #undef TEST_BINARY_REL_FUNC_MACRO
142
143 if(error != CL_SUCCESS)
144 {
145 return -1;
146 }
147 return error;
148 }
149
150 #endif // TEST_CONFORMANCE_CLCPP_RELATIONAL_FUNCS_COMPARISON_FUNCS_HPP
151