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_INTEGER_FUNCS_BITWISE_HPP
17 #define TEST_CONFORMANCE_CLCPP_INTEGER_FUNCS_BITWISE_HPP
18
19 #include "common.hpp"
20 #include <type_traits>
21
22 template<class IN1, class OUT1>
23 struct int_func_popcount : public unary_func<IN1, OUT1>
24 {
strint_func_popcount25 std::string str()
26 {
27 return "popcount";
28 }
29
headersint_func_popcount30 std::string headers()
31 {
32 return "#include <opencl_integer>\n";
33 }
34
operator ()int_func_popcount35 OUT1 operator()(IN1 x)
36 {
37 OUT1 count = 0;
38 for (count = 0; x != 0; count++)
39 {
40 x &= x - 1;
41 }
42 return count;
43 }
44 };
45
46 template<class IN1, class OUT1>
47 struct int_func_clz : public unary_func<IN1, OUT1>
48 {
strint_func_clz49 std::string str()
50 {
51 return "clz";
52 }
53
headersint_func_clz54 std::string headers()
55 {
56 return "#include <opencl_integer>\n";
57 }
58
operator ()int_func_clz59 OUT1 operator()(IN1 x)
60 {
61 OUT1 count = 0;
62 if(std::is_unsigned<IN1>::value)
63 {
64 cl_ulong value = x;
65 value <<= 8 * sizeof(value) - (8 * sizeof(x));
66 for(count = 0; 0 == (value & (CL_LONG_MIN)); count++)
67 {
68 value <<= 1;
69 }
70 }
71 else
72 {
73 cl_long value = x;
74 value <<= 8 * sizeof(value) - (8 * sizeof(x));
75 for(count = 0; 0 == (value & (CL_LONG_MIN)); count++)
76 {
77 value <<= 1;
78 }
79 }
80 return count;
81 }
82 };
83
84 template<class IN1, class OUT1>
85 struct int_func_ctz : public unary_func<IN1, OUT1>
86 {
strint_func_ctz87 std::string str()
88 {
89 return "ctz";
90 }
91
headersint_func_ctz92 std::string headers()
93 {
94 return "#include <opencl_integer>\n";
95 }
96
operator ()int_func_ctz97 OUT1 operator()(IN1 x)
98 {
99 if(x == 0)
100 return sizeof(x);
101
102 OUT1 count = 0;
103 IN1 value = x;
104 for(count = 0; 0 == (value & 0x1); count++)
105 {
106 value >>= 1;
107 }
108 return count;
109 }
110 };
111
112 template<class IN1, class IN2, class OUT1>
113 struct int_func_rotate : public binary_func<IN1, IN2, OUT1>
114 {
strint_func_rotate115 std::string str()
116 {
117 return "rotate";
118 }
119
headersint_func_rotate120 std::string headers()
121 {
122 return "#include <opencl_integer>\n";
123 }
124
operator ()int_func_rotate125 OUT1 operator()(IN1 value, IN2 shift)
126 {
127 static_assert(
128 std::is_unsigned<IN1>::value,
129 "Only unsigned integers are supported"
130 );
131 if ((shift &= sizeof(value)*8 - 1) == 0)
132 return value;
133 return (value << shift) | (value >> (sizeof(value)*8 - shift));
134 }
135
min2int_func_rotate136 IN2 min2()
137 {
138 return 0;
139 }
140
max2int_func_rotate141 IN2 max2()
142 {
143 return sizeof(IN1) * 8;
144 }
145 };
146
147 template<class IN1, class IN2, class OUT1>
148 struct int_func_upsample : public binary_func<IN1, IN2, OUT1>
149 {
strint_func_upsample150 std::string str()
151 {
152 return "upsample";
153 }
154
headersint_func_upsample155 std::string headers()
156 {
157 return "#include <opencl_integer>\n";
158 }
159
operator ()int_func_upsample160 OUT1 operator()(IN1 hi, IN2 lo)
161 {
162 static_assert(
163 sizeof(IN1) == sizeof(IN2),
164 "sizeof(IN1) != sizeof(IN2)"
165 );
166 static_assert(
167 sizeof(OUT1) == 2 * sizeof(IN1),
168 "sizeof(OUT1) != 2 * sizeof(IN1)"
169 );
170 static_assert(
171 std::is_unsigned<IN2>::value,
172 "IN2 type must be unsigned"
173 );
174 return (static_cast<OUT1>(hi) << (8*sizeof(IN1))) | lo;
175 }
176
min2int_func_upsample177 IN2 min2()
178 {
179 return 0;
180 }
181
max2int_func_upsample182 IN2 max2()
183 {
184 return sizeof(IN1) * 8;
185 }
186 };
187
AUTO_TEST_CASE(test_int_bitwise_funcs)188 AUTO_TEST_CASE(test_int_bitwise_funcs)
189 (cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
190 {
191 int error = CL_SUCCESS;
192 int last_error = CL_SUCCESS;
193
194 TEST_UNARY_FUNC_MACRO((int_func_popcount<cl_int, cl_int>()))
195 TEST_UNARY_FUNC_MACRO((int_func_popcount<cl_uint, cl_uint>()))
196 TEST_UNARY_FUNC_MACRO((int_func_popcount<cl_long, cl_long>()))
197 TEST_UNARY_FUNC_MACRO((int_func_popcount<cl_ulong, cl_ulong>()))
198
199 TEST_UNARY_FUNC_MACRO((int_func_clz<cl_int, cl_int>()))
200 TEST_UNARY_FUNC_MACRO((int_func_clz<cl_uint, cl_uint>()))
201 TEST_UNARY_FUNC_MACRO((int_func_clz<cl_long, cl_long>()))
202 TEST_UNARY_FUNC_MACRO((int_func_clz<cl_ulong, cl_ulong>()))
203
204 TEST_UNARY_FUNC_MACRO((int_func_ctz<cl_int, cl_int>()))
205 TEST_UNARY_FUNC_MACRO((int_func_ctz<cl_uint, cl_uint>()))
206 TEST_UNARY_FUNC_MACRO((int_func_ctz<cl_long, cl_long>()))
207 TEST_UNARY_FUNC_MACRO((int_func_ctz<cl_ulong, cl_ulong>()))
208
209 TEST_BINARY_FUNC_MACRO((int_func_rotate<cl_uint, cl_uint, cl_uint>()))
210 TEST_BINARY_FUNC_MACRO((int_func_rotate<cl_ulong, cl_ulong, cl_ulong>()))
211
212 // shortn upsample(charn hi, ucharn lo);
213 TEST_BINARY_FUNC_MACRO((int_func_upsample<cl_char, cl_uchar, cl_short>()))
214 // ushortn upsample(ucharn hi, ucharn lo);
215 TEST_BINARY_FUNC_MACRO((int_func_upsample<cl_uchar, cl_uchar, cl_ushort>()))
216 // intn upsample(shortn hi, ushortn lo);
217 TEST_BINARY_FUNC_MACRO((int_func_upsample<cl_short, cl_ushort, cl_int>()))
218 // uintn upsample(ushortn hi, ushortn lo);
219 TEST_BINARY_FUNC_MACRO((int_func_upsample<cl_ushort, cl_ushort, cl_uint>()))
220 // longn upsample(intn hi, uintn lo);
221 TEST_BINARY_FUNC_MACRO((int_func_upsample<cl_int, cl_uint, cl_long>()))
222 // ulongn upsample(uintn hi, uintn lo);
223 TEST_BINARY_FUNC_MACRO((int_func_upsample<cl_uint, cl_uint, cl_ulong>()))
224
225 if(error != CL_SUCCESS)
226 {
227 return -1;
228 }
229 return error;
230 }
231
232 #endif // TEST_CONFORMANCE_CLCPP_INTEGER_FUNCS_BITWISE_HPP
233