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_NUMERIC_HPP
17 #define TEST_CONFORMANCE_CLCPP_INTEGER_FUNCS_NUMERIC_HPP
18
19 #include "common.hpp"
20 #include <type_traits>
21
22 template<class IN1, class OUT1>
23 struct int_func_abs : public unary_func<IN1, OUT1>
24 {
strint_func_abs25 std::string str()
26 {
27 return "abs";
28 }
29
headersint_func_abs30 std::string headers()
31 {
32 return "#include <opencl_integer>\n";
33 }
34
operator ()int_func_abs35 OUT1 operator()(const IN1& x)
36 {
37 static_assert(
38 std::is_unsigned<OUT1>::value,
39 "OUT1 type must be unsigned"
40 );
41 if(x < IN1(0))
42 return static_cast<OUT1>(-x);
43 return static_cast<OUT1>(x);
44 }
45 };
46
47 template<class IN1, class IN2, class OUT1>
48 struct int_func_abs_diff : public binary_func<IN1, IN2, OUT1>
49 {
strint_func_abs_diff50 std::string str()
51 {
52 return "abs_diff";
53 }
54
headersint_func_abs_diff55 std::string headers()
56 {
57 return "#include <opencl_integer>\n";
58 }
59
operator ()int_func_abs_diff60 OUT1 operator()(const IN1& x, const IN2& y)
61 {
62 static_assert(
63 std::is_same<IN1, IN2>::value,
64 "IN1 must be IN2"
65 );
66 static_assert(
67 std::is_unsigned<OUT1>::value,
68 "OUT1 type must be unsigned"
69 );
70 if(x < y)
71 return static_cast<OUT1>(y-x);
72 return static_cast<OUT1>(x-y);
73 }
74 };
75
76 template<class IN1, class IN2, class OUT1>
77 struct int_func_add_sat : public binary_func<IN1, IN2, OUT1>
78 {
strint_func_add_sat79 std::string str()
80 {
81 return "add_sat";
82 }
83
headersint_func_add_sat84 std::string headers()
85 {
86 return "#include <opencl_integer>\n";
87 }
88
operator ()int_func_add_sat89 OUT1 operator()(const IN1& x, const IN2& y)
90 {
91 static_assert(
92 std::is_same<IN1, IN2>::value,
93 "IN1 must be IN2"
94 );
95 static_assert(
96 std::is_same<OUT1, IN2>::value,
97 "OUT1 must be IN2"
98 );
99 // sat unsigned integers
100 if(std::is_unsigned<OUT1>::value)
101 {
102 OUT1 z = x + y;
103 if(z < x || z < y)
104 return (std::numeric_limits<OUT1>::max)();
105 return z;
106 }
107 // sat signed integers
108 OUT1 z = x + y;
109 if(y > 0)
110 {
111 if(z < x)
112 return (std::numeric_limits<OUT1>::max)();
113 }
114 else
115 {
116 if(z > x)
117 return (std::numeric_limits<OUT1>::min)();
118 }
119 return z;
120 }
121 };
122
123 template<class IN1, class IN2, class OUT1>
124 struct int_func_hadd : public binary_func<IN1, IN2, OUT1>
125 {
strint_func_hadd126 std::string str()
127 {
128 return "hadd";
129 }
130
headersint_func_hadd131 std::string headers()
132 {
133 return "#include <opencl_integer>\n";
134 }
135
operator ()int_func_hadd136 OUT1 operator()(const IN1& x, const IN2& y)
137 {
138 static_assert(
139 std::is_same<IN1, IN2>::value,
140 "IN1 must be IN2"
141 );
142 static_assert(
143 std::is_same<OUT1, IN2>::value,
144 "OUT1 must be IN2"
145 );
146 return (x >> OUT1(1)) + (y >> OUT1(1)) + (x & y & OUT1(1));
147 }
148 };
149
150 template<class IN1, class IN2, class OUT1>
151 struct int_func_rhadd : public binary_func<IN1, IN2, OUT1>
152 {
strint_func_rhadd153 std::string str()
154 {
155 return "rhadd";
156 }
157
headersint_func_rhadd158 std::string headers()
159 {
160 return "#include <opencl_integer>\n";
161 }
162
operator ()int_func_rhadd163 OUT1 operator()(const IN1& x, const IN2& y)
164 {
165 static_assert(
166 std::is_same<IN1, IN2>::value,
167 "IN1 must be IN2"
168 );
169 static_assert(
170 std::is_same<OUT1, IN2>::value,
171 "OUT1 must be IN2"
172 );
173 return (x >> OUT1(1)) + (y >> OUT1(1)) + ((x | y) & OUT1(1));
174 }
175 };
176
177 // clamp for scalars
178 template<class IN1, class IN2, class IN3, class OUT1, class Enable = void>
179 struct int_func_clamp : public ternary_func<IN1, IN2, IN3, OUT1>
180 {
strint_func_clamp181 std::string str()
182 {
183 return "clamp";
184 }
185
headersint_func_clamp186 std::string headers()
187 {
188 return "#include <opencl_integer>\n";
189 }
190
operator ()int_func_clamp191 OUT1 operator()(const IN1& x, const IN2& minval, const IN3& maxval)
192 {
193 static_assert(
194 std::is_same<IN2, IN3>::value,
195 "IN3 must be IN2"
196 );
197 static_assert(
198 std::is_same<OUT1, IN1>::value,
199 "OUT1 must be IN1"
200 );
201 return (std::min)((std::max)(x, minval), maxval);
202 }
203
min2int_func_clamp204 IN2 min2()
205 {
206 return (std::numeric_limits<IN2>::min)();
207 }
208
max2int_func_clamp209 IN2 max2()
210 {
211 return (std::numeric_limits<IN2>::max)() / IN2(2);
212 }
213
min3int_func_clamp214 IN3 min3()
215 {
216 return IN3(1) + ((std::numeric_limits<IN3>::max)() / IN3(2));
217 }
218
max3int_func_clamp219 IN3 max3()
220 {
221 return (std::numeric_limits<IN3>::max)();
222 }
223 };
224
225 // gentype clamp(gentype x, scalar minval, scalar maxval);
226 template<class IN1, class IN2, class IN3, class OUT1>
227 struct int_func_clamp<IN1, IN2, IN3, OUT1, typename std::enable_if<is_vector_type<OUT1>::value>::type> : public ternary_func<IN1, IN2, IN3, OUT1>
228 {
strint_func_clamp229 std::string str()
230 {
231 return "clamp";
232 }
233
headersint_func_clamp234 std::string headers()
235 {
236 return "#include <opencl_integer>\n";
237 }
238
operator ()int_func_clamp239 OUT1 operator()(const IN1& x, const IN2& minval, const IN3& maxval)
240 {
241 static_assert(
242 std::is_same<IN2, IN3>::value,
243 "IN3 must be IN2"
244 );
245 static_assert(
246 !is_vector_type<IN2>::value && !is_vector_type<IN3>::value,
247 "IN3 and IN2 must be scalar"
248 );
249 static_assert(
250 std::is_same<OUT1, IN1>::value,
251 "OUT1 must be IN1"
252 );
253 OUT1 result;
254 for(size_t i = 0; i < vector_size<OUT1>::value; i++)
255 {
256 result.s[i] = (std::min)((std::max)(x.s[i], minval), maxval);
257 }
258 return result;
259 }
260
min1int_func_clamp261 IN1 min1()
262 {
263 typedef typename scalar_type<IN1>::type SCALAR1;
264 IN1 min1;
265 for(size_t i = 0; i < vector_size<IN1>::value; i++)
266 {
267 min1.s[i] = (std::numeric_limits<SCALAR1>::min)();
268 }
269 return min1;
270 }
271
max1int_func_clamp272 IN1 max1()
273 {
274 typedef typename scalar_type<IN1>::type SCALAR1;
275 IN1 max1;
276 for(size_t i = 0; i < vector_size<IN1>::value; i++)
277 {
278 max1.s[i] = (std::numeric_limits<SCALAR1>::max)();
279 }
280 return max1;
281 }
282
min2int_func_clamp283 IN2 min2()
284 {
285 return (std::numeric_limits<IN2>::min)();
286 }
287
max2int_func_clamp288 IN2 max2()
289 {
290 return (std::numeric_limits<IN2>::max)() / IN2(2);
291 }
292
min3int_func_clamp293 IN3 min3()
294 {
295 return IN3(1) + ((std::numeric_limits<IN3>::max)() / IN3(2));
296 }
297
max3int_func_clamp298 IN3 max3()
299 {
300 return (std::numeric_limits<IN3>::max)();
301 }
302 };
303
304 template<class IN1, class IN2, class OUT1>
305 struct int_func_mul_hi : public binary_func<IN1, IN2, OUT1>
306 {
strint_func_mul_hi307 std::string str()
308 {
309 return "mul_hi";
310 }
311
headersint_func_mul_hi312 std::string headers()
313 {
314 return "#include <opencl_integer>\n";
315 }
316
operator ()int_func_mul_hi317 OUT1 operator()(const IN1& x, const IN2& y)
318 {
319 static_assert(
320 std::is_same<IN1, IN2>::value
321 && std::is_same<IN2, OUT1>::value,
322 "Types must be the same"
323 );
324 static_assert(
325 !std::is_same<IN1, cl_long>::value && !std::is_same<IN1, cl_ulong>::value,
326 "Operation unimplemented for 64-bit scalars"
327 );
328 cl_long xl = static_cast<cl_long>(x);
329 cl_long yl = static_cast<cl_long>(y);
330 return static_cast<OUT1>((xl * yl) >> (8 * sizeof(OUT1)));
331 }
332 };
333
334 template<class IN1, class IN2, class IN3, class OUT1>
335 struct int_func_mad_hi : public ternary_func<IN1, IN2, IN3, OUT1>
336 {
strint_func_mad_hi337 std::string str()
338 {
339 return "mad_hi";
340 }
341
headersint_func_mad_hi342 std::string headers()
343 {
344 return "#include <opencl_integer>\n";
345 }
346
operator ()int_func_mad_hi347 OUT1 operator()(const IN1& x, const IN2& y, const IN3& z)
348 {
349 static_assert(
350 std::is_same<IN1, IN2>::value
351 && std::is_same<IN2, IN3>::value
352 && std::is_same<IN3, OUT1>::value,
353 "Types must be the same"
354 );
355 return int_func_mul_hi<IN1, IN2, OUT1>()(x, y) + z;
356 }
357 };
358
359 // This test is implemented only for unsigned integers
360 template<class IN1, class IN2, class IN3, class OUT1>
361 struct int_func_mad_sat : public ternary_func<IN1, IN2, IN3, OUT1>
362 {
strint_func_mad_sat363 std::string str()
364 {
365 return "mad_sat";
366 }
367
headersint_func_mad_sat368 std::string headers()
369 {
370 return "#include <opencl_integer>\n";
371 }
372
operator ()int_func_mad_sat373 OUT1 operator()(const IN1& x, const IN2& y, const IN3& z)
374 {
375 static_assert(
376 std::is_same<IN1, IN2>::value
377 && std::is_same<IN2, IN3>::value
378 && std::is_same<IN3, OUT1>::value,
379 "Types must be the same"
380 );
381 static_assert(
382 std::is_unsigned<OUT1>::value,
383 "Test operation is not implemented for signed integers"
384 );
385 // mad_sat unsigned integers
386 OUT1 w1 = (x * y);
387 if (x != 0 && w1 / x != y)
388 return (std::numeric_limits<OUT1>::max)();
389 OUT1 w2 = w1 + z;
390 if(w2 < w1)
391 return (std::numeric_limits<OUT1>::max)();
392 return w2;
393 }
394 };
395
396 template<class IN1, class IN2, class OUT1>
397 struct int_func_sub_sat : public binary_func<IN1, IN2, OUT1>
398 {
strint_func_sub_sat399 std::string str()
400 {
401 return "sub_sat";
402 }
403
headersint_func_sub_sat404 std::string headers()
405 {
406 return "#include <opencl_integer>\n";
407 }
408
operator ()int_func_sub_sat409 OUT1 operator()(const IN1& x, const IN2& y)
410 {
411 static_assert(
412 std::is_same<IN1, IN2>::value && std::is_same<IN2, OUT1>::value,
413 "IN1, IN2 and OUT1 must be the same types"
414 );
415 // sat unsigned integers
416 if(std::is_unsigned<OUT1>::value)
417 {
418 OUT1 z = x - y;
419 if(x < y)
420 return (std::numeric_limits<OUT1>::min)();
421 return z;
422 }
423 // sat signed integers
424 OUT1 z = x - y;
425 if(y < 0)
426 {
427 if(z < x)
428 return (std::numeric_limits<OUT1>::max)();
429 }
430 else
431 {
432 if(z > x)
433 return (std::numeric_limits<OUT1>::min)();
434 }
435 return z;
436 }
437 };
438
439 template<class IN1, class IN2, class OUT1, class Enable = void>
440 struct int_func_max : public binary_func<IN1, IN2, OUT1>
441 {
strint_func_max442 std::string str()
443 {
444 return "max";
445 }
446
headersint_func_max447 std::string headers()
448 {
449 return "#include <opencl_integer>\n";
450 }
451
operator ()int_func_max452 OUT1 operator()(const IN1& x, const IN2& y)
453 {
454 static_assert(
455 std::is_same<IN1, IN2>::value && std::is_same<IN2, OUT1>::value,
456 "IN1, IN2 and OUT1 must be the same types"
457 );
458 return (std::max)(x, y);
459 }
460 };
461
462 template<class IN1, class IN2, class OUT1>
463 struct int_func_max<IN1, IN2, OUT1, typename std::enable_if<is_vector_type<OUT1>::value>::type> : public binary_func<IN1, IN2, OUT1>
464 {
strint_func_max465 std::string str()
466 {
467 return "max";
468 }
469
headersint_func_max470 std::string headers()
471 {
472 return "#include <opencl_integer>\n";
473 }
474
min1int_func_max475 IN1 min1()
476 {
477 typedef typename scalar_type<IN1>::type SCALAR1;
478 IN1 min1;
479 for(size_t i = 0; i < vector_size<IN1>::value; i++)
480 {
481 min1.s[i] = (std::numeric_limits<SCALAR1>::min)();
482 }
483 return min1;
484 }
485
max1int_func_max486 IN1 max1()
487 {
488 typedef typename scalar_type<IN1>::type SCALAR1;
489 IN1 max1;
490 for(size_t i = 0; i < vector_size<IN1>::value; i++)
491 {
492 max1.s[i] = (std::numeric_limits<SCALAR1>::max)();
493 }
494 return max1;
495 }
496
operator ()int_func_max497 OUT1 operator()(const IN1& x, const IN2& y)
498 {
499 static_assert(
500 std::is_same<IN1, OUT1>::value,
501 "IN1 and OUT1 must be the same types"
502 );
503 static_assert(
504 !is_vector_type<IN2>::value,
505 "IN2 must be scalar"
506 );
507 static_assert(
508 std::is_same<typename scalar_type<OUT1>::type, IN2>::value,
509 "IN2 must match with OUT1 and IN1"
510 );
511 IN1 result = x;
512 for(size_t i = 0; i < vector_size<IN1>::value; i++)
513 {
514 result.s[i] = (std::max)(x.s[i], y);
515 }
516 return result;
517 }
518 };
519
520 template<class IN1, class IN2, class OUT1, class Enable = void>
521 struct int_func_min : public binary_func<IN1, IN2, OUT1>
522 {
strint_func_min523 std::string str()
524 {
525 return "min";
526 }
527
headersint_func_min528 std::string headers()
529 {
530 return "#include <opencl_integer>\n";
531 }
532
operator ()int_func_min533 OUT1 operator()(const IN1& x, const IN2& y)
534 {
535 static_assert(
536 std::is_same<IN1, IN2>::value && std::is_same<IN2, OUT1>::value,
537 "IN1, IN2 and OUT1 must be the same types"
538 );
539 return (std::min)(x, y);
540 }
541 };
542
543 template<class IN1, class IN2, class OUT1>
544 struct int_func_min<IN1, IN2, OUT1, typename std::enable_if<is_vector_type<OUT1>::value>::type> : public binary_func<IN1, IN2, OUT1>
545 {
strint_func_min546 std::string str()
547 {
548 return "min";
549 }
550
headersint_func_min551 std::string headers()
552 {
553 return "#include <opencl_integer>\n";
554 }
555
min1int_func_min556 IN1 min1()
557 {
558 typedef typename scalar_type<IN1>::type SCALAR1;
559 IN1 min1;
560 for(size_t i = 0; i < vector_size<IN1>::value; i++)
561 {
562 min1.s[i] = (std::numeric_limits<SCALAR1>::min)();
563 }
564 return min1;
565 }
566
max1int_func_min567 IN1 max1()
568 {
569 typedef typename scalar_type<IN1>::type SCALAR1;
570 IN1 max1;
571 for(size_t i = 0; i < vector_size<IN1>::value; i++)
572 {
573 max1.s[i] = (std::numeric_limits<SCALAR1>::max)();
574 }
575 return max1;
576 }
577
operator ()int_func_min578 OUT1 operator()(const IN1& x, const IN2& y)
579 {
580 static_assert(
581 std::is_same<IN1, OUT1>::value,
582 "IN1 and OUT1 must be the same types"
583 );
584 static_assert(
585 !is_vector_type<IN2>::value,
586 "IN2 must be scalar"
587 );
588 static_assert(
589 std::is_same<typename scalar_type<OUT1>::type, IN2>::value,
590 "IN2 must match with OUT1 and IN1"
591 );
592 IN1 result = x;
593 for(size_t i = 0; i < vector_size<IN1>::value; i++)
594 {
595 result.s[i] = (std::min)(x.s[i], y);
596 }
597 return result;
598 }
599 };
600
AUTO_TEST_CASE(test_int_numeric_funcs)601 AUTO_TEST_CASE(test_int_numeric_funcs)
602 (cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
603 {
604 int error = CL_SUCCESS;
605 int last_error = CL_SUCCESS;
606
607 // ugentype abs(gentype x);
608 TEST_UNARY_FUNC_MACRO((int_func_abs<cl_int, cl_uint>()))
609 TEST_UNARY_FUNC_MACRO((int_func_abs<cl_uint, cl_uint>()))
610 TEST_UNARY_FUNC_MACRO((int_func_abs<cl_long, cl_ulong>()))
611 TEST_UNARY_FUNC_MACRO((int_func_abs<cl_ulong, cl_ulong>()))
612
613 // ugentype abs_diff(gentype x, gentype y);
614 TEST_BINARY_FUNC_MACRO((int_func_abs_diff<cl_int, cl_int, cl_uint>()))
615 TEST_BINARY_FUNC_MACRO((int_func_abs_diff<cl_uint, cl_uint, cl_uint>()))
616 TEST_BINARY_FUNC_MACRO((int_func_abs_diff<cl_long, cl_long, cl_ulong>()))
617 TEST_BINARY_FUNC_MACRO((int_func_abs_diff<cl_ulong, cl_ulong, cl_ulong>()))
618
619 // gentype add_sat(gentype x, gentype y);
620 TEST_BINARY_FUNC_MACRO((int_func_add_sat<cl_int, cl_int, cl_int>()))
621 TEST_BINARY_FUNC_MACRO((int_func_add_sat<cl_uint, cl_uint, cl_uint>()))
622 TEST_BINARY_FUNC_MACRO((int_func_add_sat<cl_long, cl_long, cl_long>()))
623 TEST_BINARY_FUNC_MACRO((int_func_add_sat<cl_ulong, cl_ulong, cl_ulong>()))
624
625 // gentype hadd(gentype x, gentype y);
626 TEST_BINARY_FUNC_MACRO((int_func_hadd<cl_int, cl_int, cl_int>()))
627 TEST_BINARY_FUNC_MACRO((int_func_hadd<cl_uint, cl_uint, cl_uint>()))
628 TEST_BINARY_FUNC_MACRO((int_func_hadd<cl_long, cl_long, cl_long>()))
629 TEST_BINARY_FUNC_MACRO((int_func_hadd<cl_ulong, cl_ulong, cl_ulong>()))
630
631 // gentype rhadd(gentype x, gentype y);
632 TEST_BINARY_FUNC_MACRO((int_func_rhadd<cl_int, cl_int, cl_int>()))
633 TEST_BINARY_FUNC_MACRO((int_func_rhadd<cl_uint, cl_uint, cl_uint>()))
634 TEST_BINARY_FUNC_MACRO((int_func_rhadd<cl_long, cl_long, cl_long>()))
635 TEST_BINARY_FUNC_MACRO((int_func_rhadd<cl_ulong, cl_ulong, cl_ulong>()))
636
637 // gentype clamp(gentype x, gentype minval, gentype maxval);
638 TEST_TERNARY_FUNC_MACRO((int_func_clamp<cl_int, cl_int, cl_int, cl_int>()))
639 TEST_TERNARY_FUNC_MACRO((int_func_clamp<cl_uint, cl_uint, cl_uint, cl_uint>()))
640 TEST_TERNARY_FUNC_MACRO((int_func_clamp<cl_long, cl_long, cl_long, cl_long>()))
641 TEST_TERNARY_FUNC_MACRO((int_func_clamp<cl_ulong, cl_ulong, cl_ulong, cl_ulong>()))
642
643 // gentype clamp(gentype x, scalar minval, scalar maxval);
644 TEST_TERNARY_FUNC_MACRO((int_func_clamp<cl_int2, cl_int, cl_int, cl_int2>()))
645 TEST_TERNARY_FUNC_MACRO((int_func_clamp<cl_uint4, cl_uint, cl_uint, cl_uint4>()))
646 TEST_TERNARY_FUNC_MACRO((int_func_clamp<cl_long8, cl_long, cl_long, cl_long8>()))
647 TEST_TERNARY_FUNC_MACRO((int_func_clamp<cl_ulong16, cl_ulong, cl_ulong, cl_ulong16>()))
648
649 // gentype mad_hi(gentype a, gentype b, gentype c);
650 TEST_TERNARY_FUNC_MACRO((int_func_mad_hi<cl_short, cl_short, cl_short, cl_short>()))
651 TEST_TERNARY_FUNC_MACRO((int_func_mad_hi<cl_ushort, cl_ushort, cl_ushort, cl_ushort>()))
652 TEST_TERNARY_FUNC_MACRO((int_func_mad_hi<cl_int, cl_int, cl_int, cl_int>()))
653 TEST_TERNARY_FUNC_MACRO((int_func_mad_hi<cl_uint, cl_uint, cl_uint, cl_uint>()))
654
655 // gentype mad_sat(gentype a, gentype b, gentype c);
656 TEST_TERNARY_FUNC_MACRO((int_func_mad_sat<cl_ushort, cl_ushort, cl_ushort, cl_ushort>()))
657 TEST_TERNARY_FUNC_MACRO((int_func_mad_sat<cl_uint, cl_uint, cl_uint, cl_uint>()))
658 TEST_TERNARY_FUNC_MACRO((int_func_mad_sat<cl_ulong, cl_ulong, cl_ulong, cl_ulong>()))
659
660 // gentype max(gentype x, gentype y);
661 TEST_BINARY_FUNC_MACRO((int_func_max<cl_int, cl_int, cl_int>()))
662 TEST_BINARY_FUNC_MACRO((int_func_max<cl_uint, cl_uint, cl_uint>()))
663 TEST_BINARY_FUNC_MACRO((int_func_max<cl_long, cl_long, cl_long>()))
664 TEST_BINARY_FUNC_MACRO((int_func_max<cl_ulong, cl_ulong, cl_ulong>()))
665
666 // gentype max(gentype x, scalar y);
667 TEST_BINARY_FUNC_MACRO((int_func_max<cl_int2, cl_int, cl_int2>()))
668 TEST_BINARY_FUNC_MACRO((int_func_max<cl_uint4, cl_uint, cl_uint4>()))
669 TEST_BINARY_FUNC_MACRO((int_func_max<cl_long8, cl_long, cl_long8>()))
670 TEST_BINARY_FUNC_MACRO((int_func_max<cl_ulong16, cl_ulong, cl_ulong16>()))
671
672 // gentype min(gentype x, gentype y);
673 TEST_BINARY_FUNC_MACRO((int_func_min<cl_int, cl_int, cl_int>()))
674 TEST_BINARY_FUNC_MACRO((int_func_min<cl_uint, cl_uint, cl_uint>()))
675 TEST_BINARY_FUNC_MACRO((int_func_min<cl_long, cl_long, cl_long>()))
676 TEST_BINARY_FUNC_MACRO((int_func_min<cl_ulong, cl_ulong, cl_ulong>()))
677
678 // gentype min(gentype x, scalar y);
679 TEST_BINARY_FUNC_MACRO((int_func_min<cl_int2, cl_int, cl_int2>()))
680 TEST_BINARY_FUNC_MACRO((int_func_min<cl_uint4, cl_uint, cl_uint4>()))
681 TEST_BINARY_FUNC_MACRO((int_func_min<cl_long8, cl_long, cl_long8>()))
682 TEST_BINARY_FUNC_MACRO((int_func_min<cl_ulong16, cl_ulong, cl_ulong16>()))
683
684 // gentype mul_hi(gentype x, gentype y);
685 TEST_BINARY_FUNC_MACRO((int_func_mul_hi<cl_short, cl_short, cl_short>()))
686 TEST_BINARY_FUNC_MACRO((int_func_mul_hi<cl_ushort, cl_ushort, cl_ushort>()))
687 TEST_BINARY_FUNC_MACRO((int_func_mul_hi<cl_int, cl_int, cl_int>()))
688 TEST_BINARY_FUNC_MACRO((int_func_mul_hi<cl_uint, cl_uint, cl_uint>()))
689
690 // gentype sub_sat(gentype x, gentype y);
691 TEST_BINARY_FUNC_MACRO((int_func_sub_sat<cl_int, cl_int, cl_int>()))
692 TEST_BINARY_FUNC_MACRO((int_func_sub_sat<cl_uint, cl_uint, cl_uint>()))
693 TEST_BINARY_FUNC_MACRO((int_func_sub_sat<cl_long, cl_long, cl_long>()))
694 TEST_BINARY_FUNC_MACRO((int_func_sub_sat<cl_ulong, cl_ulong, cl_ulong>()))
695
696 if(error != CL_SUCCESS)
697 {
698 return -1;
699 }
700 return error;
701 }
702
703 #endif // TEST_CONFORMANCE_CLCPP_INTEGER_FUNCS_NUMERIC_HPP
704