blob: c03238aa46f89e2dc0eed7b3aebd53d088374221 [file] [log] [blame] [edit]
/*
* Copyright (c) 2025, 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 "config/av1_rtcd.h"
#include "test/acm_random.h"
#include "test/util.h"
namespace {
typedef void (*make_bawp_func)(uint16_t *dst, int dst_stride, int16_t alpha,
int32_t beta, int shift, int bw, int bh, int bd);
#if HAVE_AVX2
const BLOCK_SIZE kValidBlockSize[] = {
BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, BLOCK_8X8, BLOCK_8X16,
BLOCK_16X8, BLOCK_16X16, BLOCK_16X32, BLOCK_32X16, BLOCK_32X32,
BLOCK_32X64, BLOCK_64X32, BLOCK_64X64, BLOCK_64X128, BLOCK_128X64,
BLOCK_128X128, BLOCK_128X256, BLOCK_256X128, BLOCK_256X256, BLOCK_4X16,
BLOCK_16X4, BLOCK_8X32, BLOCK_32X8, BLOCK_16X64, BLOCK_64X16,
BLOCK_4X32, BLOCK_32X4, BLOCK_8X64, BLOCK_64X8, BLOCK_4X64,
BLOCK_64X4,
};
#endif // HAVE_AVX2
typedef std::tuple<make_bawp_func, BLOCK_SIZE> BAWPParam;
class BAWPTest : public ::testing::TestWithParam<BAWPParam> {
public:
~BAWPTest();
void SetUp();
void TearDown();
protected:
void RunCheckOutput(make_bawp_func test_impl, BLOCK_SIZE bsize);
void RunSpeedTest(make_bawp_func test_impl, BLOCK_SIZE bsize);
bool CheckResult(int width, int height) {
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
const int idx = y * width + x;
if (pred1_[idx] != pred2_[idx]) {
printf("%dx%d mismatch @%d(%d,%d) ", width, height, idx, x, y);
printf("%d != %d ", pred1_[idx], pred2_[idx]);
return false;
}
}
}
return true;
}
libaom_test::ACMRandom rnd_;
uint16_t *pred1_;
uint16_t *pred2_;
};
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BAWPTest);
BAWPTest::~BAWPTest() {}
void BAWPTest::SetUp() {
rnd_.Reset(libaom_test::ACMRandom::DeterministicSeed());
pred1_ = (uint16_t *)aom_memalign(
16, MAX_SB_SIZE * MAX_SB_SIZE * sizeof(uint16_t));
ASSERT_NE(pred1_, nullptr);
pred2_ = (uint16_t *)aom_memalign(
16, MAX_SB_SIZE * MAX_SB_SIZE * sizeof(uint16_t));
ASSERT_NE(pred2_, nullptr);
for (int i = 0; i < (MAX_SB_SIZE * MAX_SB_SIZE); ++i) {
pred1_[i] = rnd_.Rand16();
pred2_[i] = pred1_[i];
}
}
void BAWPTest::TearDown() {
aom_free(pred1_);
aom_free(pred2_);
}
void BAWPTest::RunCheckOutput(make_bawp_func test_impl, BLOCK_SIZE bsize) {
const int w = block_size_wide[bsize];
const int h = block_size_high[bsize];
const int16_t alpha = 320;
const int32_t beta = -42036;
const int shift = 8;
int bd[3] = { 8, 10, 12 };
for (int i = 0; i < 3; ++i) {
av1_make_bawp_block_c(pred1_, MAX_SB_SIZE, alpha, beta, shift, w, h, bd[i]);
test_impl(pred2_, MAX_SB_SIZE, alpha, beta, shift, w, h, bd[i]);
ASSERT_EQ(CheckResult(w, h), true);
}
}
void BAWPTest::RunSpeedTest(make_bawp_func test_impl, BLOCK_SIZE bsize) {
const int w = block_size_wide[bsize];
const int h = block_size_high[bsize];
const int num_loops = 1000000000 / (w + h);
const int16_t alpha = 320;
const int32_t beta = -42036;
const int shift = 8;
int bd = 8;
make_bawp_func functions[2] = { av1_make_bawp_block_c, test_impl };
double elapsed_time[2] = { 0.0 };
for (int i = 0; i < 2; ++i) {
aom_usec_timer timer;
aom_usec_timer_start(&timer);
make_bawp_func func = functions[i];
for (int j = 0; j < num_loops; ++j) {
func(pred1_, MAX_SB_SIZE, alpha, beta, shift, w, h, bd);
}
aom_usec_timer_mark(&timer);
const double time = static_cast<double>(aom_usec_timer_elapsed(&timer));
elapsed_time[i] = 1000.0 * time;
}
printf("BAWP %3dx%-3d: c_time=%7.2fs, simd_time=%7.2fs, scaling=%3.2f\n", w,
h, elapsed_time[0], elapsed_time[1],
elapsed_time[0] / elapsed_time[1]);
}
TEST_P(BAWPTest, CheckOutput) { RunCheckOutput(GET_PARAM(0), GET_PARAM(1)); }
TEST_P(BAWPTest, DISABLED_Speed) { RunSpeedTest(GET_PARAM(0), GET_PARAM(1)); }
#if HAVE_AVX2
INSTANTIATE_TEST_SUITE_P(
AVX2, BAWPTest,
::testing::Combine(::testing::Values(&av1_make_bawp_block_avx2),
::testing::ValuesIn(kValidBlockSize)));
#endif // HAVE_AVX2
} // namespace