shithub: libvpx

Download patch

ref: ea54bcc7f34ee13e7ed99d8b77645bc6ae148fbc
parent: f6176a73a20b07e6388cc8526d8eb23d434dc1e7
parent: 8f0f274ec0285a7b3b371d4ee1d270e8e732750b
author: Sai Deng <sdeng@google.com>
date: Tue Nov 6 14:03:17 EST 2018

Merge "Refactor Hadamard tests and add highbd tests"

--- a/test/acm_random.h
+++ b/test/acm_random.h
@@ -34,6 +34,12 @@
     return (value >> 15) & 0xffff;
   }
 
+  int16_t Rand13Signed(void) {
+    // Use 13 bits: values between 4095 and -4096.
+    const uint32_t value = random_.Generate(8192);
+    return static_cast<int16_t>(value) - 4096;
+  }
+
   int16_t Rand9Signed(void) {
     // Use 9 bits: values between 255 (0x0FF) and -256 (0x100).
     const uint32_t value = random_.Generate(512);
--- a/test/hadamard_test.cc
+++ b/test/hadamard_test.cc
@@ -25,13 +25,13 @@
 typedef void (*HadamardFunc)(const int16_t *a, ptrdiff_t a_stride,
                              tran_low_t *b);
 
-void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
-  int16_t b[8];
+void hadamard_loop(const tran_low_t *a, tran_low_t *out) {
+  tran_low_t b[8];
   for (int i = 0; i < 8; i += 2) {
-    b[i + 0] = a[i * a_stride] + a[(i + 1) * a_stride];
-    b[i + 1] = a[i * a_stride] - a[(i + 1) * a_stride];
+    b[i + 0] = a[i * 8] + a[(i + 1) * 8];
+    b[i + 1] = a[i * 8] - a[(i + 1) * 8];
   }
-  int16_t c[8];
+  tran_low_t c[8];
   for (int i = 0; i < 8; i += 4) {
     c[i + 0] = b[i + 0] + b[i + 2];
     c[i + 1] = b[i + 1] + b[i + 3];
@@ -49,12 +49,15 @@
 }
 
 void reference_hadamard8x8(const int16_t *a, int a_stride, tran_low_t *b) {
-  int16_t buf[64];
-  int16_t buf2[64];
-  for (int i = 0; i < 8; ++i) hadamard_loop(a + i, a_stride, buf + i * 8);
-  for (int i = 0; i < 8; ++i) hadamard_loop(buf + i, 8, buf2 + i * 8);
-
-  for (int i = 0; i < 64; ++i) b[i] = (tran_low_t)buf2[i];
+  tran_low_t input[64];
+  tran_low_t buf[64];
+  for (int i = 0; i < 8; ++i) {
+    for (int j = 0; j < 8; ++j) {
+      input[i * 8 + j] = static_cast<tran_low_t>(a[i * a_stride + j]);
+    }
+  }
+  for (int i = 0; i < 8; ++i) hadamard_loop(input + i, buf + i * 8);
+  for (int i = 0; i < 8; ++i) hadamard_loop(buf + i, b + i * 8);
 }
 
 void reference_hadamard16x16(const int16_t *a, int a_stride, tran_low_t *b) {
@@ -115,13 +118,23 @@
   }
 }
 
-class HadamardTestBase : public ::testing::TestWithParam<HadamardFunc> {
+struct HadamardFuncWithSize {
+  HadamardFuncWithSize(HadamardFunc f, int s) : func(f), block_size(s) {}
+  HadamardFunc func;
+  int block_size;
+};
+
+class HadamardTestBase : public ::testing::TestWithParam<HadamardFuncWithSize> {
  public:
   virtual void SetUp() {
-    h_func_ = GetParam();
+    h_func_ = GetParam().func;
+    bwh_ = GetParam().block_size;
+    block_size_ = bwh_ * bwh_;
     rnd_.Reset(ACMRandom::DeterministicSeed());
   }
 
+  virtual int16_t Rand() = 0;
+
   void ReferenceHadamard(const int16_t *a, int a_stride, tran_low_t *b,
                          int bwh) {
     if (bwh == 32)
@@ -132,107 +145,122 @@
       reference_hadamard8x8(a, a_stride, b);
   }
 
-  template <int bwh>
   void CompareReferenceRandom() {
-    const int kBlockSize = bwh * bwh;
-    DECLARE_ALIGNED(16, int16_t, a[kBlockSize]);
-    DECLARE_ALIGNED(16, tran_low_t, b[kBlockSize]);
-    tran_low_t b_ref[kBlockSize];
-    for (int i = 0; i < kBlockSize; ++i) {
-      a[i] = rnd_.Rand9Signed();
-    }
+    const int kMaxBlockSize = 32 * 32;
+    DECLARE_ALIGNED(16, int16_t, a[kMaxBlockSize]);
+    DECLARE_ALIGNED(16, tran_low_t, b[kMaxBlockSize]);
+    memset(a, 0, sizeof(a));
     memset(b, 0, sizeof(b));
+
+    tran_low_t b_ref[kMaxBlockSize];
     memset(b_ref, 0, sizeof(b_ref));
 
-    ReferenceHadamard(a, bwh, b_ref, bwh);
-    ASM_REGISTER_STATE_CHECK(h_func_(a, bwh, b));
+    for (int i = 0; i < block_size_; ++i) a[i] = Rand();
 
+    ReferenceHadamard(a, bwh_, b_ref, bwh_);
+    ASM_REGISTER_STATE_CHECK(h_func_(a, bwh_, b));
+
     // The order of the output is not important. Sort before checking.
-    std::sort(b, b + kBlockSize);
-    std::sort(b_ref, b_ref + kBlockSize);
+    std::sort(b, b + block_size_);
+    std::sort(b_ref, b_ref + block_size_);
     EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
   }
 
-  template <int bwh>
   void VaryStride() {
-    const int kBlockSize = bwh * bwh;
-    DECLARE_ALIGNED(16, int16_t, a[kBlockSize * 8]);
-    DECLARE_ALIGNED(16, tran_low_t, b[kBlockSize]);
-    tran_low_t b_ref[kBlockSize];
-    for (int i = 0; i < kBlockSize * 8; ++i) {
-      a[i] = rnd_.Rand9Signed();
-    }
+    const int kMaxBlockSize = 32 * 32;
+    DECLARE_ALIGNED(16, int16_t, a[kMaxBlockSize * 8]);
+    DECLARE_ALIGNED(16, tran_low_t, b[kMaxBlockSize]);
+    memset(a, 0, sizeof(a));
+    for (int i = 0; i < block_size_ * 8; ++i) a[i] = Rand();
 
+    tran_low_t b_ref[kMaxBlockSize];
     for (int i = 8; i < 64; i += 8) {
       memset(b, 0, sizeof(b));
       memset(b_ref, 0, sizeof(b_ref));
 
-      ReferenceHadamard(a, i, b_ref, bwh);
+      ReferenceHadamard(a, i, b_ref, bwh_);
       ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
 
       // The order of the output is not important. Sort before checking.
-      std::sort(b, b + kBlockSize);
-      std::sort(b_ref, b_ref + kBlockSize);
+      std::sort(b, b + block_size_);
+      std::sort(b_ref, b_ref + block_size_);
       EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
     }
   }
 
+  void SpeedTest(int times) {
+    const int kMaxBlockSize = 32 * 32;
+    DECLARE_ALIGNED(16, int16_t, input[kMaxBlockSize]);
+    DECLARE_ALIGNED(16, tran_low_t, output[kMaxBlockSize]);
+    memset(input, 1, sizeof(input));
+    memset(output, 0, sizeof(output));
+
+    vpx_usec_timer timer;
+    vpx_usec_timer_start(&timer);
+    for (int i = 0; i < times; ++i) {
+      h_func_(input, bwh_, output);
+    }
+    vpx_usec_timer_mark(&timer);
+
+    const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
+    printf("Hadamard%dx%d[%12d runs]: %d us\n", bwh_, bwh_, times,
+           elapsed_time);
+  }
+
  protected:
+  int bwh_;
+  int block_size_;
   HadamardFunc h_func_;
   ACMRandom rnd_;
 };
 
-void HadamardSpeedTest(const char *name, HadamardFunc const func,
-                       const int16_t *input, int stride, tran_low_t *output,
-                       int times) {
-  int i;
-  vpx_usec_timer timer;
+class HadamardLowbdTest : public HadamardTestBase {
+ protected:
+  virtual int16_t Rand() { return rnd_.Rand9Signed(); }
+};
 
-  vpx_usec_timer_start(&timer);
-  for (i = 0; i < times; ++i) {
-    func(input, stride, output);
-  }
-  vpx_usec_timer_mark(&timer);
+TEST_P(HadamardLowbdTest, CompareReferenceRandom) { CompareReferenceRandom(); }
 
-  const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
-  printf("%s[%12d runs]: %d us\n", name, times, elapsed_time);
-}
+TEST_P(HadamardLowbdTest, VaryStride) { VaryStride(); }
 
-class Hadamard8x8Test : public HadamardTestBase {};
-
-void HadamardSpeedTest8x8(HadamardFunc const func, int times) {
-  DECLARE_ALIGNED(16, int16_t, input[64]);
-  DECLARE_ALIGNED(16, tran_low_t, output[64]);
-  memset(input, 1, sizeof(input));
-  HadamardSpeedTest("Hadamard8x8", func, input, 8, output, times);
+TEST_P(HadamardLowbdTest, DISABLED_Speed) {
+  SpeedTest(10);
+  SpeedTest(10000);
+  SpeedTest(10000000);
 }
 
-TEST_P(Hadamard8x8Test, CompareReferenceRandom) { CompareReferenceRandom<8>(); }
+INSTANTIATE_TEST_CASE_P(
+    C, HadamardLowbdTest,
+    ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_c, 8),
+                      HadamardFuncWithSize(&vpx_hadamard_16x16_c, 16),
+                      HadamardFuncWithSize(&vpx_hadamard_32x32_c, 32)));
 
-TEST_P(Hadamard8x8Test, VaryStride) { VaryStride<8>(); }
-
-TEST_P(Hadamard8x8Test, DISABLED_Speed) {
-  HadamardSpeedTest8x8(h_func_, 10);
-  HadamardSpeedTest8x8(h_func_, 10000);
-  HadamardSpeedTest8x8(h_func_, 10000000);
-}
-
-INSTANTIATE_TEST_CASE_P(C, Hadamard8x8Test,
-                        ::testing::Values(&vpx_hadamard_8x8_c));
-
 #if HAVE_SSE2
-INSTANTIATE_TEST_CASE_P(SSE2, Hadamard8x8Test,
-                        ::testing::Values(&vpx_hadamard_8x8_sse2));
+INSTANTIATE_TEST_CASE_P(
+    SSE2, HadamardLowbdTest,
+    ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_sse2, 8),
+                      HadamardFuncWithSize(&vpx_hadamard_16x16_sse2, 16),
+                      HadamardFuncWithSize(&vpx_hadamard_32x32_sse2, 32)));
 #endif  // HAVE_SSE2
 
