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