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