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