xref: /aosp_15_r20/external/OpenCL-Headers/tests/test_cl_half.h.c (revision 3cc257528f335c5672e46865a03b8ee020e5fe2d)
1*3cc25752SFrank Piva //
2*3cc25752SFrank Piva // Copyright (c) 2020 The Khronos Group Inc.
3*3cc25752SFrank Piva //
4*3cc25752SFrank Piva // Licensed under the Apache License, Version 2.0 (the "License");
5*3cc25752SFrank Piva // you may not use this file except in compliance with the License.
6*3cc25752SFrank Piva // You may obtain a copy of the License at
7*3cc25752SFrank Piva //
8*3cc25752SFrank Piva //    http://www.apache.org/licenses/LICENSE-2.0
9*3cc25752SFrank Piva //
10*3cc25752SFrank Piva // Unless required by applicable law or agreed to in writing, software
11*3cc25752SFrank Piva // distributed under the License is distributed on an "AS IS" BASIS,
12*3cc25752SFrank Piva // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*3cc25752SFrank Piva // See the License for the specific language governing permissions and
14*3cc25752SFrank Piva // limitations under the License.
15*3cc25752SFrank Piva //
16*3cc25752SFrank Piva 
17*3cc25752SFrank Piva #include <math.h>
18*3cc25752SFrank Piva #include <stdio.h>
19*3cc25752SFrank Piva 
20*3cc25752SFrank Piva #include "CL/cl_half.h"
21*3cc25752SFrank Piva 
22*3cc25752SFrank Piva union FI {
23*3cc25752SFrank Piva   float f;
24*3cc25752SFrank Piva   uint32_t i;
25*3cc25752SFrank Piva };
26*3cc25752SFrank Piva 
test_half_to_float(cl_half h,cl_float ref)27*3cc25752SFrank Piva int test_half_to_float(cl_half h, cl_float ref)
28*3cc25752SFrank Piva {
29*3cc25752SFrank Piva   cl_float f = cl_half_to_float(h);
30*3cc25752SFrank Piva   if (f != ref) {
31*3cc25752SFrank Piva     union FI f_i, ref_i;
32*3cc25752SFrank Piva     f_i.f = f;
33*3cc25752SFrank Piva     ref_i.f = ref;
34*3cc25752SFrank Piva     printf("\nERROR: converting 0x%04x to float: expected 0x%08x, got 0x%08x\n",
35*3cc25752SFrank Piva            h, ref_i.i, f_i.i);
36*3cc25752SFrank Piva     return 0;
37*3cc25752SFrank Piva   }
38*3cc25752SFrank Piva   return 1;
39*3cc25752SFrank Piva }
40*3cc25752SFrank Piva 
test_half_from_float(cl_float f,cl_half ref,cl_half_rounding_mode mode,const char * mode_str)41*3cc25752SFrank Piva int test_half_from_float(cl_float f, cl_half ref,
42*3cc25752SFrank Piva                          cl_half_rounding_mode mode, const char *mode_str)
43*3cc25752SFrank Piva {
44*3cc25752SFrank Piva   cl_half h = cl_half_from_float(f, mode);
45*3cc25752SFrank Piva   if (h != ref) {
46*3cc25752SFrank Piva     union FI f_i;
47*3cc25752SFrank Piva     f_i.f = f;
48*3cc25752SFrank Piva     printf(
49*3cc25752SFrank Piva       "\nERROR: converting 0x%08x to half (%s): expected 0x%04x, got 0x%04x\n",
50*3cc25752SFrank Piva       f_i.i, mode_str, ref, h);
51*3cc25752SFrank Piva     return 0;
52*3cc25752SFrank Piva   }
53*3cc25752SFrank Piva   return 1;
54*3cc25752SFrank Piva }
55*3cc25752SFrank Piva 
main(void)56*3cc25752SFrank Piva int main(void)
57*3cc25752SFrank Piva {
58*3cc25752SFrank Piva   printf("\nChecking conversion routines in cl_half.h\n");
59*3cc25752SFrank Piva 
60*3cc25752SFrank Piva #define CHECK_TO_FLOAT(h, ref)                     \
61*3cc25752SFrank Piva   if (!test_half_to_float(h, ref)) {               \
62*3cc25752SFrank Piva     printf("Test failed on line %d.\n", __LINE__); \
63*3cc25752SFrank Piva     return 1;                                      \
64*3cc25752SFrank Piva   }
65*3cc25752SFrank Piva 
66*3cc25752SFrank Piva   // Check a handful of values
67*3cc25752SFrank Piva   CHECK_TO_FLOAT(0x0000, 0.f);
68*3cc25752SFrank Piva   CHECK_TO_FLOAT(0x3c00, 1.f);
69*3cc25752SFrank Piva   CHECK_TO_FLOAT(0xbc00, -1.f);
70*3cc25752SFrank Piva   CHECK_TO_FLOAT(0x7c00, INFINITY);
71*3cc25752SFrank Piva   CHECK_TO_FLOAT(0xfc00, -INFINITY);
72*3cc25752SFrank Piva 
73*3cc25752SFrank Piva 
74*3cc25752SFrank Piva #define CHECK_FROM_FLOAT(f, ref, mode)                         \
75*3cc25752SFrank Piva   if (!test_half_from_float(f, ref, CL_HALF_##mode, #mode)) {  \
76*3cc25752SFrank Piva     printf("Test failed on line %d.\n", __LINE__);             \
77*3cc25752SFrank Piva     return 1;                                                  \
78*3cc25752SFrank Piva   }
79*3cc25752SFrank Piva 
80*3cc25752SFrank Piva   // Check a handful of normal values
81*3cc25752SFrank Piva   CHECK_FROM_FLOAT(0.f, 0x0000, RTE);
82*3cc25752SFrank Piva   CHECK_FROM_FLOAT(1.f, 0x3c00, RTE);
83*3cc25752SFrank Piva   CHECK_FROM_FLOAT(-1.f, 0xbc00, RTE);
84*3cc25752SFrank Piva   CHECK_FROM_FLOAT(CL_HALF_MAX, 0x7bff, RTE);
85*3cc25752SFrank Piva   CHECK_FROM_FLOAT(CL_HALF_MIN, 0x0400, RTE);
86*3cc25752SFrank Piva 
87*3cc25752SFrank Piva   // Check huge positive (non-inf) values round properly
88*3cc25752SFrank Piva   CHECK_FROM_FLOAT(CL_HALF_MAX + 1000.f, 0x7c00, RTE);
89*3cc25752SFrank Piva   CHECK_FROM_FLOAT(CL_HALF_MAX + 1000.f, 0x7c00, RTP);
90*3cc25752SFrank Piva   CHECK_FROM_FLOAT(CL_HALF_MAX + 1000.f, 0x7bff, RTN);
91*3cc25752SFrank Piva   CHECK_FROM_FLOAT(CL_HALF_MAX + 1000.f, 0x7bff, RTZ);
92*3cc25752SFrank Piva 
93*3cc25752SFrank Piva   // Check huge negative (non-inf) values round properly
94*3cc25752SFrank Piva   CHECK_FROM_FLOAT(-(CL_HALF_MAX + 1000.f), 0xfc00, RTE);
95*3cc25752SFrank Piva   CHECK_FROM_FLOAT(-(CL_HALF_MAX + 1000.f), 0xfbff, RTP);
96*3cc25752SFrank Piva   CHECK_FROM_FLOAT(-(CL_HALF_MAX + 1000.f), 0xfc00, RTN);
97*3cc25752SFrank Piva   CHECK_FROM_FLOAT(-(CL_HALF_MAX + 1000.f), 0xfbff, RTZ);
98*3cc25752SFrank Piva #if 0 // Hexadecimal float constant is C++17
99*3cc25752SFrank Piva   // Check tiny positive values round properly
100*3cc25752SFrank Piva   CHECK_FROM_FLOAT(0x1.000000p-25, 0x0000, RTE);
101*3cc25752SFrank Piva   CHECK_FROM_FLOAT(0x1.000000p-25, 0x0001, RTP);
102*3cc25752SFrank Piva   CHECK_FROM_FLOAT(0x1.000000p-25, 0x0000, RTN);
103*3cc25752SFrank Piva   CHECK_FROM_FLOAT(0x1.000000p-25, 0x0000, RTZ);
104*3cc25752SFrank Piva 
105*3cc25752SFrank Piva   // Check tiny negative values round properly
106*3cc25752SFrank Piva   CHECK_FROM_FLOAT(-0x1.000000p-25, 0x8000, RTE);
107*3cc25752SFrank Piva   CHECK_FROM_FLOAT(-0x1.000000p-25, 0x8000, RTP);
108*3cc25752SFrank Piva   CHECK_FROM_FLOAT(-0x1.000000p-25, 0x8001, RTN);
109*3cc25752SFrank Piva   CHECK_FROM_FLOAT(-0x1.000000p-25, 0x8000, RTZ);
110*3cc25752SFrank Piva #else
111*3cc25752SFrank Piva   // Check tiny positive values round properly
112*3cc25752SFrank Piva   CHECK_FROM_FLOAT(2.98023223876953125e-08, 0x0000, RTE);
113*3cc25752SFrank Piva   CHECK_FROM_FLOAT(2.98023223876953125e-08, 0x0001, RTP);
114*3cc25752SFrank Piva   CHECK_FROM_FLOAT(2.98023223876953125e-08, 0x0000, RTN);
115*3cc25752SFrank Piva   CHECK_FROM_FLOAT(2.98023223876953125e-08, 0x0000, RTZ);
116*3cc25752SFrank Piva 
117*3cc25752SFrank Piva   // Check tiny negative values round properly
118*3cc25752SFrank Piva   CHECK_FROM_FLOAT(-2.98023223876953125e-08, 0x8000, RTE);
119*3cc25752SFrank Piva   CHECK_FROM_FLOAT(-2.98023223876953125e-08, 0x8000, RTP);
120*3cc25752SFrank Piva   CHECK_FROM_FLOAT(-2.98023223876953125e-08, 0x8001, RTN);
121*3cc25752SFrank Piva   CHECK_FROM_FLOAT(-2.98023223876953125e-08, 0x8000, RTZ);
122*3cc25752SFrank Piva #endif
123*3cc25752SFrank Piva   printf("\nAll tests passed!\n");
124*3cc25752SFrank Piva 
125*3cc25752SFrank Piva   return 0;
126*3cc25752SFrank Piva }
127