[non-normative] Multiple inheritance for CfL Test Add more flexibility to cfl_test for upcoming tests on 4:2:2 and 4:4:4 luma subsampling SIMD. Change-Id: I8f686654f7b0bf8b8a7a79d7c60b6429492e67d3
diff --git a/test/cfl_test.cc b/test/cfl_test.cc index 5dfd28e..dadbfdc 100644 --- a/test/cfl_test.cc +++ b/test/cfl_test.cc
@@ -32,21 +32,6 @@ make_tuple(TX_32X16, &function), make_tuple(TX_32X32, &function) namespace { -typedef cfl_subsample_lbd_fn (*get_subsample_fn)(TX_SIZE tx_size); - -typedef cfl_predict_lbd_fn (*get_predict_fn)(TX_SIZE tx_size); - -typedef cfl_predict_hbd_fn (*get_predict_fn_hbd)(TX_SIZE tx_size); - -typedef cfl_subtract_average_fn (*sub_avg_fn)(TX_SIZE tx_size); - -typedef ::testing::tuple<TX_SIZE, get_subsample_fn> subsample_param; - -typedef ::testing::tuple<TX_SIZE, get_predict_fn> predict_param; - -typedef ::testing::tuple<TX_SIZE, get_predict_fn_hbd> predict_param_hbd; - -typedef ::testing::tuple<TX_SIZE, sub_avg_fn> sub_avg_param; template <typename A> static void assert_eq(const A *a, const A *b, int width, int height) { @@ -74,37 +59,32 @@ << std::endl; } -template <typename F> -class CFLTest - : public ::testing::TestWithParam< ::testing::tuple<TX_SIZE, F> > { +class CFLTest { public: virtual ~CFLTest() {} - virtual void SetUp() { - tx_size = ::testing::get<0>(this->GetParam()); + void init(TX_SIZE tx) { + tx_size = tx; width = tx_size_wide[tx_size]; height = tx_size_high[tx_size]; - fun_under_test = ::testing::get<1>(this->GetParam()); rnd(ACMRandom::DeterministicSeed()); } protected: - ACMRandom rnd; - F fun_under_test; TX_SIZE tx_size; int width; int height; + ACMRandom rnd; }; -template <typename F, typename I> -class CFLTestWithData : public CFLTest<F> { +template <typename I> +class CFLTestWithData : public CFLTest { public: virtual ~CFLTestWithData() {} protected: I data[CFL_BUF_SQUARE]; I data_ref[CFL_BUF_SQUARE]; - - void init(I (ACMRandom::*random)()) { + void randData(I (ACMRandom::*random)()) { for (int j = 0; j < this->height; j++) { for (int i = 0; i < this->width; i++) { const I d = (this->rnd.*random)(); @@ -115,12 +95,10 @@ } }; -template <typename F, typename I> -class CFLTestWithAlignedData : public CFLTest<F> { +template <typename I> +class CFLTestWithAlignedData : public CFLTest { public: - virtual ~CFLTestWithAlignedData() {} - virtual void SetUp() { - CFLTest<F>::SetUp(); + CFLTestWithAlignedData() { chroma_pels_ref = reinterpret_cast<I *>(aom_memalign(32, sizeof(I) * CFL_BUF_SQUARE)); chroma_pels = @@ -134,8 +112,7 @@ memset(sub_luma_pels_ref, 0, sizeof(int16_t) * CFL_BUF_SQUARE); memset(sub_luma_pels, 0, sizeof(int16_t) * CFL_BUF_SQUARE); } - - virtual void TearDown() { + ~CFLTestWithAlignedData() { aom_free(chroma_pels_ref); aom_free(sub_luma_pels_ref); aom_free(chroma_pels); @@ -149,7 +126,7 @@ int16_t *sub_luma_pels; int alpha_q3; I dc; - void init(int bd) { + void randData(int bd) { alpha_q3 = this->rnd(33) - 16; dc = this->rnd(1 << bd); for (int j = 0; j < this->height; j++) { @@ -163,180 +140,211 @@ } }; -class CFLSubAvgTest : public CFLTestWithData<sub_avg_fn, int16_t> { +typedef cfl_subtract_average_fn (*sub_avg_fn)(TX_SIZE tx_size); +typedef ::testing::tuple<TX_SIZE, sub_avg_fn> sub_avg_param; +class CFLSubAvgTest : public ::testing::TestWithParam<sub_avg_param>, + public CFLTestWithData<int16_t> { public: + virtual void SetUp() { + CFLTest::init(::testing::get<0>(this->GetParam())); + sub_avg = ::testing::get<1>(this->GetParam())(tx_size); + sub_avg_ref = get_subtract_average_fn_c(tx_size); + } virtual ~CFLSubAvgTest() {} -}; -class CFLSubsampleTest : public CFLTestWithData<get_subsample_fn, uint8_t> { - public: - virtual ~CFLSubsampleTest() {} -}; - -class CFLPredictTest : public CFLTestWithAlignedData<get_predict_fn, uint8_t> { - public: - virtual ~CFLPredictTest() {} -}; - -class CFLPredictHBDTest - : public CFLTestWithAlignedData<get_predict_fn_hbd, uint16_t> { - public: - virtual ~CFLPredictHBDTest() {} + protected: + cfl_subtract_average_fn sub_avg; + cfl_subtract_average_fn sub_avg_ref; }; TEST_P(CFLSubAvgTest, SubAvgTest) { - const cfl_subtract_average_fn ref_sub = get_subtract_average_fn_c(tx_size); - const cfl_subtract_average_fn sub = fun_under_test(tx_size); for (int it = 0; it < NUM_ITERATIONS; it++) { - init(&ACMRandom::Rand15Signed); - sub(data); - ref_sub(data_ref); + randData(&ACMRandom::Rand15Signed); + sub_avg(data); + sub_avg_ref(data_ref); assert_eq<int16_t>(data, data_ref, width, height); } } TEST_P(CFLSubAvgTest, DISABLED_SubAvgSpeedTest) { - const cfl_subtract_average_fn ref_sub = get_subtract_average_fn_c(tx_size); - const cfl_subtract_average_fn sub = fun_under_test(tx_size); - aom_usec_timer ref_timer; aom_usec_timer timer; - - init(&ACMRandom::Rand15Signed); + randData(&ACMRandom::Rand15Signed); aom_usec_timer_start(&ref_timer); for (int k = 0; k < NUM_ITERATIONS_SPEED; k++) { - ref_sub(data_ref); + sub_avg_ref(data_ref); } aom_usec_timer_mark(&ref_timer); int ref_elapsed_time = (int)aom_usec_timer_elapsed(&ref_timer); - aom_usec_timer_start(&timer); for (int k = 0; k < NUM_ITERATIONS_SPEED; k++) { - sub(data); + sub_avg(data); } aom_usec_timer_mark(&timer); int elapsed_time = (int)aom_usec_timer_elapsed(&timer); - printSpeed(ref_elapsed_time, elapsed_time, width, height); assertFaster(ref_elapsed_time, elapsed_time); } -TEST_P(CFLSubsampleTest, SubsampleTest) { - int16_t sub_luma_pels[CFL_BUF_SQUARE]; - int16_t sub_luma_pels_ref[CFL_BUF_SQUARE]; - const int sub_width = width >> 1; - const int sub_height = height >> 1; +typedef cfl_subsample_lbd_fn (*get_subsample_fn)(TX_SIZE tx_size); +typedef ::testing::tuple<TX_SIZE, get_subsample_fn> subsample_param; +class CFLSubsampleTest : public ::testing::TestWithParam<subsample_param>, + public CFLTestWithData<uint8_t> { + public: + virtual ~CFLSubsampleTest() {} - for (int it = 0; it < NUM_ITERATIONS; it++) { - init(&ACMRandom::Rand8); - fun_under_test(tx_size)(data, CFL_BUF_LINE, sub_luma_pels); - cfl_get_luma_subsampling_420_lbd_c(tx_size)(data_ref, CFL_BUF_LINE, - sub_luma_pels_ref); - assert_eq<int16_t>(sub_luma_pels, sub_luma_pels_ref, sub_width, sub_height); + virtual void SetUp() { + CFLTest::init(::testing::get<0>(this->GetParam())); + fun_420 = ::testing::get<1>(this->GetParam())(tx_size); + fun_420_ref = cfl_get_luma_subsampling_420_lbd_c(tx_size); } + + protected: + cfl_subsample_lbd_fn fun_420; + cfl_subsample_lbd_fn fun_420_ref; + + void subsampleTest(cfl_subsample_lbd_fn fun, cfl_subsample_lbd_fn fun_ref, + int sub_width, int sub_height) { + int16_t sub_luma_pels[CFL_BUF_SQUARE]; + int16_t sub_luma_pels_ref[CFL_BUF_SQUARE]; + + for (int it = 0; it < NUM_ITERATIONS; it++) { + randData(&ACMRandom::Rand8); + fun(data, CFL_BUF_LINE, sub_luma_pels); + fun_ref(data_ref, CFL_BUF_LINE, sub_luma_pels_ref); + assert_eq<int16_t>(sub_luma_pels, sub_luma_pels_ref, sub_width, + sub_height); + } + } + + void subsampleSpeedTest(cfl_subsample_lbd_fn fun, + cfl_subsample_lbd_fn fun_ref) { + int16_t sub_luma_pels[CFL_BUF_SQUARE]; + int16_t sub_luma_pels_ref[CFL_BUF_SQUARE]; + + aom_usec_timer ref_timer; + aom_usec_timer timer; + + randData(&ACMRandom::Rand8); + aom_usec_timer_start(&ref_timer); + for (int k = 0; k < NUM_ITERATIONS_SPEED; k++) { + fun_ref(data_ref, CFL_BUF_LINE, sub_luma_pels); + } + aom_usec_timer_mark(&ref_timer); + int ref_elapsed_time = (int)aom_usec_timer_elapsed(&ref_timer); + aom_usec_timer_start(&timer); + for (int k = 0; k < NUM_ITERATIONS_SPEED; k++) { + fun(data, CFL_BUF_LINE, sub_luma_pels_ref); + } + aom_usec_timer_mark(&timer); + int elapsed_time = (int)aom_usec_timer_elapsed(&timer); + printSpeed(ref_elapsed_time, elapsed_time, width, height); + assertFaster(ref_elapsed_time, elapsed_time); + } +}; + +TEST_P(CFLSubsampleTest, Subsample420Test) { + subsampleTest(fun_420, fun_420_ref, width >> 1, height >> 1); } -TEST_P(CFLSubsampleTest, DISABLED_SubsampleSpeedTest) { - int16_t sub_luma_pels[CFL_BUF_SQUARE]; - int16_t sub_luma_pels_ref[CFL_BUF_SQUARE]; - cfl_subsample_lbd_fn subsample = fun_under_test(tx_size); - cfl_subsample_lbd_fn subsample_ref = - cfl_get_luma_subsampling_420_lbd_c(tx_size); - aom_usec_timer ref_timer; - aom_usec_timer timer; - - init(&ACMRandom::Rand8); - aom_usec_timer_start(&ref_timer); - for (int k = 0; k < NUM_ITERATIONS_SPEED; k++) { - subsample_ref(data_ref, CFL_BUF_LINE, sub_luma_pels); - } - aom_usec_timer_mark(&ref_timer); - int ref_elapsed_time = (int)aom_usec_timer_elapsed(&ref_timer); - - aom_usec_timer_start(&timer); - for (int k = 0; k < NUM_ITERATIONS_SPEED; k++) { - subsample(data, CFL_BUF_LINE, sub_luma_pels_ref); - } - aom_usec_timer_mark(&timer); - int elapsed_time = (int)aom_usec_timer_elapsed(&timer); - - printSpeed(ref_elapsed_time, elapsed_time, width, height); - assertFaster(ref_elapsed_time, elapsed_time); +TEST_P(CFLSubsampleTest, DISABLED_Subsample420SpeedTest) { + subsampleSpeedTest(fun_420, fun_420_ref); } +typedef cfl_predict_lbd_fn (*get_predict_fn)(TX_SIZE tx_size); +typedef ::testing::tuple<TX_SIZE, get_predict_fn> predict_param; +class CFLPredictTest : public ::testing::TestWithParam<predict_param>, + public CFLTestWithAlignedData<uint8_t> { + public: + virtual void SetUp() { + CFLTest::init(::testing::get<0>(this->GetParam())); + predict = ::testing::get<1>(this->GetParam())(tx_size); + predict_ref = get_predict_lbd_fn_c(tx_size); + } + + virtual ~CFLPredictTest() {} + + protected: + cfl_predict_lbd_fn predict; + cfl_predict_lbd_fn predict_ref; +}; + TEST_P(CFLPredictTest, PredictTest) { for (int it = 0; it < NUM_ITERATIONS; it++) { - init(8); - fun_under_test(tx_size)(sub_luma_pels, chroma_pels, CFL_BUF_LINE, alpha_q3); - get_predict_lbd_fn_c(tx_size)(sub_luma_pels_ref, chroma_pels_ref, - CFL_BUF_LINE, alpha_q3); - + randData(8); + predict(sub_luma_pels, chroma_pels, CFL_BUF_LINE, alpha_q3); + predict_ref(sub_luma_pels_ref, chroma_pels_ref, CFL_BUF_LINE, alpha_q3); assert_eq<uint8_t>(chroma_pels, chroma_pels_ref, width, height); } } - TEST_P(CFLPredictTest, DISABLED_PredictSpeedTest) { aom_usec_timer ref_timer; aom_usec_timer timer; + randData(8); - init(8); - cfl_predict_lbd_fn predict_impl = get_predict_lbd_fn_c(tx_size); aom_usec_timer_start(&ref_timer); - for (int k = 0; k < NUM_ITERATIONS_SPEED; k++) { - predict_impl(sub_luma_pels_ref, chroma_pels_ref, CFL_BUF_LINE, alpha_q3); + predict_ref(sub_luma_pels_ref, chroma_pels_ref, CFL_BUF_LINE, alpha_q3); } aom_usec_timer_mark(&ref_timer); int ref_elapsed_time = (int)aom_usec_timer_elapsed(&ref_timer); - predict_impl = fun_under_test(tx_size); aom_usec_timer_start(&timer); for (int k = 0; k < NUM_ITERATIONS_SPEED; k++) { - predict_impl(sub_luma_pels, chroma_pels, CFL_BUF_LINE, alpha_q3); + predict(sub_luma_pels, chroma_pels, CFL_BUF_LINE, alpha_q3); } aom_usec_timer_mark(&timer); int elapsed_time = (int)aom_usec_timer_elapsed(&timer); - printSpeed(ref_elapsed_time, elapsed_time, width, height); assertFaster(ref_elapsed_time, elapsed_time); } +typedef cfl_predict_hbd_fn (*get_predict_fn_hbd)(TX_SIZE tx_size); +typedef ::testing::tuple<TX_SIZE, get_predict_fn_hbd> predict_param_hbd; +class CFLPredictHBDTest : public ::testing::TestWithParam<predict_param_hbd>, + public CFLTestWithAlignedData<uint16_t> { + public: + virtual void SetUp() { + CFLTest::init(::testing::get<0>(this->GetParam())); + predict = ::testing::get<1>(this->GetParam())(tx_size); + predict_ref = get_predict_hbd_fn_c(tx_size); + } + + virtual ~CFLPredictHBDTest() {} + + protected: + cfl_predict_hbd_fn predict; + cfl_predict_hbd_fn predict_ref; +}; + TEST_P(CFLPredictHBDTest, PredictHBDTest) { int bd = 12; for (int it = 0; it < NUM_ITERATIONS; it++) { - init(bd); - fun_under_test(tx_size)(sub_luma_pels, chroma_pels, CFL_BUF_LINE, alpha_q3, - bd); - get_predict_hbd_fn_c(tx_size)(sub_luma_pels_ref, chroma_pels_ref, - CFL_BUF_LINE, alpha_q3, bd); - + randData(bd); + predict(sub_luma_pels, chroma_pels, CFL_BUF_LINE, alpha_q3, bd); + predict_ref(sub_luma_pels_ref, chroma_pels_ref, CFL_BUF_LINE, alpha_q3, bd); assert_eq<uint16_t>(chroma_pels, chroma_pels_ref, width, height); } } - TEST_P(CFLPredictHBDTest, DISABLED_PredictHBDSpeedTest) { aom_usec_timer ref_timer; aom_usec_timer timer; - int bd = 12; - init(bd); - cfl_predict_hbd_fn predict_impl = get_predict_hbd_fn_c(tx_size); - aom_usec_timer_start(&ref_timer); + const int bd = 12; + randData(bd); + aom_usec_timer_start(&ref_timer); for (int k = 0; k < NUM_ITERATIONS_SPEED; k++) { - predict_impl(sub_luma_pels_ref, chroma_pels_ref, CFL_BUF_LINE, alpha_q3, - bd); + predict_ref(sub_luma_pels_ref, chroma_pels_ref, CFL_BUF_LINE, alpha_q3, bd); } aom_usec_timer_mark(&ref_timer); int ref_elapsed_time = (int)aom_usec_timer_elapsed(&ref_timer); - predict_impl = fun_under_test(tx_size); aom_usec_timer_start(&timer); for (int k = 0; k < NUM_ITERATIONS_SPEED; k++) { - predict_impl(sub_luma_pels, chroma_pels, CFL_BUF_LINE, alpha_q3, bd); + predict(sub_luma_pels, chroma_pels, CFL_BUF_LINE, alpha_q3, bd); } aom_usec_timer_mark(&timer); int elapsed_time = (int)aom_usec_timer_elapsed(&timer); - printSpeed(ref_elapsed_time, elapsed_time, width, height); assertFaster(ref_elapsed_time, elapsed_time); }