blob: 5fca4b60ecfe358c01bf0d8bfa3ced259d4e6663 [file] [log] [blame]
/*
* Copyright (c) 2018, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include <vector>
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "test/function_equivalence_test.h"
#include "test/register_state_check.h"
#include "config/aom_config.h"
#include "config/aom_dsp_rtcd.h"
#include "config/av1_rtcd.h"
#include "aom/aom_integer.h"
#include "av1/encoder/rdopt.h"
using libaom_test::FunctionEquivalenceTest;
namespace {
typedef void (*horver_Func)(const int16_t *diff, int stride, int w, int h,
float *hcorr, float *vcorr);
typedef libaom_test::FuncParam<horver_Func> TestFuncs;
typedef ::testing::tuple<const horver_Func> HorverTestParam;
class HorverTest : public ::testing::TestWithParam<HorverTestParam> {
public:
virtual void SetUp() {
data_buf = (int16_t *)aom_malloc(MAX_SB_SQUARE * sizeof(int16_t));
target_func_ = GET_PARAM(0);
}
virtual void TearDown() { aom_free(data_buf); }
void runHorverTest(void);
void runHorverTest_ExtremeValues(void);
void runHorverSpeedTest(int run_times);
private:
horver_Func target_func_;
ACMRandom rng_;
int16_t *data_buf;
};
void HorverTest::runHorverTest(void) {
for (int block_size = 0; block_size < BLOCK_SIZES_ALL; block_size++) {
const int w = block_size_wide[block_size];
const int h = block_size_high[block_size];
for (int iter = 0; iter < 1000 && !HasFatalFailure(); ++iter) {
float hcorr_ref = 0.0, vcorr_ref = 0.0;
float hcorr_test = 0.0, vcorr_test = 0.0;
for (int i = 0; i < MAX_SB_SQUARE; ++i) {
data_buf[i] = rng_.Rand16() % (1 << 12);
}
av1_get_horver_correlation_full_c(data_buf, MAX_SB_SIZE, w, h, &hcorr_ref,
&vcorr_ref);
target_func_(data_buf, MAX_SB_SIZE, w, h, &hcorr_test, &vcorr_test);
ASSERT_LE(fabs(hcorr_ref - hcorr_test), 1e-6)
<< "hcorr incorrect (" << w << "x" << h << ")";
ASSERT_LE(fabs(vcorr_ref - vcorr_test), 1e-6)
<< "vcorr incorrect (" << w << "x" << h << ")";
}
// printf("(%3dx%-3d) passed\n", w, h);
}
}
void HorverTest::runHorverSpeedTest(int run_times) {
for (int i = 0; i < MAX_SB_SQUARE; ++i) {
data_buf[i] = rng_.Rand16() % (1 << 12);
}
for (int block_size = 0; block_size < BLOCK_SIZES_ALL; block_size++) {
const int w = block_size_wide[block_size];
const int h = block_size_high[block_size];
float hcorr_ref = 0.0, vcorr_ref = 0.0;
float hcorr_test = 0.0, vcorr_test = 0.0;
aom_usec_timer timer;
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
av1_get_horver_correlation_full_c(data_buf, MAX_SB_SIZE, w, h, &hcorr_ref,
&vcorr_ref);
}
aom_usec_timer_mark(&timer);
const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer));
aom_usec_timer_start(&timer);
for (int i = 0; i < run_times; ++i) {
target_func_(data_buf, MAX_SB_SIZE, w, h, &hcorr_test, &vcorr_test);
}
aom_usec_timer_mark(&timer);
const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer));
printf("%3dx%-3d:%7.2f/%7.2fns (%3.2f)\n", w, h, time1, time2,
time1 / time2);
}
}
void HorverTest::runHorverTest_ExtremeValues(void) {
for (int i = 0; i < MAX_SB_SQUARE; ++i) {
// Most of get_horver_test is squaring and summing, so simply saturating
// the whole buffer is mostly likely to cause an overflow.
data_buf[i] = (1 << 12) - 1;
}
for (int block_size = 0; block_size < BLOCK_SIZES_ALL; block_size++) {
const int w = block_size_wide[block_size];
const int h = block_size_high[block_size];
float hcorr_ref = 0.0, vcorr_ref = 0.0;
float hcorr_test = 0.0, vcorr_test = 0.0;
av1_get_horver_correlation_full_c(data_buf, MAX_SB_SIZE, w, h, &hcorr_ref,
&vcorr_ref);
target_func_(data_buf, MAX_SB_SIZE, w, h, &hcorr_test, &vcorr_test);
ASSERT_LE(fabs(hcorr_ref - hcorr_test), 1e-6) << "hcorr incorrect";
ASSERT_LE(fabs(vcorr_ref - vcorr_test), 1e-6) << "vcorr incorrect";
}
}
TEST_P(HorverTest, RandomValues) { runHorverTest(); }
TEST_P(HorverTest, ExtremeValues) { runHorverTest_ExtremeValues(); }
TEST_P(HorverTest, DISABLED_Speed) { runHorverSpeedTest(100000); }
#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(
SSE4_1, HorverTest,
::testing::Values(av1_get_horver_correlation_full_sse4_1));
#endif // HAVE_SSE4_1
#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(
AVX2, HorverTest, ::testing::Values(av1_get_horver_correlation_full_avx2));
#endif // HAVE_AVX2
} // namespace