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 <functional> 18 #include <limits> 19 #include <random> 20 #include <vector> 21 22 #include <xnnpack/params.h> 23 24 25 class RMaxMicrokernelTester { 26 public: n(size_t n)27 inline RMaxMicrokernelTester& n(size_t n) { 28 assert(n != 0); 29 this->n_ = n; 30 return *this; 31 } 32 n()33 inline size_t n() const { 34 return this->n_; 35 } 36 iterations(size_t iterations)37 inline RMaxMicrokernelTester& iterations(size_t iterations) { 38 this->iterations_ = iterations; 39 return *this; 40 } 41 iterations()42 inline size_t iterations() const { 43 return this->iterations_; 44 } 45 Test(xnn_u8_rmax_ukernel_function rmax)46 void Test(xnn_u8_rmax_ukernel_function rmax) const { 47 std::random_device random_device; 48 auto rng = std::mt19937(random_device()); 49 auto u8rng = std::bind(std::uniform_int_distribution<uint32_t>(0, std::numeric_limits<uint8_t>::max()), rng); 50 51 std::vector<uint8_t> x(n()); 52 for (size_t iteration = 0; iteration < iterations(); iteration++) { 53 std::generate(x.begin(), x.end(), std::ref(u8rng)); 54 55 // Compute reference results. 56 uint8_t y_ref = 0; 57 for (size_t i = 0; i < n(); i++) { 58 y_ref = std::max(y_ref, x[i]); 59 } 60 61 // Call optimized micro-kernel. 62 uint8_t y = u8rng(); 63 rmax(n() * sizeof(uint8_t), x.data(), &y); 64 65 // Verify results. 66 ASSERT_EQ(y_ref, y) << "n = " << n(); 67 } 68 } 69 Test(xnn_f32_rmax_ukernel_function rmax)70 void Test(xnn_f32_rmax_ukernel_function rmax) const { 71 std::random_device random_device; 72 auto rng = std::mt19937(random_device()); 73 auto f32rng = std::bind(std::uniform_real_distribution<float>(), rng); 74 75 std::vector<float> x(n()); 76 for (size_t iteration = 0; iteration < iterations(); iteration++) { 77 std::generate(x.begin(), x.end(), std::ref(f32rng)); 78 79 // Compute reference results. 80 float y_ref = 0; 81 for (size_t i = 0; i < n(); i++) { 82 y_ref = std::max(y_ref, x[i]); 83 } 84 85 // Call optimized micro-kernel. 86 float y = std::nanf(""); 87 rmax(n() * sizeof(float), x.data(), &y); 88 89 // Verify results. 90 ASSERT_EQ(y_ref, y) << "n = " << n(); 91 } 92 } 93 94 private: 95 size_t n_{1}; 96 size_t iterations_{15}; 97 }; 98