Home | History | Annotate | Download | only in test
      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