• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <gtest/gtest.h>
2 
3 #include <cstdint>
4 
5 #include <fp16.h>
6 #include "tables.h"
7 
8 
TEST(FP16_ALT_TO_FP32_BITS,normalized_powers_of_2)9 TEST(FP16_ALT_TO_FP32_BITS, normalized_powers_of_2) {
10 	const uint16_t min_po2_f16   = UINT16_C(0x0400);
11 	const uint16_t eighths_f16   = UINT16_C(0x3000);
12 	const uint16_t quarter_f16   = UINT16_C(0x3400);
13 	const uint16_t half_f16      = UINT16_C(0x3800);
14 	const uint16_t one_f16       = UINT16_C(0x3C00);
15 	const uint16_t two_f16       = UINT16_C(0x4000);
16 	const uint16_t four_f16      = UINT16_C(0x4400);
17 	const uint16_t eight_f16     = UINT16_C(0x4800);
18 	const uint16_t sixteen_f16   = UINT16_C(0x4C00);
19 	const uint16_t thirtytwo_f16 = UINT16_C(0x5000);
20 	const uint16_t sixtyfour_f16 = UINT16_C(0x5400);
21 	const uint16_t max_po2_f16   = UINT16_C(0x7C00);
22 
23 	const uint32_t min_po2_f32   = UINT32_C(0x38800000);
24 	const uint32_t eighths_f32   = UINT32_C(0x3E000000);
25 	const uint32_t quarter_f32   = UINT32_C(0x3E800000);
26 	const uint32_t half_f32      = UINT32_C(0x3F000000);
27 	const uint32_t one_f32       = UINT32_C(0x3F800000);
28 	const uint32_t two_f32       = UINT32_C(0x40000000);
29 	const uint32_t four_f32      = UINT32_C(0x40800000);
30 	const uint32_t eight_f32     = UINT32_C(0x41000000);
31 	const uint32_t sixteen_f32   = UINT32_C(0x41800000);
32 	const uint32_t thirtytwo_f32 = UINT32_C(0x42000000);
33 	const uint32_t sixtyfour_f32 = UINT32_C(0x42800000);
34 	const uint32_t max_po2_f32   = UINT32_C(0x47800000);
35 
36 	EXPECT_EQ(min_po2_f32, fp16_alt_to_fp32_bits(min_po2_f16)) <<
37 		std::hex << std::uppercase << std::setfill('0') <<
38 		"F16 = 0x" << std::setw(4) << min_po2_f16 << ", " <<
39 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(min_po2_f16) << ", " <<
40 		"F32 = 0x" << std::setw(8) << min_po2_f32;
41 
42 	EXPECT_EQ(eighths_f32, fp16_alt_to_fp32_bits(eighths_f16)) <<
43 		std::hex << std::uppercase << std::setfill('0') <<
44 		"F16 = 0x" << std::setw(4) << eighths_f16 << ", " <<
45 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(eighths_f16) << ", " <<
46 		"F32 = 0x" << std::setw(8) << eighths_f32;
47 
48 	EXPECT_EQ(quarter_f32, fp16_alt_to_fp32_bits(quarter_f16)) <<
49 		std::hex << std::uppercase << std::setfill('0') <<
50 		"F16 = 0x" << std::setw(4) << quarter_f16 << ", " <<
51 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(quarter_f16) << ", " <<
52 		"F32 = 0x" << std::setw(8) << quarter_f32;
53 
54 	EXPECT_EQ(half_f32, fp16_alt_to_fp32_bits(half_f16)) <<
55 		std::hex << std::uppercase << std::setfill('0') <<
56 		"F16 = 0x" << std::setw(4) << half_f16 << ", " <<
57 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(half_f16) << ", " <<
58 		"F32 = 0x" << std::setw(8) << half_f32;
59 
60 	EXPECT_EQ(one_f32, fp16_alt_to_fp32_bits(one_f16)) <<
61 		std::hex << std::uppercase << std::setfill('0') <<
62 		"F16 = 0x" << std::setw(4) << one_f16 << ", " <<
63 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(one_f16) << ", " <<
64 		"F32 = 0x" << std::setw(8) << one_f32;
65 
66 	EXPECT_EQ(two_f32, fp16_alt_to_fp32_bits(two_f16)) <<
67 		std::hex << std::uppercase << std::setfill('0') <<
68 		"F16 = 0x" << std::setw(4) << two_f16 << ", " <<
69 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(two_f16) << ", " <<
70 		"F32 = 0x" << std::setw(8) << two_f32;
71 
72 	EXPECT_EQ(four_f32, fp16_alt_to_fp32_bits(four_f16)) <<
73 		std::hex << std::uppercase << std::setfill('0') <<
74 		"F16 = 0x" << std::setw(4) << four_f16 << ", " <<
75 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(four_f16) << ", " <<
76 		"F32 = 0x" << std::setw(8) << four_f32;
77 
78 	EXPECT_EQ(eight_f32, fp16_alt_to_fp32_bits(eight_f16)) <<
79 		std::hex << std::uppercase << std::setfill('0') <<
80 		"F16 = 0x" << std::setw(4) << eight_f16 << ", " <<
81 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(eight_f16) << ", " <<
82 		"F32 = 0x" << std::setw(8) << eight_f32;
83 
84 	EXPECT_EQ(sixteen_f32, fp16_alt_to_fp32_bits(sixteen_f16)) <<
85 		std::hex << std::uppercase << std::setfill('0') <<
86 		"F16 = 0x" << std::setw(4) << sixteen_f16 << ", " <<
87 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(sixteen_f16) << ", " <<
88 		"F32 = 0x" << std::setw(8) << sixteen_f32;
89 
90 	EXPECT_EQ(thirtytwo_f32, fp16_alt_to_fp32_bits(thirtytwo_f16)) <<
91 		std::hex << std::uppercase << std::setfill('0') <<
92 		"F16 = 0x" << std::setw(4) << thirtytwo_f16 << ", " <<
93 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(thirtytwo_f16) << ", " <<
94 		"F32 = 0x" << std::setw(8) << thirtytwo_f32;
95 
96 	EXPECT_EQ(sixtyfour_f32, fp16_alt_to_fp32_bits(sixtyfour_f16)) <<
97 		std::hex << std::uppercase << std::setfill('0') <<
98 		"F16 = 0x" << std::setw(4) << sixtyfour_f16 << ", " <<
99 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(sixtyfour_f16) << ", " <<
100 		"F32 = 0x" << std::setw(8) << sixtyfour_f32;
101 
102 	EXPECT_EQ(max_po2_f32, fp16_alt_to_fp32_bits(max_po2_f16)) <<
103 		std::hex << std::uppercase << std::setfill('0') <<
104 		"F16 = 0x" << std::setw(4) << max_po2_f16 << ", " <<
105 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(max_po2_f16) << ", " <<
106 		"F32 = 0x" << std::setw(8) << max_po2_f32;
107 }
108 
TEST(FP16_ALT_TO_FP32_BITS,denormalized_powers_of_2)109 TEST(FP16_ALT_TO_FP32_BITS, denormalized_powers_of_2) {
110 	const uint16_t exp2_minus_15_f16 = UINT16_C(0x0200);
111 	const uint16_t exp2_minus_16_f16 = UINT16_C(0x0100);
112 	const uint16_t exp2_minus_17_f16 = UINT16_C(0x0080);
113 	const uint16_t exp2_minus_18_f16 = UINT16_C(0x0040);
114 	const uint16_t exp2_minus_19_f16 = UINT16_C(0x0020);
115 	const uint16_t exp2_minus_20_f16 = UINT16_C(0x0010);
116 	const uint16_t exp2_minus_21_f16 = UINT16_C(0x0008);
117 	const uint16_t exp2_minus_22_f16 = UINT16_C(0x0004);
118 	const uint16_t exp2_minus_23_f16 = UINT16_C(0x0002);
119 	const uint16_t exp2_minus_24_f16 = UINT16_C(0x0001);
120 
121 	const uint32_t exp2_minus_15_f32 = UINT32_C(0x38000000);
122 	const uint32_t exp2_minus_16_f32 = UINT32_C(0x37800000);
123 	const uint32_t exp2_minus_17_f32 = UINT32_C(0x37000000);
124 	const uint32_t exp2_minus_18_f32 = UINT32_C(0x36800000);
125 	const uint32_t exp2_minus_19_f32 = UINT32_C(0x36000000);
126 	const uint32_t exp2_minus_20_f32 = UINT32_C(0x35800000);
127 	const uint32_t exp2_minus_21_f32 = UINT32_C(0x35000000);
128 	const uint32_t exp2_minus_22_f32 = UINT32_C(0x34800000);
129 	const uint32_t exp2_minus_23_f32 = UINT32_C(0x34000000);
130 	const uint32_t exp2_minus_24_f32 = UINT32_C(0x33800000);
131 
132 	EXPECT_EQ(exp2_minus_15_f32, fp16_alt_to_fp32_bits(exp2_minus_15_f16)) <<
133 		std::hex << std::uppercase << std::setfill('0') <<
134 		"F16 = 0x" << std::setw(4) << exp2_minus_15_f16 << ", " <<
135 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(exp2_minus_15_f16) << ", " <<
136 		"F32 = 0x" << std::setw(8) << exp2_minus_15_f32;
137 
138 	EXPECT_EQ(exp2_minus_16_f32, fp16_alt_to_fp32_bits(exp2_minus_16_f16)) <<
139 		std::hex << std::uppercase << std::setfill('0') <<
140 		"F16 = 0x" << std::setw(4) << exp2_minus_16_f16 << ", " <<
141 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(exp2_minus_16_f16) << ", " <<
142 		"F32 = 0x" << std::setw(8) << exp2_minus_16_f32;
143 
144 	EXPECT_EQ(exp2_minus_17_f32, fp16_alt_to_fp32_bits(exp2_minus_17_f16)) <<
145 		std::hex << std::uppercase << std::setfill('0') <<
146 		"F16 = 0x" << std::setw(4) << exp2_minus_17_f16 << ", " <<
147 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(exp2_minus_17_f16) << ", " <<
148 		"F32 = 0x" << std::setw(8) << exp2_minus_17_f32;
149 
150 	EXPECT_EQ(exp2_minus_18_f32, fp16_alt_to_fp32_bits(exp2_minus_18_f16)) <<
151 		std::hex << std::uppercase << std::setfill('0') <<
152 		"F16 = 0x" << std::setw(4) << exp2_minus_18_f16 << ", " <<
153 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(exp2_minus_18_f16) << ", " <<
154 		"F32 = 0x" << std::setw(8) << exp2_minus_18_f32;
155 
156 	EXPECT_EQ(exp2_minus_19_f32, fp16_alt_to_fp32_bits(exp2_minus_19_f16)) <<
157 		std::hex << std::uppercase << std::setfill('0') <<
158 		"F16 = 0x" << std::setw(4) << exp2_minus_19_f16 << ", " <<
159 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(exp2_minus_19_f16) << ", " <<
160 		"F32 = 0x" << std::setw(8) << exp2_minus_19_f32;
161 
162 	EXPECT_EQ(exp2_minus_20_f32, fp16_alt_to_fp32_bits(exp2_minus_20_f16)) <<
163 		std::hex << std::uppercase << std::setfill('0') <<
164 		"F16 = 0x" << std::setw(4) << exp2_minus_20_f16 << ", " <<
165 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(exp2_minus_20_f16) << ", " <<
166 		"F32 = 0x" << std::setw(8) << exp2_minus_20_f32;
167 
168 	EXPECT_EQ(exp2_minus_21_f32, fp16_alt_to_fp32_bits(exp2_minus_21_f16)) <<
169 		std::hex << std::uppercase << std::setfill('0') <<
170 		"F16 = 0x" << std::setw(4) << exp2_minus_21_f16 << ", " <<
171 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(exp2_minus_21_f16) << ", " <<
172 		"F32 = 0x" << std::setw(8) << exp2_minus_21_f32;
173 
174 	EXPECT_EQ(exp2_minus_22_f32, fp16_alt_to_fp32_bits(exp2_minus_22_f16)) <<
175 		std::hex << std::uppercase << std::setfill('0') <<
176 		"F16 = 0x" << std::setw(4) << exp2_minus_22_f16 << ", " <<
177 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(exp2_minus_22_f16) << ", " <<
178 		"F32 = 0x" << std::setw(8) << exp2_minus_22_f32;
179 
180 	EXPECT_EQ(exp2_minus_23_f32, fp16_alt_to_fp32_bits(exp2_minus_23_f16)) <<
181 		std::hex << std::uppercase << std::setfill('0') <<
182 		"F16 = 0x" << std::setw(4) << exp2_minus_23_f16 << ", " <<
183 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(exp2_minus_23_f16) << ", " <<
184 		"F32 = 0x" << std::setw(8) << exp2_minus_23_f32;
185 
186 	EXPECT_EQ(exp2_minus_24_f32, fp16_alt_to_fp32_bits(exp2_minus_24_f16)) <<
187 		std::hex << std::uppercase << std::setfill('0') <<
188 		"F16 = 0x" << std::setw(4) << exp2_minus_24_f16 << ", " <<
189 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(exp2_minus_24_f16) << ", " <<
190 		"F32 = 0x" << std::setw(8) << exp2_minus_24_f32;
191 }
192 
TEST(FP16_ALT_TO_FP32_BITS,zero)193 TEST(FP16_ALT_TO_FP32_BITS, zero) {
194 	const uint16_t positive_zero_f16 = UINT16_C(0x0000);
195 	const uint16_t negative_zero_f16 = UINT16_C(0x8000);
196 
197 	const uint32_t positive_zero_f32 = UINT32_C(0x00000000);
198 	const uint32_t negative_zero_f32 = UINT32_C(0x80000000);
199 
200 	EXPECT_EQ(positive_zero_f32, fp16_alt_to_fp32_bits(positive_zero_f16)) <<
201 		std::hex << std::uppercase << std::setfill('0') <<
202 		"F16 = 0x" << std::setw(4) << positive_zero_f16 << ", " <<
203 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(positive_zero_f16) << ", " <<
204 		"F32 = 0x" << std::setw(8) << positive_zero_f32;
205 
206 	EXPECT_EQ(negative_zero_f32, fp16_alt_to_fp32_bits(negative_zero_f16)) <<
207 		std::hex << std::uppercase << std::setfill('0') <<
208 		"F16 = 0x" << std::setw(4) << negative_zero_f16 << ", " <<
209 		"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(negative_zero_f16) << ", " <<
210 		"F32 = 0x" << std::setw(8) << negative_zero_f32;
211 }
212 
TEST(FP16_ALT_TO_FP32_BITS,positive_normalized_values)213 TEST(FP16_ALT_TO_FP32_BITS, positive_normalized_values) {
214 	const uint32_t exponentBias = 15;
215 	for (int32_t e = -14; e <= 16; e++) {
216 		for (uint16_t h = 0; h < 0x0400; h++) {
217 			const uint16_t fp16 = h + ((uint16_t) (e + exponentBias) << 10);
218 			const uint32_t fp32 = fp16::normalizedValues[h] + ((uint32_t) e << 23);
219 			EXPECT_EQ(fp32, fp16_alt_to_fp32_bits(fp16)) <<
220 				std::hex << std::uppercase << std::setfill('0') <<
221 				"F16 = 0x" << std::setw(4) << fp16 << ", " <<
222 				"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16) << ", " <<
223 				"F32 = 0x" << std::setw(8) << fp32;
224 		}
225 	}
226 }
227 
TEST(FP16_ALT_TO_FP32_BITS,negative_normalized_values)228 TEST(FP16_ALT_TO_FP32_BITS, negative_normalized_values) {
229 	const uint32_t exponentBias = 15;
230 	for (int32_t e = -14; e <= 16; e++) {
231 		for (uint16_t h = 0; h < 0x0400; h++) {
232 			const uint16_t fp16 = (h + ((uint16_t) (e + exponentBias) << 10)) ^ UINT16_C(0x8000);
233 			const uint32_t fp32 = (fp16::normalizedValues[h] + ((uint32_t) e << 23)) ^ UINT32_C(0x80000000);
234 			EXPECT_EQ(fp32, fp16_alt_to_fp32_bits(fp16)) <<
235 				std::hex << std::uppercase << std::setfill('0') <<
236 				"F16 = 0x" << std::setw(4) << fp16 << ", " <<
237 				"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16) << ", " <<
238 				"F32 = 0x" << std::setw(8) << fp32;
239 		}
240 	}
241 }
242 
TEST(FP16_ALT_TO_FP32_BITS,positive_denormalized_values)243 TEST(FP16_ALT_TO_FP32_BITS, positive_denormalized_values) {
244 	for (uint16_t h = 0; h < 0x0400; h++) {
245 		EXPECT_EQ(fp16::denormalizedValues[h], fp16_alt_to_fp32_bits(h)) <<
246 			std::hex << std::uppercase << std::setfill('0') <<
247 			"F16 = 0x" << std::setw(4) << h << ", " <<
248 			"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(h) << ", " <<
249 			"F32 = 0x" << std::setw(8) << fp16::denormalizedValues[h];
250 	}
251 }
252 
TEST(FP16_ALT_TO_FP32_BITS,negative_denormalized_values)253 TEST(FP16_ALT_TO_FP32_BITS, negative_denormalized_values) {
254 	for (uint16_t h = 0; h < 0x0400; h++) {
255 		const uint16_t fp16 = h ^ UINT16_C(0x8000);
256 		const uint32_t fp32 = fp16::denormalizedValues[h] ^ UINT32_C(0x80000000);
257 		EXPECT_EQ(fp32, fp16_alt_to_fp32_bits(fp16)) <<
258 			std::hex << std::uppercase << std::setfill('0') <<
259 			"F16 = 0x" << std::setw(4) << fp16 << ", " <<
260 			"F32(F16) = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16) << ", " <<
261 			"F32 = 0x" << std::setw(8) << fp32;
262 	}
263 }
264