• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cstddef>
14 #include <cstdlib>
15 
16 #include <algorithm>
17 #include <cfloat>
18 #include <cmath>
19 #include <functional>
20 #include <random>
21 #include <vector>
22 
23 #include <xnnpack/params.h>
24 
25 
26 class ZipMicrokernelTester {
27  public:
n(size_t n)28   inline ZipMicrokernelTester& n(size_t n) {
29     assert(n != 0);
30     this->n_ = n;
31     return *this;
32   }
33 
n()34   inline size_t n() const {
35     return this->n_;
36   }
37 
g(size_t g)38   inline ZipMicrokernelTester& g(size_t g) {
39     assert(g != 0);
40     this->g_ = g;
41     return *this;
42   }
43 
g()44   inline size_t g() const {
45     return this->g_;
46   }
47 
iterations(size_t iterations)48   inline ZipMicrokernelTester& iterations(size_t iterations) {
49     this->iterations_ = iterations;
50     return *this;
51   }
52 
iterations()53   inline size_t iterations() const {
54     return this->iterations_;
55   }
56 
Test(xnn_x8_zipc_ukernel_function zip)57   void Test(xnn_x8_zipc_ukernel_function zip) const {
58     std::random_device random_device;
59     auto rng = std::mt19937(random_device());
60     auto u8rng = std::bind(std::uniform_int_distribution<uint8_t>(), rng);
61 
62     std::vector<uint8_t> x(n() * g());
63     std::vector<uint8_t> y(g() * n());
64 
65     for (size_t iteration = 0; iteration < iterations(); iteration++) {
66       std::generate(x.begin(), x.end(), std::ref(u8rng));
67       std::fill(y.begin(), y.end(), 0xA5);
68 
69       // Call optimized micro-kernel.
70       zip(n() * sizeof(uint8_t), x.data(), y.data());
71 
72       // Verify results.
73       for (size_t i = 0; i < n(); i++) {
74         for (size_t j = 0; j < g(); j++) {
75           ASSERT_EQ(uint32_t(y[i * g() + j]), uint32_t(x[j * n() + i]))
76             << "at element " << i << ", group " << j;
77         }
78       }
79     }
80   }
81 
Test(xnn_x8_zipv_ukernel_function zip)82   void Test(xnn_x8_zipv_ukernel_function zip) const {
83     std::random_device random_device;
84     auto rng = std::mt19937(random_device());
85     auto u8rng = std::bind(std::uniform_int_distribution<uint8_t>(), rng);
86 
87     std::vector<uint8_t> x(n() * g());
88     std::vector<uint8_t> y(g() * n());
89 
90     for (size_t iteration = 0; iteration < iterations(); iteration++) {
91       std::generate(x.begin(), x.end(), std::ref(u8rng));
92       std::fill(y.begin(), y.end(), 0xA5);
93 
94       // Call optimized micro-kernel.
95       zip(n() * sizeof(uint8_t), g(), x.data(), y.data());
96 
97       // Verify results.
98       for (size_t i = 0; i < n(); i++) {
99         for (size_t j = 0; j < g(); j++) {
100           ASSERT_EQ(uint32_t(y[i * g() + j]), uint32_t(x[j * n() + i]))
101             << "at element " << i << ", group " << j;
102         }
103       }
104     }
105   }
106 
Test(xnn_x32_zipc_ukernel_function zip)107   void Test(xnn_x32_zipc_ukernel_function zip) const {
108     std::random_device random_device;
109     auto rng = std::mt19937(random_device());
110     auto u32rng = std::bind(std::uniform_int_distribution<uint32_t>(), rng);
111 
112     std::vector<uint32_t> x(n() * g());
113     std::vector<uint32_t> y(g() * n());
114 
115     for (size_t iteration = 0; iteration < iterations(); iteration++) {
116       std::generate(x.begin(), x.end(), std::ref(u32rng));
117       std::fill(y.begin(), y.end(), 0xA55A5AA5);
118 
119       // Call optimized micro-kernel.
120       zip(n() * sizeof(uint32_t), x.data(), y.data());
121 
122       // Verify results.
123       for (size_t i = 0; i < n(); i++) {
124         for (size_t j = 0; j < g(); j++) {
125           ASSERT_EQ(y[i * g() + j], x[j * n() + i])
126             << "at element " << i << ", group " << j;
127         }
128       }
129     }
130   }
131 
Test(xnn_x32_zipv_ukernel_function zip)132   void Test(xnn_x32_zipv_ukernel_function zip) const {
133     std::random_device random_device;
134     auto rng = std::mt19937(random_device());
135     auto u32rng = std::bind(std::uniform_int_distribution<uint32_t>(), rng);
136 
137     std::vector<uint32_t> x(n() * g());
138     std::vector<uint32_t> y(g() * n());
139 
140     for (size_t iteration = 0; iteration < iterations(); iteration++) {
141       std::generate(x.begin(), x.end(), std::ref(u32rng));
142       std::fill(y.begin(), y.end(), 0xA55A5AA5);
143 
144       // Call optimized micro-kernel.
145       zip(n() * sizeof(uint32_t), g(), x.data(), y.data());
146 
147       // Verify results.
148       for (size_t i = 0; i < n(); i++) {
149         for (size_t j = 0; j < g(); j++) {
150           ASSERT_EQ(y[i * g() + j], x[j * n() + i])
151             << "at element " << i << ", group " << j;
152         }
153       }
154     }
155   }
156 
157  private:
158   size_t n_{1};
159   size_t g_{1};
160   size_t iterations_{3};
161 };
162