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/isa-checks.h>
22*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/math.h>
23*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/math-stubs.h>
24*4bdc9457SAndroid Build Coastguard Worker
25*4bdc9457SAndroid Build Coastguard Worker
26*4bdc9457SAndroid Build Coastguard Worker constexpr int kBlockSize = 1024;
27*4bdc9457SAndroid Build Coastguard Worker
28*4bdc9457SAndroid Build Coastguard Worker
29*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_ARM || XNN_ARCH_ARM64
TEST(EXPMINUS__NEONFMA_RR2_LUT64_P2,negative_zero)30*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_LUT64_P2, negative_zero) {
31*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
32*4bdc9457SAndroid Build Coastguard Worker
33*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
34*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
35*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), -0.0f);
36*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_lut64_p2(kBlockSize * sizeof(float), inputs.data(), outputs.data());
37*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
38*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
39*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
40*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
41*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
42*4bdc9457SAndroid Build Coastguard Worker }
43*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__NEONFMA_RR2_LUT64_P2,positive_zero)44*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_LUT64_P2, positive_zero) {
45*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
46*4bdc9457SAndroid Build Coastguard Worker
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 std::fill(inputs.begin(), inputs.end(), +0.0f);
50*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_lut64_p2(kBlockSize * sizeof(float), inputs.data(), outputs.data());
51*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
52*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
53*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
54*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
55*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
56*4bdc9457SAndroid Build Coastguard Worker }
57*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__NEONFMA_RR2_LUT64_P2,negative_saturation)58*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_LUT64_P2, negative_saturation) {
59*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
60*4bdc9457SAndroid Build Coastguard Worker
61*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
62*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
63*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0xC2AEAC50); n <= UINT32_C(0xFF800000); n += kBlockSize) {
64*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
65*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(n + i, UINT32_C(0xFF800000)));
66*4bdc9457SAndroid Build Coastguard Worker }
67*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_lut64_p2(kBlockSize * sizeof(float), inputs.data(), outputs.data());
68*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
69*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = UINT32_C(0x00000000);
70*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
71*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
72*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
73*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
74*4bdc9457SAndroid Build Coastguard Worker }
75*4bdc9457SAndroid Build Coastguard Worker }
76*4bdc9457SAndroid Build Coastguard Worker }
77*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__NEONFMA_RR2_LUT64_P2,positive_nan)78*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_LUT64_P2, positive_nan) {
79*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
80*4bdc9457SAndroid Build Coastguard Worker
81*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
82*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
83*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0x7F800001); n < UINT32_C(0x80000000); n += kBlockSize) {
84*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
85*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), n + i));
86*4bdc9457SAndroid Build Coastguard Worker }
87*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_lut64_p2(kBlockSize * sizeof(float), inputs.data(), outputs.data());
88*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
89*4bdc9457SAndroid Build Coastguard Worker ASSERT_TRUE(std::isnan(outputs[i]))
90*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
91*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
92*4bdc9457SAndroid Build Coastguard Worker }
93*4bdc9457SAndroid Build Coastguard Worker }
94*4bdc9457SAndroid Build Coastguard Worker }
95*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__NEONFMA_RR2_LUT64_P2,negative_nan)96*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_LUT64_P2, negative_nan) {
97*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
98*4bdc9457SAndroid Build Coastguard Worker
99*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
100*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
101*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0x7F800001); n < UINT32_C(0x80000000); n += kBlockSize) {
102*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
103*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), UINT32_C(0x80000000) | (n + i)));
104*4bdc9457SAndroid Build Coastguard Worker }
105*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_lut64_p2(kBlockSize * sizeof(float), inputs.data(), outputs.data());
106*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
107*4bdc9457SAndroid Build Coastguard Worker ASSERT_TRUE(std::isnan(outputs[i]))
108*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
109*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
110*4bdc9457SAndroid Build Coastguard Worker }
111*4bdc9457SAndroid Build Coastguard Worker }
112*4bdc9457SAndroid Build Coastguard Worker }
113*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_ARM || XNN_ARCH_ARM64
114*4bdc9457SAndroid Build Coastguard Worker
115*4bdc9457SAndroid Build Coastguard Worker
116*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_ARM || XNN_ARCH_ARM64
TEST(EXPMINUS__NEONFMA_RR2_LUT2048_P1,negative_zero)117*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_LUT2048_P1, negative_zero) {
118*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
119*4bdc9457SAndroid Build Coastguard Worker
120*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
121*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
122*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), -0.0f);
123*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_lut2048_p1(kBlockSize * sizeof(float), inputs.data(), outputs.data());
124*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
125*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
126*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
127*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
128*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
129*4bdc9457SAndroid Build Coastguard Worker }
130*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__NEONFMA_RR2_LUT2048_P1,positive_zero)131*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_LUT2048_P1, positive_zero) {
132*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
133*4bdc9457SAndroid Build Coastguard Worker
134*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
135*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
136*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), +0.0f);
137*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_lut2048_p1(kBlockSize * sizeof(float), inputs.data(), outputs.data());
138*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
139*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
140*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
141*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
142*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
143*4bdc9457SAndroid Build Coastguard Worker }
144*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__NEONFMA_RR2_LUT2048_P1,negative_saturation)145*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_LUT2048_P1, negative_saturation) {
146*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
147*4bdc9457SAndroid Build Coastguard Worker
148*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
149*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
150*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0xC2AEAC50); n <= UINT32_C(0xFF800000); n += kBlockSize) {
151*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
152*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(n + i, UINT32_C(0xFF800000)));
153*4bdc9457SAndroid Build Coastguard Worker }
154*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_lut2048_p1(kBlockSize * sizeof(float), inputs.data(), outputs.data());
155*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
156*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = UINT32_C(0x00000000);
157*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
158*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
159*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
160*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
161*4bdc9457SAndroid Build Coastguard Worker }
162*4bdc9457SAndroid Build Coastguard Worker }
163*4bdc9457SAndroid Build Coastguard Worker }
164*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__NEONFMA_RR2_LUT2048_P1,positive_nan)165*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_LUT2048_P1, positive_nan) {
166*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
167*4bdc9457SAndroid Build Coastguard Worker
168*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
169*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
170*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0x7F800001); n < UINT32_C(0x80000000); n += kBlockSize) {
171*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
172*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), n + i));
173*4bdc9457SAndroid Build Coastguard Worker }
174*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_lut2048_p1(kBlockSize * sizeof(float), inputs.data(), outputs.data());
175*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
176*4bdc9457SAndroid Build Coastguard Worker ASSERT_TRUE(std::isnan(outputs[i]))
177*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
178*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
179*4bdc9457SAndroid Build Coastguard Worker }
180*4bdc9457SAndroid Build Coastguard Worker }
181*4bdc9457SAndroid Build Coastguard Worker }
182*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__NEONFMA_RR2_LUT2048_P1,negative_nan)183*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_LUT2048_P1, negative_nan) {
184*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
185*4bdc9457SAndroid Build Coastguard Worker
186*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
187*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
188*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0x7F800001); n < UINT32_C(0x80000000); n += kBlockSize) {
189*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
190*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), UINT32_C(0x80000000) | (n + i)));
191*4bdc9457SAndroid Build Coastguard Worker }
192*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_lut2048_p1(kBlockSize * sizeof(float), inputs.data(), outputs.data());
193*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
194*4bdc9457SAndroid Build Coastguard Worker ASSERT_TRUE(std::isnan(outputs[i]))
195*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
196*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
197*4bdc9457SAndroid Build Coastguard Worker }
198*4bdc9457SAndroid Build Coastguard Worker }
199*4bdc9457SAndroid Build Coastguard Worker }
200*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_ARM || XNN_ARCH_ARM64
201*4bdc9457SAndroid Build Coastguard Worker
202*4bdc9457SAndroid Build Coastguard Worker
203*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_ARM || XNN_ARCH_ARM64
TEST(EXPMINUS__NEONFMA_RR2_P5,negative_zero)204*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_P5, negative_zero) {
205*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
206*4bdc9457SAndroid Build Coastguard Worker
207*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
208*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
209*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), -0.0f);
210*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
211*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
212*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
213*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
214*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
215*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
216*4bdc9457SAndroid Build Coastguard Worker }
217*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__NEONFMA_RR2_P5,positive_zero)218*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_P5, positive_zero) {
219*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
220*4bdc9457SAndroid Build Coastguard Worker
221*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
222*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
223*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), +0.0f);
224*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
225*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
226*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
227*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
228*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
229*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
230*4bdc9457SAndroid Build Coastguard Worker }
231*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__NEONFMA_RR2_P5,negative_saturation)232*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_P5, negative_saturation) {
233*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
234*4bdc9457SAndroid Build Coastguard Worker
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(0xC2AEAC50); n <= UINT32_C(0xFF800000); 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(std::min<uint32_t>(n + i, UINT32_C(0xFF800000)));
240*4bdc9457SAndroid Build Coastguard Worker }
241*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_p5(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 = UINT32_C(0x00000000);
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(EXPMINUS__NEONFMA_RR2_P5,positive_nan)252*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_P5, positive_nan) {
253*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
254*4bdc9457SAndroid Build Coastguard Worker
255*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
256*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
257*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0x7F800001); n < UINT32_C(0x80000000); n += kBlockSize) {
258*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
259*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), n + i));
260*4bdc9457SAndroid Build Coastguard Worker }
261*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
262*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
263*4bdc9457SAndroid Build Coastguard Worker ASSERT_TRUE(std::isnan(outputs[i]))
264*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
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(EXPMINUS__NEONFMA_RR2_P5,negative_nan)270*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__NEONFMA_RR2_P5, negative_nan) {
271*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FMA;
272*4bdc9457SAndroid Build Coastguard Worker
273*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
274*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
275*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0x7F800001); n < UINT32_C(0x80000000); n += kBlockSize) {
276*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
277*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), UINT32_C(0x80000000) | (n + i)));
278*4bdc9457SAndroid Build Coastguard Worker }
279*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__neonfma_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
280*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
281*4bdc9457SAndroid Build Coastguard Worker ASSERT_TRUE(std::isnan(outputs[i]))
282*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
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 #endif // XNN_ARCH_ARM || XNN_ARCH_ARM64
288*4bdc9457SAndroid Build Coastguard Worker
289*4bdc9457SAndroid Build Coastguard Worker
290*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_X86 || XNN_ARCH_X86_64
TEST(EXPMINUS__AVX2_RR2_P5,negative_zero)291*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__AVX2_RR2_P5, negative_zero) {
292*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_AVX2;
293*4bdc9457SAndroid Build Coastguard Worker
294*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
295*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
296*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), -0.0f);
297*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__avx2_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
298*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
299*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
300*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
301*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
302*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
303*4bdc9457SAndroid Build Coastguard Worker }
304*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__AVX2_RR2_P5,positive_zero)305*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__AVX2_RR2_P5, positive_zero) {
306*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_AVX2;
307*4bdc9457SAndroid Build Coastguard Worker
308*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
309*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
310*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), +0.0f);
311*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__avx2_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
312*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
313*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
314*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
315*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
316*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
317*4bdc9457SAndroid Build Coastguard Worker }
318*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__AVX2_RR2_P5,negative_saturation)319*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__AVX2_RR2_P5, negative_saturation) {
320*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_AVX2;
321*4bdc9457SAndroid Build Coastguard Worker
322*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
323*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
324*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0xC2AEAC50); n <= UINT32_C(0xFF800000); n += kBlockSize) {
325*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
326*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(n + i, UINT32_C(0xFF800000)));
327*4bdc9457SAndroid Build Coastguard Worker }
328*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__avx2_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
329*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
330*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = UINT32_C(0x00000000);
331*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
332*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
333*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
334*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
335*4bdc9457SAndroid Build Coastguard Worker }
336*4bdc9457SAndroid Build Coastguard Worker }
337*4bdc9457SAndroid Build Coastguard Worker }
338*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__AVX2_RR2_P5,positive_nan)339*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__AVX2_RR2_P5, positive_nan) {
340*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_AVX2;
341*4bdc9457SAndroid Build Coastguard Worker
342*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
343*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
344*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0x7F800001); n < UINT32_C(0x80000000); n += kBlockSize) {
345*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
346*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), n + i));
347*4bdc9457SAndroid Build Coastguard Worker }
348*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__avx2_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
349*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
350*4bdc9457SAndroid Build Coastguard Worker ASSERT_TRUE(std::isnan(outputs[i]))
351*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
352*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
353*4bdc9457SAndroid Build Coastguard Worker }
354*4bdc9457SAndroid Build Coastguard Worker }
355*4bdc9457SAndroid Build Coastguard Worker }
356*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__AVX2_RR2_P5,negative_nan)357*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__AVX2_RR2_P5, negative_nan) {
358*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_AVX2;
359*4bdc9457SAndroid Build Coastguard Worker
360*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
361*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
362*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0x7F800001); n < UINT32_C(0x80000000); n += kBlockSize) {
363*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
364*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), UINT32_C(0x80000000) | (n + i)));
365*4bdc9457SAndroid Build Coastguard Worker }
366*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__avx2_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
367*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
368*4bdc9457SAndroid Build Coastguard Worker ASSERT_TRUE(std::isnan(outputs[i]))
369*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
370*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
371*4bdc9457SAndroid Build Coastguard Worker }
372*4bdc9457SAndroid Build Coastguard Worker }
373*4bdc9457SAndroid Build Coastguard Worker }
374*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_X86 || XNN_ARCH_X86_64
375*4bdc9457SAndroid Build Coastguard Worker
376*4bdc9457SAndroid Build Coastguard Worker
377*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_X86 || XNN_ARCH_X86_64
TEST(EXPMINUS__SSE2_RR2_P5,negative_zero)378*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SSE2_RR2_P5, negative_zero) {
379*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
380*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
381*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), -0.0f);
382*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__sse2_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
383*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
384*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
385*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
386*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
387*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
388*4bdc9457SAndroid Build Coastguard Worker }
389*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SSE2_RR2_P5,positive_zero)390*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SSE2_RR2_P5, positive_zero) {
391*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
392*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
393*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), +0.0f);
394*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__sse2_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
395*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
396*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
397*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
398*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
399*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
400*4bdc9457SAndroid Build Coastguard Worker }
401*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SSE2_RR2_P5,negative_saturation)402*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SSE2_RR2_P5, negative_saturation) {
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(0xC2AEAC50); n <= UINT32_C(0xFF800000); 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::min<uint32_t>(n + i, UINT32_C(0xFF800000)));
408*4bdc9457SAndroid Build Coastguard Worker }
409*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__sse2_rr2_p5(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 = UINT32_C(0x00000000);
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(EXPMINUS__SSE2_RR2_P5,positive_nan)420*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SSE2_RR2_P5, positive_nan) {
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(0x7F800001); n < UINT32_C(0x80000000); 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(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), n + i));
426*4bdc9457SAndroid Build Coastguard Worker }
427*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__sse2_rr2_p5(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 ASSERT_TRUE(std::isnan(outputs[i]))
430*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
431*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
432*4bdc9457SAndroid Build Coastguard Worker }
433*4bdc9457SAndroid Build Coastguard Worker }
434*4bdc9457SAndroid Build Coastguard Worker }
435*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SSE2_RR2_P5,negative_nan)436*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SSE2_RR2_P5, negative_nan) {
437*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
438*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
439*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0x7F800001); n < UINT32_C(0x80000000); n += kBlockSize) {
440*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
441*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), UINT32_C(0x80000000) | (n + i)));
442*4bdc9457SAndroid Build Coastguard Worker }
443*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__sse2_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
444*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
445*4bdc9457SAndroid Build Coastguard Worker ASSERT_TRUE(std::isnan(outputs[i]))
446*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
447*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
448*4bdc9457SAndroid Build Coastguard Worker }
449*4bdc9457SAndroid Build Coastguard Worker }
450*4bdc9457SAndroid Build Coastguard Worker }
451*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_X86 || XNN_ARCH_X86_64
452*4bdc9457SAndroid Build Coastguard Worker
453*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SCALAR_RR2_LUT64_P2,negative_zero)454*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_LUT64_P2, negative_zero) {
455*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
456*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
457*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), -0.0f);
458*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_lut64_p2(kBlockSize * sizeof(float), inputs.data(), outputs.data());
459*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
460*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
461*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
462*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
463*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
464*4bdc9457SAndroid Build Coastguard Worker }
465*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SCALAR_RR2_LUT64_P2,positive_zero)466*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_LUT64_P2, positive_zero) {
467*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
468*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
469*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), +0.0f);
470*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_lut64_p2(kBlockSize * sizeof(float), inputs.data(), outputs.data());
471*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
472*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
473*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
474*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
475*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
476*4bdc9457SAndroid Build Coastguard Worker }
477*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SCALAR_RR2_LUT64_P2,negative_saturation)478*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_LUT64_P2, negative_saturation) {
479*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
480*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
481*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0xC2AEAC50); n <= UINT32_C(0xFF800000); n += kBlockSize) {
482*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
483*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(n + i, UINT32_C(0xFF800000)));
484*4bdc9457SAndroid Build Coastguard Worker }
485*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_lut64_p2(kBlockSize * sizeof(float), inputs.data(), outputs.data());
486*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
487*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = UINT32_C(0x00000000);
488*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
489*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
490*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
491*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
492*4bdc9457SAndroid Build Coastguard Worker }
493*4bdc9457SAndroid Build Coastguard Worker }
494*4bdc9457SAndroid Build Coastguard Worker }
495*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SCALAR_RR2_LUT64_P2,positive_nan)496*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_LUT64_P2, positive_nan) {
497*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
498*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
499*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0x7F800001); n < UINT32_C(0x80000000); n += kBlockSize) {
500*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
501*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), n + i));
502*4bdc9457SAndroid Build Coastguard Worker }
503*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_lut64_p2(kBlockSize * sizeof(float), inputs.data(), outputs.data());
504*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
505*4bdc9457SAndroid Build Coastguard Worker ASSERT_TRUE(std::isnan(outputs[i]))
506*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
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(EXPMINUS__SCALAR_RR2_LUT64_P2,negative_nan)512*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_LUT64_P2, negative_nan) {
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 for (uint32_t n = UINT32_C(0x7F800001); n < UINT32_C(0x80000000); n += kBlockSize) {
516*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
517*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), UINT32_C(0x80000000) | (n + i)));
518*4bdc9457SAndroid Build Coastguard Worker }
519*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_lut64_p2(kBlockSize * sizeof(float), inputs.data(), outputs.data());
520*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
521*4bdc9457SAndroid Build Coastguard Worker ASSERT_TRUE(std::isnan(outputs[i]))
522*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
523*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
524*4bdc9457SAndroid Build Coastguard Worker }
525*4bdc9457SAndroid Build Coastguard Worker }
526*4bdc9457SAndroid Build Coastguard Worker }
527*4bdc9457SAndroid Build Coastguard Worker
528*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SCALAR_RR2_LUT2048_P1,negative_zero)529*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_LUT2048_P1, negative_zero) {
530*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
531*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
532*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), -0.0f);
533*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_lut2048_p1(kBlockSize * sizeof(float), inputs.data(), outputs.data());
534*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
535*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
536*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
537*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
538*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
539*4bdc9457SAndroid Build Coastguard Worker }
540*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SCALAR_RR2_LUT2048_P1,positive_zero)541*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_LUT2048_P1, positive_zero) {
542*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
543*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
544*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), +0.0f);
545*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_lut2048_p1(kBlockSize * sizeof(float), inputs.data(), outputs.data());
546*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
547*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
548*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
549*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
550*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
551*4bdc9457SAndroid Build Coastguard Worker }
552*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SCALAR_RR2_LUT2048_P1,negative_saturation)553*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_LUT2048_P1, negative_saturation) {
554*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
555*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
556*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0xC2AEAC50); n <= UINT32_C(0xFF800000); n += kBlockSize) {
557*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
558*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(n + i, UINT32_C(0xFF800000)));
559*4bdc9457SAndroid Build Coastguard Worker }
560*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_lut2048_p1(kBlockSize * sizeof(float), inputs.data(), outputs.data());
561*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
562*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = UINT32_C(0x00000000);
563*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
564*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
565*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
566*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
567*4bdc9457SAndroid Build Coastguard Worker }
568*4bdc9457SAndroid Build Coastguard Worker }
569*4bdc9457SAndroid Build Coastguard Worker }
570*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SCALAR_RR2_LUT2048_P1,positive_nan)571*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_LUT2048_P1, positive_nan) {
572*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
573*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
574*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0x7F800001); n < UINT32_C(0x80000000); n += kBlockSize) {
575*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
576*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), n + i));
577*4bdc9457SAndroid Build Coastguard Worker }
578*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_lut2048_p1(kBlockSize * sizeof(float), inputs.data(), outputs.data());
579*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
580*4bdc9457SAndroid Build Coastguard Worker ASSERT_TRUE(std::isnan(outputs[i]))
581*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
582*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
583*4bdc9457SAndroid Build Coastguard Worker }
584*4bdc9457SAndroid Build Coastguard Worker }
585*4bdc9457SAndroid Build Coastguard Worker }
586*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SCALAR_RR2_LUT2048_P1,negative_nan)587*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_LUT2048_P1, negative_nan) {
588*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
589*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
590*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0x7F800001); n < UINT32_C(0x80000000); n += kBlockSize) {
591*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
592*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), UINT32_C(0x80000000) | (n + i)));
593*4bdc9457SAndroid Build Coastguard Worker }
594*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_lut2048_p1(kBlockSize * sizeof(float), inputs.data(), outputs.data());
595*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
596*4bdc9457SAndroid Build Coastguard Worker ASSERT_TRUE(std::isnan(outputs[i]))
597*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
598*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
599*4bdc9457SAndroid Build Coastguard Worker }
600*4bdc9457SAndroid Build Coastguard Worker }
601*4bdc9457SAndroid Build Coastguard Worker }
602*4bdc9457SAndroid Build Coastguard Worker
603*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SCALAR_RR2_P5,negative_zero)604*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_P5, negative_zero) {
605*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
606*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
607*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), -0.0f);
608*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
609*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
610*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
611*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
612*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
613*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
614*4bdc9457SAndroid Build Coastguard Worker }
615*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SCALAR_RR2_P5,positive_zero)616*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_P5, positive_zero) {
617*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
618*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
619*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), +0.0f);
620*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
621*4bdc9457SAndroid Build Coastguard Worker const float reference_output = 1.0f;
622*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, outputs[0])
623*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[0])
624*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(reference_output)
625*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]);
626*4bdc9457SAndroid Build Coastguard Worker }
627*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SCALAR_RR2_P5,negative_saturation)628*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_P5, negative_saturation) {
629*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
630*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
631*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0xC2AEAC50); n <= UINT32_C(0xFF800000); n += kBlockSize) {
632*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
633*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(n + i, UINT32_C(0xFF800000)));
634*4bdc9457SAndroid Build Coastguard Worker }
635*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
636*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
637*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = UINT32_C(0x00000000);
638*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i]))
639*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
640*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output
641*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
642*4bdc9457SAndroid Build Coastguard Worker }
643*4bdc9457SAndroid Build Coastguard Worker }
644*4bdc9457SAndroid Build Coastguard Worker }
645*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SCALAR_RR2_P5,positive_nan)646*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_P5, positive_nan) {
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(0x7F800001); n < UINT32_C(0x80000000); 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(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), n + i));
652*4bdc9457SAndroid Build Coastguard Worker }
653*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_p5(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 ASSERT_TRUE(std::isnan(outputs[i]))
656*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
657*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
658*4bdc9457SAndroid Build Coastguard Worker }
659*4bdc9457SAndroid Build Coastguard Worker }
660*4bdc9457SAndroid Build Coastguard Worker }
661*4bdc9457SAndroid Build Coastguard Worker
TEST(EXPMINUS__SCALAR_RR2_P5,negative_nan)662*4bdc9457SAndroid Build Coastguard Worker TEST(EXPMINUS__SCALAR_RR2_P5, negative_nan) {
663*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> inputs(kBlockSize);
664*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize);
665*4bdc9457SAndroid Build Coastguard Worker for (uint32_t n = UINT32_C(0x7F800001); n < UINT32_C(0x80000000); n += kBlockSize) {
666*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
667*4bdc9457SAndroid Build Coastguard Worker inputs[i] = uint32_as_float(std::min<uint32_t>(UINT32_C(0x7FFFFFFF), UINT32_C(0x80000000) | (n + i)));
668*4bdc9457SAndroid Build Coastguard Worker }
669*4bdc9457SAndroid Build Coastguard Worker xnn_math_f32_expminus__scalar_rr2_p5(kBlockSize * sizeof(float), inputs.data(), outputs.data());
670*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) {
671*4bdc9457SAndroid Build Coastguard Worker ASSERT_TRUE(std::isnan(outputs[i]))
672*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(inputs[i])
673*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]);
674*4bdc9457SAndroid Build Coastguard Worker }
675*4bdc9457SAndroid Build Coastguard Worker }
676*4bdc9457SAndroid Build Coastguard Worker }
677