hadamard 16x16 test
BUG=webm:1027 Change-Id: Ibe58781905b372b9fe29dace39b4bfdd33fd0f83
This commit is contained in:
parent
181988d372
commit
32ff4906da
@ -21,20 +21,7 @@ namespace {
|
||||
|
||||
using ::libvpx_test::ACMRandom;
|
||||
|
||||
typedef void (*Hadamard8x8Func)(const int16_t *a, int a_stride,
|
||||
int16_t *b);
|
||||
|
||||
class HadamardTest : public ::testing::TestWithParam<Hadamard8x8Func> {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
h_func_ = GetParam();
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
protected:
|
||||
Hadamard8x8Func h_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
typedef void (*HadamardFunc)(const int16_t *a, int a_stride, int16_t *b);
|
||||
|
||||
void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
||||
int16_t b[8];
|
||||
@ -59,28 +46,74 @@ void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
||||
out[5] = c[3] - c[7];
|
||||
}
|
||||
|
||||
void reference_hadamard(const int16_t *a, int a_stride, int16_t *b) {
|
||||
void reference_hadamard8x8(const int16_t *a, int a_stride, int16_t *b) {
|
||||
int16_t buf[64];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
hadamard_loop(a + i, a_stride, buf + i * 8);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
hadamard_loop(buf + i, 8, b + i * 8);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(HadamardTest, CompareReferenceRandom) {
|
||||
void reference_hadamard16x16(const int16_t *a, int a_stride, int16_t *b) {
|
||||
/* The source is a 16x16 block. The destination is rearranged to 8x32.
|
||||
* Input is 9 bit. */
|
||||
reference_hadamard8x8(a + 0 + 0 * a_stride, a_stride, b + 0);
|
||||
reference_hadamard8x8(a + 8 + 0 * a_stride, a_stride, b + 64);
|
||||
reference_hadamard8x8(a + 0 + 8 * a_stride, a_stride, b + 128);
|
||||
reference_hadamard8x8(a + 8 + 8 * a_stride, a_stride, b + 192);
|
||||
|
||||
/* Overlay the 8x8 blocks and combine. */
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
/* 8x8 steps the range up to 15 bits. */
|
||||
const int16_t a0 = b[0];
|
||||
const int16_t a1 = b[64];
|
||||
const int16_t a2 = b[128];
|
||||
const int16_t a3 = b[192];
|
||||
|
||||
/* Prevent the result from escaping int16_t. */
|
||||
const int16_t b0 = (a0 + a1) >> 1;
|
||||
const int16_t b1 = (a0 - a1) >> 1;
|
||||
const int16_t b2 = (a2 + a3) >> 1;
|
||||
const int16_t b3 = (a2 - a3) >> 1;
|
||||
|
||||
/* Store a 16 bit value. */
|
||||
b[ 0] = b0 + b2;
|
||||
b[ 64] = b1 + b3;
|
||||
b[128] = b0 - b2;
|
||||
b[192] = b1 - b3;
|
||||
|
||||
++b;
|
||||
}
|
||||
}
|
||||
|
||||
class HadamardTestBase : public ::testing::TestWithParam<HadamardFunc> {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
h_func_ = GetParam();
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
protected:
|
||||
HadamardFunc h_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
class Hadamard8x8Test : public HadamardTestBase {};
|
||||
|
||||
TEST_P(Hadamard8x8Test, CompareReferenceRandom) {
|
||||
DECLARE_ALIGNED(16, int16_t, a[64]);
|
||||
DECLARE_ALIGNED(16, int16_t, b[64]);
|
||||
int16_t b_ref[64];
|
||||
for (int i = 0; i < 64; i++) {
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
memset(b, 0, sizeof(b));
|
||||
memset(b_ref, 0, sizeof(b_ref));
|
||||
|
||||
reference_hadamard(a, 8, b_ref);
|
||||
reference_hadamard8x8(a, 8, b_ref);
|
||||
ASM_REGISTER_STATE_CHECK(h_func_(a, 8, b));
|
||||
|
||||
// The order of the output is not important. Sort before checking.
|
||||
@ -89,11 +122,11 @@ TEST_P(HadamardTest, CompareReferenceRandom) {
|
||||
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
||||
}
|
||||
|
||||
TEST_P(HadamardTest, VaryStride) {
|
||||
TEST_P(Hadamard8x8Test, VaryStride) {
|
||||
DECLARE_ALIGNED(16, int16_t, a[64 * 8]);
|
||||
DECLARE_ALIGNED(16, int16_t, b[64]);
|
||||
int16_t b_ref[64];
|
||||
for (int i = 0; i < 64 * 8; i++) {
|
||||
for (int i = 0; i < 64 * 8; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
|
||||
@ -101,7 +134,7 @@ TEST_P(HadamardTest, VaryStride) {
|
||||
memset(b, 0, sizeof(b));
|
||||
memset(b_ref, 0, sizeof(b_ref));
|
||||
|
||||
reference_hadamard(a, i, b_ref);
|
||||
reference_hadamard8x8(a, i, b_ref);
|
||||
ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
|
||||
|
||||
// The order of the output is not important. Sort before checking.
|
||||
@ -111,21 +144,72 @@ TEST_P(HadamardTest, VaryStride) {
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, HadamardTest,
|
||||
INSTANTIATE_TEST_CASE_P(C, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_c));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, HadamardTest,
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_sse2));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_SSSE3 && CONFIG_USE_X86INC && ARCH_X86_64
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, HadamardTest,
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_ssse3));
|
||||
#endif // HAVE_SSSE3 && CONFIG_USE_X86INC && ARCH_X86_64
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, HadamardTest,
|
||||
INSTANTIATE_TEST_CASE_P(NEON, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
class Hadamard16x16Test : public HadamardTestBase {};
|
||||
|
||||
TEST_P(Hadamard16x16Test, CompareReferenceRandom) {
|
||||
DECLARE_ALIGNED(16, int16_t, a[16 * 16]);
|
||||
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
|
||||
int16_t b_ref[16 * 16];
|
||||
for (int i = 0; i < 16 * 16; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
memset(b, 0, sizeof(b));
|
||||
memset(b_ref, 0, sizeof(b_ref));
|
||||
|
||||
reference_hadamard16x16(a, 16, b_ref);
|
||||
ASM_REGISTER_STATE_CHECK(h_func_(a, 16, b));
|
||||
|
||||
// The order of the output is not important. Sort before checking.
|
||||
std::sort(b, b + 16 * 16);
|
||||
std::sort(b_ref, b_ref + 16 * 16);
|
||||
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
||||
}
|
||||
|
||||
TEST_P(Hadamard16x16Test, VaryStride) {
|
||||
DECLARE_ALIGNED(16, int16_t, a[16 * 16 * 8]);
|
||||
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
|
||||
int16_t b_ref[16 * 16];
|
||||
for (int i = 0; i < 16 * 16 * 8; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
|
||||
for (int i = 8; i < 64; i += 8) {
|
||||
memset(b, 0, sizeof(b));
|
||||
memset(b_ref, 0, sizeof(b_ref));
|
||||
|
||||
reference_hadamard16x16(a, i, b_ref);
|
||||
ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
|
||||
|
||||
// The order of the output is not important. Sort before checking.
|
||||
std::sort(b, b + 16 * 16);
|
||||
std::sort(b_ref, b_ref + 16 * 16);
|
||||
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
} // namespace
|
||||
|
Loading…
x
Reference in New Issue
Block a user