1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker *
4*77c1e3ccSAndroid Build Coastguard Worker * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker */
11*77c1e3ccSAndroid Build Coastguard Worker
12*77c1e3ccSAndroid Build Coastguard Worker #include "gtest/gtest.h"
13*77c1e3ccSAndroid Build Coastguard Worker
14*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_config.h"
15*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_dsp_rtcd.h"
16*77c1e3ccSAndroid Build Coastguard Worker #include "config/av1_rtcd.h"
17*77c1e3ccSAndroid Build Coastguard Worker
18*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/aom_dsp_common.h"
19*77c1e3ccSAndroid Build Coastguard Worker
20*77c1e3ccSAndroid Build Coastguard Worker #include "av1/common/enums.h"
21*77c1e3ccSAndroid Build Coastguard Worker
22*77c1e3ccSAndroid Build Coastguard Worker #include "test/acm_random.h"
23*77c1e3ccSAndroid Build Coastguard Worker #include "test/function_equivalence_test.h"
24*77c1e3ccSAndroid Build Coastguard Worker #include "test/register_state_check.h"
25*77c1e3ccSAndroid Build Coastguard Worker
26*77c1e3ccSAndroid Build Coastguard Worker #define WEDGE_WEIGHT_BITS 6
27*77c1e3ccSAndroid Build Coastguard Worker #define MAX_MASK_VALUE (1 << (WEDGE_WEIGHT_BITS))
28*77c1e3ccSAndroid Build Coastguard Worker
29*77c1e3ccSAndroid Build Coastguard Worker using libaom_test::ACMRandom;
30*77c1e3ccSAndroid Build Coastguard Worker using libaom_test::FunctionEquivalenceTest;
31*77c1e3ccSAndroid Build Coastguard Worker
32*77c1e3ccSAndroid Build Coastguard Worker namespace {
33*77c1e3ccSAndroid Build Coastguard Worker
34*77c1e3ccSAndroid Build Coastguard Worker static const int16_t kInt13Max = (1 << 12) - 1;
35*77c1e3ccSAndroid Build Coastguard Worker
36*77c1e3ccSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
37*77c1e3ccSAndroid Build Coastguard Worker // av1_wedge_sse_from_residuals - functionality
38*77c1e3ccSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
39*77c1e3ccSAndroid Build Coastguard Worker
40*77c1e3ccSAndroid Build Coastguard Worker class WedgeUtilsSSEFuncTest : public testing::Test {
41*77c1e3ccSAndroid Build Coastguard Worker protected:
WedgeUtilsSSEFuncTest()42*77c1e3ccSAndroid Build Coastguard Worker WedgeUtilsSSEFuncTest() : rng_(ACMRandom::DeterministicSeed()) {}
43*77c1e3ccSAndroid Build Coastguard Worker
44*77c1e3ccSAndroid Build Coastguard Worker static const int kIterations = 1000;
45*77c1e3ccSAndroid Build Coastguard Worker
46*77c1e3ccSAndroid Build Coastguard Worker ACMRandom rng_;
47*77c1e3ccSAndroid Build Coastguard Worker };
48*77c1e3ccSAndroid Build Coastguard Worker
equiv_blend_residuals(int16_t * r,const int16_t * r0,const int16_t * r1,const uint8_t * m,int N)49*77c1e3ccSAndroid Build Coastguard Worker static void equiv_blend_residuals(int16_t *r, const int16_t *r0,
50*77c1e3ccSAndroid Build Coastguard Worker const int16_t *r1, const uint8_t *m, int N) {
51*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < N; i++) {
52*77c1e3ccSAndroid Build Coastguard Worker const int32_t m0 = m[i];
53*77c1e3ccSAndroid Build Coastguard Worker const int32_t m1 = MAX_MASK_VALUE - m0;
54*77c1e3ccSAndroid Build Coastguard Worker const int16_t R = m0 * r0[i] + m1 * r1[i];
55*77c1e3ccSAndroid Build Coastguard Worker // Note that this rounding is designed to match the result
56*77c1e3ccSAndroid Build Coastguard Worker // you would get when actually blending the 2 predictors and computing
57*77c1e3ccSAndroid Build Coastguard Worker // the residuals.
58*77c1e3ccSAndroid Build Coastguard Worker r[i] = ROUND_POWER_OF_TWO(R - 1, WEDGE_WEIGHT_BITS);
59*77c1e3ccSAndroid Build Coastguard Worker }
60*77c1e3ccSAndroid Build Coastguard Worker }
61*77c1e3ccSAndroid Build Coastguard Worker
equiv_sse_from_residuals(const int16_t * r0,const int16_t * r1,const uint8_t * m,int N)62*77c1e3ccSAndroid Build Coastguard Worker static uint64_t equiv_sse_from_residuals(const int16_t *r0, const int16_t *r1,
63*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *m, int N) {
64*77c1e3ccSAndroid Build Coastguard Worker uint64_t acc = 0;
65*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < N; i++) {
66*77c1e3ccSAndroid Build Coastguard Worker const int32_t m0 = m[i];
67*77c1e3ccSAndroid Build Coastguard Worker const int32_t m1 = MAX_MASK_VALUE - m0;
68*77c1e3ccSAndroid Build Coastguard Worker const int16_t R = m0 * r0[i] + m1 * r1[i];
69*77c1e3ccSAndroid Build Coastguard Worker const int32_t r = ROUND_POWER_OF_TWO(R - 1, WEDGE_WEIGHT_BITS);
70*77c1e3ccSAndroid Build Coastguard Worker acc += r * r;
71*77c1e3ccSAndroid Build Coastguard Worker }
72*77c1e3ccSAndroid Build Coastguard Worker return acc;
73*77c1e3ccSAndroid Build Coastguard Worker }
74*77c1e3ccSAndroid Build Coastguard Worker
TEST_F(WedgeUtilsSSEFuncTest,ResidualBlendingEquiv)75*77c1e3ccSAndroid Build Coastguard Worker TEST_F(WedgeUtilsSSEFuncTest, ResidualBlendingEquiv) {
76*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, uint8_t, s[MAX_SB_SQUARE]);
77*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, uint8_t, p0[MAX_SB_SQUARE]);
78*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, uint8_t, p1[MAX_SB_SQUARE]);
79*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, uint8_t, p[MAX_SB_SQUARE]);
80*77c1e3ccSAndroid Build Coastguard Worker
81*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
82*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
83*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, r_ref[MAX_SB_SQUARE]);
84*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, r_tst[MAX_SB_SQUARE]);
85*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, uint8_t, m[MAX_SB_SQUARE]);
86*77c1e3ccSAndroid Build Coastguard Worker
87*77c1e3ccSAndroid Build Coastguard Worker for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
88*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) {
89*77c1e3ccSAndroid Build Coastguard Worker s[i] = rng_.Rand8();
90*77c1e3ccSAndroid Build Coastguard Worker m[i] = rng_(MAX_MASK_VALUE + 1);
91*77c1e3ccSAndroid Build Coastguard Worker }
92*77c1e3ccSAndroid Build Coastguard Worker
93*77c1e3ccSAndroid Build Coastguard Worker const int w = 1 << (rng_(MAX_SB_SIZE_LOG2 + 1 - 3) + 3);
94*77c1e3ccSAndroid Build Coastguard Worker const int h = 1 << (rng_(MAX_SB_SIZE_LOG2 + 1 - 3) + 3);
95*77c1e3ccSAndroid Build Coastguard Worker const int N = w * h;
96*77c1e3ccSAndroid Build Coastguard Worker
97*77c1e3ccSAndroid Build Coastguard Worker for (int j = 0; j < N; j++) {
98*77c1e3ccSAndroid Build Coastguard Worker p0[j] = clamp(s[j] + rng_(33) - 16, 0, UINT8_MAX);
99*77c1e3ccSAndroid Build Coastguard Worker p1[j] = clamp(s[j] + rng_(33) - 16, 0, UINT8_MAX);
100*77c1e3ccSAndroid Build Coastguard Worker }
101*77c1e3ccSAndroid Build Coastguard Worker
102*77c1e3ccSAndroid Build Coastguard Worker aom_blend_a64_mask(p, w, p0, w, p1, w, m, w, w, h, 0, 0);
103*77c1e3ccSAndroid Build Coastguard Worker
104*77c1e3ccSAndroid Build Coastguard Worker aom_subtract_block(h, w, r0, w, s, w, p0, w);
105*77c1e3ccSAndroid Build Coastguard Worker aom_subtract_block(h, w, r1, w, s, w, p1, w);
106*77c1e3ccSAndroid Build Coastguard Worker
107*77c1e3ccSAndroid Build Coastguard Worker aom_subtract_block(h, w, r_ref, w, s, w, p, w);
108*77c1e3ccSAndroid Build Coastguard Worker equiv_blend_residuals(r_tst, r0, r1, m, N);
109*77c1e3ccSAndroid Build Coastguard Worker
110*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < N; ++i) ASSERT_EQ(r_ref[i], r_tst[i]);
111*77c1e3ccSAndroid Build Coastguard Worker
112*77c1e3ccSAndroid Build Coastguard Worker uint64_t ref_sse = aom_sum_squares_i16(r_ref, N);
113*77c1e3ccSAndroid Build Coastguard Worker uint64_t tst_sse = equiv_sse_from_residuals(r0, r1, m, N);
114*77c1e3ccSAndroid Build Coastguard Worker
115*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(ref_sse, tst_sse);
116*77c1e3ccSAndroid Build Coastguard Worker }
117*77c1e3ccSAndroid Build Coastguard Worker }
118*77c1e3ccSAndroid Build Coastguard Worker
sse_from_residuals(const int16_t * r0,const int16_t * r1,const uint8_t * m,int N)119*77c1e3ccSAndroid Build Coastguard Worker static uint64_t sse_from_residuals(const int16_t *r0, const int16_t *r1,
120*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *m, int N) {
121*77c1e3ccSAndroid Build Coastguard Worker uint64_t acc = 0;
122*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < N; i++) {
123*77c1e3ccSAndroid Build Coastguard Worker const int32_t m0 = m[i];
124*77c1e3ccSAndroid Build Coastguard Worker const int32_t m1 = MAX_MASK_VALUE - m0;
125*77c1e3ccSAndroid Build Coastguard Worker const int32_t r = m0 * r0[i] + m1 * r1[i];
126*77c1e3ccSAndroid Build Coastguard Worker acc += r * r;
127*77c1e3ccSAndroid Build Coastguard Worker }
128*77c1e3ccSAndroid Build Coastguard Worker return ROUND_POWER_OF_TWO(acc, 2 * WEDGE_WEIGHT_BITS);
129*77c1e3ccSAndroid Build Coastguard Worker }
130*77c1e3ccSAndroid Build Coastguard Worker
TEST_F(WedgeUtilsSSEFuncTest,ResidualBlendingMethod)131*77c1e3ccSAndroid Build Coastguard Worker TEST_F(WedgeUtilsSSEFuncTest, ResidualBlendingMethod) {
132*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
133*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
134*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, d[MAX_SB_SQUARE]);
135*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, uint8_t, m[MAX_SB_SQUARE]);
136*77c1e3ccSAndroid Build Coastguard Worker
137*77c1e3ccSAndroid Build Coastguard Worker for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
138*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) {
139*77c1e3ccSAndroid Build Coastguard Worker r1[i] = rng_(2 * INT8_MAX - 2 * INT8_MIN + 1) + 2 * INT8_MIN;
140*77c1e3ccSAndroid Build Coastguard Worker d[i] = rng_(2 * INT8_MAX - 2 * INT8_MIN + 1) + 2 * INT8_MIN;
141*77c1e3ccSAndroid Build Coastguard Worker m[i] = rng_(MAX_MASK_VALUE + 1);
142*77c1e3ccSAndroid Build Coastguard Worker }
143*77c1e3ccSAndroid Build Coastguard Worker
144*77c1e3ccSAndroid Build Coastguard Worker const int N = 64 * (rng_(MAX_SB_SQUARE / 64) + 1);
145*77c1e3ccSAndroid Build Coastguard Worker
146*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < N; i++) r0[i] = r1[i] + d[i];
147*77c1e3ccSAndroid Build Coastguard Worker
148*77c1e3ccSAndroid Build Coastguard Worker const uint64_t ref_res = sse_from_residuals(r0, r1, m, N);
149*77c1e3ccSAndroid Build Coastguard Worker const uint64_t tst_res = av1_wedge_sse_from_residuals(r1, d, m, N);
150*77c1e3ccSAndroid Build Coastguard Worker
151*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(ref_res, tst_res);
152*77c1e3ccSAndroid Build Coastguard Worker }
153*77c1e3ccSAndroid Build Coastguard Worker }
154*77c1e3ccSAndroid Build Coastguard Worker
155*77c1e3ccSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
156*77c1e3ccSAndroid Build Coastguard Worker // av1_wedge_sse_from_residuals - optimizations
157*77c1e3ccSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
158*77c1e3ccSAndroid Build Coastguard Worker
159*77c1e3ccSAndroid Build Coastguard Worker typedef uint64_t (*FSSE)(const int16_t *r1, const int16_t *d, const uint8_t *m,
160*77c1e3ccSAndroid Build Coastguard Worker int N);
161*77c1e3ccSAndroid Build Coastguard Worker typedef libaom_test::FuncParam<FSSE> TestFuncsFSSE;
162*77c1e3ccSAndroid Build Coastguard Worker
163*77c1e3ccSAndroid Build Coastguard Worker class WedgeUtilsSSEOptTest : public FunctionEquivalenceTest<FSSE> {
164*77c1e3ccSAndroid Build Coastguard Worker protected:
165*77c1e3ccSAndroid Build Coastguard Worker static const int kIterations = 10000;
166*77c1e3ccSAndroid Build Coastguard Worker };
167*77c1e3ccSAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WedgeUtilsSSEOptTest);
168*77c1e3ccSAndroid Build Coastguard Worker
TEST_P(WedgeUtilsSSEOptTest,RandomValues)169*77c1e3ccSAndroid Build Coastguard Worker TEST_P(WedgeUtilsSSEOptTest, RandomValues) {
170*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
171*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, d[MAX_SB_SQUARE]);
172*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, uint8_t, m[MAX_SB_SQUARE]);
173*77c1e3ccSAndroid Build Coastguard Worker
174*77c1e3ccSAndroid Build Coastguard Worker for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
175*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) {
176*77c1e3ccSAndroid Build Coastguard Worker r1[i] = rng_(2 * kInt13Max + 1) - kInt13Max;
177*77c1e3ccSAndroid Build Coastguard Worker d[i] = rng_(2 * kInt13Max + 1) - kInt13Max;
178*77c1e3ccSAndroid Build Coastguard Worker m[i] = rng_(MAX_MASK_VALUE + 1);
179*77c1e3ccSAndroid Build Coastguard Worker }
180*77c1e3ccSAndroid Build Coastguard Worker
181*77c1e3ccSAndroid Build Coastguard Worker const int N = 64 * (rng_(MAX_SB_SQUARE / 64) + 1);
182*77c1e3ccSAndroid Build Coastguard Worker
183*77c1e3ccSAndroid Build Coastguard Worker const uint64_t ref_res = params_.ref_func(r1, d, m, N);
184*77c1e3ccSAndroid Build Coastguard Worker uint64_t tst_res;
185*77c1e3ccSAndroid Build Coastguard Worker API_REGISTER_STATE_CHECK(tst_res = params_.tst_func(r1, d, m, N));
186*77c1e3ccSAndroid Build Coastguard Worker
187*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(ref_res, tst_res);
188*77c1e3ccSAndroid Build Coastguard Worker }
189*77c1e3ccSAndroid Build Coastguard Worker }
190*77c1e3ccSAndroid Build Coastguard Worker
TEST_P(WedgeUtilsSSEOptTest,ExtremeValues)191*77c1e3ccSAndroid Build Coastguard Worker TEST_P(WedgeUtilsSSEOptTest, ExtremeValues) {
192*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
193*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, d[MAX_SB_SQUARE]);
194*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, uint8_t, m[MAX_SB_SQUARE]);
195*77c1e3ccSAndroid Build Coastguard Worker
196*77c1e3ccSAndroid Build Coastguard Worker for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
197*77c1e3ccSAndroid Build Coastguard Worker if (rng_(2)) {
198*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) r1[i] = kInt13Max;
199*77c1e3ccSAndroid Build Coastguard Worker } else {
200*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) r1[i] = -kInt13Max;
201*77c1e3ccSAndroid Build Coastguard Worker }
202*77c1e3ccSAndroid Build Coastguard Worker
203*77c1e3ccSAndroid Build Coastguard Worker if (rng_(2)) {
204*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) d[i] = kInt13Max;
205*77c1e3ccSAndroid Build Coastguard Worker } else {
206*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) d[i] = -kInt13Max;
207*77c1e3ccSAndroid Build Coastguard Worker }
208*77c1e3ccSAndroid Build Coastguard Worker
209*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) m[i] = MAX_MASK_VALUE;
210*77c1e3ccSAndroid Build Coastguard Worker
211*77c1e3ccSAndroid Build Coastguard Worker const int N = 64 * (rng_(MAX_SB_SQUARE / 64) + 1);
212*77c1e3ccSAndroid Build Coastguard Worker
213*77c1e3ccSAndroid Build Coastguard Worker const uint64_t ref_res = params_.ref_func(r1, d, m, N);
214*77c1e3ccSAndroid Build Coastguard Worker uint64_t tst_res;
215*77c1e3ccSAndroid Build Coastguard Worker API_REGISTER_STATE_CHECK(tst_res = params_.tst_func(r1, d, m, N));
216*77c1e3ccSAndroid Build Coastguard Worker
217*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(ref_res, tst_res);
218*77c1e3ccSAndroid Build Coastguard Worker }
219*77c1e3ccSAndroid Build Coastguard Worker }
220*77c1e3ccSAndroid Build Coastguard Worker
221*77c1e3ccSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
222*77c1e3ccSAndroid Build Coastguard Worker // av1_wedge_sign_from_residuals
223*77c1e3ccSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
224*77c1e3ccSAndroid Build Coastguard Worker
225*77c1e3ccSAndroid Build Coastguard Worker typedef int8_t (*FSign)(const int16_t *ds, const uint8_t *m, int N,
226*77c1e3ccSAndroid Build Coastguard Worker int64_t limit);
227*77c1e3ccSAndroid Build Coastguard Worker typedef libaom_test::FuncParam<FSign> TestFuncsFSign;
228*77c1e3ccSAndroid Build Coastguard Worker
229*77c1e3ccSAndroid Build Coastguard Worker class WedgeUtilsSignOptTest : public FunctionEquivalenceTest<FSign> {
230*77c1e3ccSAndroid Build Coastguard Worker protected:
231*77c1e3ccSAndroid Build Coastguard Worker static const int kIterations = 10000;
232*77c1e3ccSAndroid Build Coastguard Worker static const int kMaxSize = 8196; // Size limited by SIMD implementation.
233*77c1e3ccSAndroid Build Coastguard Worker };
234*77c1e3ccSAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WedgeUtilsSignOptTest);
235*77c1e3ccSAndroid Build Coastguard Worker
TEST_P(WedgeUtilsSignOptTest,RandomValues)236*77c1e3ccSAndroid Build Coastguard Worker TEST_P(WedgeUtilsSignOptTest, RandomValues) {
237*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
238*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
239*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
240*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, uint8_t, m[MAX_SB_SQUARE]);
241*77c1e3ccSAndroid Build Coastguard Worker
242*77c1e3ccSAndroid Build Coastguard Worker for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
243*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) {
244*77c1e3ccSAndroid Build Coastguard Worker r0[i] = rng_(2 * kInt13Max + 1) - kInt13Max;
245*77c1e3ccSAndroid Build Coastguard Worker r1[i] = rng_(2 * kInt13Max + 1) - kInt13Max;
246*77c1e3ccSAndroid Build Coastguard Worker m[i] = rng_(MAX_MASK_VALUE + 1);
247*77c1e3ccSAndroid Build Coastguard Worker }
248*77c1e3ccSAndroid Build Coastguard Worker
249*77c1e3ccSAndroid Build Coastguard Worker const int maxN = AOMMIN(kMaxSize, MAX_SB_SQUARE);
250*77c1e3ccSAndroid Build Coastguard Worker const int N = 64 * (rng_(maxN / 64 - 1) + 1);
251*77c1e3ccSAndroid Build Coastguard Worker
252*77c1e3ccSAndroid Build Coastguard Worker int64_t limit;
253*77c1e3ccSAndroid Build Coastguard Worker limit = (int64_t)aom_sum_squares_i16(r0, N);
254*77c1e3ccSAndroid Build Coastguard Worker limit -= (int64_t)aom_sum_squares_i16(r1, N);
255*77c1e3ccSAndroid Build Coastguard Worker limit *= (1 << WEDGE_WEIGHT_BITS) / 2;
256*77c1e3ccSAndroid Build Coastguard Worker
257*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < N; i++)
258*77c1e3ccSAndroid Build Coastguard Worker ds[i] = clamp(r0[i] * r0[i] - r1[i] * r1[i], INT16_MIN, INT16_MAX);
259*77c1e3ccSAndroid Build Coastguard Worker
260*77c1e3ccSAndroid Build Coastguard Worker const int ref_res = params_.ref_func(ds, m, N, limit);
261*77c1e3ccSAndroid Build Coastguard Worker int tst_res;
262*77c1e3ccSAndroid Build Coastguard Worker API_REGISTER_STATE_CHECK(tst_res = params_.tst_func(ds, m, N, limit));
263*77c1e3ccSAndroid Build Coastguard Worker
264*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(ref_res, tst_res);
265*77c1e3ccSAndroid Build Coastguard Worker }
266*77c1e3ccSAndroid Build Coastguard Worker }
267*77c1e3ccSAndroid Build Coastguard Worker
TEST_P(WedgeUtilsSignOptTest,ExtremeValues)268*77c1e3ccSAndroid Build Coastguard Worker TEST_P(WedgeUtilsSignOptTest, ExtremeValues) {
269*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
270*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
271*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
272*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, uint8_t, m[MAX_SB_SQUARE]);
273*77c1e3ccSAndroid Build Coastguard Worker
274*77c1e3ccSAndroid Build Coastguard Worker for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
275*77c1e3ccSAndroid Build Coastguard Worker switch (rng_(4)) {
276*77c1e3ccSAndroid Build Coastguard Worker case 0:
277*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) {
278*77c1e3ccSAndroid Build Coastguard Worker r0[i] = 0;
279*77c1e3ccSAndroid Build Coastguard Worker r1[i] = kInt13Max;
280*77c1e3ccSAndroid Build Coastguard Worker }
281*77c1e3ccSAndroid Build Coastguard Worker break;
282*77c1e3ccSAndroid Build Coastguard Worker case 1:
283*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) {
284*77c1e3ccSAndroid Build Coastguard Worker r0[i] = kInt13Max;
285*77c1e3ccSAndroid Build Coastguard Worker r1[i] = 0;
286*77c1e3ccSAndroid Build Coastguard Worker }
287*77c1e3ccSAndroid Build Coastguard Worker break;
288*77c1e3ccSAndroid Build Coastguard Worker case 2:
289*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) {
290*77c1e3ccSAndroid Build Coastguard Worker r0[i] = 0;
291*77c1e3ccSAndroid Build Coastguard Worker r1[i] = -kInt13Max;
292*77c1e3ccSAndroid Build Coastguard Worker }
293*77c1e3ccSAndroid Build Coastguard Worker break;
294*77c1e3ccSAndroid Build Coastguard Worker default:
295*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) {
296*77c1e3ccSAndroid Build Coastguard Worker r0[i] = -kInt13Max;
297*77c1e3ccSAndroid Build Coastguard Worker r1[i] = 0;
298*77c1e3ccSAndroid Build Coastguard Worker }
299*77c1e3ccSAndroid Build Coastguard Worker break;
300*77c1e3ccSAndroid Build Coastguard Worker }
301*77c1e3ccSAndroid Build Coastguard Worker
302*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) m[i] = MAX_MASK_VALUE;
303*77c1e3ccSAndroid Build Coastguard Worker
304*77c1e3ccSAndroid Build Coastguard Worker const int maxN = AOMMIN(kMaxSize, MAX_SB_SQUARE);
305*77c1e3ccSAndroid Build Coastguard Worker const int N = 64 * (rng_(maxN / 64 - 1) + 1);
306*77c1e3ccSAndroid Build Coastguard Worker
307*77c1e3ccSAndroid Build Coastguard Worker int64_t limit;
308*77c1e3ccSAndroid Build Coastguard Worker limit = (int64_t)aom_sum_squares_i16(r0, N);
309*77c1e3ccSAndroid Build Coastguard Worker limit -= (int64_t)aom_sum_squares_i16(r1, N);
310*77c1e3ccSAndroid Build Coastguard Worker limit *= (1 << WEDGE_WEIGHT_BITS) / 2;
311*77c1e3ccSAndroid Build Coastguard Worker
312*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < N; i++)
313*77c1e3ccSAndroid Build Coastguard Worker ds[i] = clamp(r0[i] * r0[i] - r1[i] * r1[i], INT16_MIN, INT16_MAX);
314*77c1e3ccSAndroid Build Coastguard Worker
315*77c1e3ccSAndroid Build Coastguard Worker const int ref_res = params_.ref_func(ds, m, N, limit);
316*77c1e3ccSAndroid Build Coastguard Worker int tst_res;
317*77c1e3ccSAndroid Build Coastguard Worker API_REGISTER_STATE_CHECK(tst_res = params_.tst_func(ds, m, N, limit));
318*77c1e3ccSAndroid Build Coastguard Worker
319*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(ref_res, tst_res);
320*77c1e3ccSAndroid Build Coastguard Worker }
321*77c1e3ccSAndroid Build Coastguard Worker }
322*77c1e3ccSAndroid Build Coastguard Worker
323*77c1e3ccSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
324*77c1e3ccSAndroid Build Coastguard Worker // av1_wedge_compute_delta_squares
325*77c1e3ccSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
326*77c1e3ccSAndroid Build Coastguard Worker
327*77c1e3ccSAndroid Build Coastguard Worker typedef void (*FDS)(int16_t *d, const int16_t *a, const int16_t *b, int N);
328*77c1e3ccSAndroid Build Coastguard Worker typedef libaom_test::FuncParam<FDS> TestFuncsFDS;
329*77c1e3ccSAndroid Build Coastguard Worker
330*77c1e3ccSAndroid Build Coastguard Worker class WedgeUtilsDeltaSquaresOptTest : public FunctionEquivalenceTest<FDS> {
331*77c1e3ccSAndroid Build Coastguard Worker protected:
332*77c1e3ccSAndroid Build Coastguard Worker static const int kIterations = 10000;
333*77c1e3ccSAndroid Build Coastguard Worker };
334*77c1e3ccSAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WedgeUtilsDeltaSquaresOptTest);
335*77c1e3ccSAndroid Build Coastguard Worker
TEST_P(WedgeUtilsDeltaSquaresOptTest,RandomValues)336*77c1e3ccSAndroid Build Coastguard Worker TEST_P(WedgeUtilsDeltaSquaresOptTest, RandomValues) {
337*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, a[MAX_SB_SQUARE]);
338*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, b[MAX_SB_SQUARE]);
339*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, d_ref[MAX_SB_SQUARE]);
340*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, d_tst[MAX_SB_SQUARE]);
341*77c1e3ccSAndroid Build Coastguard Worker
342*77c1e3ccSAndroid Build Coastguard Worker for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
343*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) {
344*77c1e3ccSAndroid Build Coastguard Worker a[i] = rng_.Rand16Signed();
345*77c1e3ccSAndroid Build Coastguard Worker b[i] = rng_(2 * INT16_MAX + 1) - INT16_MAX;
346*77c1e3ccSAndroid Build Coastguard Worker }
347*77c1e3ccSAndroid Build Coastguard Worker
348*77c1e3ccSAndroid Build Coastguard Worker const int N = 64 * (rng_(MAX_SB_SQUARE / 64) + 1);
349*77c1e3ccSAndroid Build Coastguard Worker
350*77c1e3ccSAndroid Build Coastguard Worker memset(&d_ref, INT16_MAX, sizeof(d_ref));
351*77c1e3ccSAndroid Build Coastguard Worker memset(&d_tst, INT16_MAX, sizeof(d_tst));
352*77c1e3ccSAndroid Build Coastguard Worker
353*77c1e3ccSAndroid Build Coastguard Worker params_.ref_func(d_ref, a, b, N);
354*77c1e3ccSAndroid Build Coastguard Worker API_REGISTER_STATE_CHECK(params_.tst_func(d_tst, a, b, N));
355*77c1e3ccSAndroid Build Coastguard Worker
356*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < MAX_SB_SQUARE; ++i) ASSERT_EQ(d_ref[i], d_tst[i]);
357*77c1e3ccSAndroid Build Coastguard Worker }
358*77c1e3ccSAndroid Build Coastguard Worker }
359*77c1e3ccSAndroid Build Coastguard Worker
360*77c1e3ccSAndroid Build Coastguard Worker #if HAVE_SSE2
361*77c1e3ccSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
362*77c1e3ccSAndroid Build Coastguard Worker SSE2, WedgeUtilsSSEOptTest,
363*77c1e3ccSAndroid Build Coastguard Worker ::testing::Values(TestFuncsFSSE(av1_wedge_sse_from_residuals_c,
364*77c1e3ccSAndroid Build Coastguard Worker av1_wedge_sse_from_residuals_sse2)));
365*77c1e3ccSAndroid Build Coastguard Worker
366*77c1e3ccSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
367*77c1e3ccSAndroid Build Coastguard Worker SSE2, WedgeUtilsSignOptTest,
368*77c1e3ccSAndroid Build Coastguard Worker ::testing::Values(TestFuncsFSign(av1_wedge_sign_from_residuals_c,
369*77c1e3ccSAndroid Build Coastguard Worker av1_wedge_sign_from_residuals_sse2)));
370*77c1e3ccSAndroid Build Coastguard Worker
371*77c1e3ccSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
372*77c1e3ccSAndroid Build Coastguard Worker SSE2, WedgeUtilsDeltaSquaresOptTest,
373*77c1e3ccSAndroid Build Coastguard Worker ::testing::Values(TestFuncsFDS(av1_wedge_compute_delta_squares_c,
374*77c1e3ccSAndroid Build Coastguard Worker av1_wedge_compute_delta_squares_sse2)));
375*77c1e3ccSAndroid Build Coastguard Worker #endif // HAVE_SSE2
376*77c1e3ccSAndroid Build Coastguard Worker
377*77c1e3ccSAndroid Build Coastguard Worker #if HAVE_NEON
378*77c1e3ccSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
379*77c1e3ccSAndroid Build Coastguard Worker NEON, WedgeUtilsSSEOptTest,
380*77c1e3ccSAndroid Build Coastguard Worker ::testing::Values(TestFuncsFSSE(av1_wedge_sse_from_residuals_c,
381*77c1e3ccSAndroid Build Coastguard Worker av1_wedge_sse_from_residuals_neon)));
382*77c1e3ccSAndroid Build Coastguard Worker
383*77c1e3ccSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
384*77c1e3ccSAndroid Build Coastguard Worker NEON, WedgeUtilsSignOptTest,
385*77c1e3ccSAndroid Build Coastguard Worker ::testing::Values(TestFuncsFSign(av1_wedge_sign_from_residuals_c,
386*77c1e3ccSAndroid Build Coastguard Worker av1_wedge_sign_from_residuals_neon)));
387*77c1e3ccSAndroid Build Coastguard Worker
388*77c1e3ccSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
389*77c1e3ccSAndroid Build Coastguard Worker NEON, WedgeUtilsDeltaSquaresOptTest,
390*77c1e3ccSAndroid Build Coastguard Worker ::testing::Values(TestFuncsFDS(av1_wedge_compute_delta_squares_c,
391*77c1e3ccSAndroid Build Coastguard Worker av1_wedge_compute_delta_squares_neon)));
392*77c1e3ccSAndroid Build Coastguard Worker #endif // HAVE_NEON
393*77c1e3ccSAndroid Build Coastguard Worker
394*77c1e3ccSAndroid Build Coastguard Worker #if HAVE_AVX2
395*77c1e3ccSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
396*77c1e3ccSAndroid Build Coastguard Worker AVX2, WedgeUtilsSSEOptTest,
397*77c1e3ccSAndroid Build Coastguard Worker ::testing::Values(TestFuncsFSSE(av1_wedge_sse_from_residuals_sse2,
398*77c1e3ccSAndroid Build Coastguard Worker av1_wedge_sse_from_residuals_avx2)));
399*77c1e3ccSAndroid Build Coastguard Worker
400*77c1e3ccSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
401*77c1e3ccSAndroid Build Coastguard Worker AVX2, WedgeUtilsSignOptTest,
402*77c1e3ccSAndroid Build Coastguard Worker ::testing::Values(TestFuncsFSign(av1_wedge_sign_from_residuals_sse2,
403*77c1e3ccSAndroid Build Coastguard Worker av1_wedge_sign_from_residuals_avx2)));
404*77c1e3ccSAndroid Build Coastguard Worker
405*77c1e3ccSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
406*77c1e3ccSAndroid Build Coastguard Worker AVX2, WedgeUtilsDeltaSquaresOptTest,
407*77c1e3ccSAndroid Build Coastguard Worker ::testing::Values(TestFuncsFDS(av1_wedge_compute_delta_squares_sse2,
408*77c1e3ccSAndroid Build Coastguard Worker av1_wedge_compute_delta_squares_avx2)));
409*77c1e3ccSAndroid Build Coastguard Worker #endif // HAVE_AVX2
410*77c1e3ccSAndroid Build Coastguard Worker
411*77c1e3ccSAndroid Build Coastguard Worker #if HAVE_SVE
412*77c1e3ccSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
413*77c1e3ccSAndroid Build Coastguard Worker SVE, WedgeUtilsSSEOptTest,
414*77c1e3ccSAndroid Build Coastguard Worker ::testing::Values(TestFuncsFSSE(av1_wedge_sse_from_residuals_c,
415*77c1e3ccSAndroid Build Coastguard Worker av1_wedge_sse_from_residuals_sve)));
416*77c1e3ccSAndroid Build Coastguard Worker
417*77c1e3ccSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
418*77c1e3ccSAndroid Build Coastguard Worker SVE, WedgeUtilsSignOptTest,
419*77c1e3ccSAndroid Build Coastguard Worker ::testing::Values(TestFuncsFSign(av1_wedge_sign_from_residuals_c,
420*77c1e3ccSAndroid Build Coastguard Worker av1_wedge_sign_from_residuals_sve)));
421*77c1e3ccSAndroid Build Coastguard Worker #endif // HAVE_SVE
422*77c1e3ccSAndroid Build Coastguard Worker
423*77c1e3ccSAndroid Build Coastguard Worker } // namespace
424