ref: 8f0f274ec0285a7b3b371d4ee1d270e8e732750b
parent: ee8920732d1b1446799c5cb9195cfcb2df1fefe8
author: sdeng <sdeng@google.com>
date: Thu Nov 1 06:21:13 EDT 2018
Refactor Hadamard tests and add highbd tests Change-Id: I306083f233e53884ac21fb4621066713edddc8f7
--- 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