tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

subtract_test.cc (9513B)


      1 /*
      2 * Copyright (c) 2016, 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 <cstdint>
     13 #include <tuple>
     14 
     15 #include "gtest/gtest.h"
     16 
     17 #include "config/aom_config.h"
     18 #include "config/aom_dsp_rtcd.h"
     19 
     20 #include "test/acm_random.h"
     21 #include "test/register_state_check.h"
     22 #include "test/util.h"
     23 #include "av1/common/blockd.h"
     24 #include "aom_mem/aom_mem.h"
     25 #include "aom_ports/mem.h"
     26 
     27 using SubtractFunc = void (*)(int rows, int cols, int16_t *diff_ptr,
     28                              ptrdiff_t diff_stride, const uint8_t *src_ptr,
     29                              ptrdiff_t src_stride, const uint8_t *pred_ptr,
     30                              ptrdiff_t pred_stride);
     31 
     32 namespace {
     33 
     34 using std::get;
     35 using std::make_tuple;
     36 using std::tuple;
     37 
     38 using libaom_test::ACMRandom;
     39 
     40 // <BLOCK_SIZE, optimized subtract func, reference subtract func>
     41 using Params = tuple<BLOCK_SIZE, SubtractFunc, SubtractFunc>;
     42 
     43 class AV1SubtractBlockTestBase : public ::testing::Test {
     44 public:
     45  AV1SubtractBlockTestBase(BLOCK_SIZE bs, int bit_depth, SubtractFunc func,
     46                           SubtractFunc ref_func) {
     47    block_width_ = block_size_wide[bs];
     48    block_height_ = block_size_high[bs];
     49    func_ = func;
     50    ref_func_ = ref_func;
     51    if (bit_depth == -1) {
     52      hbd_ = false;
     53      bit_depth_ = AOM_BITS_8;
     54    } else {
     55      hbd_ = true;
     56      bit_depth_ = static_cast<aom_bit_depth_t>(bit_depth);
     57    }
     58  }
     59 
     60  void SetUp() override {
     61    rnd_.Reset(ACMRandom::DeterministicSeed());
     62 
     63    const size_t max_width = 128;
     64    const size_t max_block_size = max_width * max_width;
     65    if (hbd_) {
     66      src_ = CONVERT_TO_BYTEPTR(reinterpret_cast<uint16_t *>(
     67          aom_memalign(16, max_block_size * sizeof(uint16_t))));
     68      ASSERT_NE(src_, nullptr);
     69      pred_ = CONVERT_TO_BYTEPTR(reinterpret_cast<uint16_t *>(
     70          aom_memalign(16, max_block_size * sizeof(uint16_t))));
     71      ASSERT_NE(pred_, nullptr);
     72    } else {
     73      src_ = reinterpret_cast<uint8_t *>(
     74          aom_memalign(16, max_block_size * sizeof(uint8_t)));
     75      ASSERT_NE(src_, nullptr);
     76      pred_ = reinterpret_cast<uint8_t *>(
     77          aom_memalign(16, max_block_size * sizeof(uint8_t)));
     78      ASSERT_NE(pred_, nullptr);
     79    }
     80    diff_ = reinterpret_cast<int16_t *>(
     81        aom_memalign(32, max_block_size * sizeof(int16_t)));
     82    ASSERT_NE(diff_, nullptr);
     83  }
     84 
     85  void TearDown() override {
     86    if (hbd_) {
     87      aom_free(CONVERT_TO_SHORTPTR(src_));
     88      aom_free(CONVERT_TO_SHORTPTR(pred_));
     89    } else {
     90      aom_free(src_);
     91      aom_free(pred_);
     92    }
     93    aom_free(diff_);
     94  }
     95 
     96 protected:
     97  void CheckResult();
     98  void RunForSpeed();
     99 
    100 private:
    101  void FillInputs();
    102 
    103  ACMRandom rnd_;
    104  int block_height_;
    105  int block_width_;
    106  bool hbd_;
    107  aom_bit_depth_t bit_depth_;
    108  SubtractFunc func_;
    109  SubtractFunc ref_func_;
    110  uint8_t *src_;
    111  uint8_t *pred_;
    112  int16_t *diff_;
    113 };
    114 
    115 void AV1SubtractBlockTestBase::FillInputs() {
    116  const size_t max_width = 128;
    117  const int max_block_size = max_width * max_width;
    118  if (hbd_) {
    119    const int mask = (1 << bit_depth_) - 1;
    120    for (int i = 0; i < max_block_size; ++i) {
    121      CONVERT_TO_SHORTPTR(src_)[i] = rnd_.Rand16() & mask;
    122      CONVERT_TO_SHORTPTR(pred_)[i] = rnd_.Rand16() & mask;
    123    }
    124  } else {
    125    if (src_ == nullptr) {
    126      std::cerr << "gadfg" << std::endl;
    127    }
    128    for (int i = 0; i < max_block_size; ++i) {
    129      src_[i] = rnd_.Rand8();
    130      pred_[i] = rnd_.Rand8();
    131    }
    132  }
    133 }
    134 
    135 void AV1SubtractBlockTestBase::CheckResult() {
    136  const int test_num = 100;
    137  int i;
    138 
    139  for (i = 0; i < test_num; ++i) {
    140    FillInputs();
    141 
    142    func_(block_height_, block_width_, diff_, block_width_, src_, block_width_,
    143          pred_, block_width_);
    144 
    145    if (hbd_)
    146      for (int r = 0; r < block_height_; ++r) {
    147        for (int c = 0; c < block_width_; ++c) {
    148          EXPECT_EQ(diff_[r * block_width_ + c],
    149                    (CONVERT_TO_SHORTPTR(src_)[r * block_width_ + c] -
    150                     CONVERT_TO_SHORTPTR(pred_)[r * block_width_ + c]))
    151              << "r = " << r << ", c = " << c << ", test: " << i;
    152        }
    153      }
    154    else {
    155      for (int r = 0; r < block_height_; ++r) {
    156        for (int c = 0; c < block_width_; ++c) {
    157          EXPECT_EQ(diff_[r * block_width_ + c],
    158                    src_[r * block_width_ + c] - pred_[r * block_width_ + c])
    159              << "r = " << r << ", c = " << c << ", test: " << i;
    160        }
    161      }
    162    }
    163  }
    164 }
    165 
    166 void AV1SubtractBlockTestBase::RunForSpeed() {
    167  const int test_num = 200000;
    168  int i;
    169 
    170  if (ref_func_ == func_) GTEST_SKIP();
    171 
    172  FillInputs();
    173 
    174  aom_usec_timer ref_timer;
    175  aom_usec_timer_start(&ref_timer);
    176  for (i = 0; i < test_num; ++i) {
    177    ref_func_(block_height_, block_width_, diff_, block_width_, src_,
    178              block_width_, pred_, block_width_);
    179  }
    180  aom_usec_timer_mark(&ref_timer);
    181  const int64_t ref_elapsed_time = aom_usec_timer_elapsed(&ref_timer);
    182 
    183  FillInputs();
    184 
    185  aom_usec_timer timer;
    186  aom_usec_timer_start(&timer);
    187  for (i = 0; i < test_num; ++i) {
    188    func_(block_height_, block_width_, diff_, block_width_, src_, block_width_,
    189          pred_, block_width_);
    190  }
    191  aom_usec_timer_mark(&timer);
    192  const int64_t elapsed_time = aom_usec_timer_elapsed(&timer);
    193 
    194  printf(
    195      "[%dx%d]: "
    196      "ref_time=%6" PRId64 " \t simd_time=%6" PRId64
    197      " \t "
    198      "gain=%f \n",
    199      block_width_, block_height_, ref_elapsed_time, elapsed_time,
    200      static_cast<double>(ref_elapsed_time) /
    201          static_cast<double>(elapsed_time));
    202 }
    203 
    204 class AV1SubtractBlockTest : public ::testing::WithParamInterface<Params>,
    205                             public AV1SubtractBlockTestBase {
    206 public:
    207  AV1SubtractBlockTest()
    208      : AV1SubtractBlockTestBase(GET_PARAM(0), -1, GET_PARAM(1), GET_PARAM(2)) {
    209  }
    210 };
    211 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AV1SubtractBlockTest);
    212 
    213 TEST_P(AV1SubtractBlockTest, CheckResult) { CheckResult(); }
    214 TEST_P(AV1SubtractBlockTest, DISABLED_Speed) { RunForSpeed(); }
    215 
    216 const BLOCK_SIZE kValidBlockSize[] = { BLOCK_4X4,    BLOCK_4X8,    BLOCK_8X4,
    217                                       BLOCK_8X8,    BLOCK_8X16,   BLOCK_16X8,
    218                                       BLOCK_16X16,  BLOCK_16X32,  BLOCK_32X16,
    219                                       BLOCK_32X32,  BLOCK_32X64,  BLOCK_64X32,
    220                                       BLOCK_64X64,  BLOCK_64X128, BLOCK_128X64,
    221                                       BLOCK_128X128 };
    222 
    223 INSTANTIATE_TEST_SUITE_P(
    224    C, AV1SubtractBlockTest,
    225    ::testing::Combine(::testing::ValuesIn(kValidBlockSize),
    226                       ::testing::Values(&aom_subtract_block_c),
    227                       ::testing::Values(&aom_subtract_block_c)));
    228 
    229 #if HAVE_SSE2
    230 INSTANTIATE_TEST_SUITE_P(
    231    SSE2, AV1SubtractBlockTest,
    232    ::testing::Combine(::testing::ValuesIn(kValidBlockSize),
    233                       ::testing::Values(&aom_subtract_block_sse2),
    234                       ::testing::Values(&aom_subtract_block_c)));
    235 #endif
    236 #if HAVE_AVX2
    237 INSTANTIATE_TEST_SUITE_P(
    238    AVX2, AV1SubtractBlockTest,
    239    ::testing::Combine(::testing::ValuesIn(kValidBlockSize),
    240                       ::testing::Values(&aom_subtract_block_avx2),
    241                       ::testing::Values(&aom_subtract_block_c)));
    242 
    243 #endif
    244 #if HAVE_NEON
    245 INSTANTIATE_TEST_SUITE_P(
    246    NEON, AV1SubtractBlockTest,
    247    ::testing::Combine(::testing::ValuesIn(kValidBlockSize),
    248                       ::testing::Values(&aom_subtract_block_neon),
    249                       ::testing::Values(&aom_subtract_block_c)));
    250 
    251 #endif
    252 
    253 #if CONFIG_AV1_HIGHBITDEPTH
    254 
    255 // <BLOCK_SIZE, bit_depth, optimized subtract func, reference subtract func>
    256 using ParamsHBD = tuple<BLOCK_SIZE, int, SubtractFunc, SubtractFunc>;
    257 
    258 class AV1HBDSubtractBlockTest : public ::testing::WithParamInterface<ParamsHBD>,
    259                                public AV1SubtractBlockTestBase {
    260 public:
    261  AV1HBDSubtractBlockTest()
    262      : AV1SubtractBlockTestBase(GET_PARAM(0), GET_PARAM(1), GET_PARAM(2),
    263                                 GET_PARAM(3)) {}
    264 };
    265 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AV1HBDSubtractBlockTest);
    266 
    267 INSTANTIATE_TEST_SUITE_P(
    268    C, AV1HBDSubtractBlockTest,
    269    ::testing::Combine(::testing::ValuesIn(kValidBlockSize),
    270                       ::testing::Values(12),
    271                       ::testing::Values(&aom_highbd_subtract_block_c),
    272                       ::testing::Values(&aom_highbd_subtract_block_c)));
    273 
    274 #if HAVE_SSE2
    275 INSTANTIATE_TEST_SUITE_P(
    276    SSE2, AV1HBDSubtractBlockTest,
    277    ::testing::Combine(::testing::ValuesIn(kValidBlockSize),
    278                       ::testing::Values(12),
    279                       ::testing::Values(&aom_highbd_subtract_block_sse2),
    280                       ::testing::Values(&aom_highbd_subtract_block_c)));
    281 #endif  // HAVE_SSE2
    282 
    283 #if HAVE_NEON
    284 INSTANTIATE_TEST_SUITE_P(
    285    NEON, AV1HBDSubtractBlockTest,
    286    ::testing::Combine(::testing::ValuesIn(kValidBlockSize),
    287                       ::testing::Values(12),
    288                       ::testing::Values(&aom_highbd_subtract_block_neon),
    289                       ::testing::Values(&aom_highbd_subtract_block_c)));
    290 #endif
    291 #endif  // CONFIG_AV1_HIGHBITDEPTH
    292 }  // namespace