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