xref: /aosp_15_r20/external/XNNPACK/test/rmax-microkernel-tester.h (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
1 // Copyright (c) Facebook, Inc. and its affiliates.
2 // All rights reserved.
3 //
4 // Copyright 2019 Google LLC
5 //
6 // This source code is licensed under the BSD-style license found in the
7 // LICENSE file in the root directory of this source tree.
8 
9 #pragma once
10 
11 #include <gtest/gtest.h>
12 
13 #include <algorithm>
14 #include <cassert>
15 #include <cstddef>
16 #include <cstdlib>
17 #include <limits>
18 #include <random>
19 #include <vector>
20 
21 #include <fp16.h>
22 
23 #include <xnnpack.h>
24 #include <xnnpack/microfnptr.h>
25 
26 
27 class RMaxMicrokernelTester {
28  public:
n(size_t n)29   inline RMaxMicrokernelTester& n(size_t n) {
30     assert(n != 0);
31     this->n_ = n;
32     return *this;
33   }
34 
n()35   inline size_t n() const {
36     return this->n_;
37   }
38 
iterations(size_t iterations)39   inline RMaxMicrokernelTester& iterations(size_t iterations) {
40     this->iterations_ = iterations;
41     return *this;
42   }
43 
iterations()44   inline size_t iterations() const {
45     return this->iterations_;
46   }
47 
Test(xnn_f16_rmax_ukernel_function rmax)48   void Test(xnn_f16_rmax_ukernel_function rmax) const {
49     std::random_device random_device;
50     auto rng = std::mt19937(random_device());
51     std::uniform_real_distribution<float> f32dist;
52 
53     std::vector<uint16_t> x(n() + XNN_EXTRA_BYTES / sizeof(uint16_t));
54     for (size_t iteration = 0; iteration < iterations(); iteration++) {
55       std::generate(x.begin(), x.end(), [&]() { return fp16_ieee_from_fp32_value(f32dist(rng)); });
56 
57       // Compute reference results.
58       float y_ref = -std::numeric_limits<float>::infinity();
59       for (size_t i = 0; i < n(); i++) {
60         y_ref = std::max(y_ref, fp16_ieee_to_fp32_value(x[i]));
61       }
62 
63       // Call optimized micro-kernel.
64       uint16_t y = UINT16_C(0x7E00) /* NaN */;
65       rmax(n() * sizeof(uint16_t), x.data(), &y);
66 
67       // Verify results.
68       ASSERT_EQ(fp16_ieee_to_fp32_value(y), y_ref)
69         << "batch " << n() << " y = " << y;
70     }
71   }
72 
Test(xnn_f32_rmax_ukernel_function rmax)73   void Test(xnn_f32_rmax_ukernel_function rmax) const {
74     std::random_device random_device;
75     auto rng = std::mt19937(random_device());
76     std::uniform_real_distribution<float> f32dist;
77 
78     std::vector<float> x(n());
79     for (size_t iteration = 0; iteration < iterations(); iteration++) {
80       std::generate(x.begin(), x.end(), [&]() { return f32dist(rng); });
81 
82       // Compute reference results.
83       float y_ref = -std::numeric_limits<float>::infinity();
84       for (size_t i = 0; i < n(); i++) {
85         y_ref = std::max(y_ref, x[i]);
86       }
87 
88       // Call optimized micro-kernel.
89       float y = std::nanf("");
90       rmax(n() * sizeof(float), x.data(), &y);
91 
92       // Verify results.
93       ASSERT_EQ(y_ref, y)
94         << "batch " << n();
95     }
96   }
97 
Test(xnn_u8_rmax_ukernel_function rmax)98   void Test(xnn_u8_rmax_ukernel_function rmax) const {
99     std::random_device random_device;
100     auto rng = std::mt19937(random_device());
101     std::uniform_int_distribution<int32_t> u8dist(
102       std::numeric_limits<uint8_t>::min(), std::numeric_limits<uint8_t>::max());
103 
104     std::vector<uint8_t> x(n());
105     for (size_t iteration = 0; iteration < iterations(); iteration++) {
106       std::generate(x.begin(), x.end(), [&]() { return u8dist(rng); });
107 
108       // Compute reference results.
109       uint8_t y_ref = 0;
110       for (size_t i = 0; i < n(); i++) {
111         y_ref = std::max(y_ref, x[i]);
112       }
113 
114       // Call optimized micro-kernel.
115       uint8_t y = u8dist(rng);
116       rmax(n() * sizeof(uint8_t), x.data(), &y);
117 
118       // Verify results.
119       ASSERT_EQ(int32_t(y_ref), int32_t(y))
120         << "batch " << n();
121     }
122   }
123 
124  private:
125   size_t n_{1};
126   size_t iterations_{15};
127 };
128