• 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_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