+#if HAVE_AVX2
+INSTANTIATE_TEST_CASE_P(
+    AVX2, HadamardLowbdTest,
+    ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_16x16_avx2, 16),
+                      HadamardFuncWithSize(&vpx_hadamard_32x32_avx2, 32)));
+#endif  // HAVE_AVX2
+
 #if HAVE_SSSE3 && ARCH_X86_64
-INSTANTIATE_TEST_CASE_P(SSSE3, Hadamard8x8Test,
-                        ::testing::Values(&vpx_hadamard_8x8_ssse3));
+INSTANTIATE_TEST_CASE_P(
+    SSSE3, HadamardLowbdTest,
+    ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_ssse3, 8)));
 #endif  // HAVE_SSSE3 && ARCH_X86_64
 
 #if HAVE_NEON
-INSTANTIATE_TEST_CASE_P(NEON, Hadamard8x8Test,
-                        ::testing::Values(&vpx_hadamard_8x8_neon));
+INSTANTIATE_TEST_CASE_P(
+    NEON, HadamardLowbdTest,
+    ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_neon, 8),
+                      HadamardFuncWithSize(&vpx_hadamard_16x16_neon, 16)));
 #endif  // HAVE_NEON
 
 // TODO(jingning): Remove highbitdepth flag when the SIMD functions are
