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/microfnptr.h> 20 21 22 class VSquareAbsMicrokernelTester { 23 public: batch_size(size_t batch_size)24 inline VSquareAbsMicrokernelTester& batch_size(size_t batch_size) { 25 assert(batch_size != 0); 26 this->batch_ = batch_size; 27 return *this; 28 } 29 batch_size()30 inline size_t batch_size() const { 31 return this->batch_; 32 } 33 iterations(size_t iterations)34 inline VSquareAbsMicrokernelTester& iterations(size_t iterations) { 35 this->iterations_ = iterations; 36 return *this; 37 } 38 iterations()39 inline size_t iterations() const { 40 return this->iterations_; 41 } 42 Test(xnn_cs16_vsquareabs_ukernel_function vsquareabs)43 void Test(xnn_cs16_vsquareabs_ukernel_function vsquareabs) const { 44 std::random_device random_device; 45 auto rng = std::mt19937(random_device()); 46 auto i16rng = std::bind(std::uniform_int_distribution<int16_t>(), std::ref(rng)); 47 48 std::vector<int16_t> x(batch_size() * 2 + XNN_EXTRA_BYTES / sizeof(int16_t)); 49 std::vector<uint32_t> y(batch_size()); 50 std::vector<uint32_t> y_ref(batch_size()); 51 52 for (size_t iteration = 0; iteration < iterations(); iteration++) { 53 std::generate(x.begin(), x.end(), std::ref(i16rng)); 54 std::fill(y.begin(), y.end(), INT32_C(0x12345678)); 55 56 // Compute reference results. 57 for (size_t n = 0; n < batch_size(); n++) { 58 const int16_t r = x[n * 2]; 59 const int16_t i = x[n * 2 + 1]; 60 uint32_t rsquare = static_cast<uint32_t>(static_cast<int32_t>(r) * static_cast<int32_t>(r)); 61 uint32_t isquare = static_cast<uint32_t>(static_cast<int32_t>(i) * static_cast<int32_t>(i)); 62 uint32_t value = rsquare + isquare; 63 y_ref[n] = value; 64 } 65 66 // Call optimized micro-kernel. 67 vsquareabs(batch_size(), x.data(), y.data()); 68 69 // Verify results. 70 for (size_t n = 0; n < batch_size(); n++) { 71 ASSERT_EQ(y[n], y_ref[n]) 72 << ", batch " << n << " / " << batch_size(); 73 } 74 } 75 } 76 77 private: 78 size_t batch_{1}; 79 size_t iterations_{15}; 80 }; 81