blob: b8701c19645a5d1266560896eba6fec2389121c8 [file] [log] [blame]
Geza Loreabd00502016-02-12 16:04:35 +00001/*
Yaowu Xubde4ac82016-11-28 15:26:06 -08002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Geza Loreabd00502016-02-12 16:04:35 +00003 *
Yaowu Xubde4ac82016-11-28 15:26:06 -08004 * 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.
Geza Loreabd00502016-02-12 16:04:35 +000010 */
11
James Zern5e831c52016-06-09 23:38:31 -070012#include <cmath>
13#include <cstdlib>
14#include <string>
15
Tom Finegan7a07ece2017-02-07 17:14:05 -080016#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
Geza Loreabd00502016-02-12 16:04:35 +000017
Yaowu Xuf883b422016-08-30 14:01:10 -070018#include "./aom_config.h"
19#include "./aom_dsp_rtcd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070020#include "aom_ports/mem.h"
James Zern5e831c52016-06-09 23:38:31 -070021#include "test/acm_random.h"
22#include "test/clear_system_state.h"
Geza Loreabd00502016-02-12 16:04:35 +000023#include "test/register_state_check.h"
James Zern5e831c52016-06-09 23:38:31 -070024#include "test/util.h"
Geza Lore471362f2016-06-21 20:23:13 +010025#include "test/function_equivalence_test.h"
James Zern5e831c52016-06-09 23:38:31 -070026
Yaowu Xuc27fc142016-08-22 16:08:15 -070027using libaom_test::ACMRandom;
28using libaom_test::FunctionEquivalenceTest;
Geza Loreabd00502016-02-12 16:04:35 +000029
30namespace {
James Zern5e831c52016-06-09 23:38:31 -070031const int kNumIterations = 10000;
Geza Loreabd00502016-02-12 16:04:35 +000032
Geza Lore471362f2016-06-21 20:23:13 +010033static const int16_t kInt13Max = (1 << 12) - 1;
34
Alex Converse4c5b0202017-03-29 15:48:40 -070035typedef uint64_t (*SSI16Func)(const int16_t *src, int stride, int width,
36 int height);
Yaowu Xuc27fc142016-08-22 16:08:15 -070037typedef libaom_test::FuncParam<SSI16Func> TestFuncs;
Geza Loreabd00502016-02-12 16:04:35 +000038
clang-format3a826f12016-08-11 17:46:05 -070039class SumSquaresTest : public ::testing::TestWithParam<TestFuncs> {
James Zern5e831c52016-06-09 23:38:31 -070040 public:
41 virtual ~SumSquaresTest() {}
clang-format3a826f12016-08-11 17:46:05 -070042 virtual void SetUp() { params_ = this->GetParam(); }
Geza Loreabd00502016-02-12 16:04:35 +000043
Yaowu Xuc27fc142016-08-22 16:08:15 -070044 virtual void TearDown() { libaom_test::ClearSystemState(); }
Geza Loreabd00502016-02-12 16:04:35 +000045
James Zern5e831c52016-06-09 23:38:31 -070046 protected:
Geza Lorea3f7ddc2016-07-12 15:26:36 +010047 TestFuncs params_;
Geza Loreabd00502016-02-12 16:04:35 +000048};
49
James Zern5e831c52016-06-09 23:38:31 -070050TEST_P(SumSquaresTest, OperationCheck) {
51 ACMRandom rnd(ACMRandom::DeterministicSeed());
clang-format3a826f12016-08-11 17:46:05 -070052 DECLARE_ALIGNED(16, int16_t, src[256 * 256]);
Geza Loreabd00502016-02-12 16:04:35 +000053
James Zern5e831c52016-06-09 23:38:31 -070054 int failed = 0;
55
clang-format3a826f12016-08-11 17:46:05 -070056 const int msb = 11; // Up to 12 bit input
57 const int limit = 1 << (msb + 1);
James Zern5e831c52016-06-09 23:38:31 -070058
59 for (int k = 0; k < kNumIterations; k++) {
Alex Converse4c5b0202017-03-29 15:48:40 -070060 int width = 4 * rnd(32); // Up to 128x128
61 int height = 4 * rnd(32); // Up to 128x128
clang-format3a826f12016-08-11 17:46:05 -070062 int stride = 4 << rnd(7); // Up to 256 stride
Alex Converse4c5b0202017-03-29 15:48:40 -070063 while (stride < width) { // Make sure it's valid
James Zern5e831c52016-06-09 23:38:31 -070064 stride = 4 << rnd(7);
65 }
66
Alex Converse4c5b0202017-03-29 15:48:40 -070067 for (int ii = 0; ii < height; ii++) {
68 for (int jj = 0; jj < width; jj++) {
clang-format3a826f12016-08-11 17:46:05 -070069 src[ii * stride + jj] = rnd(2) ? rnd(limit) : -rnd(limit);
James Zern5e831c52016-06-09 23:38:31 -070070 }
71 }
72
Alex Converse4c5b0202017-03-29 15:48:40 -070073 const uint64_t res_ref = params_.ref_func(src, stride, width, height);
James Zern5e831c52016-06-09 23:38:31 -070074 uint64_t res_tst;
Alex Converse4c5b0202017-03-29 15:48:40 -070075 ASM_REGISTER_STATE_CHECK(res_tst =
76 params_.tst_func(src, stride, width, height));
James Zern5e831c52016-06-09 23:38:31 -070077
78 if (!failed) {
79 failed = res_ref != res_tst;
80 EXPECT_EQ(res_ref, res_tst)
clang-format3a826f12016-08-11 17:46:05 -070081 << "Error: Sum Squares Test"
82 << " C output does not match optimized output.";
James Zern5e831c52016-06-09 23:38:31 -070083 }
Geza Loreabd00502016-02-12 16:04:35 +000084 }
85}
86
James Zern5e831c52016-06-09 23:38:31 -070087TEST_P(SumSquaresTest, ExtremeValues) {
88 ACMRandom rnd(ACMRandom::DeterministicSeed());
clang-format3a826f12016-08-11 17:46:05 -070089 DECLARE_ALIGNED(16, int16_t, src[256 * 256]);
Geza Loreabd00502016-02-12 16:04:35 +000090
James Zern5e831c52016-06-09 23:38:31 -070091 int failed = 0;
92
clang-format3a826f12016-08-11 17:46:05 -070093 const int msb = 11; // Up to 12 bit input
94 const int limit = 1 << (msb + 1);
James Zern5e831c52016-06-09 23:38:31 -070095
96 for (int k = 0; k < kNumIterations; k++) {
Alex Converse4c5b0202017-03-29 15:48:40 -070097 int width = 4 * rnd(32); // Up to 128x128
98 int height = 4 * rnd(32); // Up to 128x128
clang-format3a826f12016-08-11 17:46:05 -070099 int stride = 4 << rnd(7); // Up to 256 stride
Alex Converse4c5b0202017-03-29 15:48:40 -0700100 while (stride < width) { // Make sure it's valid
James Zern5e831c52016-06-09 23:38:31 -0700101 stride = 4 << rnd(7);
102 }
103
clang-format3a826f12016-08-11 17:46:05 -0700104 int val = rnd(2) ? limit - 1 : -(limit - 1);
Alex Converse4c5b0202017-03-29 15:48:40 -0700105 for (int ii = 0; ii < height; ii++) {
106 for (int jj = 0; jj < width; jj++) {
clang-format3a826f12016-08-11 17:46:05 -0700107 src[ii * stride + jj] = val;
James Zern5e831c52016-06-09 23:38:31 -0700108 }
109 }
110
Alex Converse4c5b0202017-03-29 15:48:40 -0700111 const uint64_t res_ref = params_.ref_func(src, stride, width, height);
James Zern5e831c52016-06-09 23:38:31 -0700112 uint64_t res_tst;
Alex Converse4c5b0202017-03-29 15:48:40 -0700113 ASM_REGISTER_STATE_CHECK(res_tst =
114 params_.tst_func(src, stride, width, height));
James Zern5e831c52016-06-09 23:38:31 -0700115
116 if (!failed) {
117 failed = res_ref != res_tst;
118 EXPECT_EQ(res_ref, res_tst)
clang-format3a826f12016-08-11 17:46:05 -0700119 << "Error: Sum Squares Test"
120 << " C output does not match optimized output.";
James Zern5e831c52016-06-09 23:38:31 -0700121 }
Geza Loreabd00502016-02-12 16:04:35 +0000122 }
123}
Geza Loreabd00502016-02-12 16:04:35 +0000124
125#if HAVE_SSE2
James Zern5e831c52016-06-09 23:38:31 -0700126
Geza Loreabd00502016-02-12 16:04:35 +0000127INSTANTIATE_TEST_CASE_P(
James Zern5e831c52016-06-09 23:38:31 -0700128 SSE2, SumSquaresTest,
Yaowu Xuf883b422016-08-30 14:01:10 -0700129 ::testing::Values(TestFuncs(&aom_sum_squares_2d_i16_c,
130 &aom_sum_squares_2d_i16_sse2)));
Geza Lorea3f7ddc2016-07-12 15:26:36 +0100131
Geza Loreabd00502016-02-12 16:04:35 +0000132#endif // HAVE_SSE2
Geza Lore471362f2016-06-21 20:23:13 +0100133
134//////////////////////////////////////////////////////////////////////////////
135// 1D version
136//////////////////////////////////////////////////////////////////////////////
137
138typedef uint64_t (*F1D)(const int16_t *src, uint32_t N);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700139typedef libaom_test::FuncParam<F1D> TestFuncs1D;
Geza Lore471362f2016-06-21 20:23:13 +0100140
141class SumSquares1DTest : public FunctionEquivalenceTest<F1D> {
142 protected:
Geza Lore471362f2016-06-21 20:23:13 +0100143 static const int kIterations = 1000;
144 static const int kMaxSize = 256;
Geza Lore471362f2016-06-21 20:23:13 +0100145};
146
147TEST_P(SumSquares1DTest, RandomValues) {
148 DECLARE_ALIGNED(16, int16_t, src[kMaxSize * kMaxSize]);
149
clang-format3a826f12016-08-11 17:46:05 -0700150 for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
151 for (int i = 0; i < kMaxSize * kMaxSize; ++i)
Geza Lore471362f2016-06-21 20:23:13 +0100152 src[i] = rng_(kInt13Max * 2 + 1) - kInt13Max;
153
154 const int N = rng_(2) ? rng_(kMaxSize * kMaxSize + 1 - kMaxSize) + kMaxSize
155 : rng_(kMaxSize) + 1;
156
Geza Lorea3f7ddc2016-07-12 15:26:36 +0100157 const uint64_t ref_res = params_.ref_func(src, N);
158 uint64_t tst_res;
159 ASM_REGISTER_STATE_CHECK(tst_res = params_.tst_func(src, N));
Geza Lore471362f2016-06-21 20:23:13 +0100160
161 ASSERT_EQ(ref_res, tst_res);
162 }
163}
164
165TEST_P(SumSquares1DTest, ExtremeValues) {
166 DECLARE_ALIGNED(16, int16_t, src[kMaxSize * kMaxSize]);
167
clang-format3a826f12016-08-11 17:46:05 -0700168 for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
Geza Lore471362f2016-06-21 20:23:13 +0100169 if (rng_(2)) {
clang-format3a826f12016-08-11 17:46:05 -0700170 for (int i = 0; i < kMaxSize * kMaxSize; ++i) src[i] = kInt13Max;
Geza Lore471362f2016-06-21 20:23:13 +0100171 } else {
clang-format3a826f12016-08-11 17:46:05 -0700172 for (int i = 0; i < kMaxSize * kMaxSize; ++i) src[i] = -kInt13Max;
Geza Lore471362f2016-06-21 20:23:13 +0100173 }
174
175 const int N = rng_(2) ? rng_(kMaxSize * kMaxSize + 1 - kMaxSize) + kMaxSize
176 : rng_(kMaxSize) + 1;
177
Geza Lorea3f7ddc2016-07-12 15:26:36 +0100178 const uint64_t ref_res = params_.ref_func(src, N);
179 uint64_t tst_res;
180 ASM_REGISTER_STATE_CHECK(tst_res = params_.tst_func(src, N));
Geza Lore471362f2016-06-21 20:23:13 +0100181
182 ASSERT_EQ(ref_res, tst_res);
183 }
184}
185
Geza Lore471362f2016-06-21 20:23:13 +0100186#if HAVE_SSE2
clang-format3a826f12016-08-11 17:46:05 -0700187INSTANTIATE_TEST_CASE_P(SSE2, SumSquares1DTest,
188 ::testing::Values(TestFuncs1D(
Yaowu Xuf883b422016-08-30 14:01:10 -0700189 aom_sum_squares_i16_c, aom_sum_squares_i16_sse2)));
Geza Lorea3f7ddc2016-07-12 15:26:36 +0100190
Geza Lore471362f2016-06-21 20:23:13 +0100191#endif // HAVE_SSE2
Geza Loreabd00502016-02-12 16:04:35 +0000192} // namespace