1 #include <gtest/gtest.h>
2
3 #include <cstdint>
4
5 #include <fp16.h>
6 #include <fp16/psimd.h>
7
8
TEST(FP16_ALT_TO_FP32x2_PSIMD,positive_normalized_values)9 TEST(FP16_ALT_TO_FP32x2_PSIMD, positive_normalized_values) {
10 const uint32_t exponentBias = 15;
11 for (int32_t e = -14; e <= 16; e++) {
12 for (uint16_t h = 0; h < 0x0400; h += 8) {
13 const psimd_u16 fp16 = {
14 (uint16_t) (h + ((e + exponentBias) << 10) + 0),
15 (uint16_t) (h + ((e + exponentBias) << 10) + 1),
16 (uint16_t) (h + ((e + exponentBias) << 10) + 2),
17 (uint16_t) (h + ((e + exponentBias) << 10) + 3),
18 (uint16_t) (h + ((e + exponentBias) << 10) + 4),
19 (uint16_t) (h + ((e + exponentBias) << 10) + 5),
20 (uint16_t) (h + ((e + exponentBias) << 10) + 6),
21 (uint16_t) (h + ((e + exponentBias) << 10) + 7)
22 };
23 const psimd_u32x2 fp32 =
24 psimd_cast_f32x2_u32x2(fp16_alt_to_fp32x2_psimd(fp16));
25
26 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[0]), fp32.lo[0]) <<
27 std::hex << std::uppercase << std::setfill('0') <<
28 "F16 = 0x" << std::setw(4) << fp16[0] << ", " <<
29 "F32(F16) = 0x" << std::setw(8) << fp32.lo[0] << ", " <<
30 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[0]);
31 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[1]), fp32.lo[1]) <<
32 std::hex << std::uppercase << std::setfill('0') <<
33 "F16 = 0x" << std::setw(4) << fp16[1] << ", " <<
34 "F32(F16) = 0x" << std::setw(8) << fp32.lo[1] << ", " <<
35 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[1]);
36 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[2]), fp32.lo[2]) <<
37 std::hex << std::uppercase << std::setfill('0') <<
38 "F16 = 0x" << std::setw(4) << fp16[2] << ", " <<
39 "F32(F16) = 0x" << std::setw(8) << fp32.lo[2] << ", " <<
40 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[2]);
41 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[3]), fp32.lo[3]) <<
42 std::hex << std::uppercase << std::setfill('0') <<
43 "F16 = 0x" << std::setw(4) << fp16[3] << ", " <<
44 "F32(F16) = 0x" << std::setw(8) << fp32.lo[3] << ", " <<
45 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[3]);
46 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[4]), fp32.hi[0]) <<
47 std::hex << std::uppercase << std::setfill('0') <<
48 "F16 = 0x" << std::setw(4) << fp16[4] << ", " <<
49 "F32(F16) = 0x" << std::setw(8) << fp32.hi[0] << ", " <<
50 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[4]);
51 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[5]), fp32.hi[1]) <<
52 std::hex << std::uppercase << std::setfill('0') <<
53 "F16 = 0x" << std::setw(4) << fp16[5] << ", " <<
54 "F32(F16) = 0x" << std::setw(8) << fp32.hi[1] << ", " <<
55 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[5]);
56 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[6]), fp32.hi[2]) <<
57 std::hex << std::uppercase << std::setfill('0') <<
58 "F16 = 0x" << std::setw(4) << fp16[6] << ", " <<
59 "F32(F16) = 0x" << std::setw(8) << fp32.hi[2] << ", " <<
60 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[6]);
61 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[7]), fp32.hi[3]) <<
62 std::hex << std::uppercase << std::setfill('0') <<
63 "F16 = 0x" << std::setw(4) << fp16[7] << ", " <<
64 "F32(F16) = 0x" << std::setw(8) << fp32.hi[3] << ", " <<
65 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[7]);
66 }
67 }
68 }
69
TEST(FP16_ALT_TO_FP32x2_PSIMD,negative_normalized_values)70 TEST(FP16_ALT_TO_FP32x2_PSIMD, negative_normalized_values) {
71 const uint32_t exponentBias = 15;
72 for (int32_t e = -14; e <= 16; e++) {
73 for (uint16_t h = 0; h < 0x0400; h += 8) {
74 const psimd_u16 fp16 = {
75 (uint16_t) (h + ((e + exponentBias) << 10) + 0x8000),
76 (uint16_t) (h + ((e + exponentBias) << 10) + 0x8001),
77 (uint16_t) (h + ((e + exponentBias) << 10) + 0x8002),
78 (uint16_t) (h + ((e + exponentBias) << 10) + 0x8003),
79 (uint16_t) (h + ((e + exponentBias) << 10) + 0x8004),
80 (uint16_t) (h + ((e + exponentBias) << 10) + 0x8005),
81 (uint16_t) (h + ((e + exponentBias) << 10) + 0x8006),
82 (uint16_t) (h + ((e + exponentBias) << 10) + 0x8007)
83 };
84 const psimd_u32x2 fp32 =
85 psimd_cast_f32x2_u32x2(fp16_alt_to_fp32x2_psimd(fp16));
86
87 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[0]), fp32.lo[0]) <<
88 std::hex << std::uppercase << std::setfill('0') <<
89 "F16 = 0x" << std::setw(4) << fp16[0] << ", " <<
90 "F32(F16) = 0x" << std::setw(8) << fp32.lo[0] << ", " <<
91 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[0]);
92 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[1]), fp32.lo[1]) <<
93 std::hex << std::uppercase << std::setfill('0') <<
94 "F16 = 0x" << std::setw(4) << fp16[1] << ", " <<
95 "F32(F16) = 0x" << std::setw(8) << fp32.lo[1] << ", " <<
96 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[1]);
97 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[2]), fp32.lo[2]) <<
98 std::hex << std::uppercase << std::setfill('0') <<
99 "F16 = 0x" << std::setw(4) << fp16[2] << ", " <<
100 "F32(F16) = 0x" << std::setw(8) << fp32.lo[2] << ", " <<
101 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[2]);
102 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[3]), fp32.lo[3]) <<
103 std::hex << std::uppercase << std::setfill('0') <<
104 "F16 = 0x" << std::setw(4) << fp16[3] << ", " <<
105 "F32(F16) = 0x" << std::setw(8) << fp32.lo[3] << ", " <<
106 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[3]);
107 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[4]), fp32.hi[0]) <<
108 std::hex << std::uppercase << std::setfill('0') <<
109 "F16 = 0x" << std::setw(4) << fp16[4] << ", " <<
110 "F32(F16) = 0x" << std::setw(8) << fp32.hi[0] << ", " <<
111 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[4]);
112 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[5]), fp32.hi[1]) <<
113 std::hex << std::uppercase << std::setfill('0') <<
114 "F16 = 0x" << std::setw(4) << fp16[5] << ", " <<
115 "F32(F16) = 0x" << std::setw(8) << fp32.hi[1] << ", " <<
116 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[5]);
117 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[6]), fp32.hi[2]) <<
118 std::hex << std::uppercase << std::setfill('0') <<
119 "F16 = 0x" << std::setw(4) << fp16[6] << ", " <<
120 "F32(F16) = 0x" << std::setw(8) << fp32.hi[2] << ", " <<
121 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[6]);
122 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[7]), fp32.hi[3]) <<
123 std::hex << std::uppercase << std::setfill('0') <<
124 "F16 = 0x" << std::setw(4) << fp16[7] << ", " <<
125 "F32(F16) = 0x" << std::setw(8) << fp32.hi[3] << ", " <<
126 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[7]);
127 }
128 }
129 }
130
TEST(FP16_ALT_TO_FP32x2_PSIMD,positive_denormalized_values)131 TEST(FP16_ALT_TO_FP32x2_PSIMD, positive_denormalized_values) {
132 for (uint16_t h = 0; h < 0x0400; h += 8) {
133 const psimd_u16 fp16 = {
134 (uint16_t) (h + 0),
135 (uint16_t) (h + 1),
136 (uint16_t) (h + 2),
137 (uint16_t) (h + 3),
138 (uint16_t) (h + 4),
139 (uint16_t) (h + 5),
140 (uint16_t) (h + 6),
141 (uint16_t) (h + 7)
142 };
143 const psimd_u32x2 fp32 =
144 psimd_cast_f32x2_u32x2(fp16_alt_to_fp32x2_psimd(fp16));
145
146 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[0]), fp32.lo[0]) <<
147 std::hex << std::uppercase << std::setfill('0') <<
148 "F16 = 0x" << std::setw(4) << fp16[0] << ", " <<
149 "F32(F16) = 0x" << std::setw(8) << fp32.lo[0] << ", " <<
150 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[0]);
151 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[1]), fp32.lo[1]) <<
152 std::hex << std::uppercase << std::setfill('0') <<
153 "F16 = 0x" << std::setw(4) << fp16[1] << ", " <<
154 "F32(F16) = 0x" << std::setw(8) << fp32.lo[1] << ", " <<
155 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[1]);
156 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[2]), fp32.lo[2]) <<
157 std::hex << std::uppercase << std::setfill('0') <<
158 "F16 = 0x" << std::setw(4) << fp16[2] << ", " <<
159 "F32(F16) = 0x" << std::setw(8) << fp32.lo[2] << ", " <<
160 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[2]);
161 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[3]), fp32.lo[3]) <<
162 std::hex << std::uppercase << std::setfill('0') <<
163 "F16 = 0x" << std::setw(4) << fp16[3] << ", " <<
164 "F32(F16) = 0x" << std::setw(8) << fp32.lo[3] << ", " <<
165 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[3]);
166 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[4]), fp32.hi[0]) <<
167 std::hex << std::uppercase << std::setfill('0') <<
168 "F16 = 0x" << std::setw(4) << fp16[4] << ", " <<
169 "F32(F16) = 0x" << std::setw(8) << fp32.hi[0] << ", " <<
170 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[4]);
171 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[5]), fp32.hi[1]) <<
172 std::hex << std::uppercase << std::setfill('0') <<
173 "F16 = 0x" << std::setw(4) << fp16[5] << ", " <<
174 "F32(F16) = 0x" << std::setw(8) << fp32.hi[1] << ", " <<
175 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[5]);
176 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[6]), fp32.hi[2]) <<
177 std::hex << std::uppercase << std::setfill('0') <<
178 "F16 = 0x" << std::setw(4) << fp16[6] << ", " <<
179 "F32(F16) = 0x" << std::setw(8) << fp32.hi[2] << ", " <<
180 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[6]);
181 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[7]), fp32.hi[3]) <<
182 std::hex << std::uppercase << std::setfill('0') <<
183 "F16 = 0x" << std::setw(4) << fp16[7] << ", " <<
184 "F32(F16) = 0x" << std::setw(8) << fp32.hi[3] << ", " <<
185 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[7]);
186 }
187 }
188
TEST(FP16_ALT_TO_FP32x2_PSIMD,negative_denormalized_values)189 TEST(FP16_ALT_TO_FP32x2_PSIMD, negative_denormalized_values) {
190 for (uint16_t h = 0; h < 0x0400; h += 8) {
191 const psimd_u16 fp16 = {
192 (uint16_t) (h + 0x8000),
193 (uint16_t) (h + 0x8001),
194 (uint16_t) (h + 0x8002),
195 (uint16_t) (h + 0x8003),
196 (uint16_t) (h + 0x8004),
197 (uint16_t) (h + 0x8005),
198 (uint16_t) (h + 0x8006),
199 (uint16_t) (h + 0x8007)
200 };
201 const psimd_u32x2 fp32 =
202 psimd_cast_f32x2_u32x2(fp16_alt_to_fp32x2_psimd(fp16));
203
204 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[0]), fp32.lo[0]) <<
205 std::hex << std::uppercase << std::setfill('0') <<
206 "F16 = 0x" << std::setw(4) << fp16[0] << ", " <<
207 "F32(F16) = 0x" << std::setw(8) << fp32.lo[0] << ", " <<
208 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[0]);
209 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[1]), fp32.lo[1]) <<
210 std::hex << std::uppercase << std::setfill('0') <<
211 "F16 = 0x" << std::setw(4) << fp16[1] << ", " <<
212 "F32(F16) = 0x" << std::setw(8) << fp32.lo[1] << ", " <<
213 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[1]);
214 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[2]), fp32.lo[2]) <<
215 std::hex << std::uppercase << std::setfill('0') <<
216 "F16 = 0x" << std::setw(4) << fp16[2] << ", " <<
217 "F32(F16) = 0x" << std::setw(8) << fp32.lo[2] << ", " <<
218 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[2]);
219 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[3]), fp32.lo[3]) <<
220 std::hex << std::uppercase << std::setfill('0') <<
221 "F16 = 0x" << std::setw(4) << fp16[3] << ", " <<
222 "F32(F16) = 0x" << std::setw(8) << fp32.lo[3] << ", " <<
223 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[3]);
224 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[4]), fp32.hi[0]) <<
225 std::hex << std::uppercase << std::setfill('0') <<
226 "F16 = 0x" << std::setw(4) << fp16[4] << ", " <<
227 "F32(F16) = 0x" << std::setw(8) << fp32.hi[0] << ", " <<
228 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[4]);
229 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[5]), fp32.hi[1]) <<
230 std::hex << std::uppercase << std::setfill('0') <<
231 "F16 = 0x" << std::setw(4) << fp16[5] << ", " <<
232 "F32(F16) = 0x" << std::setw(8) << fp32.hi[1] << ", " <<
233 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[5]);
234 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[6]), fp32.hi[2]) <<
235 std::hex << std::uppercase << std::setfill('0') <<
236 "F16 = 0x" << std::setw(4) << fp16[6] << ", " <<
237 "F32(F16) = 0x" << std::setw(8) << fp32.hi[2] << ", " <<
238 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[6]);
239 EXPECT_EQ(fp16_alt_to_fp32_bits(fp16[7]), fp32.hi[3]) <<
240 std::hex << std::uppercase << std::setfill('0') <<
241 "F16 = 0x" << std::setw(4) << fp16[7] << ", " <<
242 "F32(F16) = 0x" << std::setw(8) << fp32.hi[3] << ", " <<
243 "F32 = 0x" << std::setw(8) << fp16_alt_to_fp32_bits(fp16[7]);
244 }
245 }
246