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 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: 65 Matrix() : Map(nullptr, 0, 0, 0) {} 66 67 Matrix(int rows, int cols) : Map(nullptr, 0, 0, 0) { Resize(rows, cols); } 68 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 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 90 int size() const { return rows_ * cols_; } 91 92 Map& map() { return *static_cast<Map*>(this); } 93 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> 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> 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> 121 void MakeZero(MatrixType* m) { 122 MakeConstant(m, 0); 123 } 124 125 } // namespace gemmlowp 126 127 #endif // GEMMLOWP_TEST_TEST_H_ 128