1 // Copyright 2022 Google LLC 2 // 3 // This source code is licensed under the BSD-style license found in the 4 // LICENSE file in the root directory of this source tree. 5 6 #pragma once 7 8 #include <gtest/gtest.h> 9 10 #include <algorithm> 11 #include <cassert> 12 #include <cmath> 13 #include <cstddef> 14 #include <cstdlib> 15 #include <random> 16 #include <vector> 17 18 #include <xnnpack.h> 19 #include <xnnpack/aligned-allocator.h> 20 #include <xnnpack/microfnptr.h> 21 22 23 class RMaxAbsMicrokernelTester { 24 public: 25 batch(size_t batch)26 inline RMaxAbsMicrokernelTester& batch(size_t batch) { 27 assert(batch != 0); 28 this->batch_ = batch; 29 return *this; 30 } 31 batch()32 inline size_t batch() const { 33 return this->batch_; 34 } 35 iterations(size_t iterations)36 inline RMaxAbsMicrokernelTester& iterations(size_t iterations) { 37 this->iterations_ = iterations; 38 return *this; 39 } 40 iterations()41 inline size_t iterations() const { 42 return this->iterations_; 43 } 44 Test(xnn_s16_rmaxabs_ukernel_function rmaxabs)45 void Test(xnn_s16_rmaxabs_ukernel_function rmaxabs) const { 46 std::random_device random_device; 47 auto rng = std::mt19937(random_device()); 48 auto i16rng = std::bind(std::uniform_int_distribution<int16_t>(), std::ref(rng)); 49 50 std::vector<int16_t> x(batch() + XNN_EXTRA_BYTES / sizeof(int16_t)); 51 52 for (size_t iteration = 0; iteration < iterations(); iteration++) { 53 std::generate(x.begin(), x.end(), std::ref(i16rng)); 54 int32_t y_ref = 0; 55 56 // Compute reference results. 57 for (size_t n = 0; n < batch(); n++) { 58 const int32_t i = static_cast<int32_t>(x[n]); 59 const int32_t abs = std::abs(i); 60 y_ref = std::max(y_ref, abs); 61 } 62 63 // Call optimized micro-kernel. 64 uint16_t y = UINT16_C(0xDEAD); 65 rmaxabs(batch(), x.data(), &y); 66 67 // Verify results. 68 ASSERT_EQ(static_cast<int32_t>(y), y_ref); 69 } 70 } 71 72 private: 73 size_t batch_{1}; 74 size_t iterations_{15}; 75 }; 76