1a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang// Copyright 2015 The Gemmlowp Authors. All Rights Reserved. 275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// 375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// Licensed under the Apache License, Version 2.0 (the "License"); 475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// you may not use this file except in compliance with the License. 575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// You may obtain a copy of the License at 675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// 775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// http://www.apache.org/licenses/LICENSE-2.0 875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// 975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// Unless required by applicable law or agreed to in writing, software 1075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// distributed under the License is distributed on an "AS IS" BASIS, 1175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// See the License for the specific language governing permissions and 1375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// limitations under the License. 1475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 1575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// map.h: a minimalist view-existing-buffer-as-a-matrix class, 1675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// which is how gemmlowp interfaces with external matrix data. 1775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 1875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob#ifndef GEMMLOWP_PUBLIC_MAP_H_ 1975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob#define GEMMLOWP_PUBLIC_MAP_H_ 2075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 21544690cac8f06f1b2f5fa3799e1e8f13c75d95e9Miao Wang#include "../internal/common.h" 2275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 2375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobnamespace gemmlowp { 2475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 2575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// The two storage orders allowed to map buffers as matrices: ColMajor 2675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// means column-major, RowMajor means row-major. 2775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobenum class MapOrder { ColMajor, RowMajor }; 2875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 2975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// A MatrixMap is a view of an existing buffer as a matrix. It does not own 3075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob// the buffer. 3175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobtemplate <typename tScalar, MapOrder tOrder> 3275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacobclass MatrixMap { 3375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob public: 3475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob typedef tScalar Scalar; 3575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob static const MapOrder kOrder = tOrder; 3675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 3775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob protected: 3875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Scalar* data_; // not owned. 3975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob int rows_, cols_, stride_; 4075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 4175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob public: 427b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang MatrixMap() : data_(nullptr), rows_(0), cols_(0), stride_(0) {} 43a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang MatrixMap(Scalar* data, int rows, int cols) 44a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang : data_(data), 45a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang rows_(rows), 46a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang cols_(cols), 47a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang stride_(kOrder == MapOrder::ColMajor ? rows : cols) {} 4875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob MatrixMap(Scalar* data, int rows, int cols, int stride) 4975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob : data_(data), rows_(rows), cols_(cols), stride_(stride) {} 5075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob MatrixMap(const MatrixMap& other) 5175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob : data_(other.data_), 5275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob rows_(other.rows_), 5375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob cols_(other.cols_), 5475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob stride_(other.stride_) {} 5575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 5675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob int rows() const { return rows_; } 5775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob int cols() const { return cols_; } 5875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob int stride() const { return stride_; } 5975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob int rows_stride() const { return kOrder == MapOrder::ColMajor ? 1 : stride_; } 6075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob int cols_stride() const { return kOrder == MapOrder::RowMajor ? 1 : stride_; } 6175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Scalar* data() const { return data_; } 6275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob Scalar* data(int row, int col) const { 6375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob return data_ + row * rows_stride() + col * cols_stride(); 6475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob } 657b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang Scalar& operator()(int row, int col) const { return *data(row, col); } 6675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 6775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob MatrixMap block(int start_row, int start_col, int block_rows, 6875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob int block_cols) const { 6975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob assert(start_row >= 0); 7075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob assert(start_row + block_rows <= rows_); 7175c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob assert(start_col >= 0); 7275c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob assert(start_col + block_cols <= cols_); 7375c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 7475c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob return MatrixMap(data(start_row, start_col), block_rows, block_cols, 7575c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob stride_); 7675c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob } 7775c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob}; 7875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 797b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wangenum class VectorShape { Col, Row }; 807b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang 817b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang// A VectorMap is a view of an existing buffer as a vector. It does not own 827b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang// the buffer. 837b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wangtemplate <typename tScalar, VectorShape tShape> 847b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wangclass VectorMap { 857b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang public: 867b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang typedef tScalar Scalar; 877b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang static const VectorShape kShape = tShape; 887b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang 897b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang protected: 907b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang Scalar* data_; // not owned. 917b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang int size_; 927b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang 937b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang public: 947b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang VectorMap() : data_(nullptr), size_(0) {} 957b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang VectorMap(Scalar* data, int size) : data_(data), size_(size) {} 967b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang VectorMap(const VectorMap& other) : data_(other.data_), size_(other.size_) {} 977b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang 987b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang int size() const { return size_; } 997b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang Scalar* data() const { return data_; } 1007b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang Scalar* data(int index) const { return data_ + index; } 1017b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang Scalar& operator()(int index) const { return *data(index); } 102a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang 103a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang VectorMap block(int start, int len) const { 104a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang assert(start >= 0); 105a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang assert(start + len <= size_); 106a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang 107a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang return VectorMap(data(start), len); 108a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang } 1097b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang}; 1107b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang 1117b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang// A VectorDup is a (duplicated value) vector where all components are the same. 1127b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wangtemplate <typename tScalar, VectorShape tShape> 1137b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wangclass VectorDup { 1147b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang public: 1157b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang typedef tScalar Scalar; 1167b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang static const VectorShape kShape = tShape; 1177b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang 1187b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang protected: 1197b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang Scalar data_; 1207b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang int size_; 1217b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang 1227b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang public: 1237b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang VectorDup() : data_(0), size_(0) {} 1247b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang VectorDup(Scalar data, int size) : data_(data), size_(size) {} 1257b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang VectorDup(const VectorDup& other) : data_(other.data_), size_(other.size_) {} 1267b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang 1277b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang int size() const { return size_; } 128a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang Scalar& operator()(int) const { return data_; } 129a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang 130a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang VectorDup block(int start, int len) const { 131a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang assert(start >= 0); 132a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang assert(start + len <= size_); 133a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang 134a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang return VectorDup(data_, len); 135a9fd919a0080e2c3c7ed1ce451c85a4d86f2f8c1Miao Wang } 1367b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang}; 1377b05d573cf2e0fd3a58e98cdbfc65153a83fd6f1Miao Wang 13875c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob} // namespace gemmlowp 13975c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob 14075c4ec0ba4dd86e4f763a54e01002ff29f1d57aBenoit Jacob#endif // GEMMLOWP_PUBLIC_MAP_H_ 141