tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

vector_math_unittest.cc (6356B)


      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 <algorithm>
     14 #include <array>
     15 #include <cmath>
     16 #include <cstddef>
     17 
     18 #include "modules/audio_processing/aec3/aec3_common.h"
     19 #include "rtc_base/cpu_info.h"
     20 #include "rtc_base/system/arch.h"
     21 #include "test/gtest.h"
     22 
     23 namespace webrtc {
     24 
     25 #if defined(WEBRTC_HAS_NEON)
     26 
     27 TEST(VectorMath, Sqrt) {
     28  std::array<float, kFftLengthBy2Plus1> x;
     29  std::array<float, kFftLengthBy2Plus1> z;
     30  std::array<float, kFftLengthBy2Plus1> z_neon;
     31 
     32  for (size_t k = 0; k < x.size(); ++k) {
     33    x[k] = (2.f / 3.f) * k;
     34  }
     35 
     36  std::copy(x.begin(), x.end(), z.begin());
     37  aec3::VectorMath(Aec3Optimization::kNone).Sqrt(z);
     38  std::copy(x.begin(), x.end(), z_neon.begin());
     39  aec3::VectorMath(Aec3Optimization::kNeon).Sqrt(z_neon);
     40  for (size_t k = 0; k < z.size(); ++k) {
     41    EXPECT_NEAR(z[k], z_neon[k], 0.0001f);
     42    EXPECT_NEAR(sqrtf(x[k]), z_neon[k], 0.0001f);
     43  }
     44 }
     45 
     46 TEST(VectorMath, Multiply) {
     47  std::array<float, kFftLengthBy2Plus1> x;
     48  std::array<float, kFftLengthBy2Plus1> y;
     49  std::array<float, kFftLengthBy2Plus1> z;
     50  std::array<float, kFftLengthBy2Plus1> z_neon;
     51 
     52  for (size_t k = 0; k < x.size(); ++k) {
     53    x[k] = k;
     54    y[k] = (2.f / 3.f) * k;
     55  }
     56 
     57  aec3::VectorMath(Aec3Optimization::kNone).Multiply(x, y, z);
     58  aec3::VectorMath(Aec3Optimization::kNeon).Multiply(x, y, z_neon);
     59  for (size_t k = 0; k < z.size(); ++k) {
     60    EXPECT_FLOAT_EQ(z[k], z_neon[k]);
     61    EXPECT_FLOAT_EQ(x[k] * y[k], z_neon[k]);
     62  }
     63 }
     64 
     65 TEST(VectorMath, Accumulate) {
     66  std::array<float, kFftLengthBy2Plus1> x;
     67  std::array<float, kFftLengthBy2Plus1> z;
     68  std::array<float, kFftLengthBy2Plus1> z_neon;
     69 
     70  for (size_t k = 0; k < x.size(); ++k) {
     71    x[k] = k;
     72    z[k] = z_neon[k] = 2.f * k;
     73  }
     74 
     75  aec3::VectorMath(Aec3Optimization::kNone).Accumulate(x, z);
     76  aec3::VectorMath(Aec3Optimization::kNeon).Accumulate(x, z_neon);
     77  for (size_t k = 0; k < z.size(); ++k) {
     78    EXPECT_FLOAT_EQ(z[k], z_neon[k]);
     79    EXPECT_FLOAT_EQ(x[k] + 2.f * x[k], z_neon[k]);
     80  }
     81 }
     82 #endif
     83 
     84 #if defined(WEBRTC_ARCH_X86_FAMILY)
     85 
     86 TEST(VectorMath, Sse2Sqrt) {
     87  if (cpu_info::Supports(cpu_info::ISA::kSSE2)) {
     88    std::array<float, kFftLengthBy2Plus1> x;
     89    std::array<float, kFftLengthBy2Plus1> z;
     90    std::array<float, kFftLengthBy2Plus1> z_sse2;
     91 
     92    for (size_t k = 0; k < x.size(); ++k) {
     93      x[k] = (2.f / 3.f) * k;
     94    }
     95 
     96    std::copy(x.begin(), x.end(), z.begin());
     97    aec3::VectorMath(Aec3Optimization::kNone).Sqrt(z);
     98    std::copy(x.begin(), x.end(), z_sse2.begin());
     99    aec3::VectorMath(Aec3Optimization::kSse2).Sqrt(z_sse2);
    100    EXPECT_EQ(z, z_sse2);
    101    for (size_t k = 0; k < z.size(); ++k) {
    102      EXPECT_FLOAT_EQ(z[k], z_sse2[k]);
    103      EXPECT_FLOAT_EQ(sqrtf(x[k]), z_sse2[k]);
    104    }
    105  }
    106 }
    107 
    108 TEST(VectorMath, Avx2Sqrt) {
    109  if (cpu_info::Supports(cpu_info::ISA::kAVX2)) {
    110    std::array<float, kFftLengthBy2Plus1> x;
    111    std::array<float, kFftLengthBy2Plus1> z;
    112    std::array<float, kFftLengthBy2Plus1> z_avx2;
    113 
    114    for (size_t k = 0; k < x.size(); ++k) {
    115      x[k] = (2.f / 3.f) * k;
    116    }
    117 
    118    std::copy(x.begin(), x.end(), z.begin());
    119    aec3::VectorMath(Aec3Optimization::kNone).Sqrt(z);
    120    std::copy(x.begin(), x.end(), z_avx2.begin());
    121    aec3::VectorMath(Aec3Optimization::kAvx2).Sqrt(z_avx2);
    122    EXPECT_EQ(z, z_avx2);
    123    for (size_t k = 0; k < z.size(); ++k) {
    124      EXPECT_FLOAT_EQ(z[k], z_avx2[k]);
    125      EXPECT_FLOAT_EQ(sqrtf(x[k]), z_avx2[k]);
    126    }
    127  }
    128 }
    129 
    130 TEST(VectorMath, Sse2Multiply) {
    131  if (cpu_info::Supports(cpu_info::ISA::kSSE2)) {
    132    std::array<float, kFftLengthBy2Plus1> x;
    133    std::array<float, kFftLengthBy2Plus1> y;
    134    std::array<float, kFftLengthBy2Plus1> z;
    135    std::array<float, kFftLengthBy2Plus1> z_sse2;
    136 
    137    for (size_t k = 0; k < x.size(); ++k) {
    138      x[k] = k;
    139      y[k] = (2.f / 3.f) * k;
    140    }
    141 
    142    aec3::VectorMath(Aec3Optimization::kNone).Multiply(x, y, z);
    143    aec3::VectorMath(Aec3Optimization::kSse2).Multiply(x, y, z_sse2);
    144    for (size_t k = 0; k < z.size(); ++k) {
    145      EXPECT_FLOAT_EQ(z[k], z_sse2[k]);
    146      EXPECT_FLOAT_EQ(x[k] * y[k], z_sse2[k]);
    147    }
    148  }
    149 }
    150 
    151 TEST(VectorMath, Avx2Multiply) {
    152  if (cpu_info::Supports(cpu_info::ISA::kAVX2)) {
    153    std::array<float, kFftLengthBy2Plus1> x;
    154    std::array<float, kFftLengthBy2Plus1> y;
    155    std::array<float, kFftLengthBy2Plus1> z;
    156    std::array<float, kFftLengthBy2Plus1> z_avx2;
    157 
    158    for (size_t k = 0; k < x.size(); ++k) {
    159      x[k] = k;
    160      y[k] = (2.f / 3.f) * k;
    161    }
    162 
    163    aec3::VectorMath(Aec3Optimization::kNone).Multiply(x, y, z);
    164    aec3::VectorMath(Aec3Optimization::kAvx2).Multiply(x, y, z_avx2);
    165    for (size_t k = 0; k < z.size(); ++k) {
    166      EXPECT_FLOAT_EQ(z[k], z_avx2[k]);
    167      EXPECT_FLOAT_EQ(x[k] * y[k], z_avx2[k]);
    168    }
    169  }
    170 }
    171 
    172 TEST(VectorMath, Sse2Accumulate) {
    173  if (cpu_info::Supports(cpu_info::ISA::kSSE2)) {
    174    std::array<float, kFftLengthBy2Plus1> x;
    175    std::array<float, kFftLengthBy2Plus1> z;
    176    std::array<float, kFftLengthBy2Plus1> z_sse2;
    177 
    178    for (size_t k = 0; k < x.size(); ++k) {
    179      x[k] = k;
    180      z[k] = z_sse2[k] = 2.f * k;
    181    }
    182 
    183    aec3::VectorMath(Aec3Optimization::kNone).Accumulate(x, z);
    184    aec3::VectorMath(Aec3Optimization::kSse2).Accumulate(x, z_sse2);
    185    for (size_t k = 0; k < z.size(); ++k) {
    186      EXPECT_FLOAT_EQ(z[k], z_sse2[k]);
    187      EXPECT_FLOAT_EQ(x[k] + 2.f * x[k], z_sse2[k]);
    188    }
    189  }
    190 }
    191 
    192 TEST(VectorMath, Avx2Accumulate) {
    193  if (cpu_info::Supports(cpu_info::ISA::kAVX2)) {
    194    std::array<float, kFftLengthBy2Plus1> x;
    195    std::array<float, kFftLengthBy2Plus1> z;
    196    std::array<float, kFftLengthBy2Plus1> z_avx2;
    197 
    198    for (size_t k = 0; k < x.size(); ++k) {
    199      x[k] = k;
    200      z[k] = z_avx2[k] = 2.f * k;
    201    }
    202 
    203    aec3::VectorMath(Aec3Optimization::kNone).Accumulate(x, z);
    204    aec3::VectorMath(Aec3Optimization::kAvx2).Accumulate(x, z_avx2);
    205    for (size_t k = 0; k < z.size(); ++k) {
    206      EXPECT_FLOAT_EQ(z[k], z_avx2[k]);
    207      EXPECT_FLOAT_EQ(x[k] + 2.f * x[k], z_avx2[k]);
    208    }
    209  }
    210 }
    211 #endif
    212 
    213 }  // namespace webrtc