xref: /aosp_15_r20/external/XNNPACK/test/vsquareabs-microkernel-tester.h (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
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