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