blob: a98533d495784618b2bad2772e36fbcb55f9aa45 [file] [log] [blame]
/*
* Copyright (c) 2021, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 3-Clause Clear License
* and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
* License was not distributed with this source code in the LICENSE file, you
* can obtain it at aomedia.org/license/software-license/bsd-3-c-c/. 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
* aomedia.org/license/patent-license/.
*/
#include <tuple>
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "test/acm_random.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "config/aom_config.h"
#include "config/aom_dsp_rtcd.h"
#include "config/av1_rtcd.h"
#include "aom/aom_integer.h"
using libaom_test::ACMRandom;
namespace {
typedef void (*HorverFunc)(const int16_t *diff, int stride, int w, int h,
float *hcorr, float *vcorr);
typedef std::tuple<const HorverFunc> HorverTestParam;
class HorverTest : public ::testing::TestWithParam<HorverTestParam> {
public:
virtual void SetUp() {
data_buf_ = (int16_t *)aom_malloc(MAX_SB_SQUARE * sizeof(int16_t));
ASSERT_NE(data_buf_, nullptr);
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:
HorverFunc target_func_;
ACMRandom rng_;
int16_t *data_buf_;
};
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HorverTest);
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)) - (1 << 11);
}
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_SUITE_P(
SSE4_1, HorverTest,
::testing::Values(av1_get_horver_correlation_full_sse4_1));
#endif // HAVE_SSE4_1
#if HAVE_NEON
INSTANTIATE_TEST_SUITE_P(
NEON, HorverTest, ::testing::Values(av1_get_horver_correlation_full_neon));
#endif // HAVE_NEON
#if HAVE_AVX2
INSTANTIATE_TEST_SUITE_P(
AVX2, HorverTest, ::testing::Values(av1_get_horver_correlation_full_avx2));
#endif // HAVE_AVX2
} // namespace