// Copyright 2015 Google Inc. 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. // map.h: a minimalist view-existing-buffer-as-a-matrix class, // which is how gemmlowp interfaces with external matrix data. #ifndef GEMMLOWP_PUBLIC_MAP_H_ #define GEMMLOWP_PUBLIC_MAP_H_ #include "../internal/common.h" #include "../internal/iterator.h" namespace gemmlowp { // The two storage orders allowed to map buffers as matrices: ColMajor // means column-major, RowMajor means row-major. enum class MapOrder { ColMajor, RowMajor }; // A MatrixMap is a view of an existing buffer as a matrix. It does not own // the buffer. template class MatrixMap { public: typedef tScalar Scalar; static const MapOrder kOrder = tOrder; protected: Scalar* data_; // not owned. int rows_, cols_, stride_; public: MatrixMap() : data_(nullptr), rows_(0), cols_(0), stride_(0) {} MatrixMap(Scalar* data, int rows, int cols, int stride) : data_(data), rows_(rows), cols_(cols), stride_(stride) {} MatrixMap(const MatrixMap& other) : data_(other.data_), rows_(other.rows_), cols_(other.cols_), stride_(other.stride_) {} int rows() const { return rows_; } int cols() const { return cols_; } int stride() const { return stride_; } int rows_stride() const { return kOrder == MapOrder::ColMajor ? 1 : stride_; } int cols_stride() const { return kOrder == MapOrder::RowMajor ? 1 : stride_; } Scalar* data() const { return data_; } Scalar* data(int row, int col) const { return data_ + row * rows_stride() + col * cols_stride(); } Scalar& operator()(int row, int col) const { return *data(row, col); } MatrixMap block(int start_row, int start_col, int block_rows, int block_cols) const { assert(start_row >= 0); assert(start_row + block_rows <= rows_); assert(start_col >= 0); assert(start_col + block_cols <= cols_); return MatrixMap(data(start_row, start_col), block_rows, block_cols, stride_); } }; enum class VectorShape { Col, Row }; // A VectorMap is a view of an existing buffer as a vector. It does not own // the buffer. template class VectorMap { public: typedef tScalar Scalar; static const VectorShape kShape = tShape; protected: Scalar* data_; // not owned. int size_; public: VectorMap() : data_(nullptr), size_(0) {} VectorMap(Scalar* data, int size) : data_(data), size_(size) {} VectorMap(const VectorMap& other) : data_(other.data_), size_(other.size_) {} int size() const { return size_; } Scalar* data() const { return data_; } Scalar* data(int index) const { return data_ + index; } Scalar& operator()(int index) const { return *data(index); } }; // A VectorDup is a (duplicated value) vector where all components are the same. template class VectorDup { public: typedef tScalar Scalar; static const VectorShape kShape = tShape; protected: Scalar data_; int size_; public: VectorDup() : data_(0), size_(0) {} VectorDup(Scalar data, int size) : data_(data), size_(size) {} VectorDup(const VectorDup& other) : data_(other.data_), size_(other.size_) {} int size() const { return size_; } Scalar& operator()(int index) const { return data_; } }; } // namespace gemmlowp #endif // GEMMLOWP_PUBLIC_MAP_H_