xref: /aosp_15_r20/external/gemmlowp/test/test.h (revision 5f39d1b313f0528e11bae88b3029b54b9e1033e7)
1*5f39d1b3SJooyung Han // Copyright 2015 The Gemmlowp Authors. All Rights Reserved.
2*5f39d1b3SJooyung Han //
3*5f39d1b3SJooyung Han // Licensed under the Apache License, Version 2.0 (the "License");
4*5f39d1b3SJooyung Han // you may not use this file except in compliance with the License.
5*5f39d1b3SJooyung Han // You may obtain a copy of the License at
6*5f39d1b3SJooyung Han //
7*5f39d1b3SJooyung Han //     http://www.apache.org/licenses/LICENSE-2.0
8*5f39d1b3SJooyung Han //
9*5f39d1b3SJooyung Han // Unless required by applicable law or agreed to in writing, software
10*5f39d1b3SJooyung Han // distributed under the License is distributed on an "AS IS" BASIS,
11*5f39d1b3SJooyung Han // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*5f39d1b3SJooyung Han // See the License for the specific language governing permissions and
13*5f39d1b3SJooyung Han // limitations under the License.
14*5f39d1b3SJooyung Han 
15*5f39d1b3SJooyung Han // test.h: shared testing helpers.
16*5f39d1b3SJooyung Han 
17*5f39d1b3SJooyung Han #ifndef GEMMLOWP_TEST_TEST_H_
18*5f39d1b3SJooyung Han #define GEMMLOWP_TEST_TEST_H_
19*5f39d1b3SJooyung Han 
20*5f39d1b3SJooyung Han #ifdef GEMMLOWP_TEST_PROFILE
21*5f39d1b3SJooyung Han #define GEMMLOWP_PROFILING
22*5f39d1b3SJooyung Han #include "../profiling/profiler.h"
23*5f39d1b3SJooyung Han #endif
24*5f39d1b3SJooyung Han 
25*5f39d1b3SJooyung Han #include <cstring>
26*5f39d1b3SJooyung Han #include <iostream>
27*5f39d1b3SJooyung Han #include <random>
28*5f39d1b3SJooyung Han #include <vector>
29*5f39d1b3SJooyung Han 
30*5f39d1b3SJooyung Han #include "../public/gemmlowp.h"
31*5f39d1b3SJooyung Han 
32*5f39d1b3SJooyung Han namespace gemmlowp {
33*5f39d1b3SJooyung Han 
34*5f39d1b3SJooyung Han #define GEMMLOWP_STRINGIFY2(x) #x
35*5f39d1b3SJooyung Han #define GEMMLOWP_STRINGIFY(x) GEMMLOWP_STRINGIFY2(x)
36*5f39d1b3SJooyung Han 
37*5f39d1b3SJooyung Han #define Check(b)                                                         \
38*5f39d1b3SJooyung Han   do {                                                                   \
39*5f39d1b3SJooyung Han     ReleaseBuildAssertion(                                               \
40*5f39d1b3SJooyung Han         b, "test failed at " __FILE__ ":" GEMMLOWP_STRINGIFY(__LINE__)); \
41*5f39d1b3SJooyung Han   } while (false)
42*5f39d1b3SJooyung Han 
43*5f39d1b3SJooyung Han // gemmlowp itself doesn't have a Matrix class, only a MatrixMap class,
44*5f39d1b3SJooyung Han // since it only maps existing data. In tests though, we need to
45*5f39d1b3SJooyung Han // create our own matrices.
46*5f39d1b3SJooyung Han template <typename tScalar, MapOrder tOrder>
47*5f39d1b3SJooyung Han class Matrix : public MatrixMap<tScalar, tOrder> {
48*5f39d1b3SJooyung Han  public:
49*5f39d1b3SJooyung Han   typedef MatrixMap<tScalar, tOrder> Map;
50*5f39d1b3SJooyung Han   typedef MatrixMap<const tScalar, tOrder> ConstMap;
51*5f39d1b3SJooyung Han   typedef typename Map::Scalar Scalar;
52*5f39d1b3SJooyung Han   static constexpr MapOrder Order = tOrder;
53*5f39d1b3SJooyung Han   using Map::kOrder;
54*5f39d1b3SJooyung Han   using Map::rows_;
55*5f39d1b3SJooyung Han   using Map::cols_;
56*5f39d1b3SJooyung Han   using Map::stride_;
57*5f39d1b3SJooyung Han   using Map::data_;
58*5f39d1b3SJooyung Han 
59*5f39d1b3SJooyung Han  public:
Matrix()60*5f39d1b3SJooyung Han   Matrix() : Map(nullptr, 0, 0, 0) {}
61*5f39d1b3SJooyung Han 
Matrix(int rows,int cols)62*5f39d1b3SJooyung Han   Matrix(int rows, int cols) : Map(nullptr, 0, 0, 0) { Resize(rows, cols); }
63*5f39d1b3SJooyung Han 
Matrix(const Matrix & other)64*5f39d1b3SJooyung Han   Matrix(const Matrix& other) : Map(nullptr, 0, 0, 0) { *this = other; }
65*5f39d1b3SJooyung Han 
66*5f39d1b3SJooyung Han   Matrix& operator=(const Matrix& other) {
67*5f39d1b3SJooyung Han     Resize(other.rows_, other.cols_);
68*5f39d1b3SJooyung Han     std::memcpy(data_, other.data_, size() * sizeof(Scalar));
69*5f39d1b3SJooyung Han     return *this;
70*5f39d1b3SJooyung Han   }
71*5f39d1b3SJooyung Han 
72*5f39d1b3SJooyung Han   friend bool operator==(const Matrix& a, const Matrix& b) {
73*5f39d1b3SJooyung Han     return a.rows_ == b.rows_ && a.cols_ == b.cols_ &&
74*5f39d1b3SJooyung Han            !std::memcmp(a.data_, b.data_, a.size());
75*5f39d1b3SJooyung Han   }
76*5f39d1b3SJooyung Han 
Resize(int rows,int cols)77*5f39d1b3SJooyung Han   void Resize(int rows, int cols) {
78*5f39d1b3SJooyung Han     rows_ = rows;
79*5f39d1b3SJooyung Han     cols_ = cols;
80*5f39d1b3SJooyung Han     stride_ = kOrder == MapOrder::ColMajor ? rows : cols;
81*5f39d1b3SJooyung Han     storage.resize(size());
82*5f39d1b3SJooyung Han     data_ = storage.data();
83*5f39d1b3SJooyung Han   }
84*5f39d1b3SJooyung Han 
size()85*5f39d1b3SJooyung Han   int size() const { return rows_ * cols_; }
86*5f39d1b3SJooyung Han 
map()87*5f39d1b3SJooyung Han   Map& map() { return *static_cast<Map*>(this); }
88*5f39d1b3SJooyung Han 
const_map()89*5f39d1b3SJooyung Han   ConstMap const_map() const { return ConstMap(data_, rows_, cols_, stride_); }
90*5f39d1b3SJooyung Han 
91*5f39d1b3SJooyung Han  protected:
92*5f39d1b3SJooyung Han   std::vector<Scalar> storage;
93*5f39d1b3SJooyung Han };
94*5f39d1b3SJooyung Han 
RandomEngine()95*5f39d1b3SJooyung Han inline std::mt19937& RandomEngine() {
96*5f39d1b3SJooyung Han   static std::mt19937 engine;
97*5f39d1b3SJooyung Han   return engine;
98*5f39d1b3SJooyung Han }
99*5f39d1b3SJooyung Han 
Random()100*5f39d1b3SJooyung Han inline int Random() {
101*5f39d1b3SJooyung Han   std::uniform_int_distribution<int> dist(0, std::numeric_limits<int>::max());
102*5f39d1b3SJooyung Han   return dist(RandomEngine());
103*5f39d1b3SJooyung Han }
104*5f39d1b3SJooyung Han 
105*5f39d1b3SJooyung Han #ifdef _MSC_VER
106*5f39d1b3SJooyung Han // msvc does not support 8bit types in uniform_int_distribution<>.
107*5f39d1b3SJooyung Han // Take 32 bit uniform_int_distribution<> and only use the lower 8 bits.
108*5f39d1b3SJooyung Han template <typename OperandRange, typename MatrixType>
MakeRandom(MatrixType * m)109*5f39d1b3SJooyung Han void MakeRandom(MatrixType* m) {
110*5f39d1b3SJooyung Han   ScopedProfilingLabel("MakeRandom(matrix)");
111*5f39d1b3SJooyung Han   for (int c = 0; c < m->cols(); c++) {
112*5f39d1b3SJooyung Han     for (int r = 0; r < m->rows(); r++) {
113*5f39d1b3SJooyung Han       (*m)(r, c) = Random() % OperandRange::kMaxValue;
114*5f39d1b3SJooyung Han     }
115*5f39d1b3SJooyung Han   }
116*5f39d1b3SJooyung Han }
117*5f39d1b3SJooyung Han #else
118*5f39d1b3SJooyung Han template <typename OperandRange, typename MatrixType>
MakeRandom(MatrixType * m)119*5f39d1b3SJooyung Han void MakeRandom(MatrixType* m) {
120*5f39d1b3SJooyung Han   ScopedProfilingLabel("MakeRandom(matrix)");
121*5f39d1b3SJooyung Han   typedef typename MatrixType::Scalar Scalar;
122*5f39d1b3SJooyung Han   std::uniform_int_distribution<Scalar> dist(OperandRange::kMinValue,
123*5f39d1b3SJooyung Han                                              OperandRange::kMaxValue);
124*5f39d1b3SJooyung Han   for (int c = 0; c < m->cols(); c++) {
125*5f39d1b3SJooyung Han     for (int r = 0; r < m->rows(); r++) {
126*5f39d1b3SJooyung Han       (*m)(r, c) = dist(RandomEngine());
127*5f39d1b3SJooyung Han     }
128*5f39d1b3SJooyung Han   }
129*5f39d1b3SJooyung Han }
130*5f39d1b3SJooyung Han #endif
131*5f39d1b3SJooyung Han 
132*5f39d1b3SJooyung Han template <typename MatrixType>
MakeConstant(MatrixType * m,typename MatrixType::Scalar val)133*5f39d1b3SJooyung Han void MakeConstant(MatrixType* m, typename MatrixType::Scalar val) {
134*5f39d1b3SJooyung Han   ScopedProfilingLabel("MakeConstant(matrix)");
135*5f39d1b3SJooyung Han   for (int c = 0; c < m->cols(); c++) {
136*5f39d1b3SJooyung Han     for (int r = 0; r < m->rows(); r++) {
137*5f39d1b3SJooyung Han       (*m)(r, c) = val;
138*5f39d1b3SJooyung Han     }
139*5f39d1b3SJooyung Han   }
140*5f39d1b3SJooyung Han }
141*5f39d1b3SJooyung Han 
142*5f39d1b3SJooyung Han template <typename MatrixType>
MakeZero(MatrixType * m)143*5f39d1b3SJooyung Han void MakeZero(MatrixType* m) {
144*5f39d1b3SJooyung Han   ScopedProfilingLabel("MakeZero(matrix)");
145*5f39d1b3SJooyung Han   MakeConstant(m, 0);
146*5f39d1b3SJooyung Han }
147*5f39d1b3SJooyung Han 
148*5f39d1b3SJooyung Han }  // namespace gemmlowp
149*5f39d1b3SJooyung Han 
150*5f39d1b3SJooyung Han #endif  // GEMMLOWP_TEST_TEST_H_
151