tor-browser

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

hadamard_test.cc (18271B)


      1 /*
      2 * Copyright (c) 2019, 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 <algorithm>
     13 #include <ostream>
     14 
     15 #include "gtest/gtest.h"
     16 
     17 #include "config/aom_dsp_rtcd.h"
     18 
     19 #include "test/acm_random.h"
     20 #include "test/register_state_check.h"
     21 #include "test/util.h"
     22 
     23 namespace {
     24 
     25 using libaom_test::ACMRandom;
     26 
     27 using HadamardFunc = void (*)(const int16_t *a, ptrdiff_t a_stride,
     28                              tran_low_t *b);
     29 // Low precision version of Hadamard Transform
     30 using HadamardLPFunc = void (*)(const int16_t *a, ptrdiff_t a_stride,
     31                                int16_t *b);
     32 // Low precision version of Hadamard Transform 8x8 - Dual
     33 using HadamardLP8x8DualFunc = void (*)(const int16_t *a, ptrdiff_t a_stride,
     34                                       int16_t *b);
     35 
     36 template <typename OutputType>
     37 void Hadamard4x4(const OutputType *a, OutputType *out) {
     38  OutputType b[8];
     39  for (int i = 0; i < 4; i += 2) {
     40    b[i + 0] = (a[i * 4] + a[(i + 1) * 4]) >> 1;
     41    b[i + 1] = (a[i * 4] - a[(i + 1) * 4]) >> 1;
     42  }
     43 
     44  out[0] = b[0] + b[2];
     45  out[1] = b[1] + b[3];
     46  out[2] = b[0] - b[2];
     47  out[3] = b[1] - b[3];
     48 }
     49 
     50 template <typename OutputType>
     51 void ReferenceHadamard4x4(const int16_t *a, int a_stride, OutputType *b) {
     52  OutputType input[16];
     53  OutputType buf[16];
     54  for (int i = 0; i < 4; ++i) {
     55    for (int j = 0; j < 4; ++j) {
     56      input[i * 4 + j] = static_cast<OutputType>(a[i * a_stride + j]);
     57    }
     58  }
     59  for (int i = 0; i < 4; ++i) Hadamard4x4(input + i, buf + i * 4);
     60  for (int i = 0; i < 4; ++i) Hadamard4x4(buf + i, b + i * 4);
     61 
     62  // Extra transpose to match C and SSE2 behavior(i.e., aom_hadamard_4x4).
     63  for (int i = 0; i < 4; i++) {
     64    for (int j = i + 1; j < 4; j++) {
     65      OutputType temp = b[j * 4 + i];
     66      b[j * 4 + i] = b[i * 4 + j];
     67      b[i * 4 + j] = temp;
     68    }
     69  }
     70 }
     71 
     72 template <typename OutputType>
     73 void HadamardLoop(const OutputType *a, OutputType *out) {
     74  OutputType b[8];
     75  for (int i = 0; i < 8; i += 2) {
     76    b[i + 0] = a[i * 8] + a[(i + 1) * 8];
     77    b[i + 1] = a[i * 8] - a[(i + 1) * 8];
     78  }
     79  OutputType c[8];
     80  for (int i = 0; i < 8; i += 4) {
     81    c[i + 0] = b[i + 0] + b[i + 2];
     82    c[i + 1] = b[i + 1] + b[i + 3];
     83    c[i + 2] = b[i + 0] - b[i + 2];
     84    c[i + 3] = b[i + 1] - b[i + 3];
     85  }
     86  out[0] = c[0] + c[4];
     87  out[7] = c[1] + c[5];
     88  out[3] = c[2] + c[6];
     89  out[4] = c[3] + c[7];
     90  out[2] = c[0] - c[4];
     91  out[6] = c[1] - c[5];
     92  out[1] = c[2] - c[6];
     93  out[5] = c[3] - c[7];
     94 }
     95 
     96 template <typename OutputType>
     97 void ReferenceHadamard8x8(const int16_t *a, int a_stride, OutputType *b) {
     98  OutputType input[64];
     99  OutputType buf[64];
    100  for (int i = 0; i < 8; ++i) {
    101    for (int j = 0; j < 8; ++j) {
    102      input[i * 8 + j] = static_cast<OutputType>(a[i * a_stride + j]);
    103    }
    104  }
    105  for (int i = 0; i < 8; ++i) HadamardLoop(input + i, buf + i * 8);
    106  for (int i = 0; i < 8; ++i) HadamardLoop(buf + i, b + i * 8);
    107 
    108  // Extra transpose to match SSE2 behavior (i.e., aom_hadamard_8x8 and
    109  // aom_hadamard_lp_8x8).
    110  for (int i = 0; i < 8; i++) {
    111    for (int j = i + 1; j < 8; j++) {
    112      OutputType temp = b[j * 8 + i];
    113      b[j * 8 + i] = b[i * 8 + j];
    114      b[i * 8 + j] = temp;
    115    }
    116  }
    117 }
    118 
    119 template <typename OutputType>
    120 void ReferenceHadamard8x8Dual(const int16_t *a, int a_stride, OutputType *b) {
    121  /* The source is a 8x16 block. The destination is rearranged to 8x16.
    122   * Input is 9 bit. */
    123  ReferenceHadamard8x8(a, a_stride, b);
    124  ReferenceHadamard8x8(a + 8, a_stride, b + 64);
    125 }
    126 
    127 template <typename OutputType>
    128 void ReferenceHadamard16x16(const int16_t *a, int a_stride, OutputType *b,
    129                            bool shift) {
    130  /* The source is a 16x16 block. The destination is rearranged to 8x32.
    131   * Input is 9 bit. */
    132  ReferenceHadamard8x8(a + 0 + 0 * a_stride, a_stride, b + 0);
    133  ReferenceHadamard8x8(a + 8 + 0 * a_stride, a_stride, b + 64);
    134  ReferenceHadamard8x8(a + 0 + 8 * a_stride, a_stride, b + 128);
    135  ReferenceHadamard8x8(a + 8 + 8 * a_stride, a_stride, b + 192);
    136 
    137  /* Overlay the 8x8 blocks and combine. */
    138  for (int i = 0; i < 64; ++i) {
    139    /* 8x8 steps the range up to 15 bits. */
    140    const OutputType a0 = b[0];
    141    const OutputType a1 = b[64];
    142    const OutputType a2 = b[128];
    143    const OutputType a3 = b[192];
    144 
    145    /* Prevent the result from escaping int16_t. */
    146    const OutputType b0 = (a0 + a1) >> 1;
    147    const OutputType b1 = (a0 - a1) >> 1;
    148    const OutputType b2 = (a2 + a3) >> 1;
    149    const OutputType b3 = (a2 - a3) >> 1;
    150 
    151    /* Store a 16 bit value. */
    152    b[0] = b0 + b2;
    153    b[64] = b1 + b3;
    154    b[128] = b0 - b2;
    155    b[192] = b1 - b3;
    156 
    157    ++b;
    158  }
    159 
    160  if (shift) {
    161    b -= 64;
    162    // Extra shift to match aom_hadamard_16x16_c and aom_hadamard_16x16_avx2.
    163    for (int i = 0; i < 16; i++) {
    164      for (int j = 0; j < 4; j++) {
    165        OutputType temp = b[i * 16 + 4 + j];
    166        b[i * 16 + 4 + j] = b[i * 16 + 8 + j];
    167        b[i * 16 + 8 + j] = temp;
    168      }
    169    }
    170  }
    171 }
    172 
    173 template <typename OutputType>
    174 void ReferenceHadamard32x32(const int16_t *a, int a_stride, OutputType *b,
    175                            bool shift) {
    176  ReferenceHadamard16x16(a + 0 + 0 * a_stride, a_stride, b + 0, shift);
    177  ReferenceHadamard16x16(a + 16 + 0 * a_stride, a_stride, b + 256, shift);
    178  ReferenceHadamard16x16(a + 0 + 16 * a_stride, a_stride, b + 512, shift);
    179  ReferenceHadamard16x16(a + 16 + 16 * a_stride, a_stride, b + 768, shift);
    180 
    181  for (int i = 0; i < 256; ++i) {
    182    const OutputType a0 = b[0];
    183    const OutputType a1 = b[256];
    184    const OutputType a2 = b[512];
    185    const OutputType a3 = b[768];
    186 
    187    const OutputType b0 = (a0 + a1) >> 2;
    188    const OutputType b1 = (a0 - a1) >> 2;
    189    const OutputType b2 = (a2 + a3) >> 2;
    190    const OutputType b3 = (a2 - a3) >> 2;
    191 
    192    b[0] = b0 + b2;
    193    b[256] = b1 + b3;
    194    b[512] = b0 - b2;
    195    b[768] = b1 - b3;
    196 
    197    ++b;
    198  }
    199 }
    200 
    201 template <typename OutputType>
    202 void ReferenceHadamard(const int16_t *a, int a_stride, OutputType *b, int bw,
    203                       int bh, bool shift) {
    204  if (bw == 32 && bh == 32) {
    205    ReferenceHadamard32x32(a, a_stride, b, shift);
    206  } else if (bw == 16 && bh == 16) {
    207    ReferenceHadamard16x16(a, a_stride, b, shift);
    208  } else if (bw == 8 && bh == 8) {
    209    ReferenceHadamard8x8(a, a_stride, b);
    210  } else if (bw == 4 && bh == 4) {
    211    ReferenceHadamard4x4(a, a_stride, b);
    212  } else if (bw == 8 && bh == 16) {
    213    ReferenceHadamard8x8Dual(a, a_stride, b);
    214  } else {
    215    GTEST_FAIL() << "Invalid Hadamard transform size " << bw << bh << std::endl;
    216  }
    217 }
    218 
    219 template <typename HadamardFuncType>
    220 struct FuncWithSize {
    221  FuncWithSize(HadamardFuncType f, int bw, int bh)
    222      : func(f), block_width(bw), block_height(bh) {}
    223  HadamardFuncType func;
    224  int block_width;
    225  int block_height;
    226 };
    227 
    228 using HadamardFuncWithSize = FuncWithSize<HadamardFunc>;
    229 using HadamardLPFuncWithSize = FuncWithSize<HadamardLPFunc>;
    230 using HadamardLP8x8DualFuncWithSize = FuncWithSize<HadamardLP8x8DualFunc>;
    231 
    232 template <typename OutputType, typename HadamardFuncType>
    233 class HadamardTestBase
    234    : public ::testing::TestWithParam<FuncWithSize<HadamardFuncType>> {
    235 public:
    236  HadamardTestBase(const FuncWithSize<HadamardFuncType> &func_param,
    237                   bool do_shift) {
    238    h_func_ = func_param.func;
    239    bw_ = func_param.block_width;
    240    bh_ = func_param.block_height;
    241    shift_ = do_shift;
    242  }
    243 
    244  void SetUp() override { rnd_.Reset(ACMRandom::DeterministicSeed()); }
    245 
    246  // The Rand() function generates values in the range [-((1 << BitDepth) - 1),
    247  // (1 << BitDepth) - 1]. This is because the input to the Hadamard transform
    248  // is the residual pixel, which is defined as 'source pixel - predicted
    249  // pixel'. Source pixel and predicted pixel take values in the range
    250  // [0, (1 << BitDepth) - 1] and thus the residual pixel ranges from
    251  // -((1 << BitDepth) - 1) to ((1 << BitDepth) - 1).
    252  virtual int16_t Rand() = 0;
    253 
    254  void CompareReferenceRandom() {
    255    const int kMaxBlockSize = 32 * 32;
    256    const int block_size = bw_ * bh_;
    257 
    258    DECLARE_ALIGNED(16, int16_t, a[kMaxBlockSize]);
    259    DECLARE_ALIGNED(16, OutputType, b[kMaxBlockSize]);
    260    memset(a, 0, sizeof(a));
    261    memset(b, 0, sizeof(b));
    262 
    263    OutputType b_ref[kMaxBlockSize];
    264    memset(b_ref, 0, sizeof(b_ref));
    265 
    266    for (int i = 0; i < block_size; ++i) a[i] = Rand();
    267    ReferenceHadamard(a, bw_, b_ref, bw_, bh_, shift_);
    268    API_REGISTER_STATE_CHECK(h_func_(a, bw_, b));
    269 
    270    // The order of the output is not important. Sort before checking.
    271    std::sort(b, b + block_size);
    272    std::sort(b_ref, b_ref + block_size);
    273    EXPECT_EQ(memcmp(b, b_ref, sizeof(b)), 0);
    274  }
    275 
    276  void CompareReferenceExtreme() {
    277    const int kMaxBlockSize = 32 * 32;
    278    const int block_size = bw_ * bh_;
    279    const int kBitDepth = 8;
    280    DECLARE_ALIGNED(16, int16_t, a[kMaxBlockSize]);
    281    DECLARE_ALIGNED(16, OutputType, b[kMaxBlockSize]);
    282    memset(b, 0, sizeof(b));
    283 
    284    OutputType b_ref[kMaxBlockSize];
    285    memset(b_ref, 0, sizeof(b_ref));
    286    for (int i = 0; i < 2; ++i) {
    287      const int sign = (i == 0) ? 1 : -1;
    288      for (int j = 0; j < block_size; ++j) a[j] = sign * ((1 << kBitDepth) - 1);
    289 
    290      ReferenceHadamard(a, bw_, b_ref, bw_, bh_, shift_);
    291      API_REGISTER_STATE_CHECK(h_func_(a, bw_, b));
    292 
    293      // The order of the output is not important. Sort before checking.
    294      std::sort(b, b + block_size);
    295      std::sort(b_ref, b_ref + block_size);
    296      EXPECT_EQ(memcmp(b, b_ref, sizeof(b)), 0);
    297    }
    298  }
    299 
    300  void VaryStride() {
    301    const int kMaxBlockSize = 32 * 32;
    302    const int block_size = bw_ * bh_;
    303 
    304    DECLARE_ALIGNED(16, int16_t, a[kMaxBlockSize * 8]);
    305    DECLARE_ALIGNED(16, OutputType, b[kMaxBlockSize]);
    306    memset(a, 0, sizeof(a));
    307    for (int i = 0; i < block_size * 8; ++i) a[i] = Rand();
    308 
    309    OutputType b_ref[kMaxBlockSize];
    310    for (int i = 8; i < 64; i += 8) {
    311      memset(b, 0, sizeof(b));
    312      memset(b_ref, 0, sizeof(b_ref));
    313 
    314      ReferenceHadamard(a, i, b_ref, bw_, bh_, shift_);
    315      API_REGISTER_STATE_CHECK(h_func_(a, i, b));
    316 
    317      // The order of the output is not important. Sort before checking.
    318      std::sort(b, b + block_size);
    319      std::sort(b_ref, b_ref + block_size);
    320      EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
    321    }
    322  }
    323 
    324  void SpeedTest(int times) {
    325    const int kMaxBlockSize = 32 * 32;
    326    DECLARE_ALIGNED(16, int16_t, input[kMaxBlockSize]);
    327    DECLARE_ALIGNED(16, OutputType, output[kMaxBlockSize]);
    328    memset(input, 1, sizeof(input));
    329    memset(output, 0, sizeof(output));
    330 
    331    aom_usec_timer timer;
    332    aom_usec_timer_start(&timer);
    333    for (int i = 0; i < times; ++i) {
    334      h_func_(input, bw_, output);
    335    }
    336    aom_usec_timer_mark(&timer);
    337 
    338    const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
    339    printf("Hadamard%dx%d[%12d runs]: %d us\n", bw_, bh_, times, elapsed_time);
    340  }
    341 
    342 protected:
    343  ACMRandom rnd_;
    344 
    345 private:
    346  HadamardFuncType h_func_;
    347  int bw_;
    348  int bh_;
    349  bool shift_;
    350 };
    351 
    352 class HadamardLowbdTest : public HadamardTestBase<tran_low_t, HadamardFunc> {
    353 public:
    354  HadamardLowbdTest() : HadamardTestBase(GetParam(), /*do_shift=*/true) {}
    355  // Use values between -255 (0xFF01) and 255 (0x00FF)
    356  int16_t Rand() override {
    357    int16_t src = rnd_.Rand8();
    358    int16_t pred = rnd_.Rand8();
    359    return src - pred;
    360  }
    361 };
    362 
    363 TEST_P(HadamardLowbdTest, CompareReferenceRandom) { CompareReferenceRandom(); }
    364 
    365 TEST_P(HadamardLowbdTest, CompareReferenceExtreme) {
    366  CompareReferenceExtreme();
    367 }
    368 
    369 TEST_P(HadamardLowbdTest, VaryStride) { VaryStride(); }
    370 
    371 TEST_P(HadamardLowbdTest, DISABLED_SpeedTest) { SpeedTest(1000000); }
    372 
    373 INSTANTIATE_TEST_SUITE_P(
    374    C, HadamardLowbdTest,
    375    ::testing::Values(HadamardFuncWithSize(&aom_hadamard_4x4_c, 4, 4),
    376                      HadamardFuncWithSize(&aom_hadamard_8x8_c, 8, 8),
    377                      HadamardFuncWithSize(&aom_hadamard_16x16_c, 16, 16),
    378                      HadamardFuncWithSize(&aom_hadamard_32x32_c, 32, 32)));
    379 
    380 #if HAVE_SSE2
    381 INSTANTIATE_TEST_SUITE_P(
    382    SSE2, HadamardLowbdTest,
    383    ::testing::Values(HadamardFuncWithSize(&aom_hadamard_4x4_sse2, 4, 4),
    384                      HadamardFuncWithSize(&aom_hadamard_8x8_sse2, 8, 8),
    385                      HadamardFuncWithSize(&aom_hadamard_16x16_sse2, 16, 16),
    386                      HadamardFuncWithSize(&aom_hadamard_32x32_sse2, 32, 32)));
    387 #endif  // HAVE_SSE2
    388 
    389 #if HAVE_AVX2
    390 INSTANTIATE_TEST_SUITE_P(
    391    AVX2, HadamardLowbdTest,
    392    ::testing::Values(HadamardFuncWithSize(&aom_hadamard_16x16_avx2, 16, 16),
    393                      HadamardFuncWithSize(&aom_hadamard_32x32_avx2, 32, 32)));
    394 #endif  // HAVE_AVX2
    395 
    396 // TODO(aomedia:3314): Disable NEON unit test for now, since hadamard 16x16 NEON
    397 // need modifications to match C/AVX2 behavior.
    398 #if HAVE_NEON
    399 INSTANTIATE_TEST_SUITE_P(
    400    NEON, HadamardLowbdTest,
    401    ::testing::Values(HadamardFuncWithSize(&aom_hadamard_4x4_neon, 4, 4),
    402                      HadamardFuncWithSize(&aom_hadamard_8x8_neon, 8, 8),
    403                      HadamardFuncWithSize(&aom_hadamard_16x16_neon, 16, 16),
    404                      HadamardFuncWithSize(&aom_hadamard_32x32_neon, 32, 32)));
    405 #endif  // HAVE_NEON
    406 
    407 #if CONFIG_AV1_HIGHBITDEPTH
    408 class HadamardHighbdTest : public HadamardTestBase<tran_low_t, HadamardFunc> {
    409 protected:
    410  HadamardHighbdTest() : HadamardTestBase(GetParam(), /*do_shift=*/true) {}
    411  // Use values between -4095 (0xF001) and 4095 (0x0FFF)
    412  int16_t Rand() override {
    413    int16_t src = rnd_.Rand12();
    414    int16_t pred = rnd_.Rand12();
    415    return src - pred;
    416  }
    417 };
    418 
    419 TEST_P(HadamardHighbdTest, CompareReferenceRandom) { CompareReferenceRandom(); }
    420 
    421 TEST_P(HadamardHighbdTest, VaryStride) { VaryStride(); }
    422 
    423 TEST_P(HadamardHighbdTest, DISABLED_Speed) {
    424  SpeedTest(10);
    425  SpeedTest(10000);
    426  SpeedTest(10000000);
    427 }
    428 
    429 INSTANTIATE_TEST_SUITE_P(
    430    C, HadamardHighbdTest,
    431    ::testing::Values(
    432        HadamardFuncWithSize(&aom_highbd_hadamard_8x8_c, 8, 8),
    433        HadamardFuncWithSize(&aom_highbd_hadamard_16x16_c, 16, 16),
    434        HadamardFuncWithSize(&aom_highbd_hadamard_32x32_c, 32, 32)));
    435 
    436 #if HAVE_AVX2
    437 INSTANTIATE_TEST_SUITE_P(
    438    AVX2, HadamardHighbdTest,
    439    ::testing::Values(
    440        HadamardFuncWithSize(&aom_highbd_hadamard_8x8_avx2, 8, 8),
    441        HadamardFuncWithSize(&aom_highbd_hadamard_16x16_avx2, 16, 16),
    442        HadamardFuncWithSize(&aom_highbd_hadamard_32x32_avx2, 32, 32)));
    443 #endif  // HAVE_AVX2
    444 
    445 #if HAVE_NEON
    446 INSTANTIATE_TEST_SUITE_P(
    447    NEON, HadamardHighbdTest,
    448    ::testing::Values(
    449        HadamardFuncWithSize(&aom_highbd_hadamard_8x8_neon, 8, 8),
    450        HadamardFuncWithSize(&aom_highbd_hadamard_16x16_neon, 16, 16),
    451        HadamardFuncWithSize(&aom_highbd_hadamard_32x32_neon, 32, 32)));
    452 #endif  // HAVE_NEON
    453 
    454 #endif  // CONFIG_AV1_HIGHBITDEPTH
    455 
    456 // Tests for low precision
    457 class HadamardLowbdLPTest : public HadamardTestBase<int16_t, HadamardLPFunc> {
    458 public:
    459  HadamardLowbdLPTest() : HadamardTestBase(GetParam(), /*do_shift=*/false) {}
    460  // Use values between -255 (0xFF01) and 255 (0x00FF)
    461  int16_t Rand() override {
    462    int16_t src = rnd_.Rand8();
    463    int16_t pred = rnd_.Rand8();
    464    return src - pred;
    465  }
    466 };
    467 
    468 TEST_P(HadamardLowbdLPTest, CompareReferenceRandom) {
    469  CompareReferenceRandom();
    470 }
    471 
    472 TEST_P(HadamardLowbdLPTest, VaryStride) { VaryStride(); }
    473 
    474 TEST_P(HadamardLowbdLPTest, DISABLED_SpeedTest) { SpeedTest(1000000); }
    475 
    476 INSTANTIATE_TEST_SUITE_P(
    477    C, HadamardLowbdLPTest,
    478    ::testing::Values(HadamardLPFuncWithSize(&aom_hadamard_lp_8x8_c, 8, 8),
    479                      HadamardLPFuncWithSize(&aom_hadamard_lp_16x16_c, 16,
    480                                             16)));
    481 
    482 #if HAVE_SSE2
    483 INSTANTIATE_TEST_SUITE_P(
    484    SSE2, HadamardLowbdLPTest,
    485    ::testing::Values(HadamardLPFuncWithSize(&aom_hadamard_lp_8x8_sse2, 8, 8),
    486                      HadamardLPFuncWithSize(&aom_hadamard_lp_16x16_sse2, 16,
    487                                             16)));
    488 #endif  // HAVE_SSE2
    489 
    490 #if HAVE_AVX2
    491 INSTANTIATE_TEST_SUITE_P(AVX2, HadamardLowbdLPTest,
    492                         ::testing::Values(HadamardLPFuncWithSize(
    493                             &aom_hadamard_lp_16x16_avx2, 16, 16)));
    494 #endif  // HAVE_AVX2
    495 
    496 #if HAVE_NEON
    497 INSTANTIATE_TEST_SUITE_P(
    498    NEON, HadamardLowbdLPTest,
    499    ::testing::Values(HadamardLPFuncWithSize(&aom_hadamard_lp_8x8_neon, 8, 8),
    500                      HadamardLPFuncWithSize(&aom_hadamard_lp_16x16_neon, 16,
    501                                             16)));
    502 #endif  // HAVE_NEON
    503 
    504 // Tests for 8x8 dual low precision
    505 class HadamardLowbdLP8x8DualTest
    506    : public HadamardTestBase<int16_t, HadamardLP8x8DualFunc> {
    507 public:
    508  HadamardLowbdLP8x8DualTest()
    509      : HadamardTestBase(GetParam(), /*do_shift=*/false) {}
    510  // Use values between -255 (0xFF01) and 255 (0x00FF)
    511  int16_t Rand() override {
    512    int16_t src = rnd_.Rand8();
    513    int16_t pred = rnd_.Rand8();
    514    return src - pred;
    515  }
    516 };
    517 
    518 TEST_P(HadamardLowbdLP8x8DualTest, CompareReferenceRandom) {
    519  CompareReferenceRandom();
    520 }
    521 
    522 TEST_P(HadamardLowbdLP8x8DualTest, VaryStride) { VaryStride(); }
    523 
    524 TEST_P(HadamardLowbdLP8x8DualTest, DISABLED_SpeedTest) { SpeedTest(1000000); }
    525 
    526 INSTANTIATE_TEST_SUITE_P(C, HadamardLowbdLP8x8DualTest,
    527                         ::testing::Values(HadamardLP8x8DualFuncWithSize(
    528                             &aom_hadamard_lp_8x8_dual_c, 8, 16)));
    529 
    530 #if HAVE_SSE2
    531 INSTANTIATE_TEST_SUITE_P(SSE2, HadamardLowbdLP8x8DualTest,
    532                         ::testing::Values(HadamardLP8x8DualFuncWithSize(
    533                             &aom_hadamard_lp_8x8_dual_sse2, 8, 16)));
    534 #endif  // HAVE_SSE2
    535 
    536 #if HAVE_AVX2
    537 INSTANTIATE_TEST_SUITE_P(AVX2, HadamardLowbdLP8x8DualTest,
    538                         ::testing::Values(HadamardLP8x8DualFuncWithSize(
    539                             &aom_hadamard_lp_8x8_dual_avx2, 8, 16)));
    540 #endif  // HAVE_AVX2
    541 
    542 #if HAVE_NEON
    543 INSTANTIATE_TEST_SUITE_P(NEON, HadamardLowbdLP8x8DualTest,
    544                         ::testing::Values(HadamardLP8x8DualFuncWithSize(
    545                             &aom_hadamard_lp_8x8_dual_neon, 8, 16)));
    546 #endif  // HAVE_NEON
    547 
    548 }  // namespace