xref: /aosp_15_r20/external/XNNPACK/eval/f32-roundne.cc (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
1*4bdc9457SAndroid Build Coastguard Worker // Copyright 2020 Google LLC
2*4bdc9457SAndroid Build Coastguard Worker //
3*4bdc9457SAndroid Build Coastguard Worker // This source code is licensed under the BSD-style license found in the
4*4bdc9457SAndroid Build Coastguard Worker // LICENSE file in the root directory of this source tree.
5*4bdc9457SAndroid Build Coastguard Worker 
6*4bdc9457SAndroid Build Coastguard Worker #include <algorithm>
7*4bdc9457SAndroid Build Coastguard Worker #include <cmath>
8*4bdc9457SAndroid Build Coastguard Worker #include <cstddef>
9*4bdc9457SAndroid Build Coastguard Worker #include <cstdint>
10*4bdc9457SAndroid Build Coastguard Worker #include <cstdlib>
11*4bdc9457SAndroid Build Coastguard Worker #include <iomanip>
12*4bdc9457SAndroid Build Coastguard Worker #include <ios>
13*4bdc9457SAndroid Build Coastguard Worker #include <vector>
14*4bdc9457SAndroid Build Coastguard Worker 
15*4bdc9457SAndroid Build Coastguard Worker #include <gtest/gtest.h>
16*4bdc9457SAndroid Build Coastguard Worker 
17*4bdc9457SAndroid Build Coastguard Worker #include <fp16.h>
18*4bdc9457SAndroid Build Coastguard Worker 
19*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/aligned-allocator.h>
20*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/common.h>
21*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/math.h>
22*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/math-stubs.h>
23*4bdc9457SAndroid Build Coastguard Worker 
24*4bdc9457SAndroid Build Coastguard Worker 
25*4bdc9457SAndroid Build Coastguard Worker constexpr int kBlockSize = 1024;
26*4bdc9457SAndroid Build Coastguard Worker 
27*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_X86 || XNN_ARCH_X86_64
TEST(ROUNDNE__SSE_ADDSUB,positive_normal)28*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE_ADDSUB, positive_normal) {
29*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
30*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
31*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x00000000); n < UINT32_C(0x4B800000); n += kBlockSize) {
32*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
33*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
34*4bdc9457SAndroid Build Coastguard Worker       }
35*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
36*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
37*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
38*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
39*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
40*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
41*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
42*4bdc9457SAndroid Build Coastguard Worker       }
43*4bdc9457SAndroid Build Coastguard Worker     }
44*4bdc9457SAndroid Build Coastguard Worker   }
45*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE_ADDSUB,negative_normal)46*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE_ADDSUB, negative_normal) {
47*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
48*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
49*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x80000000); n < UINT32_C(0xCB800000); n += kBlockSize) {
50*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
51*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
52*4bdc9457SAndroid Build Coastguard Worker       }
53*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
54*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
55*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
56*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
57*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
58*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
59*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
60*4bdc9457SAndroid Build Coastguard Worker       }
61*4bdc9457SAndroid Build Coastguard Worker     }
62*4bdc9457SAndroid Build Coastguard Worker   }
63*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE_ADDSUB,positive_integral)64*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE_ADDSUB, positive_integral) {
65*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
66*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
67*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x4B800000); n < UINT32_C(0x7F800000); n += kBlockSize) {
68*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
69*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
70*4bdc9457SAndroid Build Coastguard Worker       }
71*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
72*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
73*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
74*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
75*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
76*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
77*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
78*4bdc9457SAndroid Build Coastguard Worker       }
79*4bdc9457SAndroid Build Coastguard Worker     }
80*4bdc9457SAndroid Build Coastguard Worker   }
81*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE_ADDSUB,negative_integral)82*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE_ADDSUB, negative_integral) {
83*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
84*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
85*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0xCB800000); n < UINT32_C(0xFF800000); n += kBlockSize) {
86*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
87*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
88*4bdc9457SAndroid Build Coastguard Worker       }
89*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
90*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
91*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
92*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
93*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
94*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
95*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
96*4bdc9457SAndroid Build Coastguard Worker       }
97*4bdc9457SAndroid Build Coastguard Worker     }
98*4bdc9457SAndroid Build Coastguard Worker   }
99*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE_ADDSUB,positive_infinity)100*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE_ADDSUB, positive_infinity) {
101*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
102*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
103*4bdc9457SAndroid Build Coastguard Worker     std::fill(inputs.begin(), inputs.end(), +std::numeric_limits<float>::infinity());
104*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__sse_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
105*4bdc9457SAndroid Build Coastguard Worker     const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
106*4bdc9457SAndroid Build Coastguard Worker     ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
107*4bdc9457SAndroid Build Coastguard Worker       << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
108*4bdc9457SAndroid Build Coastguard Worker       << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
109*4bdc9457SAndroid Build Coastguard Worker       << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
110*4bdc9457SAndroid Build Coastguard Worker   }
111*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE_ADDSUB,negative_infinity)112*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE_ADDSUB, negative_infinity) {
113*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
114*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
115*4bdc9457SAndroid Build Coastguard Worker     std::fill(inputs.begin(), inputs.end(), -std::numeric_limits<float>::infinity());
116*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__sse_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
117*4bdc9457SAndroid Build Coastguard Worker     const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
118*4bdc9457SAndroid Build Coastguard Worker     ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
119*4bdc9457SAndroid Build Coastguard Worker       << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
120*4bdc9457SAndroid Build Coastguard Worker       << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
121*4bdc9457SAndroid Build Coastguard Worker       << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
122*4bdc9457SAndroid Build Coastguard Worker   }
123*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE_ADDSUB,positive_qnan)124*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE_ADDSUB, positive_qnan) {
125*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
126*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
127*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
128*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
129*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
130*4bdc9457SAndroid Build Coastguard Worker       }
131*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
132*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
133*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
134*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
135*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
136*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
137*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
138*4bdc9457SAndroid Build Coastguard Worker       }
139*4bdc9457SAndroid Build Coastguard Worker     }
140*4bdc9457SAndroid Build Coastguard Worker   }
141*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE_ADDSUB,negative_qnan)142*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE_ADDSUB, negative_qnan) {
143*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
144*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
145*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
146*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
147*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | (n + i));
148*4bdc9457SAndroid Build Coastguard Worker       }
149*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
150*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
151*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
152*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
153*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
154*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
155*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
156*4bdc9457SAndroid Build Coastguard Worker       }
157*4bdc9457SAndroid Build Coastguard Worker     }
158*4bdc9457SAndroid Build Coastguard Worker   }
159*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE_ADDSUB,positive_snan)160*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE_ADDSUB, positive_snan) {
161*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
162*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
163*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
164*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
165*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
166*4bdc9457SAndroid Build Coastguard Worker       }
167*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
168*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
169*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
170*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
171*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
172*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
173*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
174*4bdc9457SAndroid Build Coastguard Worker       }
175*4bdc9457SAndroid Build Coastguard Worker     }
176*4bdc9457SAndroid Build Coastguard Worker   }
177*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE_ADDSUB,negative_snan)178*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE_ADDSUB, negative_snan) {
179*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
180*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
181*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
182*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
183*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
184*4bdc9457SAndroid Build Coastguard Worker       }
185*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
186*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
187*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
188*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
189*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
190*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
191*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
192*4bdc9457SAndroid Build Coastguard Worker       }
193*4bdc9457SAndroid Build Coastguard Worker     }
194*4bdc9457SAndroid Build Coastguard Worker   }
195*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE_ADDSUB,positive_snan_to_qnan)196*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE_ADDSUB, positive_snan_to_qnan) {
197*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
198*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
199*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
200*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
201*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
202*4bdc9457SAndroid Build Coastguard Worker       }
203*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
204*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
205*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
206*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
207*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
208*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
209*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
210*4bdc9457SAndroid Build Coastguard Worker       }
211*4bdc9457SAndroid Build Coastguard Worker     }
212*4bdc9457SAndroid Build Coastguard Worker   }
213*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE_ADDSUB,negative_snan_to_qnan)214*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE_ADDSUB, negative_snan_to_qnan) {
215*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
216*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
217*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
218*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
219*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
220*4bdc9457SAndroid Build Coastguard Worker       }
221*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
222*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
223*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
224*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
225*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
226*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
227*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
228*4bdc9457SAndroid Build Coastguard Worker       }
229*4bdc9457SAndroid Build Coastguard Worker     }
230*4bdc9457SAndroid Build Coastguard Worker   }
231*4bdc9457SAndroid Build Coastguard Worker #endif  // XNN_ARCH_X86 || XNN_ARCH_X86_64
232*4bdc9457SAndroid Build Coastguard Worker 
233*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_X86 || XNN_ARCH_X86_64
TEST(ROUNDNE__SSE2_CVT,positive_normal)234*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE2_CVT, positive_normal) {
235*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
236*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
237*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x00000000); n < UINT32_C(0x4B800000); n += kBlockSize) {
238*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
239*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
240*4bdc9457SAndroid Build Coastguard Worker       }
241*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse2_cvt(kBlockSize * sizeof(float), inputs.data(), outputs.data());
242*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
243*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
244*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
245*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
246*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
247*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
248*4bdc9457SAndroid Build Coastguard Worker       }
249*4bdc9457SAndroid Build Coastguard Worker     }
250*4bdc9457SAndroid Build Coastguard Worker   }
251*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE2_CVT,negative_normal)252*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE2_CVT, negative_normal) {
253*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
254*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
255*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x80000000); n < UINT32_C(0xCB800000); n += kBlockSize) {
256*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
257*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
258*4bdc9457SAndroid Build Coastguard Worker       }
259*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse2_cvt(kBlockSize * sizeof(float), inputs.data(), outputs.data());
260*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
261*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
262*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
263*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
264*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
265*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
266*4bdc9457SAndroid Build Coastguard Worker       }
267*4bdc9457SAndroid Build Coastguard Worker     }
268*4bdc9457SAndroid Build Coastguard Worker   }
269*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE2_CVT,positive_integral)270*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE2_CVT, positive_integral) {
271*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
272*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
273*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x4B800000); n < UINT32_C(0x7F800000); n += kBlockSize) {
274*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
275*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
276*4bdc9457SAndroid Build Coastguard Worker       }
277*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse2_cvt(kBlockSize * sizeof(float), inputs.data(), outputs.data());
278*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
279*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
280*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
281*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
282*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
283*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
284*4bdc9457SAndroid Build Coastguard Worker       }
285*4bdc9457SAndroid Build Coastguard Worker     }
286*4bdc9457SAndroid Build Coastguard Worker   }
287*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE2_CVT,negative_integral)288*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE2_CVT, negative_integral) {
289*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
290*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
291*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0xCB800000); n < UINT32_C(0xFF800000); n += kBlockSize) {
292*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
293*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
294*4bdc9457SAndroid Build Coastguard Worker       }
295*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse2_cvt(kBlockSize * sizeof(float), inputs.data(), outputs.data());
296*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
297*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
298*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
299*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
300*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
301*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
302*4bdc9457SAndroid Build Coastguard Worker       }
303*4bdc9457SAndroid Build Coastguard Worker     }
304*4bdc9457SAndroid Build Coastguard Worker   }
305*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE2_CVT,positive_infinity)306*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE2_CVT, positive_infinity) {
307*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
308*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
309*4bdc9457SAndroid Build Coastguard Worker     std::fill(inputs.begin(), inputs.end(), +std::numeric_limits<float>::infinity());
310*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__sse2_cvt(kBlockSize * sizeof(float), inputs.data(), outputs.data());
311*4bdc9457SAndroid Build Coastguard Worker     const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
312*4bdc9457SAndroid Build Coastguard Worker     ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
313*4bdc9457SAndroid Build Coastguard Worker       << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
314*4bdc9457SAndroid Build Coastguard Worker       << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
315*4bdc9457SAndroid Build Coastguard Worker       << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
316*4bdc9457SAndroid Build Coastguard Worker   }
317*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE2_CVT,negative_infinity)318*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE2_CVT, negative_infinity) {
319*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
320*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
321*4bdc9457SAndroid Build Coastguard Worker     std::fill(inputs.begin(), inputs.end(), -std::numeric_limits<float>::infinity());
322*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__sse2_cvt(kBlockSize * sizeof(float), inputs.data(), outputs.data());
323*4bdc9457SAndroid Build Coastguard Worker     const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
324*4bdc9457SAndroid Build Coastguard Worker     ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
325*4bdc9457SAndroid Build Coastguard Worker       << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
326*4bdc9457SAndroid Build Coastguard Worker       << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
327*4bdc9457SAndroid Build Coastguard Worker       << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
328*4bdc9457SAndroid Build Coastguard Worker   }
329*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE2_CVT,positive_qnan)330*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE2_CVT, positive_qnan) {
331*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
332*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
333*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
334*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
335*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
336*4bdc9457SAndroid Build Coastguard Worker       }
337*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse2_cvt(kBlockSize * sizeof(float), inputs.data(), outputs.data());
338*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
339*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
340*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
341*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
342*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
343*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
344*4bdc9457SAndroid Build Coastguard Worker       }
345*4bdc9457SAndroid Build Coastguard Worker     }
346*4bdc9457SAndroid Build Coastguard Worker   }
347*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE2_CVT,negative_qnan)348*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE2_CVT, negative_qnan) {
349*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
350*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
351*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
352*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
353*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | (n + i));
354*4bdc9457SAndroid Build Coastguard Worker       }
355*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse2_cvt(kBlockSize * sizeof(float), inputs.data(), outputs.data());
356*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
357*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
358*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
359*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
360*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
361*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
362*4bdc9457SAndroid Build Coastguard Worker       }
363*4bdc9457SAndroid Build Coastguard Worker     }
364*4bdc9457SAndroid Build Coastguard Worker   }
365*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE2_CVT,positive_snan)366*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE2_CVT, positive_snan) {
367*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
368*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
369*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
370*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
371*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
372*4bdc9457SAndroid Build Coastguard Worker       }
373*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse2_cvt(kBlockSize * sizeof(float), inputs.data(), outputs.data());
374*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
375*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
376*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
377*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
378*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
379*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
380*4bdc9457SAndroid Build Coastguard Worker       }
381*4bdc9457SAndroid Build Coastguard Worker     }
382*4bdc9457SAndroid Build Coastguard Worker   }
383*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE2_CVT,negative_snan)384*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE2_CVT, negative_snan) {
385*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
386*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
387*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
388*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
389*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
390*4bdc9457SAndroid Build Coastguard Worker       }
391*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse2_cvt(kBlockSize * sizeof(float), inputs.data(), outputs.data());
392*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
393*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
394*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
395*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
396*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
397*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
398*4bdc9457SAndroid Build Coastguard Worker       }
399*4bdc9457SAndroid Build Coastguard Worker     }
400*4bdc9457SAndroid Build Coastguard Worker   }
401*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE2_CVT,DISABLED_positive_snan_to_qnan)402*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE2_CVT, DISABLED_positive_snan_to_qnan) {
403*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
404*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
405*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
406*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
407*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
408*4bdc9457SAndroid Build Coastguard Worker       }
409*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse2_cvt(kBlockSize * sizeof(float), inputs.data(), outputs.data());
410*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
411*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
412*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
413*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
414*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
415*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
416*4bdc9457SAndroid Build Coastguard Worker       }
417*4bdc9457SAndroid Build Coastguard Worker     }
418*4bdc9457SAndroid Build Coastguard Worker   }
419*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE2_CVT,DISABLED_negative_snan_to_qnan)420*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE2_CVT, DISABLED_negative_snan_to_qnan) {
421*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
422*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
423*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
424*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
425*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
426*4bdc9457SAndroid Build Coastguard Worker       }
427*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse2_cvt(kBlockSize * sizeof(float), inputs.data(), outputs.data());
428*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
429*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
430*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
431*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
432*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
433*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
434*4bdc9457SAndroid Build Coastguard Worker       }
435*4bdc9457SAndroid Build Coastguard Worker     }
436*4bdc9457SAndroid Build Coastguard Worker   }
437*4bdc9457SAndroid Build Coastguard Worker #endif  // XNN_ARCH_X86 || XNN_ARCH_X86_64
438*4bdc9457SAndroid Build Coastguard Worker 
439*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_X86 || XNN_ARCH_X86_64
TEST(ROUNDNE__SSE41,positive_normal)440*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE41, positive_normal) {
441*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
442*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
443*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x00000000); n < UINT32_C(0x4B800000); n += kBlockSize) {
444*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
445*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
446*4bdc9457SAndroid Build Coastguard Worker       }
447*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse41(kBlockSize * sizeof(float), inputs.data(), outputs.data());
448*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
449*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
450*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
451*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
452*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
453*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
454*4bdc9457SAndroid Build Coastguard Worker       }
455*4bdc9457SAndroid Build Coastguard Worker     }
456*4bdc9457SAndroid Build Coastguard Worker   }
457*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE41,negative_normal)458*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE41, negative_normal) {
459*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
460*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
461*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x80000000); n < UINT32_C(0xCB800000); n += kBlockSize) {
462*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
463*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
464*4bdc9457SAndroid Build Coastguard Worker       }
465*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse41(kBlockSize * sizeof(float), inputs.data(), outputs.data());
466*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
467*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
468*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
469*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
470*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
471*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
472*4bdc9457SAndroid Build Coastguard Worker       }
473*4bdc9457SAndroid Build Coastguard Worker     }
474*4bdc9457SAndroid Build Coastguard Worker   }
475*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE41,positive_integral)476*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE41, positive_integral) {
477*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
478*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
479*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x4B800000); n < UINT32_C(0x7F800000); n += kBlockSize) {
480*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
481*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
482*4bdc9457SAndroid Build Coastguard Worker       }
483*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse41(kBlockSize * sizeof(float), inputs.data(), outputs.data());
484*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
485*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
486*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
487*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
488*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
489*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
490*4bdc9457SAndroid Build Coastguard Worker       }
491*4bdc9457SAndroid Build Coastguard Worker     }
492*4bdc9457SAndroid Build Coastguard Worker   }
493*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE41,negative_integral)494*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE41, negative_integral) {
495*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
496*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
497*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0xCB800000); n < UINT32_C(0xFF800000); n += kBlockSize) {
498*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
499*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
500*4bdc9457SAndroid Build Coastguard Worker       }
501*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse41(kBlockSize * sizeof(float), inputs.data(), outputs.data());
502*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
503*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
504*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
505*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
506*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
507*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
508*4bdc9457SAndroid Build Coastguard Worker       }
509*4bdc9457SAndroid Build Coastguard Worker     }
510*4bdc9457SAndroid Build Coastguard Worker   }
511*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE41,positive_infinity)512*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE41, positive_infinity) {
513*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
514*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
515*4bdc9457SAndroid Build Coastguard Worker     std::fill(inputs.begin(), inputs.end(), +std::numeric_limits<float>::infinity());
516*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__sse41(kBlockSize * sizeof(float), inputs.data(), outputs.data());
517*4bdc9457SAndroid Build Coastguard Worker     const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
518*4bdc9457SAndroid Build Coastguard Worker     ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
519*4bdc9457SAndroid Build Coastguard Worker       << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
520*4bdc9457SAndroid Build Coastguard Worker       << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
521*4bdc9457SAndroid Build Coastguard Worker       << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
522*4bdc9457SAndroid Build Coastguard Worker   }
523*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE41,negative_infinity)524*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE41, negative_infinity) {
525*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
526*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
527*4bdc9457SAndroid Build Coastguard Worker     std::fill(inputs.begin(), inputs.end(), -std::numeric_limits<float>::infinity());
528*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__sse41(kBlockSize * sizeof(float), inputs.data(), outputs.data());
529*4bdc9457SAndroid Build Coastguard Worker     const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
530*4bdc9457SAndroid Build Coastguard Worker     ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
531*4bdc9457SAndroid Build Coastguard Worker       << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
532*4bdc9457SAndroid Build Coastguard Worker       << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
533*4bdc9457SAndroid Build Coastguard Worker       << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
534*4bdc9457SAndroid Build Coastguard Worker   }
535*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE41,positive_qnan)536*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE41, positive_qnan) {
537*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
538*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
539*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
540*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
541*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
542*4bdc9457SAndroid Build Coastguard Worker       }
543*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse41(kBlockSize * sizeof(float), inputs.data(), outputs.data());
544*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
545*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
546*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
547*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
548*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
549*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
550*4bdc9457SAndroid Build Coastguard Worker       }
551*4bdc9457SAndroid Build Coastguard Worker     }
552*4bdc9457SAndroid Build Coastguard Worker   }
553*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE41,negative_qnan)554*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE41, negative_qnan) {
555*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
556*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
557*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
558*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
559*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | (n + i));
560*4bdc9457SAndroid Build Coastguard Worker       }
561*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse41(kBlockSize * sizeof(float), inputs.data(), outputs.data());
562*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
563*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
564*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
565*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
566*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
567*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
568*4bdc9457SAndroid Build Coastguard Worker       }
569*4bdc9457SAndroid Build Coastguard Worker     }
570*4bdc9457SAndroid Build Coastguard Worker   }
571*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE41,positive_snan)572*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE41, positive_snan) {
573*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
574*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
575*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
576*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
577*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
578*4bdc9457SAndroid Build Coastguard Worker       }
579*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse41(kBlockSize * sizeof(float), inputs.data(), outputs.data());
580*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
581*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
582*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
583*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
584*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
585*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
586*4bdc9457SAndroid Build Coastguard Worker       }
587*4bdc9457SAndroid Build Coastguard Worker     }
588*4bdc9457SAndroid Build Coastguard Worker   }
589*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE41,negative_snan)590*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE41, negative_snan) {
591*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
592*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
593*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
594*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
595*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
596*4bdc9457SAndroid Build Coastguard Worker       }
597*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse41(kBlockSize * sizeof(float), inputs.data(), outputs.data());
598*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
599*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
600*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
601*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
602*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
603*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
604*4bdc9457SAndroid Build Coastguard Worker       }
605*4bdc9457SAndroid Build Coastguard Worker     }
606*4bdc9457SAndroid Build Coastguard Worker   }
607*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE41,positive_snan_to_qnan)608*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE41, positive_snan_to_qnan) {
609*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
610*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
611*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
612*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
613*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
614*4bdc9457SAndroid Build Coastguard Worker       }
615*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse41(kBlockSize * sizeof(float), inputs.data(), outputs.data());
616*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
617*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
618*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
619*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
620*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
621*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
622*4bdc9457SAndroid Build Coastguard Worker       }
623*4bdc9457SAndroid Build Coastguard Worker     }
624*4bdc9457SAndroid Build Coastguard Worker   }
625*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SSE41,negative_snan_to_qnan)626*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__SSE41, negative_snan_to_qnan) {
627*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
628*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
629*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
630*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
631*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
632*4bdc9457SAndroid Build Coastguard Worker       }
633*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__sse41(kBlockSize * sizeof(float), inputs.data(), outputs.data());
634*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
635*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
636*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
637*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
638*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
639*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
640*4bdc9457SAndroid Build Coastguard Worker       }
641*4bdc9457SAndroid Build Coastguard Worker     }
642*4bdc9457SAndroid Build Coastguard Worker   }
643*4bdc9457SAndroid Build Coastguard Worker #endif  // XNN_ARCH_X86 || XNN_ARCH_X86_64
644*4bdc9457SAndroid Build Coastguard Worker 
645*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_ARM || XNN_ARCH_ARM64
TEST(ROUNDNE__NEON_ADDSUB,positive_normal)646*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEON_ADDSUB, positive_normal) {
647*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
648*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
649*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x00000000); n < UINT32_C(0x4B800000); n += kBlockSize) {
650*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
651*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
652*4bdc9457SAndroid Build Coastguard Worker       }
653*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neon_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
654*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
655*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
656*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
657*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
658*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
659*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
660*4bdc9457SAndroid Build Coastguard Worker       }
661*4bdc9457SAndroid Build Coastguard Worker     }
662*4bdc9457SAndroid Build Coastguard Worker   }
663*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEON_ADDSUB,negative_normal)664*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEON_ADDSUB, negative_normal) {
665*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
666*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
667*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x80000000); n < UINT32_C(0xCB800000); n += kBlockSize) {
668*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
669*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
670*4bdc9457SAndroid Build Coastguard Worker       }
671*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neon_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
672*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
673*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
674*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
675*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
676*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
677*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
678*4bdc9457SAndroid Build Coastguard Worker       }
679*4bdc9457SAndroid Build Coastguard Worker     }
680*4bdc9457SAndroid Build Coastguard Worker   }
681*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEON_ADDSUB,positive_integral)682*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEON_ADDSUB, positive_integral) {
683*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
684*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
685*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x4B800000); n < UINT32_C(0x7F800000); n += kBlockSize) {
686*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
687*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
688*4bdc9457SAndroid Build Coastguard Worker       }
689*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neon_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
690*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
691*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
692*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
693*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
694*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
695*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
696*4bdc9457SAndroid Build Coastguard Worker       }
697*4bdc9457SAndroid Build Coastguard Worker     }
698*4bdc9457SAndroid Build Coastguard Worker   }
699*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEON_ADDSUB,negative_integral)700*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEON_ADDSUB, negative_integral) {
701*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
702*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
703*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0xCB800000); n < UINT32_C(0xFF800000); n += kBlockSize) {
704*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
705*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
706*4bdc9457SAndroid Build Coastguard Worker       }
707*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neon_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
708*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
709*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
710*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
711*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
712*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
713*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
714*4bdc9457SAndroid Build Coastguard Worker       }
715*4bdc9457SAndroid Build Coastguard Worker     }
716*4bdc9457SAndroid Build Coastguard Worker   }
717*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEON_ADDSUB,positive_infinity)718*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEON_ADDSUB, positive_infinity) {
719*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
720*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
721*4bdc9457SAndroid Build Coastguard Worker     std::fill(inputs.begin(), inputs.end(), +std::numeric_limits<float>::infinity());
722*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__neon_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
723*4bdc9457SAndroid Build Coastguard Worker     const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
724*4bdc9457SAndroid Build Coastguard Worker     ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
725*4bdc9457SAndroid Build Coastguard Worker       << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
726*4bdc9457SAndroid Build Coastguard Worker       << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
727*4bdc9457SAndroid Build Coastguard Worker       << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
728*4bdc9457SAndroid Build Coastguard Worker   }
729*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEON_ADDSUB,negative_infinity)730*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEON_ADDSUB, negative_infinity) {
731*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
732*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
733*4bdc9457SAndroid Build Coastguard Worker     std::fill(inputs.begin(), inputs.end(), -std::numeric_limits<float>::infinity());
734*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__neon_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
735*4bdc9457SAndroid Build Coastguard Worker     const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
736*4bdc9457SAndroid Build Coastguard Worker     ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
737*4bdc9457SAndroid Build Coastguard Worker       << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
738*4bdc9457SAndroid Build Coastguard Worker       << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
739*4bdc9457SAndroid Build Coastguard Worker       << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
740*4bdc9457SAndroid Build Coastguard Worker   }
741*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEON_ADDSUB,positive_qnan)742*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEON_ADDSUB, positive_qnan) {
743*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
744*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
745*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
746*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
747*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
748*4bdc9457SAndroid Build Coastguard Worker       }
749*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neon_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
750*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
751*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
752*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
753*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
754*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
755*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
756*4bdc9457SAndroid Build Coastguard Worker       }
757*4bdc9457SAndroid Build Coastguard Worker     }
758*4bdc9457SAndroid Build Coastguard Worker   }
759*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEON_ADDSUB,negative_qnan)760*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEON_ADDSUB, negative_qnan) {
761*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
762*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
763*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
764*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
765*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | (n + i));
766*4bdc9457SAndroid Build Coastguard Worker       }
767*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neon_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
768*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
769*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
770*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
771*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
772*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
773*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
774*4bdc9457SAndroid Build Coastguard Worker       }
775*4bdc9457SAndroid Build Coastguard Worker     }
776*4bdc9457SAndroid Build Coastguard Worker   }
777*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEON_ADDSUB,positive_snan)778*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEON_ADDSUB, positive_snan) {
779*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
780*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
781*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
782*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
783*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
784*4bdc9457SAndroid Build Coastguard Worker       }
785*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neon_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
786*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
787*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
788*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
789*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
790*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
791*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
792*4bdc9457SAndroid Build Coastguard Worker       }
793*4bdc9457SAndroid Build Coastguard Worker     }
794*4bdc9457SAndroid Build Coastguard Worker   }
795*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEON_ADDSUB,negative_snan)796*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEON_ADDSUB, negative_snan) {
797*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
798*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
799*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
800*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
801*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
802*4bdc9457SAndroid Build Coastguard Worker       }
803*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neon_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
804*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
805*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
806*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
807*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
808*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
809*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
810*4bdc9457SAndroid Build Coastguard Worker       }
811*4bdc9457SAndroid Build Coastguard Worker     }
812*4bdc9457SAndroid Build Coastguard Worker   }
813*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEON_ADDSUB,positive_snan_to_qnan)814*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEON_ADDSUB, positive_snan_to_qnan) {
815*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
816*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
817*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
818*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
819*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
820*4bdc9457SAndroid Build Coastguard Worker       }
821*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neon_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
822*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
823*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
824*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
825*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
826*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
827*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
828*4bdc9457SAndroid Build Coastguard Worker       }
829*4bdc9457SAndroid Build Coastguard Worker     }
830*4bdc9457SAndroid Build Coastguard Worker   }
831*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEON_ADDSUB,negative_snan_to_qnan)832*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEON_ADDSUB, negative_snan_to_qnan) {
833*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
834*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
835*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
836*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
837*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
838*4bdc9457SAndroid Build Coastguard Worker       }
839*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neon_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
840*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
841*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
842*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
843*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
844*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
845*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
846*4bdc9457SAndroid Build Coastguard Worker       }
847*4bdc9457SAndroid Build Coastguard Worker     }
848*4bdc9457SAndroid Build Coastguard Worker   }
849*4bdc9457SAndroid Build Coastguard Worker #endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
850*4bdc9457SAndroid Build Coastguard Worker 
851*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_ARM || XNN_ARCH_ARM64
TEST(ROUNDNE__NEONV8,positive_normal)852*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEONV8, positive_normal) {
853*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
854*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
855*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x00000000); n < UINT32_C(0x4B800000); n += kBlockSize) {
856*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
857*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
858*4bdc9457SAndroid Build Coastguard Worker       }
859*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neonv8(kBlockSize * sizeof(float), inputs.data(), outputs.data());
860*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
861*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
862*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
863*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
864*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
865*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
866*4bdc9457SAndroid Build Coastguard Worker       }
867*4bdc9457SAndroid Build Coastguard Worker     }
868*4bdc9457SAndroid Build Coastguard Worker   }
869*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEONV8,negative_normal)870*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEONV8, negative_normal) {
871*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
872*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
873*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x80000000); n < UINT32_C(0xCB800000); n += kBlockSize) {
874*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
875*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
876*4bdc9457SAndroid Build Coastguard Worker       }
877*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neonv8(kBlockSize * sizeof(float), inputs.data(), outputs.data());
878*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
879*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
880*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
881*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
882*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
883*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
884*4bdc9457SAndroid Build Coastguard Worker       }
885*4bdc9457SAndroid Build Coastguard Worker     }
886*4bdc9457SAndroid Build Coastguard Worker   }
887*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEONV8,positive_integral)888*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEONV8, positive_integral) {
889*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
890*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
891*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x4B800000); n < UINT32_C(0x7F800000); n += kBlockSize) {
892*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
893*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
894*4bdc9457SAndroid Build Coastguard Worker       }
895*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neonv8(kBlockSize * sizeof(float), inputs.data(), outputs.data());
896*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
897*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
898*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
899*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
900*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
901*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
902*4bdc9457SAndroid Build Coastguard Worker       }
903*4bdc9457SAndroid Build Coastguard Worker     }
904*4bdc9457SAndroid Build Coastguard Worker   }
905*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEONV8,negative_integral)906*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEONV8, negative_integral) {
907*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
908*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
909*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0xCB800000); n < UINT32_C(0xFF800000); n += kBlockSize) {
910*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
911*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
912*4bdc9457SAndroid Build Coastguard Worker       }
913*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neonv8(kBlockSize * sizeof(float), inputs.data(), outputs.data());
914*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
915*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
916*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
917*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
918*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
919*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
920*4bdc9457SAndroid Build Coastguard Worker       }
921*4bdc9457SAndroid Build Coastguard Worker     }
922*4bdc9457SAndroid Build Coastguard Worker   }
923*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEONV8,positive_infinity)924*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEONV8, positive_infinity) {
925*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
926*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
927*4bdc9457SAndroid Build Coastguard Worker     std::fill(inputs.begin(), inputs.end(), +std::numeric_limits<float>::infinity());
928*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__neonv8(kBlockSize * sizeof(float), inputs.data(), outputs.data());
929*4bdc9457SAndroid Build Coastguard Worker     const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
930*4bdc9457SAndroid Build Coastguard Worker     ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
931*4bdc9457SAndroid Build Coastguard Worker       << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
932*4bdc9457SAndroid Build Coastguard Worker       << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
933*4bdc9457SAndroid Build Coastguard Worker       << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
934*4bdc9457SAndroid Build Coastguard Worker   }
935*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEONV8,negative_infinity)936*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEONV8, negative_infinity) {
937*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
938*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
939*4bdc9457SAndroid Build Coastguard Worker     std::fill(inputs.begin(), inputs.end(), -std::numeric_limits<float>::infinity());
940*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__neonv8(kBlockSize * sizeof(float), inputs.data(), outputs.data());
941*4bdc9457SAndroid Build Coastguard Worker     const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
942*4bdc9457SAndroid Build Coastguard Worker     ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
943*4bdc9457SAndroid Build Coastguard Worker       << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
944*4bdc9457SAndroid Build Coastguard Worker       << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
945*4bdc9457SAndroid Build Coastguard Worker       << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
946*4bdc9457SAndroid Build Coastguard Worker   }
947*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEONV8,positive_qnan)948*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEONV8, positive_qnan) {
949*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
950*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
951*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
952*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
953*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
954*4bdc9457SAndroid Build Coastguard Worker       }
955*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neonv8(kBlockSize * sizeof(float), inputs.data(), outputs.data());
956*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
957*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
958*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
959*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
960*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
961*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
962*4bdc9457SAndroid Build Coastguard Worker       }
963*4bdc9457SAndroid Build Coastguard Worker     }
964*4bdc9457SAndroid Build Coastguard Worker   }
965*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEONV8,negative_qnan)966*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEONV8, negative_qnan) {
967*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
968*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
969*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
970*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
971*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | (n + i));
972*4bdc9457SAndroid Build Coastguard Worker       }
973*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neonv8(kBlockSize * sizeof(float), inputs.data(), outputs.data());
974*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
975*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
976*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
977*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
978*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
979*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
980*4bdc9457SAndroid Build Coastguard Worker       }
981*4bdc9457SAndroid Build Coastguard Worker     }
982*4bdc9457SAndroid Build Coastguard Worker   }
983*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEONV8,positive_snan)984*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEONV8, positive_snan) {
985*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
986*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
987*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
988*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
989*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
990*4bdc9457SAndroid Build Coastguard Worker       }
991*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neonv8(kBlockSize * sizeof(float), inputs.data(), outputs.data());
992*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
993*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
994*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
995*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
996*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
997*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
998*4bdc9457SAndroid Build Coastguard Worker       }
999*4bdc9457SAndroid Build Coastguard Worker     }
1000*4bdc9457SAndroid Build Coastguard Worker   }
1001*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEONV8,negative_snan)1002*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEONV8, negative_snan) {
1003*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1004*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1005*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1006*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1007*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1008*4bdc9457SAndroid Build Coastguard Worker       }
1009*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neonv8(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1010*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1011*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1012*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
1013*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1014*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1015*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1016*4bdc9457SAndroid Build Coastguard Worker       }
1017*4bdc9457SAndroid Build Coastguard Worker     }
1018*4bdc9457SAndroid Build Coastguard Worker   }
1019*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEONV8,positive_snan_to_qnan)1020*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEONV8, positive_snan_to_qnan) {
1021*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1022*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1023*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1024*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1025*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1026*4bdc9457SAndroid Build Coastguard Worker       }
1027*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neonv8(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1028*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1029*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1030*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1031*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1032*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1033*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1034*4bdc9457SAndroid Build Coastguard Worker       }
1035*4bdc9457SAndroid Build Coastguard Worker     }
1036*4bdc9457SAndroid Build Coastguard Worker   }
1037*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__NEONV8,negative_snan_to_qnan)1038*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__NEONV8, negative_snan_to_qnan) {
1039*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1040*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1041*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1042*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1043*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1044*4bdc9457SAndroid Build Coastguard Worker       }
1045*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__neonv8(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1046*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1047*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1048*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1049*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1050*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1051*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1052*4bdc9457SAndroid Build Coastguard Worker       }
1053*4bdc9457SAndroid Build Coastguard Worker     }
1054*4bdc9457SAndroid Build Coastguard Worker   }
1055*4bdc9457SAndroid Build Coastguard Worker #endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
1056*4bdc9457SAndroid Build Coastguard Worker 
1057*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_WASMSIMD || XNN_ARCH_WASMRELAXEDSIMD
TEST(ROUNDNE__WASMSIMD_ADDSUB,positive_normal)1058*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_ADDSUB, positive_normal) {
1059*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1060*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1061*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x00000000); n < UINT32_C(0x4B800000); n += kBlockSize) {
1062*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1063*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
1064*4bdc9457SAndroid Build Coastguard Worker       }
1065*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1066*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1067*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1068*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1069*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1070*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1071*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1072*4bdc9457SAndroid Build Coastguard Worker       }
1073*4bdc9457SAndroid Build Coastguard Worker     }
1074*4bdc9457SAndroid Build Coastguard Worker   }
1075*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_ADDSUB,negative_normal)1076*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_ADDSUB, negative_normal) {
1077*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1078*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1079*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x80000000); n < UINT32_C(0xCB800000); n += kBlockSize) {
1080*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1081*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
1082*4bdc9457SAndroid Build Coastguard Worker       }
1083*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1084*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1085*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1086*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1087*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1088*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1089*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1090*4bdc9457SAndroid Build Coastguard Worker       }
1091*4bdc9457SAndroid Build Coastguard Worker     }
1092*4bdc9457SAndroid Build Coastguard Worker   }
1093*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_ADDSUB,positive_integral)1094*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_ADDSUB, positive_integral) {
1095*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1096*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1097*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x4B800000); n < UINT32_C(0x7F800000); n += kBlockSize) {
1098*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1099*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
1100*4bdc9457SAndroid Build Coastguard Worker       }
1101*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1102*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1103*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1104*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1105*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1106*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1107*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1108*4bdc9457SAndroid Build Coastguard Worker       }
1109*4bdc9457SAndroid Build Coastguard Worker     }
1110*4bdc9457SAndroid Build Coastguard Worker   }
1111*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_ADDSUB,negative_integral)1112*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_ADDSUB, negative_integral) {
1113*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1114*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1115*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0xCB800000); n < UINT32_C(0xFF800000); n += kBlockSize) {
1116*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1117*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
1118*4bdc9457SAndroid Build Coastguard Worker       }
1119*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1120*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1121*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1122*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1123*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1124*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1125*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1126*4bdc9457SAndroid Build Coastguard Worker       }
1127*4bdc9457SAndroid Build Coastguard Worker     }
1128*4bdc9457SAndroid Build Coastguard Worker   }
1129*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_ADDSUB,positive_infinity)1130*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_ADDSUB, positive_infinity) {
1131*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1132*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1133*4bdc9457SAndroid Build Coastguard Worker     std::fill(inputs.begin(), inputs.end(), +std::numeric_limits<float>::infinity());
1134*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__wasmsimd_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1135*4bdc9457SAndroid Build Coastguard Worker     const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
1136*4bdc9457SAndroid Build Coastguard Worker     ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
1137*4bdc9457SAndroid Build Coastguard Worker       << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
1138*4bdc9457SAndroid Build Coastguard Worker       << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1139*4bdc9457SAndroid Build Coastguard Worker       << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
1140*4bdc9457SAndroid Build Coastguard Worker   }
1141*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_ADDSUB,negative_infinity)1142*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_ADDSUB, negative_infinity) {
1143*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1144*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1145*4bdc9457SAndroid Build Coastguard Worker     std::fill(inputs.begin(), inputs.end(), -std::numeric_limits<float>::infinity());
1146*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__wasmsimd_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1147*4bdc9457SAndroid Build Coastguard Worker     const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
1148*4bdc9457SAndroid Build Coastguard Worker     ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
1149*4bdc9457SAndroid Build Coastguard Worker       << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
1150*4bdc9457SAndroid Build Coastguard Worker       << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1151*4bdc9457SAndroid Build Coastguard Worker       << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
1152*4bdc9457SAndroid Build Coastguard Worker   }
1153*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_ADDSUB,positive_qnan)1154*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_ADDSUB, positive_qnan) {
1155*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1156*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1157*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
1158*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1159*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
1160*4bdc9457SAndroid Build Coastguard Worker       }
1161*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1162*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1163*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1164*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1165*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1166*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1167*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1168*4bdc9457SAndroid Build Coastguard Worker       }
1169*4bdc9457SAndroid Build Coastguard Worker     }
1170*4bdc9457SAndroid Build Coastguard Worker   }
1171*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_ADDSUB,negative_qnan)1172*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_ADDSUB, negative_qnan) {
1173*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1174*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1175*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
1176*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1177*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | (n + i));
1178*4bdc9457SAndroid Build Coastguard Worker       }
1179*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1180*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1181*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1182*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1183*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1184*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1185*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1186*4bdc9457SAndroid Build Coastguard Worker       }
1187*4bdc9457SAndroid Build Coastguard Worker     }
1188*4bdc9457SAndroid Build Coastguard Worker   }
1189*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_ADDSUB,positive_snan)1190*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_ADDSUB, positive_snan) {
1191*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1192*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1193*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1194*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1195*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1196*4bdc9457SAndroid Build Coastguard Worker       }
1197*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1198*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1199*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1200*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
1201*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1202*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1203*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1204*4bdc9457SAndroid Build Coastguard Worker       }
1205*4bdc9457SAndroid Build Coastguard Worker     }
1206*4bdc9457SAndroid Build Coastguard Worker   }
1207*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_ADDSUB,negative_snan)1208*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_ADDSUB, negative_snan) {
1209*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1210*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1211*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1212*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1213*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1214*4bdc9457SAndroid Build Coastguard Worker       }
1215*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1216*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1217*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1218*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
1219*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1220*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1221*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1222*4bdc9457SAndroid Build Coastguard Worker       }
1223*4bdc9457SAndroid Build Coastguard Worker     }
1224*4bdc9457SAndroid Build Coastguard Worker   }
1225*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_ADDSUB,positive_snan_to_qnan)1226*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_ADDSUB, positive_snan_to_qnan) {
1227*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1228*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1229*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1230*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1231*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1232*4bdc9457SAndroid Build Coastguard Worker       }
1233*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1234*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1235*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1236*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1237*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1238*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1239*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1240*4bdc9457SAndroid Build Coastguard Worker       }
1241*4bdc9457SAndroid Build Coastguard Worker     }
1242*4bdc9457SAndroid Build Coastguard Worker   }
1243*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_ADDSUB,negative_snan_to_qnan)1244*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_ADDSUB, negative_snan_to_qnan) {
1245*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1246*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1247*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1248*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1249*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1250*4bdc9457SAndroid Build Coastguard Worker       }
1251*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1252*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1253*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1254*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1255*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1256*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1257*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1258*4bdc9457SAndroid Build Coastguard Worker       }
1259*4bdc9457SAndroid Build Coastguard Worker     }
1260*4bdc9457SAndroid Build Coastguard Worker   }
1261*4bdc9457SAndroid Build Coastguard Worker #endif  // XNN_ARCH_WASMSIMD || XNN_ARCH_WASMRELAXEDSIMD
1262*4bdc9457SAndroid Build Coastguard Worker 
1263*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_WASMSIMD || XNN_ARCH_WASMRELAXEDSIMD
TEST(ROUNDNE__WASMSIMD_NATIVE,positive_normal)1264*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_NATIVE, positive_normal) {
1265*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1266*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1267*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x00000000); n < UINT32_C(0x4B800000); n += kBlockSize) {
1268*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1269*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
1270*4bdc9457SAndroid Build Coastguard Worker       }
1271*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_native(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1272*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1273*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1274*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1275*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1276*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1277*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1278*4bdc9457SAndroid Build Coastguard Worker       }
1279*4bdc9457SAndroid Build Coastguard Worker     }
1280*4bdc9457SAndroid Build Coastguard Worker   }
1281*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_NATIVE,negative_normal)1282*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_NATIVE, negative_normal) {
1283*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1284*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1285*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x80000000); n < UINT32_C(0xCB800000); n += kBlockSize) {
1286*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1287*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
1288*4bdc9457SAndroid Build Coastguard Worker       }
1289*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_native(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1290*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1291*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1292*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1293*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1294*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1295*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1296*4bdc9457SAndroid Build Coastguard Worker       }
1297*4bdc9457SAndroid Build Coastguard Worker     }
1298*4bdc9457SAndroid Build Coastguard Worker   }
1299*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_NATIVE,positive_integral)1300*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_NATIVE, positive_integral) {
1301*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1302*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1303*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x4B800000); n < UINT32_C(0x7F800000); n += kBlockSize) {
1304*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1305*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
1306*4bdc9457SAndroid Build Coastguard Worker       }
1307*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_native(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1308*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1309*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1310*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1311*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1312*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1313*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1314*4bdc9457SAndroid Build Coastguard Worker       }
1315*4bdc9457SAndroid Build Coastguard Worker     }
1316*4bdc9457SAndroid Build Coastguard Worker   }
1317*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_NATIVE,negative_integral)1318*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_NATIVE, negative_integral) {
1319*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1320*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1321*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0xCB800000); n < UINT32_C(0xFF800000); n += kBlockSize) {
1322*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1323*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
1324*4bdc9457SAndroid Build Coastguard Worker       }
1325*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_native(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1326*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1327*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1328*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1329*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1330*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1331*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1332*4bdc9457SAndroid Build Coastguard Worker       }
1333*4bdc9457SAndroid Build Coastguard Worker     }
1334*4bdc9457SAndroid Build Coastguard Worker   }
1335*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_NATIVE,positive_infinity)1336*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_NATIVE, positive_infinity) {
1337*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1338*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1339*4bdc9457SAndroid Build Coastguard Worker     std::fill(inputs.begin(), inputs.end(), +std::numeric_limits<float>::infinity());
1340*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__wasmsimd_native(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1341*4bdc9457SAndroid Build Coastguard Worker     const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
1342*4bdc9457SAndroid Build Coastguard Worker     ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
1343*4bdc9457SAndroid Build Coastguard Worker       << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
1344*4bdc9457SAndroid Build Coastguard Worker       << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1345*4bdc9457SAndroid Build Coastguard Worker       << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
1346*4bdc9457SAndroid Build Coastguard Worker   }
1347*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_NATIVE,negative_infinity)1348*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_NATIVE, negative_infinity) {
1349*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1350*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1351*4bdc9457SAndroid Build Coastguard Worker     std::fill(inputs.begin(), inputs.end(), -std::numeric_limits<float>::infinity());
1352*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__wasmsimd_native(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1353*4bdc9457SAndroid Build Coastguard Worker     const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
1354*4bdc9457SAndroid Build Coastguard Worker     ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
1355*4bdc9457SAndroid Build Coastguard Worker       << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
1356*4bdc9457SAndroid Build Coastguard Worker       << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1357*4bdc9457SAndroid Build Coastguard Worker       << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
1358*4bdc9457SAndroid Build Coastguard Worker   }
1359*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_NATIVE,positive_qnan)1360*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_NATIVE, positive_qnan) {
1361*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1362*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1363*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
1364*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1365*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(n + i);
1366*4bdc9457SAndroid Build Coastguard Worker       }
1367*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_native(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1368*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1369*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1370*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1371*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1372*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1373*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1374*4bdc9457SAndroid Build Coastguard Worker       }
1375*4bdc9457SAndroid Build Coastguard Worker     }
1376*4bdc9457SAndroid Build Coastguard Worker   }
1377*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_NATIVE,negative_qnan)1378*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_NATIVE, negative_qnan) {
1379*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1380*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1381*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
1382*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1383*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | (n + i));
1384*4bdc9457SAndroid Build Coastguard Worker       }
1385*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_native(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1386*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1387*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1388*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1389*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1390*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1391*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1392*4bdc9457SAndroid Build Coastguard Worker       }
1393*4bdc9457SAndroid Build Coastguard Worker     }
1394*4bdc9457SAndroid Build Coastguard Worker   }
1395*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_NATIVE,positive_snan)1396*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_NATIVE, positive_snan) {
1397*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1398*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1399*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1400*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1401*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1402*4bdc9457SAndroid Build Coastguard Worker       }
1403*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_native(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1404*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1405*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1406*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
1407*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1408*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1409*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1410*4bdc9457SAndroid Build Coastguard Worker       }
1411*4bdc9457SAndroid Build Coastguard Worker     }
1412*4bdc9457SAndroid Build Coastguard Worker   }
1413*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_NATIVE,negative_snan)1414*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_NATIVE, negative_snan) {
1415*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1416*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1417*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1418*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1419*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1420*4bdc9457SAndroid Build Coastguard Worker       }
1421*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_native(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1422*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1423*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1424*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
1425*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1426*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1427*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1428*4bdc9457SAndroid Build Coastguard Worker       }
1429*4bdc9457SAndroid Build Coastguard Worker     }
1430*4bdc9457SAndroid Build Coastguard Worker   }
1431*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_NATIVE,positive_snan_to_qnan)1432*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_NATIVE, positive_snan_to_qnan) {
1433*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1434*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1435*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1436*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1437*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1438*4bdc9457SAndroid Build Coastguard Worker       }
1439*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_native(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1440*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1441*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1442*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1443*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1444*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1445*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1446*4bdc9457SAndroid Build Coastguard Worker       }
1447*4bdc9457SAndroid Build Coastguard Worker     }
1448*4bdc9457SAndroid Build Coastguard Worker   }
1449*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__WASMSIMD_NATIVE,negative_snan_to_qnan)1450*4bdc9457SAndroid Build Coastguard Worker   TEST(ROUNDNE__WASMSIMD_NATIVE, negative_snan_to_qnan) {
1451*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1452*4bdc9457SAndroid Build Coastguard Worker     std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1453*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1454*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1455*4bdc9457SAndroid Build Coastguard Worker         inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1456*4bdc9457SAndroid Build Coastguard Worker       }
1457*4bdc9457SAndroid Build Coastguard Worker       xnn_math_f32_roundne__wasmsimd_native(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1458*4bdc9457SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < kBlockSize; i++) {
1459*4bdc9457SAndroid Build Coastguard Worker         const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1460*4bdc9457SAndroid Build Coastguard Worker         ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1461*4bdc9457SAndroid Build Coastguard Worker           << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1462*4bdc9457SAndroid Build Coastguard Worker           << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1463*4bdc9457SAndroid Build Coastguard Worker           << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1464*4bdc9457SAndroid Build Coastguard Worker       }
1465*4bdc9457SAndroid Build Coastguard Worker     }
1466*4bdc9457SAndroid Build Coastguard Worker   }
1467*4bdc9457SAndroid Build Coastguard Worker #endif  // XNN_ARCH_WASMSIMD || XNN_ARCH_WASMRELAXEDSIMD
1468*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SCALAR_ADDSUB,positive_normal)1469*4bdc9457SAndroid Build Coastguard Worker TEST(ROUNDNE__SCALAR_ADDSUB, positive_normal) {
1470*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1471*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1472*4bdc9457SAndroid Build Coastguard Worker   for (uint32_t n = UINT32_C(0x00000000); n < UINT32_C(0x4B800000); n += kBlockSize) {
1473*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1474*4bdc9457SAndroid Build Coastguard Worker       inputs[i] = uint32_as_float(n + i);
1475*4bdc9457SAndroid Build Coastguard Worker     }
1476*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__scalar_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1477*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1478*4bdc9457SAndroid Build Coastguard Worker       const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1479*4bdc9457SAndroid Build Coastguard Worker       ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1480*4bdc9457SAndroid Build Coastguard Worker         << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1481*4bdc9457SAndroid Build Coastguard Worker         << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1482*4bdc9457SAndroid Build Coastguard Worker         << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1483*4bdc9457SAndroid Build Coastguard Worker     }
1484*4bdc9457SAndroid Build Coastguard Worker   }
1485*4bdc9457SAndroid Build Coastguard Worker }
1486*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SCALAR_ADDSUB,negative_normal)1487*4bdc9457SAndroid Build Coastguard Worker TEST(ROUNDNE__SCALAR_ADDSUB, negative_normal) {
1488*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1489*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1490*4bdc9457SAndroid Build Coastguard Worker   for (uint32_t n = UINT32_C(0x80000000); n < UINT32_C(0xCB800000); n += kBlockSize) {
1491*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1492*4bdc9457SAndroid Build Coastguard Worker       inputs[i] = uint32_as_float(n + i);
1493*4bdc9457SAndroid Build Coastguard Worker     }
1494*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__scalar_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1495*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1496*4bdc9457SAndroid Build Coastguard Worker       const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1497*4bdc9457SAndroid Build Coastguard Worker       ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1498*4bdc9457SAndroid Build Coastguard Worker         << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1499*4bdc9457SAndroid Build Coastguard Worker         << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1500*4bdc9457SAndroid Build Coastguard Worker         << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1501*4bdc9457SAndroid Build Coastguard Worker     }
1502*4bdc9457SAndroid Build Coastguard Worker   }
1503*4bdc9457SAndroid Build Coastguard Worker }
1504*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SCALAR_ADDSUB,positive_integral)1505*4bdc9457SAndroid Build Coastguard Worker TEST(ROUNDNE__SCALAR_ADDSUB, positive_integral) {
1506*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1507*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1508*4bdc9457SAndroid Build Coastguard Worker   for (uint32_t n = UINT32_C(0x4B800000); n < UINT32_C(0x7F800000); n += kBlockSize) {
1509*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1510*4bdc9457SAndroid Build Coastguard Worker       inputs[i] = uint32_as_float(n + i);
1511*4bdc9457SAndroid Build Coastguard Worker     }
1512*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__scalar_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1513*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1514*4bdc9457SAndroid Build Coastguard Worker       const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1515*4bdc9457SAndroid Build Coastguard Worker       ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1516*4bdc9457SAndroid Build Coastguard Worker         << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1517*4bdc9457SAndroid Build Coastguard Worker         << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1518*4bdc9457SAndroid Build Coastguard Worker         << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1519*4bdc9457SAndroid Build Coastguard Worker     }
1520*4bdc9457SAndroid Build Coastguard Worker   }
1521*4bdc9457SAndroid Build Coastguard Worker }
1522*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SCALAR_ADDSUB,negative_integral)1523*4bdc9457SAndroid Build Coastguard Worker TEST(ROUNDNE__SCALAR_ADDSUB, negative_integral) {
1524*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1525*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1526*4bdc9457SAndroid Build Coastguard Worker   for (uint32_t n = UINT32_C(0xCB800000); n < UINT32_C(0xFF800000); n += kBlockSize) {
1527*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1528*4bdc9457SAndroid Build Coastguard Worker       inputs[i] = uint32_as_float(n + i);
1529*4bdc9457SAndroid Build Coastguard Worker     }
1530*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__scalar_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1531*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1532*4bdc9457SAndroid Build Coastguard Worker       const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1533*4bdc9457SAndroid Build Coastguard Worker       ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1534*4bdc9457SAndroid Build Coastguard Worker         << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1535*4bdc9457SAndroid Build Coastguard Worker         << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1536*4bdc9457SAndroid Build Coastguard Worker         << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1537*4bdc9457SAndroid Build Coastguard Worker     }
1538*4bdc9457SAndroid Build Coastguard Worker   }
1539*4bdc9457SAndroid Build Coastguard Worker }
1540*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SCALAR_ADDSUB,positive_infinity)1541*4bdc9457SAndroid Build Coastguard Worker TEST(ROUNDNE__SCALAR_ADDSUB, positive_infinity) {
1542*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1543*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1544*4bdc9457SAndroid Build Coastguard Worker   std::fill(inputs.begin(), inputs.end(), +std::numeric_limits<float>::infinity());
1545*4bdc9457SAndroid Build Coastguard Worker   xnn_math_f32_roundne__scalar_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1546*4bdc9457SAndroid Build Coastguard Worker   const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
1547*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
1548*4bdc9457SAndroid Build Coastguard Worker     << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
1549*4bdc9457SAndroid Build Coastguard Worker     << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1550*4bdc9457SAndroid Build Coastguard Worker     << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
1551*4bdc9457SAndroid Build Coastguard Worker }
1552*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SCALAR_ADDSUB,negative_infinity)1553*4bdc9457SAndroid Build Coastguard Worker TEST(ROUNDNE__SCALAR_ADDSUB, negative_infinity) {
1554*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1555*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1556*4bdc9457SAndroid Build Coastguard Worker   std::fill(inputs.begin(), inputs.end(), -std::numeric_limits<float>::infinity());
1557*4bdc9457SAndroid Build Coastguard Worker   xnn_math_f32_roundne__scalar_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1558*4bdc9457SAndroid Build Coastguard Worker   const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[0]));
1559*4bdc9457SAndroid Build Coastguard Worker   ASSERT_EQ(reference_output, float_as_uint32(outputs[0]))
1560*4bdc9457SAndroid Build Coastguard Worker     << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
1561*4bdc9457SAndroid Build Coastguard Worker     << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1562*4bdc9457SAndroid Build Coastguard Worker     << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
1563*4bdc9457SAndroid Build Coastguard Worker }
1564*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SCALAR_ADDSUB,positive_qnan)1565*4bdc9457SAndroid Build Coastguard Worker TEST(ROUNDNE__SCALAR_ADDSUB, positive_qnan) {
1566*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1567*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1568*4bdc9457SAndroid Build Coastguard Worker   for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
1569*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1570*4bdc9457SAndroid Build Coastguard Worker       inputs[i] = uint32_as_float(n + i);
1571*4bdc9457SAndroid Build Coastguard Worker     }
1572*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__scalar_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1573*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1574*4bdc9457SAndroid Build Coastguard Worker       const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1575*4bdc9457SAndroid Build Coastguard Worker       ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1576*4bdc9457SAndroid Build Coastguard Worker         << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1577*4bdc9457SAndroid Build Coastguard Worker         << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1578*4bdc9457SAndroid Build Coastguard Worker         << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1579*4bdc9457SAndroid Build Coastguard Worker     }
1580*4bdc9457SAndroid Build Coastguard Worker   }
1581*4bdc9457SAndroid Build Coastguard Worker }
1582*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SCALAR_ADDSUB,negative_qnan)1583*4bdc9457SAndroid Build Coastguard Worker TEST(ROUNDNE__SCALAR_ADDSUB, negative_qnan) {
1584*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1585*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1586*4bdc9457SAndroid Build Coastguard Worker   for (uint32_t n = UINT32_C(0x7FC00000); n < UINT32_C(0x80000000); n += kBlockSize) {
1587*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1588*4bdc9457SAndroid Build Coastguard Worker       inputs[i] = uint32_as_float(UINT32_C(0x80000000) | (n + i));
1589*4bdc9457SAndroid Build Coastguard Worker     }
1590*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__scalar_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1591*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1592*4bdc9457SAndroid Build Coastguard Worker       const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1593*4bdc9457SAndroid Build Coastguard Worker       ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1594*4bdc9457SAndroid Build Coastguard Worker         << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1595*4bdc9457SAndroid Build Coastguard Worker         << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1596*4bdc9457SAndroid Build Coastguard Worker         << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1597*4bdc9457SAndroid Build Coastguard Worker     }
1598*4bdc9457SAndroid Build Coastguard Worker   }
1599*4bdc9457SAndroid Build Coastguard Worker }
1600*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SCALAR_ADDSUB,positive_snan)1601*4bdc9457SAndroid Build Coastguard Worker TEST(ROUNDNE__SCALAR_ADDSUB, positive_snan) {
1602*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1603*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1604*4bdc9457SAndroid Build Coastguard Worker   for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1605*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1606*4bdc9457SAndroid Build Coastguard Worker       inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1607*4bdc9457SAndroid Build Coastguard Worker     }
1608*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__scalar_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1609*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1610*4bdc9457SAndroid Build Coastguard Worker       const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1611*4bdc9457SAndroid Build Coastguard Worker       ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
1612*4bdc9457SAndroid Build Coastguard Worker         << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1613*4bdc9457SAndroid Build Coastguard Worker         << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1614*4bdc9457SAndroid Build Coastguard Worker         << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1615*4bdc9457SAndroid Build Coastguard Worker     }
1616*4bdc9457SAndroid Build Coastguard Worker   }
1617*4bdc9457SAndroid Build Coastguard Worker }
1618*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SCALAR_ADDSUB,negative_snan)1619*4bdc9457SAndroid Build Coastguard Worker TEST(ROUNDNE__SCALAR_ADDSUB, negative_snan) {
1620*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1621*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1622*4bdc9457SAndroid Build Coastguard Worker   for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1623*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1624*4bdc9457SAndroid Build Coastguard Worker       inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1625*4bdc9457SAndroid Build Coastguard Worker     }
1626*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__scalar_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1627*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1628*4bdc9457SAndroid Build Coastguard Worker       const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1629*4bdc9457SAndroid Build Coastguard Worker       ASSERT_EQ(reference_output & UINT32_C(0xFFBFFFFF), float_as_uint32(outputs[i]) & UINT32_C(0xFFBFFFFF))
1630*4bdc9457SAndroid Build Coastguard Worker         << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1631*4bdc9457SAndroid Build Coastguard Worker         << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1632*4bdc9457SAndroid Build Coastguard Worker         << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1633*4bdc9457SAndroid Build Coastguard Worker     }
1634*4bdc9457SAndroid Build Coastguard Worker   }
1635*4bdc9457SAndroid Build Coastguard Worker }
1636*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SCALAR_ADDSUB,positive_snan_to_qnan)1637*4bdc9457SAndroid Build Coastguard Worker TEST(ROUNDNE__SCALAR_ADDSUB, positive_snan_to_qnan) {
1638*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1639*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1640*4bdc9457SAndroid Build Coastguard Worker   for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1641*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1642*4bdc9457SAndroid Build Coastguard Worker       inputs[i] = uint32_as_float(std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1643*4bdc9457SAndroid Build Coastguard Worker     }
1644*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__scalar_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1645*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1646*4bdc9457SAndroid Build Coastguard Worker       const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1647*4bdc9457SAndroid Build Coastguard Worker       ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1648*4bdc9457SAndroid Build Coastguard Worker         << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1649*4bdc9457SAndroid Build Coastguard Worker         << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1650*4bdc9457SAndroid Build Coastguard Worker         << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1651*4bdc9457SAndroid Build Coastguard Worker     }
1652*4bdc9457SAndroid Build Coastguard Worker   }
1653*4bdc9457SAndroid Build Coastguard Worker }
1654*4bdc9457SAndroid Build Coastguard Worker 
TEST(ROUNDNE__SCALAR_ADDSUB,negative_snan_to_qnan)1655*4bdc9457SAndroid Build Coastguard Worker TEST(ROUNDNE__SCALAR_ADDSUB, negative_snan_to_qnan) {
1656*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
1657*4bdc9457SAndroid Build Coastguard Worker   std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
1658*4bdc9457SAndroid Build Coastguard Worker   for (uint32_t n = UINT32_C(0x7F800000); n < UINT32_C(0x7FC00000); n += kBlockSize) {
1659*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1660*4bdc9457SAndroid Build Coastguard Worker       inputs[i] = uint32_as_float(UINT32_C(0x80000000) | std::max<uint32_t>(n + i, UINT32_C(0x7F800001)));
1661*4bdc9457SAndroid Build Coastguard Worker     }
1662*4bdc9457SAndroid Build Coastguard Worker     xnn_math_f32_roundne__scalar_addsub(kBlockSize * sizeof(float), inputs.data(), outputs.data());
1663*4bdc9457SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kBlockSize; i++) {
1664*4bdc9457SAndroid Build Coastguard Worker       const uint32_t reference_output = float_as_uint32(std::nearbyint(inputs[i]));
1665*4bdc9457SAndroid Build Coastguard Worker       ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
1666*4bdc9457SAndroid Build Coastguard Worker         << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
1667*4bdc9457SAndroid Build Coastguard Worker         << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
1668*4bdc9457SAndroid Build Coastguard Worker         << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
1669*4bdc9457SAndroid Build Coastguard Worker     }
1670*4bdc9457SAndroid Build Coastguard Worker   }
1671*4bdc9457SAndroid Build Coastguard Worker }
1672