• 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_MATH_FUNCS_FP_FUNCS_HPP
17 #define TEST_CONFORMANCE_CLCPP_MATH_FUNCS_FP_FUNCS_HPP
18 
19 #include <type_traits>
20 #include <cmath>
21 
22 #include "common.hpp"
23 
24 // -------------- UNARY FUNCTIONS
25 
26 // gentype ceil(gentype x);
27 // gentype floor(gentype x);
28 // gentype rint(gentype x);
29 // gentype round(gentype x);
30 // gentype trunc(gentype x);
31 // group_name, func_name, reference_func, use_ulp, ulp, ulp_for_embedded, max_delta, min1, max1
32 MATH_FUNCS_DEFINE_UNARY_FUNC(fp, ceil, std::ceil, true, 0.0f, 0.0f, 0.001f, -1000.0f, 1000.0f)
33 MATH_FUNCS_DEFINE_UNARY_FUNC(fp, floor, std::floor, true, 0.0f, 0.0f, 0.001f, -1000.0f, 1000.0f)
34 MATH_FUNCS_DEFINE_UNARY_FUNC(fp, rint, std::rint, true, 0.0f, 0.0f, 0.001f, -1000.0f, 1000.0f)
35 MATH_FUNCS_DEFINE_UNARY_FUNC(fp, round, std::round, true, 0.0f, 0.0f, 0.001f, -1000.0f, 1000.0f)
36 MATH_FUNCS_DEFINE_UNARY_FUNC(fp, trunc, std::trunc, true, 0.0f, 0.0f, 0.001f, -1000.0f, 1000.0f)
37 
38 // floatn nan(uintn nancode);
39 struct fp_func_nan : public unary_func<cl_uint, cl_float>
40 {
strfp_func_nan41     std::string str()
42     {
43         return "nan";
44     }
45 
headersfp_func_nan46     std::string headers()
47     {
48         return "#include <opencl_math>\n";
49     }
50 
operator ()fp_func_nan51     cl_float operator()(const cl_uint& x)
52     {
53         cl_uint r = x | 0x7fc00000U;
54         // cl_float and cl_int have the same size so that's correct
55         cl_float rf = *reinterpret_cast<cl_float*>(&r);
56         return rf;
57     }
58 
min1fp_func_nan59     cl_uint min1()
60     {
61         return 0;
62     }
63 
max1fp_func_nan64     cl_uint max1()
65     {
66         return 100;
67     }
68 
in1_special_casesfp_func_nan69     std::vector<cl_uint> in1_special_cases()
70     {
71         return {
72             0, 1
73         };
74     }
75 };
76 
77 // -------------- UNARY FUNCTIONS, 2ND ARG IS POINTER
78 
79 // gentype fract(gentype x, gentype* iptr);
80 //
81 // Fuction fract() returns additional value via pointer (2nd argument). In order to test
82 // if it's correct output buffer type is cl_float2. In first compontent we store what
83 // fract() function returns, and in the 2nd component we store what is returned via its
84 // 2nd argument (gentype* iptr).
85 struct fp_func_fract : public unary_func<cl_float, cl_float2>
86 {
fp_func_fractfp_func_fract87     fp_func_fract(bool is_embedded) : m_is_embedded(is_embedded)
88     {
89 
90     }
91 
strfp_func_fract92     std::string str()
93     {
94         return "fract";
95     }
96 
headersfp_func_fract97     std::string headers()
98     {
99         return "#include <opencl_math>\n";
100     }
101 
operator ()fp_func_fract102     cl_double2 operator()(const cl_float& x)
103     {
104         return reference::fract(static_cast<cl_double>(x));
105     }
106 
min1fp_func_fract107     cl_float min1()
108     {
109         return -1000.0f;
110     }
111 
max1fp_func_fract112     cl_float max1()
113     {
114         return 1000.0f;
115     }
116 
in1_special_casesfp_func_fract117     std::vector<cl_float> in1_special_cases()
118     {
119         return {
120             cl_float(0.0f),
121             cl_float(-0.0f),
122             cl_float(1.0f),
123             cl_float(-1.0f),
124             cl_float(2.0f),
125             cl_float(-2.0f),
126             std::numeric_limits<cl_float>::infinity(),
127             -std::numeric_limits<cl_float>::infinity(),
128             std::numeric_limits<cl_float>::quiet_NaN()
129         };
130     }
131 
use_ulpfp_func_fract132     bool use_ulp()
133     {
134         return true;
135     }
136 
ulpfp_func_fract137     float ulp()
138     {
139         if(m_is_embedded)
140         {
141             return 0.0f;
142         }
143         return 0.0f;
144     }
145 private:
146     bool m_is_embedded;
147 };
148 
149 // We need to specialize generate_kernel_unary<>() function template for fp_func_fract.
150 // -----------------------------------------------------------------------------------
151 // ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
152 // -----------------------------------------------------------------------------------
153 #if defined(DEVELOPMENT) && defined(USE_OPENCLC_KERNELS)
154 template <>
generate_kernel_unary(fp_func_fract func)155 std::string generate_kernel_unary<fp_func_fract, cl_float, cl_float2>(fp_func_fract func)
156 {
157     return
158         "__kernel void test_fract(global float *input, global float2 *output)\n"
159         "{\n"
160         "    size_t gid = get_global_id(0);\n"
161         "    float2 result;\n"
162         "    float itpr = 0;\n"
163         "    result.x = fract(input[gid], &itpr);\n"
164         "    result.y = itpr;\n"
165         "    output[gid] = result;\n"
166         "}\n";
167 }
168 #else
169 template <>
generate_kernel_unary(fp_func_fract func)170 std::string generate_kernel_unary<fp_func_fract, cl_float, cl_float2>(fp_func_fract func)
171 {
172     return
173         "" + func.defs() +
174         "" + func.headers() +
175         "#include <opencl_memory>\n"
176         "#include <opencl_work_item>\n"
177         "using namespace cl;\n"
178         "__kernel void test_fract(global_ptr<float[]> input, global_ptr<float2[]> output)\n"
179         "{\n"
180         "    size_t gid = get_global_id(0);\n"
181         "    float2 result;\n"
182         "    float itpr = 0;\n"
183         "    result.x = fract(input[gid], &itpr);\n"
184         "    result.y = itpr;\n"
185         "    output[gid] = result;\n"
186         "}\n";
187 }
188 #endif
189 
190 // gentype modf(gentype x, gentype* iptr);
191 //
192 // Fuction modf() returns additional value via pointer (2nd argument). In order to test
193 // if it's correct output buffer type is cl_float2. In first compontent we store what
194 // modf() function returns, and in the 2nd component we store what is returned via its
195 // 2nd argument (gentype* iptr).
196 struct fp_func_modf : public unary_func<cl_float, cl_float2>
197 {
fp_func_modffp_func_modf198     fp_func_modf(bool is_embedded) : m_is_embedded(is_embedded)
199     {
200 
201     }
202 
strfp_func_modf203     std::string str()
204     {
205         return "modf";
206     }
207 
headersfp_func_modf208     std::string headers()
209     {
210         return "#include <opencl_math>\n";
211     }
212 
operator ()fp_func_modf213     cl_double2 operator()(const cl_float& x)
214     {
215         cl_double2 r;
216         r.s[0] = (std::modf)(static_cast<cl_double>(x), &(r.s[1]));
217         return r;
218     }
219 
min1fp_func_modf220     cl_float min1()
221     {
222         return -1000.0f;
223     }
224 
max1fp_func_modf225     cl_float max1()
226     {
227         return 1000.0f;
228     }
229 
in1_special_casesfp_func_modf230     std::vector<cl_float> in1_special_cases()
231     {
232         return {
233             cl_float(0.0f),
234             cl_float(-0.0f),
235             cl_float(1.0f),
236             cl_float(-1.0f),
237             cl_float(2.0f),
238             cl_float(-2.0f),
239             std::numeric_limits<cl_float>::infinity(),
240             -std::numeric_limits<cl_float>::infinity(),
241             std::numeric_limits<cl_float>::quiet_NaN()
242         };
243     }
244 
use_ulpfp_func_modf245     bool use_ulp()
246     {
247         return true;
248     }
249 
ulpfp_func_modf250     float ulp()
251     {
252         if(m_is_embedded)
253         {
254             return 0.0f;
255         }
256         return 0.0f;
257     }
258 private:
259     bool m_is_embedded;
260 };
261 
262 // We need to specialize generate_kernel_unary<>() function template for fp_func_modf.
263 // -----------------------------------------------------------------------------------
264 // ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
265 // -----------------------------------------------------------------------------------
266 #if defined(DEVELOPMENT) && defined(USE_OPENCLC_KERNELS)
267 template <>
generate_kernel_unary(fp_func_modf func)268 std::string generate_kernel_unary<fp_func_modf, cl_float, cl_float2>(fp_func_modf func)
269 {
270     return
271         "__kernel void test_modf(global float *input, global float2 *output)\n"
272         "{\n"
273         "    size_t gid = get_global_id(0);\n"
274         "    float2 result;\n"
275         "    float itpr = 0;\n"
276         "    result.x = modf(input[gid], &itpr);\n"
277         "    result.y = itpr;\n"
278         "    output[gid] = result;\n"
279         "}\n";
280 }
281 #else
282 template <>
generate_kernel_unary(fp_func_modf func)283 std::string generate_kernel_unary<fp_func_modf, cl_float, cl_float2>(fp_func_modf func)
284 {
285     return
286         "" + func.defs() +
287         "" + func.headers() +
288         "#include <opencl_memory>\n"
289         "#include <opencl_work_item>\n"
290         "using namespace cl;\n"
291         "__kernel void test_modf(global_ptr<float[]> input, global_ptr<float2[]> output)\n"
292         "{\n"
293         "    size_t gid = get_global_id(0);\n"
294         "    float2 result;\n"
295         "    float itpr = 0;\n"
296         "    result.x = modf(input[gid], &itpr);\n"
297         "    result.y = itpr;\n"
298         "    output[gid] = result;\n"
299         "}\n";
300 }
301 #endif
302 
303 // gentype frexp(gentype x, intn* exp);
304 //
305 // Fuction frexp() returns additional value via pointer (2nd argument). In order to test
306 // if it's correct output buffer type is cl_float2. In first compontent we store what
307 // modf() function returns, and in the 2nd component we store what is returned via its
308 // 2nd argument (intn* exp).
309 struct fp_func_frexp : public unary_func<cl_float, cl_float2>
310 {
fp_func_frexpfp_func_frexp311     fp_func_frexp(bool is_embedded) : m_is_embedded(is_embedded)
312     {
313 
314     }
315 
strfp_func_frexp316     std::string str()
317     {
318         return "frexp";
319     }
320 
headersfp_func_frexp321     std::string headers()
322     {
323         return "#include <opencl_math>\n";
324     }
325 
operator ()fp_func_frexp326     cl_double2 operator()(const cl_float& x)
327     {
328         cl_double2 r;
329         cl_int e;
330         r.s[0] = (std::frexp)(static_cast<cl_double>(x), &e);
331         r.s[1] = static_cast<cl_float>(e);
332         return r;
333     }
334 
min1fp_func_frexp335     cl_float min1()
336     {
337         return -1000.0f;
338     }
339 
max1fp_func_frexp340     cl_float max1()
341     {
342         return 1000.0f;
343     }
344 
in1_special_casesfp_func_frexp345     std::vector<cl_float> in1_special_cases()
346     {
347         return {
348             cl_float(0.0f),
349             cl_float(-0.0f),
350             cl_float(1.0f),
351             cl_float(-1.0f),
352             cl_float(2.0f),
353             cl_float(-2.0f),
354             std::numeric_limits<cl_float>::infinity(),
355             -std::numeric_limits<cl_float>::infinity(),
356             std::numeric_limits<cl_float>::quiet_NaN()
357         };
358     }
359 
use_ulpfp_func_frexp360     bool use_ulp()
361     {
362         return true;
363     }
364 
ulpfp_func_frexp365     float ulp()
366     {
367         if(m_is_embedded)
368         {
369             return 0.0f;
370         }
371         return 0.0f;
372     }
373 private:
374     bool m_is_embedded;
375 };
376 
377 // We need to specialize generate_kernel_unary<>() function template for fp_func_frexp.
378 // -----------------------------------------------------------------------------------
379 // ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
380 // -----------------------------------------------------------------------------------
381 #if defined(DEVELOPMENT) && defined(USE_OPENCLC_KERNELS)
382 template <>
generate_kernel_unary(fp_func_frexp func)383 std::string generate_kernel_unary<fp_func_frexp, cl_float, cl_float2>(fp_func_frexp func)
384 {
385     return
386         "__kernel void test_frexp(global float *input, global float2 *output)\n"
387         "{\n"
388         "    size_t gid = get_global_id(0);\n"
389         "    float2 result;\n"
390         "    int itpr = 0;\n"
391         "    result.x = frexp(input[gid], &itpr);\n"
392         "    result.y = itpr;\n"
393         "    output[gid] = result;\n"
394         "}\n";
395 }
396 #else
397 template <>
generate_kernel_unary(fp_func_frexp func)398 std::string generate_kernel_unary<fp_func_frexp, cl_float, cl_float2>(fp_func_frexp func)
399 {
400     return
401         "" + func.defs() +
402         "" + func.headers() +
403         "#include <opencl_memory>\n"
404         "#include <opencl_work_item>\n"
405         "using namespace cl;\n"
406         "__kernel void test_frexp(global_ptr<float[]> input, global_ptr<float2[]> output)\n"
407         "{\n"
408         "    size_t gid = get_global_id(0);\n"
409         "    float2 result;\n"
410         "    int itpr = 0;\n"
411         "    result.x = frexp(input[gid], &itpr);\n"
412         "    result.y = itpr;\n"
413         "    output[gid] = result;\n"
414         "}\n";
415 }
416 #endif
417 
418 // -------------- BINARY FUNCTIONS
419 
420 // gentype copysign(gentype x, gentype y);
421 // gentype fmod(gentype x, gentype y);
422 // gentype remainder(gentype x, gentype y);
423 // group_name, func_name, reference_func, use_ulp, ulp, ulp_for_embedded, max_delta, min1, max1, min2, max2
424 MATH_FUNCS_DEFINE_BINARY_FUNC(fp, copysign, std::copysign, true, 0.0f, 0.0f, 0.001f, -100.0f, 100.0f, -10.0f, 10.0f)
425 MATH_FUNCS_DEFINE_BINARY_FUNC(fp, fmod, std::fmod, true, 0.0f, 0.0f, 0.001f, -100.0f, 100.0f, -10.0f, 10.0f)
426 MATH_FUNCS_DEFINE_BINARY_FUNC(fp, remainder, std::remainder, true, 0.0f, 0.001f, 0.0f, -100.0f, 100.0f, -10.0f, 10.0f)
427 
428 // In case of function float nextafter(float, float) reference function must
429 // operate on floats and return float.
430 struct fp_func_nextafter : public binary_func<cl_float, cl_float, cl_float>
431 {
fp_func_nextafterfp_func_nextafter432     fp_func_nextafter(bool is_embedded) : m_is_embedded(is_embedded)
433     {
434 
435     }
436 
strfp_func_nextafter437     std::string str()
438     {
439         return "nextafter";
440     }
441 
headersfp_func_nextafter442     std::string headers()
443     {
444         return "#include <opencl_math>\n";
445     }
446 
447     /* In this case reference value type MUST BE cl_float */
operator ()fp_func_nextafter448     cl_float operator()(const cl_float& x, const cl_float& y)
449     {
450         return (std::nextafter)(x, y);
451     }
452 
min1fp_func_nextafter453     cl_float min1()
454     {
455         return -1000.0f;
456     }
457 
max1fp_func_nextafter458     cl_float max1()
459     {
460         return 500.0f;
461     }
462 
min2fp_func_nextafter463     cl_float min2()
464     {
465         return 501.0f;
466     }
467 
max2fp_func_nextafter468     cl_float max2()
469     {
470         return 1000.0f;
471     }
472 
in1_special_casesfp_func_nextafter473     std::vector<cl_float> in1_special_cases()
474     {
475         return {
476             cl_float(0.0f),
477             cl_float(-0.0f),
478             cl_float(1.0f),
479             cl_float(-1.0f),
480             cl_float(2.0f),
481             cl_float(-2.0f),
482             std::numeric_limits<cl_float>::infinity(),
483             -std::numeric_limits<cl_float>::infinity(),
484             std::numeric_limits<cl_float>::quiet_NaN()
485         };
486     }
487 
in2_special_casesfp_func_nextafter488     std::vector<cl_float> in2_special_cases()
489     {
490         return {
491             cl_float(0.0f),
492             cl_float(-0.0f),
493             cl_float(1.0f),
494             cl_float(-1.0f),
495             cl_float(2.0f),
496             cl_float(-2.0f),
497             std::numeric_limits<cl_float>::infinity(),
498             -std::numeric_limits<cl_float>::infinity(),
499             std::numeric_limits<cl_float>::quiet_NaN()
500         };
501     }
502 
use_ulpfp_func_nextafter503     bool use_ulp()
504     {
505         return true;
506     }
507 
ulpfp_func_nextafter508     float ulp()
509     {
510         if(m_is_embedded)
511         {
512             return 0.0f;
513         }
514         return 0.0f;
515     }
516 private:
517     bool m_is_embedded;
518 };
519 
520 // gentype remquo(gentype x, gentype y, intn* quo);
521 struct fp_func_remquo : public binary_func<cl_float, cl_float, cl_float2>
522 {
fp_func_remquofp_func_remquo523     fp_func_remquo(bool is_embedded) : m_is_embedded(is_embedded)
524     {
525 
526     }
527 
strfp_func_remquo528     std::string str()
529     {
530         return "remquo";
531     }
532 
headersfp_func_remquo533     std::string headers()
534     {
535         return "#include <opencl_math>\n";
536     }
537 
operator ()fp_func_remquo538     cl_double2 operator()(const cl_float& x, const cl_float& y)
539     {
540         return reference::remquo(static_cast<cl_double>(x), static_cast<cl_double>(y));
541     }
542 
min1fp_func_remquo543     cl_float min1()
544     {
545         return -1000.0f;
546     }
547 
max1fp_func_remquo548     cl_float max1()
549     {
550         return 1000.0f;
551     }
552 
min2fp_func_remquo553     cl_float min2()
554     {
555         return -1000.0f;
556     }
557 
max2fp_func_remquo558     cl_float max2()
559     {
560         return 1000.0f;
561     }
562 
in1_special_casesfp_func_remquo563     std::vector<cl_float> in1_special_cases()
564     {
565         return {
566             cl_float(0.0f),
567             cl_float(-0.0f),
568             cl_float(1.0f),
569             cl_float(-1.0f),
570             std::numeric_limits<cl_float>::infinity(),
571             -std::numeric_limits<cl_float>::infinity(),
572             std::numeric_limits<cl_float>::quiet_NaN()
573         };
574     }
575 
in2_special_casesfp_func_remquo576     std::vector<cl_float> in2_special_cases()
577     {
578         return {
579             cl_float(0.0f),
580             cl_float(-0.0f),
581             cl_float(1.0f),
582             cl_float(-1.0f),
583             std::numeric_limits<cl_float>::infinity(),
584             -std::numeric_limits<cl_float>::infinity(),
585             std::numeric_limits<cl_float>::quiet_NaN()
586         };
587     }
588 
use_ulpfp_func_remquo589     bool use_ulp()
590     {
591         return true;
592     }
593 
ulpfp_func_remquo594     float ulp()
595     {
596         if(m_is_embedded)
597         {
598             return 0.0f;
599         }
600         return 0.0f;
601     }
602 private:
603     bool m_is_embedded;
604 };
605 
606 
607 // We need to specialize generate_kernel_binary<>() function template for fp_func_remquo.
608 // -----------------------------------------------------------------------------------
609 // ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
610 // -----------------------------------------------------------------------------------
611 #if defined(DEVELOPMENT) && defined(USE_OPENCLC_KERNELS)
612 template <>
generate_kernel_binary(fp_func_remquo func)613 std::string generate_kernel_binary<fp_func_remquo, cl_float, cl_float, cl_float2>(fp_func_remquo func)
614 {
615     return
616         "__kernel void test_remquo(global float *input1, global float *input2, global float2 *output)\n"
617         "{\n"
618         "    size_t gid = get_global_id(0);\n"
619         "    float2 result;\n"
620         "    int quo = 0;\n"
621         "    int sign = 0;\n"
622         "    result.x = remquo(input1[gid], input2[gid], &quo);\n"
623         // Specification say:
624         // "remquo also calculates the lower seven bits of the integral quotient x/y,
625         // and gives that value the same sign as x/y. It stores this signed value in
626         // the object pointed to by quo."
627         // Implemenation may save into quo more than seven bits. We need to take
628         // care of that here.
629         "    sign = (quo < 0) ? -1 : 1;\n"
630         "    quo = (quo < 0) ? -quo : quo;\n"
631         "    quo &= 0x0000007f;\n"
632         "    result.y = (sign < 0) ? -quo : quo;\n"
633         "    output[gid] = result;\n"
634         "}\n";
635 }
636 #else
637 template <>
generate_kernel_binary(fp_func_remquo func)638 std::string generate_kernel_binary<fp_func_remquo, cl_float, cl_float, cl_float2>(fp_func_remquo func)
639 {
640     return
641         "" + func.defs() +
642         "" + func.headers() +
643         "#include <opencl_memory>\n"
644         "#include <opencl_work_item>\n"
645         "using namespace cl;\n"
646         "__kernel void test_remquo(global_ptr<float[]> input1, global_ptr<float[]> input2, global_ptr<float2[]> output)\n"
647         "{\n"
648         "    size_t gid = get_global_id(0);\n"
649         "    float2 result;\n"
650         "    int quo = 0;\n"
651         "    int sign = 0;\n"
652         "    result.x = remquo(input1[gid], input2[gid], &quo);\n"
653         // Specification say:
654         // "remquo also calculates the lower seven bits of the integral quotient x/y,
655         // and gives that value the same sign as x/y. It stores this signed value in
656         // the object pointed to by quo."
657         // Implemenation may save into quo more than seven bits. We need to take
658         // care of that here.
659         "    sign = (quo < 0) ? -1 : 1;\n"
660         "    quo = (quo < 0) ? -quo : quo;\n"
661         "    quo &= 0x0000007f;\n"
662         "    result.y = (sign < 0) ? -quo : quo;\n"
663         "    output[gid] = result;\n"
664         "}\n";
665 }
666 #endif
667 
668 // -------------- TERNARY FUNCTIONS
669 
670 // gentype fma(gentype a, gentype b, gentype c);
671 // group_name, func_name, reference_func, use_ulp, ulp, ulp_for_embedded, max_delta, min1, max1, min2, max2, min3, max3
672 MATH_FUNCS_DEFINE_TERNARY_FUNC(fp, fma, std::fma, true, 0.0f, 0.0f, 0.001f, -1000.0f, 1000.0f, -1000.0f, 1000.0f, -1000.0f, 1000.0f)
673 
674 // floating point functions
AUTO_TEST_CASE(test_fp_funcs)675 AUTO_TEST_CASE(test_fp_funcs)
676 (cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
677 {
678     int error = CL_SUCCESS;
679     int last_error = CL_SUCCESS;
680 
681     // Check for EMBEDDED_PROFILE
682     bool is_embedded_profile = false;
683     char profile[128];
684     last_error = clGetDeviceInfo(device, CL_DEVICE_PROFILE, sizeof(profile), (void *)&profile, NULL);
685     RETURN_ON_CL_ERROR(last_error, "clGetDeviceInfo")
686     if (std::strcmp(profile, "EMBEDDED_PROFILE") == 0)
687         is_embedded_profile = true;
688 
689     // gentype ceil(gentype x);
690     TEST_UNARY_FUNC_MACRO((fp_func_ceil(is_embedded_profile)))
691     // gentype floor(gentype x);
692     TEST_UNARY_FUNC_MACRO((fp_func_floor(is_embedded_profile)))
693     // gentype rint(gentype x);
694     TEST_UNARY_FUNC_MACRO((fp_func_rint(is_embedded_profile)))
695     // gentype round(gentype x);
696     TEST_UNARY_FUNC_MACRO((fp_func_round(is_embedded_profile)))
697     // gentype trunc(gentype x);
698     TEST_UNARY_FUNC_MACRO((fp_func_trunc(is_embedded_profile)))
699 
700     // floatn nan(uintn nancode);
701     TEST_UNARY_FUNC_MACRO((fp_func_nan()))
702 
703     // gentype fract(gentype x, gentype* iptr);
704     TEST_UNARY_FUNC_MACRO((fp_func_fract(is_embedded_profile)))
705     // gentype modf(gentype x, gentype* iptr);
706     TEST_UNARY_FUNC_MACRO((fp_func_modf(is_embedded_profile)))
707     // gentype frexp(gentype x, intn* exp);
708     TEST_UNARY_FUNC_MACRO((fp_func_frexp(is_embedded_profile)))
709 
710     // gentype remainder(gentype x, gentype y);
711     TEST_BINARY_FUNC_MACRO((fp_func_remainder(is_embedded_profile)))
712     // gentype copysign(gentype x, gentype y);
713     TEST_BINARY_FUNC_MACRO((fp_func_copysign(is_embedded_profile)))
714     // gentype fmod(gentype x, gentype y);
715     TEST_BINARY_FUNC_MACRO((fp_func_fmod(is_embedded_profile)))
716 
717     // gentype nextafter(gentype x, gentype y);
718     TEST_BINARY_FUNC_MACRO((fp_func_nextafter(is_embedded_profile)))
719 
720     // gentype remquo(gentype x, gentype y, intn* quo);
721     TEST_BINARY_FUNC_MACRO((fp_func_remquo(is_embedded_profile)))
722 
723     // gentype fma(gentype a, gentype b, gentype c);
724     TEST_TERNARY_FUNC_MACRO((fp_func_fma(is_embedded_profile)))
725 
726     if(error != CL_SUCCESS)
727     {
728         return -1;
729     }
730     return error;
731 }
732 
733 #endif // TEST_CONFORMANCE_CLCPP_MATH_FUNCS_FP_FUNCS_HPP
734