1 /*
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/audio_processing/aec3/vector_math.h"
12
13 #include <math.h>
14
15 #include "system_wrappers/include/cpu_features_wrapper.h"
16 #include "test/gtest.h"
17 #include "typedefs.h" // NOLINT(build/include)
18
19 namespace webrtc {
20
21 #if defined(WEBRTC_HAS_NEON)
22
TEST(VectorMath,Sqrt)23 TEST(VectorMath, Sqrt) {
24 std::array<float, kFftLengthBy2Plus1> x;
25 std::array<float, kFftLengthBy2Plus1> z;
26 std::array<float, kFftLengthBy2Plus1> z_neon;
27
28 for (size_t k = 0; k < x.size(); ++k) {
29 x[k] = (2.f / 3.f) * k;
30 }
31
32 std::copy(x.begin(), x.end(), z.begin());
33 aec3::VectorMath(Aec3Optimization::kNone).Sqrt(z);
34 std::copy(x.begin(), x.end(), z_neon.begin());
35 aec3::VectorMath(Aec3Optimization::kNeon).Sqrt(z_neon);
36 for (size_t k = 0; k < z.size(); ++k) {
37 EXPECT_NEAR(z[k], z_neon[k], 0.0001f);
38 EXPECT_NEAR(sqrtf(x[k]), z_neon[k], 0.0001f);
39 }
40 }
41
TEST(VectorMath,Multiply)42 TEST(VectorMath, Multiply) {
43 std::array<float, kFftLengthBy2Plus1> x;
44 std::array<float, kFftLengthBy2Plus1> y;
45 std::array<float, kFftLengthBy2Plus1> z;
46 std::array<float, kFftLengthBy2Plus1> z_neon;
47
48 for (size_t k = 0; k < x.size(); ++k) {
49 x[k] = k;
50 y[k] = (2.f / 3.f) * k;
51 }
52
53 aec3::VectorMath(Aec3Optimization::kNone).Multiply(x, y, z);
54 aec3::VectorMath(Aec3Optimization::kNeon).Multiply(x, y, z_neon);
55 for (size_t k = 0; k < z.size(); ++k) {
56 EXPECT_FLOAT_EQ(z[k], z_neon[k]);
57 EXPECT_FLOAT_EQ(x[k] * y[k], z_neon[k]);
58 }
59 }
60
TEST(VectorMath,Accumulate)61 TEST(VectorMath, Accumulate) {
62 std::array<float, kFftLengthBy2Plus1> x;
63 std::array<float, kFftLengthBy2Plus1> z;
64 std::array<float, kFftLengthBy2Plus1> z_neon;
65
66 for (size_t k = 0; k < x.size(); ++k) {
67 x[k] = k;
68 z[k] = z_neon[k] = 2.f * k;
69 }
70
71 aec3::VectorMath(Aec3Optimization::kNone).Accumulate(x, z);
72 aec3::VectorMath(Aec3Optimization::kNeon).Accumulate(x, z_neon);
73 for (size_t k = 0; k < z.size(); ++k) {
74 EXPECT_FLOAT_EQ(z[k], z_neon[k]);
75 EXPECT_FLOAT_EQ(x[k] + 2.f * x[k], z_neon[k]);
76 }
77 }
78 #endif
79
80 #if defined(WEBRTC_ARCH_X86_FAMILY)
81
TEST(VectorMath,Sqrt)82 TEST(VectorMath, Sqrt) {
83 if (WebRtc_GetCPUInfo(kSSE2) != 0) {
84 std::array<float, kFftLengthBy2Plus1> x;
85 std::array<float, kFftLengthBy2Plus1> z;
86 std::array<float, kFftLengthBy2Plus1> z_sse2;
87
88 for (size_t k = 0; k < x.size(); ++k) {
89 x[k] = (2.f / 3.f) * k;
90 }
91
92 std::copy(x.begin(), x.end(), z.begin());
93 aec3::VectorMath(Aec3Optimization::kNone).Sqrt(z);
94 std::copy(x.begin(), x.end(), z_sse2.begin());
95 aec3::VectorMath(Aec3Optimization::kSse2).Sqrt(z_sse2);
96 EXPECT_EQ(z, z_sse2);
97 for (size_t k = 0; k < z.size(); ++k) {
98 EXPECT_FLOAT_EQ(z[k], z_sse2[k]);
99 EXPECT_FLOAT_EQ(sqrtf(x[k]), z_sse2[k]);
100 }
101 }
102 }
103
TEST(VectorMath,Multiply)104 TEST(VectorMath, Multiply) {
105 if (WebRtc_GetCPUInfo(kSSE2) != 0) {
106 std::array<float, kFftLengthBy2Plus1> x;
107 std::array<float, kFftLengthBy2Plus1> y;
108 std::array<float, kFftLengthBy2Plus1> z;
109 std::array<float, kFftLengthBy2Plus1> z_sse2;
110
111 for (size_t k = 0; k < x.size(); ++k) {
112 x[k] = k;
113 y[k] = (2.f / 3.f) * k;
114 }
115
116 aec3::VectorMath(Aec3Optimization::kNone).Multiply(x, y, z);
117 aec3::VectorMath(Aec3Optimization::kSse2).Multiply(x, y, z_sse2);
118 for (size_t k = 0; k < z.size(); ++k) {
119 EXPECT_FLOAT_EQ(z[k], z_sse2[k]);
120 EXPECT_FLOAT_EQ(x[k] * y[k], z_sse2[k]);
121 }
122 }
123 }
124
TEST(VectorMath,Accumulate)125 TEST(VectorMath, Accumulate) {
126 if (WebRtc_GetCPUInfo(kSSE2) != 0) {
127 std::array<float, kFftLengthBy2Plus1> x;
128 std::array<float, kFftLengthBy2Plus1> z;
129 std::array<float, kFftLengthBy2Plus1> z_sse2;
130
131 for (size_t k = 0; k < x.size(); ++k) {
132 x[k] = k;
133 z[k] = z_sse2[k] = 2.f * k;
134 }
135
136 aec3::VectorMath(Aec3Optimization::kNone).Accumulate(x, z);
137 aec3::VectorMath(Aec3Optimization::kSse2).Accumulate(x, z_sse2);
138 for (size_t k = 0; k < z.size(); ++k) {
139 EXPECT_FLOAT_EQ(z[k], z_sse2[k]);
140 EXPECT_FLOAT_EQ(x[k] + 2.f * x[k], z_sse2[k]);
141 }
142 }
143 }
144 #endif
145
146 } // namespace webrtc
147