@@ -239,98 +267,40 @@
 // in place and turn on the unit test.
 #if !CONFIG_VP9_HIGHBITDEPTH
 #if HAVE_MSA
-INSTANTIATE_TEST_CASE_P(MSA, Hadamard8x8Test,
-                        ::testing::Values(&vpx_hadamard_8x8_msa));
+INSTANTIATE_TEST_CASE_P(
+    MSA, HadamardLowbdTest,
+    ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_msa, 8),
+                      HadamardFuncWithSize(&vpx_hadamard_16x16_msa, 16)));
 #endif  // HAVE_MSA
 #endif  // !CONFIG_VP9_HIGHBITDEPTH
 
 #if HAVE_VSX
-INSTANTIATE_TEST_CASE_P(VSX, Hadamard8x8Test,
-                        ::testing::Values(&vpx_hadamard_8x8_vsx));
+INSTANTIATE_TEST_CASE_P(
+    VSX, HadamardLowbdTest,
+    ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_vsx, 8),
+                      HadamardFuncWithSize(&vpx_hadamard_16x16_vsx, 16)));
 #endif  // HAVE_VSX
 
-class Hadamard16x16Test : public HadamardTestBase {};
+#if CONFIG_VP9_HIGHBITDEPTH
+class HadamardHighbdTest : public HadamardTestBase {
+ protected:
+  virtual int16_t Rand() { return rnd_.Rand13Signed(); }
+};
 
