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_SELECT_FUNCS_HPP
17 #define TEST_CONFORMANCE_CLCPP_RELATIONAL_FUNCS_SELECT_FUNCS_HPP
18
19 #include "common.hpp"
20
21 template <class IN1, cl_int N /* Vector size */>
22 struct select_func_select : public ternary_func<
23 typename make_vector_type<IN1, N>::type, /* create IN1N type */
24 typename make_vector_type<IN1, N>::type, /* create IN1N type */
25 typename make_vector_type<cl_int, N>::type, /* create cl_intN type */
26 typename make_vector_type<IN1, N>::type /* create IN1N type */
27 >
28 {
29 typedef typename make_vector_type<IN1, N>::type input1_type;
30 typedef typename make_vector_type<IN1, N>::type input2_type;
31 typedef typename make_vector_type<cl_int, N>::type input3_type;
32 typedef typename make_vector_type<IN1, N>::type result_type;
33
strselect_func_select34 std::string str()
35 {
36 return "select";
37 }
38
headersselect_func_select39 std::string headers()
40 {
41 return "#include <opencl_relational>\n";
42 }
43
operator ()select_func_select44 result_type operator()(const input1_type& x, const input2_type& y, const input3_type& z)
45 {
46 typedef typename scalar_type<input1_type>::type SCALAR1;
47 typedef typename scalar_type<input2_type>::type SCALAR2;
48 typedef typename scalar_type<input3_type>::type SCALAR3;
49
50 return perform_function<input1_type, input2_type, input3_type, result_type>(
51 x, y, z,
52 [](const SCALAR1& a, const SCALAR2& b, const SCALAR3& c)
53 {
54 return (c != 0) ? b : a;
55 }
56 );
57 }
58
is_in3_boolselect_func_select59 bool is_in3_bool()
60 {
61 return true;
62 }
63
in3_special_casesselect_func_select64 std::vector<input3_type> in3_special_cases()
65 {
66 return {
67 detail::make_value<input3_type>(0),
68 detail::make_value<input3_type>(1),
69 detail::make_value<input3_type>(12),
70 detail::make_value<input3_type>(-12)
71 };
72 }
73 };
74
75 template <class IN1, cl_int N /* Vector size */>
76 struct select_func_bitselect : public ternary_func<
77 typename make_vector_type<IN1, N>::type, /* create IN1N type */
78 typename make_vector_type<IN1, N>::type, /* create IN1N type */
79 typename make_vector_type<IN1, N>::type, /* create cl_intN type */
80 typename make_vector_type<IN1, N>::type /* create IN1N type */
81 >
82 {
83 typedef typename make_vector_type<IN1, N>::type input1_type;
84 typedef typename make_vector_type<IN1, N>::type input2_type;
85 typedef typename make_vector_type<IN1, N>::type input3_type;
86 typedef typename make_vector_type<IN1, N>::type result_type;
87
strselect_func_bitselect88 std::string str()
89 {
90 return "bitselect";
91 }
92
headersselect_func_bitselect93 std::string headers()
94 {
95 return "#include <opencl_relational>\n";
96 }
97
operator ()select_func_bitselect98 result_type operator()(const input1_type& x, const input2_type& y, const input3_type& z)
99 {
100 static_assert(
101 std::is_integral<IN1>::value,
102 "bitselect test is implemented only for integers."
103 );
104 static_assert(
105 std::is_unsigned<IN1>::value,
106 "IN1 type should be unsigned, bitwise operations on signed int may cause problems."
107 );
108 typedef typename scalar_type<input1_type>::type SCALAR1;
109 typedef typename scalar_type<input2_type>::type SCALAR2;
110 typedef typename scalar_type<input3_type>::type SCALAR3;
111
112 return perform_function<input1_type, input2_type, input3_type, result_type>(
113 x, y, z,
114 [](const SCALAR1& a, const SCALAR2& b, const SCALAR3& c)
115 {
116 return (~c & a) | (c & b);
117 }
118 );
119 }
120 };
121
AUTO_TEST_CASE(test_relational_select_funcs)122 AUTO_TEST_CASE(test_relational_select_funcs)
123 (cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
124 {
125 int error = CL_SUCCESS;
126 int last_error = CL_SUCCESS;
127
128 // Tests for select(gentype a, gentype b, booln c) are not run in USE_OPENCLC_KERNELS
129 // mode, because this functions in OpenCL C requires different reference functions on host
130 // compared to their equivalent in OpenCL C++.
131 // (In OpenCL C the result of select(), when gentype is vector type, is based on the most
132 // significant bits of c components)
133 #ifndef USE_OPENCLC_KERNELS
134 // gentype select(gentype a, gentype b, booln c)
135 TEST_TERNARY_FUNC_MACRO((select_func_select<cl_uint, 1>()))
136 TEST_TERNARY_FUNC_MACRO((select_func_select<cl_float, 2>()))
137 TEST_TERNARY_FUNC_MACRO((select_func_select<cl_short, 4>()))
138 TEST_TERNARY_FUNC_MACRO((select_func_select<cl_uint, 8>()))
139 TEST_TERNARY_FUNC_MACRO((select_func_select<cl_uint, 16>()))
140 #else
141 log_info("WARNING:\n\tTests for select(gentype a, gentype b, booln c) are not run in USE_OPENCLC_KERNELS mode\n");
142 #endif
143
144 // gentype bitselect(gentype a, gentype b, gentype c)
145 TEST_TERNARY_FUNC_MACRO((select_func_bitselect<cl_uint, 1>()))
146 TEST_TERNARY_FUNC_MACRO((select_func_bitselect<cl_ushort, 2>()))
147 TEST_TERNARY_FUNC_MACRO((select_func_bitselect<cl_uchar, 4>()))
148 TEST_TERNARY_FUNC_MACRO((select_func_bitselect<cl_ushort, 8>()))
149 TEST_TERNARY_FUNC_MACRO((select_func_bitselect<cl_uint, 16>()))
150
151 if(error != CL_SUCCESS)
152 {
153 return -1;
154 }
155 return error;
156 }
157
158 #endif // TEST_CONFORMANCE_CLCPP_RELATIONAL_FUNCS_SELECT_FUNCS_HPP
159