xref: /aosp_15_r20/external/libaom/test/reconinter_test.cc (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1 /*
2  * Copyright (c) 2017, Alliance for Open Media. All rights reserved.
3  *
4  * This source code is subject to the terms of the BSD 2 Clause License and
5  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6  * was not distributed with this source code in the LICENSE file, you can
7  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8  * Media Patent License 1.0 was not distributed with this source code in the
9  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10  */
11 
12 #include <stdint.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <tuple>
16 
17 #include "config/aom_config.h"
18 #include "config/av1_rtcd.h"
19 
20 #include "aom_ports/mem.h"
21 #include "av1/common/scan.h"
22 #include "av1/common/txb_common.h"
23 #include "gtest/gtest.h"
24 #include "test/acm_random.h"
25 #include "test/register_state_check.h"
26 #include "test/util.h"
27 
28 namespace {
29 using libaom_test::ACMRandom;
30 
31 using BuildCompDiffWtdMaskFunc = void (*)(uint8_t *mask,
32                                           DIFFWTD_MASK_TYPE mask_type,
33                                           const uint8_t *src0, int src0_stride,
34                                           const uint8_t *src1, int src1_stride,
35                                           int h, int w);
36 
37 using BuildCompDiffwtdMaskDParam =
38     std::tuple<BLOCK_SIZE, BuildCompDiffWtdMaskFunc>;
39 
40 #if HAVE_SSE4_1 || HAVE_AVX2 || HAVE_NEON
BuildParams(BuildCompDiffWtdMaskFunc filter)41 ::testing::internal::ParamGenerator<BuildCompDiffwtdMaskDParam> BuildParams(
42     BuildCompDiffWtdMaskFunc filter) {
43   return ::testing::Combine(::testing::Range(BLOCK_4X4, BLOCK_SIZES_ALL),
44                             ::testing::Values(filter));
45 }
46 #endif
47 
48 class BuildCompDiffwtdMaskTest
49     : public ::testing::TestWithParam<BuildCompDiffwtdMaskDParam> {
50  public:
BuildCompDiffwtdMaskTest()51   BuildCompDiffwtdMaskTest() : rnd_(ACMRandom::DeterministicSeed()) {}
52   ~BuildCompDiffwtdMaskTest() override = default;
53 
54  protected:
RunTest(BuildCompDiffWtdMaskFunc test_impl,bool is_speed,const DIFFWTD_MASK_TYPE type)55   void RunTest(BuildCompDiffWtdMaskFunc test_impl, bool is_speed,
56                const DIFFWTD_MASK_TYPE type) {
57     const int sb_type = GET_PARAM(0);
58     const int width = block_size_wide[sb_type];
59     const int height = block_size_high[sb_type];
60     DECLARE_ALIGNED(16, uint8_t, mask_ref[MAX_SB_SQUARE]);
61     DECLARE_ALIGNED(16, uint8_t, mask_test[MAX_SB_SQUARE]);
62     DECLARE_ALIGNED(16, uint8_t, src0[MAX_SB_SQUARE]);
63     DECLARE_ALIGNED(16, uint8_t, src1[MAX_SB_SQUARE]);
64     for (int i = 0; i < width * height; i++) {
65       src0[i] = rnd_.Rand8();
66       src1[i] = rnd_.Rand8();
67     }
68     const int run_times = is_speed ? (10000000 / (width + height)) : 1;
69     aom_usec_timer timer;
70     aom_usec_timer_start(&timer);
71     for (int i = 0; i < run_times; ++i) {
72       av1_build_compound_diffwtd_mask_c(mask_ref, type, src0, width, src1,
73                                         width, height, width);
74     }
75     const double t1 = get_time_mark(&timer);
76     aom_usec_timer_start(&timer);
77     for (int i = 0; i < run_times; ++i) {
78       test_impl(mask_test, type, src0, width, src1, width, height, width);
79     }
80     const double t2 = get_time_mark(&timer);
81     if (is_speed) {
82       printf("mask %d %3dx%-3d:%7.2f/%7.2fns", type, width, height, t1, t2);
83       printf("(%3.2f)\n", t1 / t2);
84     }
85     for (int r = 0; r < height; ++r) {
86       for (int c = 0; c < width; ++c) {
87         ASSERT_EQ(mask_ref[c + r * width], mask_test[c + r * width])
88             << "[" << r << "," << c << "] " << run_times << " @ " << width
89             << "x" << height << " inv " << type;
90       }
91     }
92   }
93 
94  private:
95   ACMRandom rnd_;
96 };
97 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BuildCompDiffwtdMaskTest);
98 
TEST_P(BuildCompDiffwtdMaskTest,match)99 TEST_P(BuildCompDiffwtdMaskTest, match) {
100   RunTest(GET_PARAM(1), 0, DIFFWTD_38);
101   RunTest(GET_PARAM(1), 0, DIFFWTD_38_INV);
102 }
TEST_P(BuildCompDiffwtdMaskTest,DISABLED_Speed)103 TEST_P(BuildCompDiffwtdMaskTest, DISABLED_Speed) {
104   RunTest(GET_PARAM(1), 1, DIFFWTD_38);
105   RunTest(GET_PARAM(1), 1, DIFFWTD_38_INV);
106 }
107 
108 #if HAVE_SSE4_1
109 INSTANTIATE_TEST_SUITE_P(SSE4_1, BuildCompDiffwtdMaskTest,
110                          BuildParams(av1_build_compound_diffwtd_mask_sse4_1));
111 #endif
112 
113 #if HAVE_AVX2
114 INSTANTIATE_TEST_SUITE_P(AVX2, BuildCompDiffwtdMaskTest,
115                          BuildParams(av1_build_compound_diffwtd_mask_avx2));
116 #endif
117 
118 #if HAVE_NEON
119 INSTANTIATE_TEST_SUITE_P(NEON, BuildCompDiffwtdMaskTest,
120                          BuildParams(av1_build_compound_diffwtd_mask_neon));
121 #endif
122 
123 #if CONFIG_AV1_HIGHBITDEPTH
124 
125 using BuildCompDiffWtdMaskHighbdFunc =
126     void (*)(uint8_t *mask, DIFFWTD_MASK_TYPE mask_type, const uint8_t *src0,
127              int src0_stride, const uint8_t *src1, int src1_stride, int h,
128              int w, int bd);
129 
130 using BuildCompDiffwtdMaskHighbdParam =
131     std::tuple<BLOCK_SIZE, int, BuildCompDiffWtdMaskHighbdFunc>;
132 
133 #if HAVE_SSSE3 || HAVE_AVX2 || HAVE_NEON
134 ::testing::internal::ParamGenerator<BuildCompDiffwtdMaskHighbdParam>
BuildParamsHighbd(BuildCompDiffWtdMaskHighbdFunc filter)135 BuildParamsHighbd(BuildCompDiffWtdMaskHighbdFunc filter) {
136   return ::testing::Combine(::testing::Range(BLOCK_4X4, BLOCK_SIZES_ALL),
137                             ::testing::Values(8, 10, 12),
138                             ::testing::Values(filter));
139 }
140 #endif
141 
142 class BuildCompDiffwtdMaskHighbdTest
143     : public ::testing::TestWithParam<BuildCompDiffwtdMaskHighbdParam> {
144  public:
BuildCompDiffwtdMaskHighbdTest()145   BuildCompDiffwtdMaskHighbdTest() : rnd_(ACMRandom::DeterministicSeed()) {}
146   ~BuildCompDiffwtdMaskHighbdTest() override = default;
147 
148  protected:
RunTest(BuildCompDiffWtdMaskHighbdFunc test_impl,bool is_speed,const DIFFWTD_MASK_TYPE type)149   void RunTest(BuildCompDiffWtdMaskHighbdFunc test_impl, bool is_speed,
150                const DIFFWTD_MASK_TYPE type) {
151     const int sb_type = GET_PARAM(0);
152     const int bd = GET_PARAM(1);
153     const int width = block_size_wide[sb_type];
154     const int height = block_size_high[sb_type];
155     const int mask = (1 << bd) - 1;
156     DECLARE_ALIGNED(16, uint8_t, mask_ref[MAX_SB_SQUARE]);
157     DECLARE_ALIGNED(16, uint8_t, mask_test[MAX_SB_SQUARE]);
158     DECLARE_ALIGNED(16, uint16_t, src0[MAX_SB_SQUARE]);
159     DECLARE_ALIGNED(16, uint16_t, src1[MAX_SB_SQUARE]);
160     for (int i = 0; i < width * height; i++) {
161       src0[i] = rnd_.Rand16() & mask;
162       src1[i] = rnd_.Rand16() & mask;
163     }
164     const int run_times = is_speed ? (10000000 / (width + height)) : 1;
165     aom_usec_timer timer;
166 
167     aom_usec_timer_start(&timer);
168     for (int i = 0; i < run_times; ++i) {
169       uint8_t *src0_8 = CONVERT_TO_BYTEPTR(src0);
170       uint8_t *src1_8 = CONVERT_TO_BYTEPTR(src1);
171       av1_build_compound_diffwtd_mask_highbd_c(
172           mask_ref, type, src0_8, width, src1_8, width, height, width, bd);
173     }
174     const double t1 = get_time_mark(&timer);
175 
176     aom_usec_timer_start(&timer);
177     for (int i = 0; i < run_times; ++i) {
178       uint8_t *src0_8 = CONVERT_TO_BYTEPTR(src0);
179       uint8_t *src1_8 = CONVERT_TO_BYTEPTR(src1);
180       test_impl(mask_test, type, src0_8, width, src1_8, width, height, width,
181                 bd);
182     }
183     const double t2 = get_time_mark(&timer);
184 
185     if (is_speed) {
186       printf("mask %d %3dx%-3d:%7.2f/%7.2fns", type, width, height, t1, t2);
187       printf("(%3.2f)\n", t1 / t2);
188     }
189     for (int r = 0; r < height; ++r) {
190       for (int c = 0; c < width; ++c) {
191         ASSERT_EQ(mask_ref[c + r * width], mask_test[c + r * width])
192             << "[" << r << "," << c << "] " << run_times << " @ " << width
193             << "x" << height << " inv " << type;
194       }
195     }
196   }
197 
198  private:
199   ACMRandom rnd_;
200 };
201 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BuildCompDiffwtdMaskHighbdTest);
202 
TEST_P(BuildCompDiffwtdMaskHighbdTest,match)203 TEST_P(BuildCompDiffwtdMaskHighbdTest, match) {
204   RunTest(GET_PARAM(2), 0, DIFFWTD_38);
205   RunTest(GET_PARAM(2), 0, DIFFWTD_38_INV);
206 }
TEST_P(BuildCompDiffwtdMaskHighbdTest,DISABLED_Speed)207 TEST_P(BuildCompDiffwtdMaskHighbdTest, DISABLED_Speed) {
208   RunTest(GET_PARAM(2), 1, DIFFWTD_38);
209   RunTest(GET_PARAM(2), 1, DIFFWTD_38_INV);
210 }
211 
212 #if HAVE_SSSE3
213 INSTANTIATE_TEST_SUITE_P(
214     SSSE3, BuildCompDiffwtdMaskHighbdTest,
215     BuildParamsHighbd(av1_build_compound_diffwtd_mask_highbd_ssse3));
216 #endif
217 
218 #if HAVE_AVX2
219 INSTANTIATE_TEST_SUITE_P(
220     AVX2, BuildCompDiffwtdMaskHighbdTest,
221     BuildParamsHighbd(av1_build_compound_diffwtd_mask_highbd_avx2));
222 #endif
223 
224 #if HAVE_NEON
225 INSTANTIATE_TEST_SUITE_P(
226     NEON, BuildCompDiffwtdMaskHighbdTest,
227     BuildParamsHighbd(av1_build_compound_diffwtd_mask_highbd_neon));
228 #endif
229 #endif  // CONFIG_AV1_HIGHBITDEPTH
230 
231 using BuildCompDiffWtdMaskD16Func = void (*)(
232     uint8_t *mask, DIFFWTD_MASK_TYPE mask_type, const CONV_BUF_TYPE *src0,
233     int src0_stride, const CONV_BUF_TYPE *src1, int src1_stride, int h, int w,
234     ConvolveParams *conv_params, int bd);
235 
236 using BuildCompDiffwtdMaskD16Param =
237     std::tuple<int, BuildCompDiffWtdMaskD16Func, BLOCK_SIZE>;
238 
239 #if HAVE_SSE4_1 || HAVE_AVX2 || HAVE_NEON
BuildParams(BuildCompDiffWtdMaskD16Func filter)240 ::testing::internal::ParamGenerator<BuildCompDiffwtdMaskD16Param> BuildParams(
241     BuildCompDiffWtdMaskD16Func filter) {
242   return ::testing::Combine(::testing::Range(8, 13, 2),
243                             ::testing::Values(filter),
244                             ::testing::Range(BLOCK_4X4, BLOCK_SIZES_ALL));
245 }
246 #endif
247 
248 class BuildCompDiffwtdMaskD16Test
249     : public ::testing::TestWithParam<BuildCompDiffwtdMaskD16Param> {
250  public:
BuildCompDiffwtdMaskD16Test()251   BuildCompDiffwtdMaskD16Test() : rnd_(ACMRandom::DeterministicSeed()) {}
252   ~BuildCompDiffwtdMaskD16Test() override = default;
253 
254  protected:
RunCheckOutput(BuildCompDiffWtdMaskD16Func test_impl)255   void RunCheckOutput(BuildCompDiffWtdMaskD16Func test_impl) {
256     const int block_idx = GET_PARAM(2);
257     const int bd = GET_PARAM(0);
258     const int width = block_size_wide[block_idx];
259     const int height = block_size_high[block_idx];
260     DECLARE_ALIGNED(16, uint8_t, mask_ref[2 * MAX_SB_SQUARE]);
261     DECLARE_ALIGNED(16, uint8_t, mask_test[2 * MAX_SB_SQUARE]);
262     DECLARE_ALIGNED(32, uint16_t, src0[MAX_SB_SQUARE]);
263     DECLARE_ALIGNED(32, uint16_t, src1[MAX_SB_SQUARE]);
264 
265     ConvolveParams conv_params =
266         get_conv_params_no_round(0, 0, nullptr, 0, 1, bd);
267 
268     const int in_precision =
269         bd + 2 * FILTER_BITS - conv_params.round_0 - conv_params.round_1 + 2;
270 
271     for (int i = 0; i < MAX_SB_SQUARE; i++) {
272       src0[i] = rnd_.Rand16() & ((1 << in_precision) - 1);
273       src1[i] = rnd_.Rand16() & ((1 << in_precision) - 1);
274     }
275 
276     for (int mask_type = 0; mask_type < DIFFWTD_MASK_TYPES; mask_type++) {
277       av1_build_compound_diffwtd_mask_d16_c(
278           mask_ref, (DIFFWTD_MASK_TYPE)mask_type, src0, width, src1, width,
279           height, width, &conv_params, bd);
280 
281       test_impl(mask_test, (DIFFWTD_MASK_TYPE)mask_type, src0, width, src1,
282                 width, height, width, &conv_params, bd);
283 
284       for (int r = 0; r < height; ++r) {
285         for (int c = 0; c < width; ++c) {
286           ASSERT_EQ(mask_ref[c + r * width], mask_test[c + r * width])
287               << "Mismatch at unit tests for BuildCompDiffwtdMaskD16Test\n"
288               << " Pixel mismatch at index "
289               << "[" << r << "," << c << "] "
290               << " @ " << width << "x" << height << " inv " << mask_type;
291         }
292       }
293     }
294   }
295 
RunSpeedTest(BuildCompDiffWtdMaskD16Func test_impl,DIFFWTD_MASK_TYPE mask_type)296   void RunSpeedTest(BuildCompDiffWtdMaskD16Func test_impl,
297                     DIFFWTD_MASK_TYPE mask_type) {
298     const int block_idx = GET_PARAM(2);
299     const int bd = GET_PARAM(0);
300     const int width = block_size_wide[block_idx];
301     const int height = block_size_high[block_idx];
302     DECLARE_ALIGNED(16, uint8_t, mask[MAX_SB_SQUARE]);
303     DECLARE_ALIGNED(32, uint16_t, src0[MAX_SB_SQUARE]);
304     DECLARE_ALIGNED(32, uint16_t, src1[MAX_SB_SQUARE]);
305 
306     ConvolveParams conv_params =
307         get_conv_params_no_round(0, 0, nullptr, 0, 1, bd);
308 
309     const int in_precision =
310         bd + 2 * FILTER_BITS - conv_params.round_0 - conv_params.round_1 + 2;
311 
312     for (int i = 0; i < MAX_SB_SQUARE; i++) {
313       src0[i] = rnd_.Rand16() & ((1 << in_precision) - 1);
314       src1[i] = rnd_.Rand16() & ((1 << in_precision) - 1);
315     }
316 
317     const int num_loops = 10000000 / (width + height);
318     aom_usec_timer timer;
319     aom_usec_timer_start(&timer);
320 
321     for (int i = 0; i < num_loops; ++i)
322       av1_build_compound_diffwtd_mask_d16_c(mask, mask_type, src0, width, src1,
323                                             width, height, width, &conv_params,
324                                             bd);
325 
326     aom_usec_timer_mark(&timer);
327     const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
328 
329     aom_usec_timer timer1;
330     aom_usec_timer_start(&timer1);
331 
332     for (int i = 0; i < num_loops; ++i)
333       test_impl(mask, mask_type, src0, width, src1, width, height, width,
334                 &conv_params, bd);
335 
336     aom_usec_timer_mark(&timer1);
337     const int elapsed_time1 = static_cast<int>(aom_usec_timer_elapsed(&timer1));
338     printf("av1_build_compound_diffwtd_mask_d16  %3dx%-3d: %7.2f \n", width,
339            height, elapsed_time / double(elapsed_time1));
340   }
341 
342  private:
343   ACMRandom rnd_;
344 };  // class BuildCompDiffwtdMaskD16Test
345 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BuildCompDiffwtdMaskD16Test);
346 
TEST_P(BuildCompDiffwtdMaskD16Test,CheckOutput)347 TEST_P(BuildCompDiffwtdMaskD16Test, CheckOutput) {
348   RunCheckOutput(GET_PARAM(1));
349 }
350 
TEST_P(BuildCompDiffwtdMaskD16Test,DISABLED_Speed)351 TEST_P(BuildCompDiffwtdMaskD16Test, DISABLED_Speed) {
352   RunSpeedTest(GET_PARAM(1), DIFFWTD_38);
353   RunSpeedTest(GET_PARAM(1), DIFFWTD_38_INV);
354 }
355 
356 #if HAVE_SSE4_1
357 INSTANTIATE_TEST_SUITE_P(
358     SSE4_1, BuildCompDiffwtdMaskD16Test,
359     BuildParams(av1_build_compound_diffwtd_mask_d16_sse4_1));
360 #endif
361 
362 #if HAVE_AVX2
363 INSTANTIATE_TEST_SUITE_P(AVX2, BuildCompDiffwtdMaskD16Test,
364                          BuildParams(av1_build_compound_diffwtd_mask_d16_avx2));
365 #endif
366 
367 #if HAVE_NEON
368 INSTANTIATE_TEST_SUITE_P(NEON, BuildCompDiffwtdMaskD16Test,
369                          BuildParams(av1_build_compound_diffwtd_mask_d16_neon));
370 #endif
371 
372 }  // namespace
373