• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2020 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 
17 #include <math.h>
18 #include <stdio.h>
19 
20 #include "CL/cl_half.h"
21 
22 union FI {
23   float f;
24   uint32_t i;
25 };
26 
test_half_to_float(cl_half h,cl_float ref)27 int test_half_to_float(cl_half h, cl_float ref)
28 {
29   cl_float f = cl_half_to_float(h);
30   if (f != ref) {
31     union FI f_i, ref_i;
32     f_i.f = f;
33     ref_i.f = ref;
34     printf("\nERROR: converting 0x%04x to float: expected 0x%08x, got 0x%08x\n",
35            h, ref_i.i, f_i.i);
36     return 0;
37   }
38   return 1;
39 }
40 
test_half_from_float(cl_float f,cl_half ref,cl_half_rounding_mode mode,const char * mode_str)41 int test_half_from_float(cl_float f, cl_half ref,
42                          cl_half_rounding_mode mode, const char *mode_str)
43 {
44   cl_half h = cl_half_from_float(f, mode);
45   if (h != ref) {
46     union FI f_i;
47     f_i.f = f;
48     printf(
49       "\nERROR: converting 0x%08x to half (%s): expected 0x%04x, got 0x%04x\n",
50       f_i.i, mode_str, ref, h);
51     return 0;
52   }
53   return 1;
54 }
55 
main(void)56 int main(void)
57 {
58   printf("\nChecking conversion routines in cl_half.h\n");
59 
60 #define CHECK_TO_FLOAT(h, ref)                     \
61   if (!test_half_to_float(h, ref)) {               \
62     printf("Test failed on line %d.\n", __LINE__); \
63     return 1;                                      \
64   }
65 
66   // Check a handful of values
67   CHECK_TO_FLOAT(0x0000, 0.f);
68   CHECK_TO_FLOAT(0x3c00, 1.f);
69   CHECK_TO_FLOAT(0xbc00, -1.f);
70   CHECK_TO_FLOAT(0x7c00, INFINITY);
71   CHECK_TO_FLOAT(0xfc00, -INFINITY);
72 
73 
74 #define CHECK_FROM_FLOAT(f, ref, mode)                         \
75   if (!test_half_from_float(f, ref, CL_HALF_##mode, #mode)) {  \
76     printf("Test failed on line %d.\n", __LINE__);             \
77     return 1;                                                  \
78   }
79 
80   // Check a handful of normal values
81   CHECK_FROM_FLOAT(0.f, 0x0000, RTE);
82   CHECK_FROM_FLOAT(1.f, 0x3c00, RTE);
83   CHECK_FROM_FLOAT(-1.f, 0xbc00, RTE);
84   CHECK_FROM_FLOAT(CL_HALF_MAX, 0x7bff, RTE);
85   CHECK_FROM_FLOAT(CL_HALF_MIN, 0x0400, RTE);
86 
87   // Check huge positive (non-inf) values round properly
88   CHECK_FROM_FLOAT(CL_HALF_MAX + 1000.f, 0x7c00, RTE);
89   CHECK_FROM_FLOAT(CL_HALF_MAX + 1000.f, 0x7c00, RTP);
90   CHECK_FROM_FLOAT(CL_HALF_MAX + 1000.f, 0x7bff, RTN);
91   CHECK_FROM_FLOAT(CL_HALF_MAX + 1000.f, 0x7bff, RTZ);
92 
93   // Check huge negative (non-inf) values round properly
94   CHECK_FROM_FLOAT(-(CL_HALF_MAX + 1000.f), 0xfc00, RTE);
95   CHECK_FROM_FLOAT(-(CL_HALF_MAX + 1000.f), 0xfbff, RTP);
96   CHECK_FROM_FLOAT(-(CL_HALF_MAX + 1000.f), 0xfc00, RTN);
97   CHECK_FROM_FLOAT(-(CL_HALF_MAX + 1000.f), 0xfbff, RTZ);
98 #ifndef _MSC_VER
99   // Check tiny positive values round properly
100   CHECK_FROM_FLOAT(0x1.000000p-25, 0x0000, RTE);
101   CHECK_FROM_FLOAT(0x1.000000p-25, 0x0001, RTP);
102   CHECK_FROM_FLOAT(0x1.000000p-25, 0x0000, RTN);
103   CHECK_FROM_FLOAT(0x1.000000p-25, 0x0000, RTZ);
104 
105   // Check tiny negative values round properly
106   CHECK_FROM_FLOAT(-0x1.000000p-25, 0x8000, RTE);
107   CHECK_FROM_FLOAT(-0x1.000000p-25, 0x8000, RTP);
108   CHECK_FROM_FLOAT(-0x1.000000p-25, 0x8001, RTN);
109   CHECK_FROM_FLOAT(-0x1.000000p-25, 0x8000, RTZ);
110 #else
111 // Check tiny positive values round properly
112   CHECK_FROM_FLOAT(2.98023223876953125e-08, 0x0000, RTE);
113   CHECK_FROM_FLOAT(2.98023223876953125e-08, 0x0001, RTP);
114   CHECK_FROM_FLOAT(2.98023223876953125e-08, 0x0000, RTN);
115   CHECK_FROM_FLOAT(2.98023223876953125e-08, 0x0000, RTZ);
116 
117   // Check tiny negative values round properly
118   CHECK_FROM_FLOAT(-2.98023223876953125e-08, 0x8000, RTE);
119   CHECK_FROM_FLOAT(-2.98023223876953125e-08, 0x8000, RTP);
120   CHECK_FROM_FLOAT(-2.98023223876953125e-08, 0x8001, RTN);
121   CHECK_FROM_FLOAT(-2.98023223876953125e-08, 0x8000, RTZ);
122 #endif
123   printf("\nAll tests passed!\n");
124 
125   return 0;
126 }
127