-void HadamardSpeedTest16x16(HadamardFunc const func, int times) {
-  DECLARE_ALIGNED(16, int16_t, input[256]);
-  DECLARE_ALIGNED(16, tran_low_t, output[256]);
-  memset(input, 1, sizeof(input));
-  HadamardSpeedTest("Hadamard16x16", func, input, 16, output, times);
-}
+TEST_P(HadamardHighbdTest, CompareReferenceRandom) { CompareReferenceRandom(); }
 
-TEST_P(Hadamard16x16Test, CompareReferenceRandom) {
-  CompareReferenceRandom<16>();
-}
+TEST_P(HadamardHighbdTest, VaryStride) { VaryStride(); }
 
-TEST_P(Hadamard16x16Test, VaryStride) { VaryStride<16>(); }
-
-TEST_P(Hadamard16x16Test, DISABLED_Speed) {
-  HadamardSpeedTest16x16(h_func_, 10);
-  HadamardSpeedTest16x16(h_func_, 10000);
-  HadamardSpeedTest16x16(h_func_, 10000000);
+TEST_P(HadamardHighbdTest, DISABLED_Speed) {
+  SpeedTest(10);
+  SpeedTest(10000);
+  SpeedTest(10000000);
 }
 
-INSTANTIATE_TEST_CASE_P(C, Hadamard16x16Test,
-                        ::testing::Values(&vpx_hadamard_16x16_c));
-
-#if HAVE_SSE2
-INSTANTIATE_TEST_CASE_P(SSE2, Hadamard16x16Test,
-                        ::testing::Values(&vpx_hadamard_16x16_sse2));
-#endif  // HAVE_SSE2
-
-#if HAVE_AVX2
-INSTANTIATE_TEST_CASE_P(AVX2, Hadamard16x16Test,
-                        ::testing::Values(&vpx_hadamard_16x16_avx2));
-#endif  // HAVE_AVX2
-
-#if HAVE_VSX
-INSTANTIATE_TEST_CASE_P(VSX, Hadamard16x16Test,
-                        ::testing::Values(&vpx_hadamard_16x16_vsx));
-#endif  // HAVE_VSX
-
-#if HAVE_NEON
-INSTANTIATE_TEST_CASE_P(NEON, Hadamard16x16Test,
-                        ::testing::Values(&vpx_hadamard_16x16_neon));
-#endif  // HAVE_NEON
-
-#if !CONFIG_VP9_HIGHBITDEPTH
-#if HAVE_MSA
-INSTANTIATE_TEST_CASE_P(MSA, Hadamard16x16Test,
-                        ::testing::Values(&vpx_hadamard_16x16_msa));
-#endif  // HAVE_MSA
-#endif  // !CONFIG_VP9_HIGHBITDEPTH
-
-class Hadamard32x32Test : public HadamardTestBase {};
-
-void HadamardSpeedTest32x32(HadamardFunc const func, int times) {
-  DECLARE_ALIGNED(16, int16_t, input[1024]);
-  DECLARE_ALIGNED(16, tran_low_t, output[1024]);
-  memset(input, 1, sizeof(input));
-  HadamardSpeedTest("Hadamard32x32", func, input, 32, output, times);
-}
-
-TEST_P(Hadamard32x32Test, CompareReferenceRandom) {
-  CompareReferenceRandom<32>();
-}
-
-TEST_P(Hadamard32x32Test, VaryStride) { VaryStride<32>(); }
-
-TEST_P(Hadamard32x32Test, DISABLED_Speed) {
-  HadamardSpeedTest32x32(h_func_, 10);
-  HadamardSpeedTest32x32(h_func_, 10000);
-  HadamardSpeedTest32x32(h_func_, 10000000);
-}
-
-INSTANTIATE_TEST_CASE_P(C, Hadamard32x32Test,
-                        ::testing::Values(&vpx_hadamard_32x32_c));
-
-#if HAVE_SSE2
-INSTANTIATE_TEST_CASE_P(SSE2, Hadamard32x32Test,
-                        ::testing::Values(&vpx_hadamard_32x32_sse2));
-#endif  // HAVE_SSE2
-
-#if HAVE_AVX2
-INSTANTIATE_TEST_CASE_P(AVX2, Hadamard32x32Test,
-                        ::testing::Values(&vpx_hadamard_32x32_avx2));
-#endif  // HAVE_AVX2
+INSTANTIATE_TEST_CASE_P(
+    C, HadamardHighbdTest,
+    ::testing::Values(HadamardFuncWithSize(&vpx_highbd_hadamard_8x8_c, 8),
+                      HadamardFuncWithSize(&vpx_highbd_hadamard_16x16_c, 16),
+                      HadamardFuncWithSize(&vpx_highbd_hadamard_32x32_c, 32)));
+#endif  // CONFIG_VP9_HIGHBITDEPTH
 }  // namespace