2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
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.
16 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
18 #include "config/aom_config.h"
19 #include "config/aom_dsp_rtcd.h"
21 #include "aom_ports/mem.h"
22 #include "test/acm_random.h"
23 #include "test/clear_system_state.h"
24 #include "test/register_state_check.h"
25 #include "test/util.h"
26 #include "test/function_equivalence_test.h"
28 using libaom_test::ACMRandom
;
29 using libaom_test::FunctionEquivalenceTest
;
32 const int kNumIterations
= 10000;
34 static const int16_t kInt13Max
= (1 << 12) - 1;
36 typedef uint64_t (*SSI16Func
)(const int16_t *src
, int stride
, int width
,
38 typedef libaom_test::FuncParam
<SSI16Func
> TestFuncs
;
40 class SumSquaresTest
: public ::testing::TestWithParam
<TestFuncs
> {
42 virtual ~SumSquaresTest() {}
43 virtual void SetUp() {
44 params_
= this->GetParam();
45 rnd_
.Reset(ACMRandom::DeterministicSeed());
46 src_
= reinterpret_cast<int16_t *>(aom_memalign(16, 256 * 256 * 2));
47 ASSERT_TRUE(src_
!= NULL
);
50 virtual void TearDown() {
51 libaom_test::ClearSystemState();
54 void RunTest(int isRandom
);
57 void GenRandomData(int width
, int height
, int stride
) {
58 const int msb
= 11; // Up to 12 bit input
59 const int limit
= 1 << (msb
+ 1);
60 for (int ii
= 0; ii
< height
; ii
++) {
61 for (int jj
= 0; jj
< width
; jj
++) {
62 src_
[ii
* stride
+ jj
] = rnd_(2) ? rnd_(limit
) : -rnd_(limit
);
67 void GenExtremeData(int width
, int height
, int stride
) {
68 const int msb
= 11; // Up to 12 bit input
69 const int limit
= 1 << (msb
+ 1);
70 const int val
= rnd_(2) ? limit
- 1 : -(limit
- 1);
71 for (int ii
= 0; ii
< height
; ii
++) {
72 for (int jj
= 0; jj
< width
; jj
++) {
73 src_
[ii
* stride
+ jj
] = val
;
84 void SumSquaresTest::RunTest(int isRandom
) {
86 for (int k
= 0; k
< kNumIterations
; k
++) {
87 const int width
= 4 * (rnd_(31) + 1); // Up to 128x128
88 const int height
= 4 * (rnd_(31) + 1); // Up to 128x128
89 int stride
= 4 << rnd_(7); // Up to 256 stride
90 while (stride
< width
) { // Make sure it's valid
91 stride
= 4 << rnd_(7);
94 GenRandomData(width
, height
, stride
);
96 GenExtremeData(width
, height
, stride
);
98 const uint64_t res_ref
= params_
.ref_func(src_
, stride
, width
, height
);
100 ASM_REGISTER_STATE_CHECK(res_tst
=
101 params_
.tst_func(src_
, stride
, width
, height
));
104 failed
= res_ref
!= res_tst
;
105 EXPECT_EQ(res_ref
, res_tst
)
106 << "Error: Sum Squares Test [" << width
<< "x" << height
107 << "] C output does not match optimized output.";
112 void SumSquaresTest::RunSpeedTest() {
113 for (int block
= BLOCK_4X4
; block
< BLOCK_SIZES_ALL
; block
++) {
114 const int width
= block_size_wide
[block
]; // Up to 128x128
115 const int height
= block_size_high
[block
]; // Up to 128x128
116 int stride
= 4 << rnd_(7); // Up to 256 stride
117 while (stride
< width
) { // Make sure it's valid
118 stride
= 4 << rnd_(7);
120 GenExtremeData(width
, height
, stride
);
121 const int num_loops
= 1000000000 / (width
+ height
);
122 aom_usec_timer timer
;
123 aom_usec_timer_start(&timer
);
125 for (int i
= 0; i
< num_loops
; ++i
)
126 params_
.ref_func(src_
, stride
, width
, height
);
128 aom_usec_timer_mark(&timer
);
129 const int elapsed_time
= static_cast<int>(aom_usec_timer_elapsed(&timer
));
130 printf("SumSquaresTest C %3dx%-3d: %7.2f ns\n", width
, height
,
131 1000.0 * elapsed_time
/ num_loops
);
133 aom_usec_timer timer1
;
134 aom_usec_timer_start(&timer1
);
135 for (int i
= 0; i
< num_loops
; ++i
)
136 params_
.tst_func(src_
, stride
, width
, height
);
137 aom_usec_timer_mark(&timer1
);
138 const int elapsed_time1
= static_cast<int>(aom_usec_timer_elapsed(&timer1
));
139 printf("SumSquaresTest Test %3dx%-3d: %7.2f ns\n", width
, height
,
140 1000.0 * elapsed_time1
/ num_loops
);
144 TEST_P(SumSquaresTest
, OperationCheck
) {
145 RunTest(1); // GenRandomData
148 TEST_P(SumSquaresTest
, ExtremeValues
) {
149 RunTest(0); // GenExtremeData
152 TEST_P(SumSquaresTest
, DISABLED_Speed
) { RunSpeedTest(); }
156 INSTANTIATE_TEST_CASE_P(
157 SSE2
, SumSquaresTest
,
158 ::testing::Values(TestFuncs(&aom_sum_squares_2d_i16_c
,
159 &aom_sum_squares_2d_i16_sse2
)));
164 INSTANTIATE_TEST_CASE_P(
165 AVX2
, SumSquaresTest
,
166 ::testing::Values(TestFuncs(&aom_sum_squares_2d_i16_c
,
167 &aom_sum_squares_2d_i16_avx2
)));
170 //////////////////////////////////////////////////////////////////////////////
172 //////////////////////////////////////////////////////////////////////////////
174 typedef uint64_t (*F1D
)(const int16_t *src
, uint32_t N
);
175 typedef libaom_test::FuncParam
<F1D
> TestFuncs1D
;
177 class SumSquares1DTest
: public FunctionEquivalenceTest
<F1D
> {
179 static const int kIterations
= 1000;
180 static const int kMaxSize
= 256;
183 TEST_P(SumSquares1DTest
, RandomValues
) {
184 DECLARE_ALIGNED(16, int16_t, src
[kMaxSize
* kMaxSize
]);
186 for (int iter
= 0; iter
< kIterations
&& !HasFatalFailure(); ++iter
) {
187 for (int i
= 0; i
< kMaxSize
* kMaxSize
; ++i
)
188 src
[i
] = rng_(kInt13Max
* 2 + 1) - kInt13Max
;
190 const int N
= rng_(2) ? rng_(kMaxSize
* kMaxSize
+ 1 - kMaxSize
) + kMaxSize
191 : rng_(kMaxSize
) + 1;
193 const uint64_t ref_res
= params_
.ref_func(src
, N
);
195 ASM_REGISTER_STATE_CHECK(tst_res
= params_
.tst_func(src
, N
));
197 ASSERT_EQ(ref_res
, tst_res
);
201 TEST_P(SumSquares1DTest
, ExtremeValues
) {
202 DECLARE_ALIGNED(16, int16_t, src
[kMaxSize
* kMaxSize
]);
204 for (int iter
= 0; iter
< kIterations
&& !HasFatalFailure(); ++iter
) {
206 for (int i
= 0; i
< kMaxSize
* kMaxSize
; ++i
) src
[i
] = kInt13Max
;
208 for (int i
= 0; i
< kMaxSize
* kMaxSize
; ++i
) src
[i
] = -kInt13Max
;
211 const int N
= rng_(2) ? rng_(kMaxSize
* kMaxSize
+ 1 - kMaxSize
) + kMaxSize
212 : rng_(kMaxSize
) + 1;
214 const uint64_t ref_res
= params_
.ref_func(src
, N
);
216 ASM_REGISTER_STATE_CHECK(tst_res
= params_
.tst_func(src
, N
));
218 ASSERT_EQ(ref_res
, tst_res
);
223 INSTANTIATE_TEST_CASE_P(SSE2
, SumSquares1DTest
,
224 ::testing::Values(TestFuncs1D(
225 aom_sum_squares_i16_c
, aom_sum_squares_i16_sse2
)));