From 8b8d7e08a46ce23cc77d295dc86a974184204592 Mon Sep 17 00:00:00 2001 From: allonli Date: Thu, 17 May 2018 20:39:54 +0800 Subject: [PATCH] add clang-tidy support --- .clang-tidy | 30 + .pre-commit-config.yaml | 16 +- src/common/log.h | 120 ++-- src/common/type_define.h | 54 +- src/common/types.h | 74 +- src/common/variant.cpp | 2 - src/common/variant.h | 126 ++-- src/framework/attribute.cpp | 4 +- src/framework/attribute.h | 192 +++--- src/framework/block_desc.h | 66 +- src/framework/data_layout.h | 76 +-- src/framework/data_transform.cpp | 126 ++-- src/operators/conv_op.cpp | 67 +- src/operators/conv_op.h | 58 +- src/operators/elementwise_add_op.cpp | 16 +- src/operators/elementwise_add_op.h | 52 +- src/operators/kernel/arm/conv_kernel.cpp | 284 ++++---- .../kernel/arm/elementwise_add_kernel.cpp | 42 +- src/operators/kernel/arm/mul_kernel.cpp | 58 +- src/operators/kernel/conv_kernel.h | 18 +- src/operators/kernel/elementwise_add_kernel.h | 18 +- src/operators/kernel/fpga/conv_kernel.cpp | 16 +- src/operators/kernel/mul_kernel.h | 16 +- src/operators/math/elementwise_op_function.h | 380 +++++------ src/operators/math/im2col.cc | 638 +++++++++--------- src/operators/math/im2col.h | 176 ++--- src/operators/math/math_function.cc | 242 +++---- src/operators/math/math_function.h | 44 +- src/operators/math/transform.h | 74 +- src/operators/math/vol2col.cc | 416 ++++++------ src/operators/math/vol2col.h | 142 ++-- src/operators/mul_op.cpp | 54 +- src/operators/mul_op.h | 56 +- src/operators/op_param.cpp | 46 +- src/operators/op_param.h | 408 +++++------ .../{cpplint.bash => .clang-tidy.hook} | 8 +- tools/pre-commit.hooks/.clang_format.hook | 15 - 37 files changed, 2117 insertions(+), 2113 deletions(-) create mode 100644 .clang-tidy rename tools/pre-commit.hooks/{cpplint.bash => .clang-tidy.hook} (67%) delete mode 100755 tools/pre-commit.hooks/.clang_format.hook diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000000..a204e955a2 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,30 @@ +--- +Checks: 'clang-diagnostic-*,clang-analyzer-*' +WarningsAsErrors: '' +HeaderFilterRegex: '' +AnalyzeTemporaryDtors: false +FormatStyle: none +User: allonli +CheckOptions: + - key: google-readability-braces-around-statements.ShortStatementLines + value: '1' + - key: google-readability-function-size.StatementThreshold + value: '800' + - key: google-readability-namespace-comments.ShortNamespaceLines + value: '10' + - key: google-readability-namespace-comments.SpacesBeforeComments + value: '2' + - key: modernize-loop-convert.MaxCopySize + value: '16' + - key: modernize-loop-convert.MinConfidence + value: reasonable + - key: modernize-loop-convert.NamingStyle + value: CamelCase + - key: modernize-pass-by-value.IncludeStyle + value: llvm + - key: modernize-replace-auto-ptr.IncludeStyle + value: llvm + - key: modernize-use-nullptr.NullMacros + value: 'NULL' +... + diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d20372987e..ab41d03232 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,14 +20,14 @@ repos: - id: trailing-whitespace files: (src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$ -#- repo: local -# hooks: -# - id: clang-format-with-version-check -# name: clang-format -# description: Format files with ClangFormat. -# entry: bash ./tools/pre-commit.hooks/.clang_format.hook -i -# language: system -# files: (src).*\.(c|cc|cxx|cpp|h|hpp|hxx)$ +- repo: local + hooks: + - id: clang-tidy + name: clang-tidy + description: Format files with tidy. + entry: bash ./tools/pre-commit.hooks/.clang-tidy.hook -i + language: system + files: (src).*\.(c|cc|cxx|cpp|h|hpp|hxx)$ # #- repo: local # hooks: diff --git a/src/common/log.h b/src/common/log.h index 4ee17df1f4..50b2159793 100644 --- a/src/common/log.h +++ b/src/common/log.h @@ -27,66 +27,66 @@ SOFTWARE. namespace paddle_mobile { - enum LogLevel { - kNO_LOG, - kLOG_ERROR, - kLOG_WARNING, - kLOG_INFO, - kLOG_DEBUG, - kLOG_DEBUG1, - kLOG_DEBUG2, - kLOG_DEBUG3, - kLOG_DEBUG4 - }; - - // log level - static LogLevel log_level = kLOG_DEBUG4; - - static std::vector logs{"NO", "ERROR ", "WARNING", - "INFO ", "DEBUG ", "DEBUG1 ", - "DEBUG2 ", "DEBUG3 ", "DEBUG4 "}; - - struct ToLog; - - struct Print { - friend struct ToLog; - template Print &operator<<(T const &value) { - buffer_ << value; - return *this; - } - - private: - void print(LogLevel level) { - buffer_ << std::endl; - if (level == kLOG_ERROR) { - std::cerr << buffer_.str(); - } else { - std::cout << buffer_.str(); - } - } - std::ostringstream buffer_; - }; - - struct ToLog { - ToLog(LogLevel level = kLOG_DEBUG, const std::string &info = "") - : level_(level) { - unsigned blanks = - (unsigned)(level > kLOG_DEBUG ? (level - kLOG_DEBUG) * 4 : 1); - printer_ << logs[level] << " " << info << ":" - << std::string(blanks, ' '); - } - - template ToLog &operator<<(T const &value) { - printer_ << value; - return *this; - } - - ~ToLog() { printer_.print(level_); } - - private: - LogLevel level_; - Print printer_; - }; +enum LogLevel { + kNO_LOG, + kLOG_ERROR, + kLOG_WARNING, + kLOG_INFO, + kLOG_DEBUG, + kLOG_DEBUG1, + kLOG_DEBUG2, + kLOG_DEBUG3, + kLOG_DEBUG4 +}; + +// log level +static LogLevel log_level = kLOG_DEBUG4; + +static std::vector logs{"NO", "ERROR ", "WARNING", + "INFO ", "DEBUG ", "DEBUG1 ", + "DEBUG2 ", "DEBUG3 ", "DEBUG4 "}; + +struct ToLog; + +struct Print { + friend struct ToLog; + template Print &operator<<(T const &value) { + buffer_ << value; + return *this; + } + +private: + void print(LogLevel level) { + buffer_ << std::endl; + if (level == kLOG_ERROR) { + std::cerr << buffer_.str(); + } else { + std::cout << buffer_.str(); + } + } + std::ostringstream buffer_; +}; + +struct ToLog { + ToLog(LogLevel level = kLOG_DEBUG, const std::string &info = "") + : level_(level) { + unsigned blanks = + (unsigned) (level > kLOG_DEBUG ? (level - kLOG_DEBUG) * 4 : 1); + printer_ << logs[level] << " " << info << ":" + << std::string(blanks, ' '); + } + + template ToLog &operator<<(T const &value) { + printer_ << value; + return *this; + } + + ~ToLog() { printer_.print(level_); } + +private: + LogLevel level_; + Print printer_; +}; #define LOG(level) \ if (level > paddle_mobile::log_level) { \ diff --git a/src/common/type_define.h b/src/common/type_define.h index 0c450f7eb0..0d12ae4d2a 100644 --- a/src/common/type_define.h +++ b/src/common/type_define.h @@ -23,31 +23,31 @@ SOFTWARE. namespace paddle_mobile { - namespace framework { - template class OperatorBase; - class OpDesc; - class BlockDesc; - class InferShapeContext; - } - - using VariableNameMap = std::map>; - - template - using OpCreator = std::function *( - const std::string & /*type*/, const VariableNameMap & /*inputs*/, - const VariableNameMap & /*outputs*/, - const framework::AttributeMap & /*attrs*/)>; - - using GradOpMakerFN = - std::function>( - const framework::OpDesc &, - const std::unordered_set & /*no_grad_set*/, - std::unordered_map * /*grad_to_var*/, - const std::vector &grad_block)>; - - using InferVarTypeFN = - std::function; - - using InferShapeFN = std::function; +namespace framework { +template class OperatorBase; +class OpDesc; +class BlockDesc; +class InferShapeContext; +} + +using VariableNameMap = std::map>; + +template +using OpCreator = std::function *( + const std::string & /*type*/, const VariableNameMap & /*inputs*/, + const VariableNameMap & /*outputs*/, + const framework::AttributeMap & /*attrs*/)>; + +using GradOpMakerFN = +std::function>( + const framework::OpDesc &, + const std::unordered_set & /*no_grad_set*/, + std::unordered_map * /*grad_to_var*/, + const std::vector &grad_block)>; + +using InferVarTypeFN = +std::function; + +using InferShapeFN = std::function; }; diff --git a/src/common/types.h b/src/common/types.h index 388ae48632..e389210a81 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -19,45 +19,45 @@ SOFTWARE. #pragma once; namespace paddle_mobile { - enum class Precision : int { FP32 = 0 }; +enum class Precision : int { FP32 = 0 }; - //! device type - enum DeviceTypeEnum { kINVALID = -1, kCPU = 0, kFPGA = 1, kGPU_MALI = 2 }; +//! device type +enum DeviceTypeEnum { kINVALID = -1, kCPU = 0, kFPGA = 1, kGPU_MALI = 2 }; - template struct DeviceType {}; +template struct DeviceType {}; - typedef DeviceType CPU; - typedef DeviceType FPGA; - typedef DeviceType GPU_MALI; +typedef DeviceType CPU; +typedef DeviceType FPGA; +typedef DeviceType GPU_MALI; - //! data type - enum DataType { - PM_INVALID = -1, - PM_HALF = 0, - PM_FLOAT = 1, - PM_DOUBLE = 2, - PM_INT8 = 3, - PM_INT16 = 4, - PM_INT32 = 5, - PM_INT64 = 6, - PM_UINT8 = 7, - PM_UINT16 = 8, - PM_UINT32 = 9, - PM_STRING = 10, - PM_BOOL = 11, - PM_SHAPE = 12, - PM_TENSOR = 13 - }; - //! - enum PMStatus { - PMSuccess = 0xFF, /*!< No errors */ - PMNotInitialized = 0x01, /*!< Data not initialized. */ - PMInvalidValue = 0x02, /*!< Incorrect variable value. */ - PMMemAllocFailed = 0x03, /*!< Memory allocation error. */ - PMUnKownError = 0x04, /*!< Unknown error. */ - PMOutOfAuthority = 0x05, /*!< Try to modified data not your own*/ - PMOutOfMem = 0x06, /*!< OOM error*/ - PMUnImplError = 0x07, /*!< Unimplement error. */ - PMWrongDevice = 0x08 /*!< un-correct device. */ - }; +//! data type +enum DataType { + PM_INVALID = -1, + PM_HALF = 0, + PM_FLOAT = 1, + PM_DOUBLE = 2, + PM_INT8 = 3, + PM_INT16 = 4, + PM_INT32 = 5, + PM_INT64 = 6, + PM_UINT8 = 7, + PM_UINT16 = 8, + PM_UINT32 = 9, + PM_STRING = 10, + PM_BOOL = 11, + PM_SHAPE = 12, + PM_TENSOR = 13 +}; +//! +enum PMStatus { + PMSuccess = 0xFF, /*!< No errors */ + PMNotInitialized = 0x01, /*!< Data not initialized. */ + PMInvalidValue = 0x02, /*!< Incorrect variable value. */ + PMMemAllocFailed = 0x03, /*!< Memory allocation error. */ + PMUnKownError = 0x04, /*!< Unknown error. */ + PMOutOfAuthority = 0x05, /*!< Try to modified data not your own*/ + PMOutOfMem = 0x06, /*!< OOM error*/ + PMUnImplError = 0x07, /*!< Unimplement error. */ + PMWrongDevice = 0x08 /*!< un-correct device. */ +}; } diff --git a/src/common/variant.cpp b/src/common/variant.cpp index 8e5a9b7279..e05a9d0df3 100644 --- a/src/common/variant.cpp +++ b/src/common/variant.cpp @@ -15,5 +15,3 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ==============================================================================*/ - -#include "variant.h" diff --git a/src/common/variant.h b/src/common/variant.h index 2b67619baa..85ca43df4c 100644 --- a/src/common/variant.h +++ b/src/common/variant.h @@ -21,79 +21,79 @@ SOFTWARE. #pragma once namespace paddle_mobile { - template struct IDToType { typedef Type type_t; }; +template struct IDToType { typedef Type type_t; }; - template struct VariantHelper { - static const size_t size = sizeof(F) > VariantHelper::size - ? sizeof(F) - : VariantHelper::size; +template struct VariantHelper { + static const size_t size = sizeof(F) > VariantHelper::size + ? sizeof(F) + : VariantHelper::size; - inline static void Destroy(size_t id, void *data) { - if (id == typeid(F).hash_code()) { - reinterpret_cast(data)->~F(); - } else { - VariantHelper::Destroy(id, data); - } - } - }; + inline static void Destroy(size_t id, void *data) { + if (id == typeid(F).hash_code()) { + reinterpret_cast(data)->~F(); + } else { + VariantHelper::Destroy(id, data); + } + } +}; - template struct VariantHelper { - static const size_t size = sizeof(F); - inline static void Destroy(size_t id, void *data) { - if (id == typeid(F).hash_code()) { - // reinterpret_cast(data)->~F(); - } else { - // std::cout << "未匹配到 " << std::endl; - } - } - }; +template struct VariantHelper { + static const size_t size = sizeof(F); + inline static void Destroy(size_t id, void *data) { + if (id == typeid(F).hash_code()) { + // reinterpret_cast(data)->~F(); + } else { + // std::cout << "未匹配到 " << std::endl; + } + } +}; - template class RawData { - public: - char data[size]; - RawData() {} - RawData(const RawData &raw_data) { strcpy(data, raw_data.data); } - // void operator=(const RawData &raw_data){ - // strcpy(data, raw_data.data); - // } - }; +template class RawData { +public: + char data[size]; + RawData() {} + RawData(const RawData &raw_data) { strcpy(data, raw_data.data); } + // void operator=(const RawData &raw_data){ + // strcpy(data, raw_data.data); + // } +}; - template struct Variant { - Variant(const Variant &variant) { - // std::cout << " 赋值构造函数 " << std::endl; - type_id = variant.type_id; - data = variant.data; - } +template struct Variant { + Variant(const Variant &variant) { + // std::cout << " 赋值构造函数 " << std::endl; + type_id = variant.type_id; + data = variant.data; + } - Variant() : type_id(invalid_type()) {} - ~Variant() { - // helper::Destroy(type_id, &data); - } + Variant() : type_id(invalid_type()) {} + ~Variant() { + // helper::Destroy(type_id, &data); + } - template void Set(Args &&... args) { - helper::Destroy(type_id, &data); - new (&data) T(std::forward(args)...); - type_id = typeid(T).hash_code(); - } + template void Set(Args &&... args) { + helper::Destroy(type_id, &data); + new(&data) T(std::forward(args)...); + type_id = typeid(T).hash_code(); + } - template T &Get() const { - if (type_id == typeid(T).hash_code()) { - return *const_cast(reinterpret_cast(&data)); - } else { - // std::cout << " bad cast in variant " << std::endl; - throw std::bad_cast(); - } - } + template T &Get() const { + if (type_id == typeid(T).hash_code()) { + return *const_cast(reinterpret_cast(&data)); + } else { + // std::cout << " bad cast in variant " << std::endl; + throw std::bad_cast(); + } + } - size_t TypeId() const { return type_id; } + size_t TypeId() const { return type_id; } - private: - static inline size_t invalid_type() { return typeid(void).hash_code(); } - typedef VariantHelper helper; - size_t type_id; - RawData data; - }; +private: + static inline size_t invalid_type() { return typeid(void).hash_code(); } + typedef VariantHelper helper; + size_t type_id; + RawData data; +}; - template struct Vistor { typedef T type_t; }; +template struct Vistor { typedef T type_t; }; } // namespace paddle_mobile diff --git a/src/framework/attribute.cpp b/src/framework/attribute.cpp index 07b2be99fd..5050ca3aba 100644 --- a/src/framework/attribute.cpp +++ b/src/framework/attribute.cpp @@ -16,8 +16,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ==============================================================================*/ -#include "attribute.h" - namespace paddle_mobile { - namespace framework {} +namespace framework {} } // namespace paddle_mobile diff --git a/src/framework/attribute.h b/src/framework/attribute.h index c80f53c079..20a027aea9 100644 --- a/src/framework/attribute.h +++ b/src/framework/attribute.h @@ -22,110 +22,110 @@ SOFTWARE. #include "framework.pb.h" namespace paddle_mobile { - namespace framework { +namespace framework { - class BlockDesc; +class BlockDesc; - class Attribute { - public: - static Attribute - GetAttrValue(const proto::OpDesc::Attr &attr_desc) { - // std::cout << "begin get attr value" << std::endl; - Attribute attr; - switch (attr_desc.type()) { - case proto::AttrType::BOOLEAN: { - attr.Set(attr_desc.b()); - break; - } - case proto::AttrType::INT: { - attr.Set(attr_desc.i()); - break; - } - case proto::AttrType::FLOAT: { - attr.Set(attr_desc.f()); - break; - } - case proto::AttrType::STRING: { - attr.Set(attr_desc.s()); - break; - } - case proto::AttrType::BOOLEANS: { - std::vector val(attr_desc.bools_size()); - for (int i = 0; i < attr_desc.bools_size(); ++i) { - val[i] = attr_desc.bools(i); - } - attr.Set>(val); - break; - } - case proto::AttrType::INTS: { - std::vector val(attr_desc.ints_size()); - for (int i = 0; i < attr_desc.ints_size(); ++i) { - val[i] = attr_desc.ints(i); - } - attr.Set>(val); - break; - } - case proto::AttrType::FLOATS: { - std::vector val(attr_desc.floats_size()); - for (int i = 0; i < attr_desc.floats_size(); ++i) { - val[i] = attr_desc.floats(i); - } - attr.Set>(val); - break; - } - case proto::AttrType::STRINGS: { - std::vector val(attr_desc.strings_size()); - for (int i = 0; i < attr_desc.strings_size(); ++i) { - val[i] = attr_desc.strings(i); - } - attr.Set>(val); - break; - } - case proto::AttrType::LONG: { - attr.Set(attr_desc.l()); - break; - } - default: - // std::cout << " not support " << std::endl; - break; - } - // std::cout << "end get attr value" << std::endl; - return attr; - } +class Attribute { +public: + static Attribute + GetAttrValue(const proto::OpDesc::Attr &attr_desc) { + // std::cout << "begin get attr value" << std::endl; + Attribute attr; + switch (attr_desc.type()) { + case proto::AttrType::BOOLEAN: { + attr.Set(attr_desc.b()); + break; + } + case proto::AttrType::INT: { + attr.Set(attr_desc.i()); + break; + } + case proto::AttrType::FLOAT: { + attr.Set(attr_desc.f()); + break; + } + case proto::AttrType::STRING: { + attr.Set(attr_desc.s()); + break; + } + case proto::AttrType::BOOLEANS: { + std::vector val(attr_desc.bools_size()); + for (int i = 0; i < attr_desc.bools_size(); ++i) { + val[i] = attr_desc.bools(i); + } + attr.Set>(val); + break; + } + case proto::AttrType::INTS: { + std::vector val(attr_desc.ints_size()); + for (int i = 0; i < attr_desc.ints_size(); ++i) { + val[i] = attr_desc.ints(i); + } + attr.Set>(val); + break; + } + case proto::AttrType::FLOATS: { + std::vector val(attr_desc.floats_size()); + for (int i = 0; i < attr_desc.floats_size(); ++i) { + val[i] = attr_desc.floats(i); + } + attr.Set>(val); + break; + } + case proto::AttrType::STRINGS: { + std::vector val(attr_desc.strings_size()); + for (int i = 0; i < attr_desc.strings_size(); ++i) { + val[i] = attr_desc.strings(i); + } + attr.Set>(val); + break; + } + case proto::AttrType::LONG: { + attr.Set(attr_desc.l()); + break; + } + default: + // std::cout << " not support " << std::endl; + break; + } + // std::cout << "end get attr value" << std::endl; + return attr; + } - Attribute() {} - template - Attribute &Set(Args &&... args) { - variant_.Set(args...); - return *this; - } + Attribute() {} + template + Attribute &Set(Args &&... args) { + variant_.Set(args...); + return *this; + } - template T &Get() const { return variant_.Get(); } + template T &Get() const { return variant_.Get(); } - private: - Variant, - std::vector, std::vector, bool, - std::vector, BlockDesc *, int64_t> - variant_; - }; +private: + Variant, + std::vector, std::vector, bool, + std::vector, BlockDesc *, int64_t> + variant_; +}; - using AttributeMap = std::unordered_map; +using AttributeMap = std::unordered_map; - class AttrReader { - public: - explicit AttrReader(const AttributeMap &attrs) : attrs_(attrs) {} +class AttrReader { +public: + explicit AttrReader(const AttributeMap &attrs) : attrs_(attrs) {} - template inline T Get(const std::string &name) const { - // PADDLE_ENFORCE(attrs_.count(name) != 0, "%s should - // be in - // AttributeMap", - // name); - return ((Attribute)attrs_.at(name)).Get(); - } + template inline T Get(const std::string &name) const { + // PADDLE_ENFORCE(attrs_.count(name) != 0, "%s should + // be in + // AttributeMap", + // name); + return ((Attribute) attrs_.at(name)).Get(); + } - private: - const AttributeMap &attrs_; - }; +private: + const AttributeMap &attrs_; +}; - } // namespace framework +} // namespace framework } // namespace paddle_mobile diff --git a/src/framework/block_desc.h b/src/framework/block_desc.h index 3e75fbbeb8..4dd013224c 100644 --- a/src/framework/block_desc.h +++ b/src/framework/block_desc.h @@ -24,50 +24,50 @@ SOFTWARE. #include "var_desc.h" namespace paddle_mobile { - namespace framework { +namespace framework { - class BlockDesc : PaddleMobileObject { - public: - BlockDesc(const proto::BlockDesc &desc); +class BlockDesc : PaddleMobileObject { +public: + BlockDesc(const proto::BlockDesc &desc); - const int &ID() const { return desc_.idx(); } + const int &ID() const { return desc_.idx(); } - const int &Parent() const { return desc_.parent_idx(); } + const int &Parent() const { return desc_.parent_idx(); } - bool operator==( - const paddle_mobile::framework::BlockDesc &in_block) const { - return this->ID() == in_block.ID() && - this->Parent() == in_block.Parent(); - } + bool operator==( + const paddle_mobile::framework::BlockDesc &in_block) const { + return this->ID() == in_block.ID() && + this->Parent() == in_block.Parent(); + } - bool operator<( - const paddle_mobile::framework::BlockDesc &in_block) const { - return this->ID() < in_block.ID() && - this->Parent() < in_block.Parent(); - } + bool operator<( + const paddle_mobile::framework::BlockDesc &in_block) const { + return this->ID() < in_block.ID() && + this->Parent() < in_block.Parent(); + } - std::vector> Vars() const; - std::vector> Ops() const; + std::vector> Vars() const; + std::vector> Ops() const; - private: - proto::BlockDesc desc_; - std::vector> ops_; - std::unordered_map> vars_; - }; +private: + proto::BlockDesc desc_; + std::vector> ops_; + std::unordered_map> vars_; +}; - } // namespace framework +} // namespace framework } // namespace paddle_mobile namespace std { - template <> struct hash { - typedef paddle_mobile::framework::BlockDesc argument_type; - typedef std::size_t result_type; - result_type operator()(argument_type const &s) const noexcept { - result_type const h1(std::hash{}(s.ID())); - result_type const h2(std::hash{}(s.ID())); - return h1 ^ (h2 << 1); - } - }; +template<> struct hash { + typedef paddle_mobile::framework::BlockDesc argument_type; + typedef std::size_t result_type; + result_type operator()(argument_type const &s) const noexcept { + result_type const h1(std::hash{}(s.ID())); + result_type const h2(std::hash{}(s.ID())); + return h1 ^ (h2 << 1); + } +}; } // namespace std diff --git a/src/framework/data_layout.h b/src/framework/data_layout.h index 5564d00047..b9271fc8df 100644 --- a/src/framework/data_layout.h +++ b/src/framework/data_layout.h @@ -19,50 +19,46 @@ limitations under the License. */ #include namespace paddle_mobile { - namespace framework { +namespace framework { - enum class DataLayout { - kNHWC = 0, - kNCHW = 1, - kAnyLayout = 2, - }; +enum class DataLayout { + kNHWC = 0, + kNCHW = 1, + kAnyLayout = 2, +}; - inline DataLayout StringToDataLayout(const std::string &str) { - std::string s(str); - for (size_t i = 0; i < s.size(); ++i) { - s[i] = toupper(s[i]); - } +inline DataLayout StringToDataLayout(const std::string &str) { + std::string s(str); + for (size_t i = 0; i < s.size(); ++i) { + s[i] = toupper(s[i]); + } - if (s == "NHWC") { - return DataLayout::kNHWC; - } else if (s == "NCHW") { - return DataLayout::kNCHW; - } else if (s == "ANYLAYOUT") { - return DataLayout::kAnyLayout; - } else { - // std::cout << "Unknown storage order string: %s", s; - } - } + if (s == "NHWC") { + return DataLayout::kNHWC; + } else if (s == "NCHW") { + return DataLayout::kNCHW; + } else if (s == "ANYLAYOUT") { + return DataLayout::kAnyLayout; + } else { + // std::cout << "Unknown storage order string: %s", s; + } +} - inline std::string DataLayoutToString(const DataLayout &data_layout) { - switch (data_layout) { - case DataLayout::kNHWC: - return "NHWC"; - case DataLayout::kNCHW: - return "NCHW"; - case DataLayout::kAnyLayout: - return "ANY_LAYOUT"; - default: - break; - // std::cout << "unknown DataLayou %d", data_layout; - } - } +inline std::string DataLayoutToString(const DataLayout &data_layout) { + switch (data_layout) { + case DataLayout::kNHWC:return "NHWC"; + case DataLayout::kNCHW:return "NCHW"; + case DataLayout::kAnyLayout:return "ANY_LAYOUT"; + default:break; + // std::cout << "unknown DataLayou %d", data_layout; + } +} - inline std::ostream &operator<<(std::ostream &out, - const DataLayout &l) { - out << DataLayoutToString(l); - return out; - } +inline std::ostream &operator<<(std::ostream &out, + const DataLayout &l) { + out << DataLayoutToString(l); + return out; +} - } // namespace framework +} // namespace framework } // namespace paddle_mobile diff --git a/src/framework/data_transform.cpp b/src/framework/data_transform.cpp index 2b9cab381c..7a7ca68d61 100644 --- a/src/framework/data_transform.cpp +++ b/src/framework/data_transform.cpp @@ -21,72 +21,72 @@ SOFTWARE. #include "data_transform.h" namespace paddle_mobile { - namespace framework { +namespace framework { - static void PassTensorData(Tensor *from, Tensor *to) { - to->ShareDataWith(*from); - *from = Tensor(); - } +static void PassTensorData(Tensor *from, Tensor *to) { + to->ShareDataWith(*from); + *from = Tensor(); +} - void DataTransform(const OpKernelType &expected_kernel_type, - const OpKernelType &kernel_type_for_var, - const Tensor &input_tensor, Tensor *output_tensor) { - bool transformed = false; - Tensor in; - in.ShareDataWith(input_tensor); - Tensor out; +void DataTransform(const OpKernelType &expected_kernel_type, + const OpKernelType &kernel_type_for_var, + const Tensor &input_tensor, Tensor *output_tensor) { + bool transformed = false; + Tensor in; + in.ShareDataWith(input_tensor); + Tensor out; - // // do layout transform - // if (NeedTransformLayout(expected_kernel_type.data_layout_, - // kernel_type_for_var.data_layout_)) { - // TransDataLayout(kernel_type_for_var, expected_kernel_type, in, - // &out); - // transformed = true; - // PassTensorData(&out, &in); - // } - // - // // do data type transform - // if (expected_kernel_type.data_type_ != - // kernel_type_for_var.data_type_) { - // TransDataType(kernel_type_for_var, expected_kernel_type, in, - // &out); - // transformed = true; - // PassTensorData(&out, &in); - // } - // - // // do device transform - // if (!platform::is_same_place(kernel_type_for_var.place_, - // expected_kernel_type.place_)) { - // TransDataDevice(in, expected_kernel_type.place_, &out); - // transformed = true; - // PassTensorData(&out, &in); - // } - // - // PADDLE_ENFORCE(transformed, "No transform is applied, please - // check!"); - // get output data - output_tensor->ShareDataWith(in); - } + // // do layout transform + // if (NeedTransformLayout(expected_kernel_type.data_layout_, + // kernel_type_for_var.data_layout_)) { + // TransDataLayout(kernel_type_for_var, expected_kernel_type, in, + // &out); + // transformed = true; + // PassTensorData(&out, &in); + // } + // + // // do data type transform + // if (expected_kernel_type.data_type_ != + // kernel_type_for_var.data_type_) { + // TransDataType(kernel_type_for_var, expected_kernel_type, in, + // &out); + // transformed = true; + // PassTensorData(&out, &in); + // } + // + // // do device transform + // if (!platform::is_same_place(kernel_type_for_var.place_, + // expected_kernel_type.place_)) { + // TransDataDevice(in, expected_kernel_type.place_, &out); + // transformed = true; + // PassTensorData(&out, &in); + // } + // + // PADDLE_ENFORCE(transformed, "No transform is applied, please + // check!"); + // get output data + output_tensor->ShareDataWith(in); +} - void CopyVariableWithTensor(const Variable &in_var, - const Tensor &tensor, Variable &out_var) { - // if (in_var.IsType()) { - // auto& in_lod_tensor = in_var.Get(); - // auto* tran_lod_tensor = out_var.GetMutable(); - // tran_lod_tensor->set_lod(in_lod_tensor.lod()); - // tran_lod_tensor->set_layout(in_lod_tensor.layout()); - // tran_lod_tensor->ShareDataWith(tensor); - // } else if (in_var.IsType()) { - // auto& in_selected_rows = in_var.Get(); - // auto* trans_selected_rows = - // out_var.GetMutable(); - // trans_selected_rows->set_height(in_selected_rows.height()); - // trans_selected_rows->set_rows(in_selected_rows.rows()); - // trans_selected_rows->mutable_value()->ShareDataWith(tensor); - // } else { - // PADDLE_THROW("unknown var type"); - // } - } +void CopyVariableWithTensor(const Variable &in_var, + const Tensor &tensor, Variable &out_var) { + // if (in_var.IsType()) { + // auto& in_lod_tensor = in_var.Get(); + // auto* tran_lod_tensor = out_var.GetMutable(); + // tran_lod_tensor->set_lod(in_lod_tensor.lod()); + // tran_lod_tensor->set_layout(in_lod_tensor.layout()); + // tran_lod_tensor->ShareDataWith(tensor); + // } else if (in_var.IsType()) { + // auto& in_selected_rows = in_var.Get(); + // auto* trans_selected_rows = + // out_var.GetMutable(); + // trans_selected_rows->set_height(in_selected_rows.height()); + // trans_selected_rows->set_rows(in_selected_rows.rows()); + // trans_selected_rows->mutable_value()->ShareDataWith(tensor); + // } else { + // PADDLE_THROW("unknown var type"); + // } +} - } // namespace framework +} // namespace framework } // namespace paddle_mobile diff --git a/src/operators/conv_op.cpp b/src/operators/conv_op.cpp index e53cd99a6c..95fea04c3a 100644 --- a/src/operators/conv_op.cpp +++ b/src/operators/conv_op.cpp @@ -19,58 +19,57 @@ SOFTWARE. #include "conv_op.h" #include "framework/data_type.h" #include "framework/op_proto_maker.h" -#include "framework/operator.h" namespace paddle_mobile { - namespace operators { +namespace operators { - int ConvOutputSize(int input_size, int filter_size, int dilation, - int padding, int stride) { - const int dkernel = dilation * (filter_size - 1) + 1; - int output_size = (input_size + 2 * padding - dkernel) / stride + 1; - return output_size; - } +int ConvOutputSize(int input_size, int filter_size, int dilation, + int padding, int stride) { + const int dkernel = dilation * (filter_size - 1) + 1; + int output_size = (input_size + 2 * padding - dkernel) / stride + 1; + return output_size; +} - template - void ConvOp::InferShape() const { - // std::cout << " begin get dims: " << std::endl; +template +void ConvOp::InferShape() const { + // std::cout << " begin get dims: " << std::endl; - auto in_dims = param_.Input()->dims(); + auto in_dims = param_.Input()->dims(); - // std::cout << " end get in dims: " << std::endl; + // std::cout << " end get in dims: " << std::endl; - // std::cout << " in_dims: " << in_dims << std::endl; + // std::cout << " in_dims: " << in_dims << std::endl; - // std::cout << " begin get Filter " << std::endl; + // std::cout << " begin get Filter " << std::endl; - auto filter_dims = param_.Filter()->dims(); + auto filter_dims = param_.Filter()->dims(); - // std::cout << " end get Filter " << std::endl; + // std::cout << " end get Filter " << std::endl; - // std::cout << " begin get Attrs " << std::endl; + // std::cout << " begin get Attrs " << std::endl; - const std::vector &strides = param_.Strides(); + const std::vector &strides = param_.Strides(); - // std::cout << " end get Attrs " << strides[0] << std::endl; + // std::cout << " end get Attrs " << strides[0] << std::endl; - std::vector paddings = param_.Paddings(); + std::vector paddings = param_.Paddings(); - int groups = param_.Groups(); + int groups = param_.Groups(); - std::vector dilations = param_.Dilations(); + std::vector dilations = param_.Dilations(); - std::vector output_shape({in_dims[0], filter_dims[0]}); - for (size_t i = 0; i < strides.size(); ++i) { - output_shape.push_back( - ConvOutputSize(in_dims[i + 2], filter_dims[i + 2], - dilations[i], paddings[i], strides[i])); - } + std::vector output_shape({in_dims[0], filter_dims[0]}); + for (size_t i = 0; i < strides.size(); ++i) { + output_shape.push_back( + ConvOutputSize(in_dims[i + 2], filter_dims[i + 2], + dilations[i], paddings[i], strides[i])); + } - framework::DDim ddim = framework::make_ddim(output_shape); - param_.Output()->Resize(ddim); - } + framework::DDim ddim = framework::make_ddim(output_shape); + param_.Output()->Resize(ddim); +} - template class ConvOp; +template class ConvOp; - } // namespace operators +} // namespace operators } // namespace paddle_mobile diff --git a/src/operators/conv_op.h b/src/operators/conv_op.h index 4b2db961cd..193a8d08f6 100644 --- a/src/operators/conv_op.h +++ b/src/operators/conv_op.h @@ -22,33 +22,33 @@ SOFTWARE. #include "operators/kernel/conv_kernel.h" namespace paddle_mobile { - namespace operators { - - using namespace framework; - - template - class ConvOp : public framework::OperatorWithKernel { - public: - ConvOp(const std::string &type, const VariableNameMap &inputs, - const VariableNameMap &outputs, - const framework::AttributeMap &attrs, - std::shared_ptr scope) - : framework::OperatorWithKernel( - type, inputs, outputs, attrs, scope), - param_(inputs, outputs, attrs, *scope) {} - - using framework::OperatorWithKernel::OperatorWithKernel; - void InferShape() const override; - - void Run() const { - operators::ConvKernel kernel; - kernel.Compute(param_); - this->ClearVariables(); - } - - private: - ConvParam param_; - }; - - } // operators +namespace operators { + +using namespace framework; + +template +class ConvOp : public framework::OperatorWithKernel { +public: + ConvOp(const std::string &type, const VariableNameMap &inputs, + const VariableNameMap &outputs, + const framework::AttributeMap &attrs, + std::shared_ptr scope) + : framework::OperatorWithKernel( + type, inputs, outputs, attrs, scope), + param_(inputs, outputs, attrs, *scope) {} + + using framework::OperatorWithKernel::OperatorWithKernel; + void InferShape() const override; + + void Run() const { + operators::ConvKernel kernel; + kernel.Compute(param_); + this->ClearVariables(); + } + +private: + ConvParam param_; +}; + +} // operators } // paddle_mobile diff --git a/src/operators/elementwise_add_op.cpp b/src/operators/elementwise_add_op.cpp index e0b702cf07..90137bfa2a 100644 --- a/src/operators/elementwise_add_op.cpp +++ b/src/operators/elementwise_add_op.cpp @@ -19,13 +19,13 @@ SOFTWARE. #include "elementwise_add_op.h" namespace paddle_mobile { - namespace operators { +namespace operators { - template - void ElementwiseAddOp::InferShape() const { - auto x_dim = param_.InputX()->dims(); - param_.Out()->Resize(x_dim); - } - template class ElementwiseAddOp; - } +template +void ElementwiseAddOp::InferShape() const { + auto x_dim = param_.InputX()->dims(); + param_.Out()->Resize(x_dim); +} +template class ElementwiseAddOp; +} } diff --git a/src/operators/elementwise_add_op.h b/src/operators/elementwise_add_op.h index 4cee2bb6c9..b41052b7dd 100644 --- a/src/operators/elementwise_add_op.h +++ b/src/operators/elementwise_add_op.h @@ -21,35 +21,35 @@ SOFTWARE. #include "op_param.h" namespace paddle_mobile { - namespace operators { +namespace operators { - using namespace framework; +using namespace framework; - template - class ElementwiseAddOp - : public framework::OperatorWithKernel { - public: - ElementwiseAddOp(const std::string &type, - const VariableNameMap &inputs, - const VariableNameMap &outputs, - const framework::AttributeMap attrs, - std::shared_ptr scope) - : framework::OperatorWithKernel( - type, inputs, outputs, attrs, scope), - param_(inputs, outputs, attrs, *scope) {} +template +class ElementwiseAddOp + : public framework::OperatorWithKernel { +public: + ElementwiseAddOp(const std::string &type, + const VariableNameMap &inputs, + const VariableNameMap &outputs, + const framework::AttributeMap attrs, + std::shared_ptr scope) + : framework::OperatorWithKernel( + type, inputs, outputs, attrs, scope), + param_(inputs, outputs, attrs, *scope) {} - void Run() const { - operators::ElementwiseAddKernel - kernel; - kernel.Compute(param_); - } + void Run() const { + operators::ElementwiseAddKernel + kernel; + kernel.Compute(param_); + } - using framework::OperatorWithKernel::OperatorWithKernel; - void InferShape() const override; + using framework::OperatorWithKernel::OperatorWithKernel; + void InferShape() const override; - protected: - ElementwiseAddParam param_; - }; - } +protected: + ElementwiseAddParam param_; +}; +} } diff --git a/src/operators/kernel/arm/conv_kernel.cpp b/src/operators/kernel/arm/conv_kernel.cpp index f2159e3d36..bd17f246cb 100644 --- a/src/operators/kernel/arm/conv_kernel.cpp +++ b/src/operators/kernel/arm/conv_kernel.cpp @@ -19,146 +19,146 @@ SOFTWARE. #include "operators/kernel/conv_kernel.h" namespace paddle_mobile { - namespace operators { - - bool IsExpand(const std::vector &filter_dim, - const std::vector &strides, - const std::vector &paddings, - const std::vector &dilations) { - bool filter_1 = true, strides_1 = true, padding_0 = true, - dilation_1 = true; - for (size_t j = 0; j < strides.size(); ++j) { - filter_1 = - filter_1 && (static_cast(filter_dim[j + 2]) == 1); - strides_1 = strides_1 && (strides[j] == 1); - padding_0 = padding_0 && (paddings[j] == 0); - dilation_1 = dilation_1 && (dilations[j] == 1); - } - return !(filter_1 && strides_1 && padding_0 && dilation_1); - } - - template <> - void ConvKernel::Compute( - const ConvParam ¶m) const { - LOG(kLOG_DEBUG) << param; - - const Tensor *input = param.Input(); - - // The filter will be reshaped in the calculations, - // so here use an assignment operation, - // that avoids modifying the variable in the Scope. - Tensor filter = *param.Filter(); - - Tensor *output = param.Output(); - // output->mutable_data(context.GetPlace()); - - int groups = param.Groups(); - std::vector strides = param.Strides(); - std::vector paddings = param.Paddings(); - std::vector dilations = param.Dilations(); - - DLOG << " compute end get Attrs " << strides[0]; - - const int batch_size = static_cast(input->dims()[0]); - - // filter_shape_vec: {k_o, k_i, k_h, k_w} or {k_o, k_i, k_d, k_h, - // k_w} - std::vector filter_shape_vec( - framework::vectorize(filter.dims())); - // output_shape_vec: {o_n, o_c, o_h, o_w} or {o_n, o_c, o_d, o_h, - // o_w} - std::vector output_shape_vec( - framework::vectorize(output->dims())); - - // use col_shape in the im2col calculation - // col_shape_vec: {i_c/g, k_h, k_w, o_h, o_w} or {i_c/g, k_d, k_h, - // k_w, o_d, - // o_h, o_w} - size_t data_dim = filter_shape_vec.size() - 2; - std::vector col_shape_vec(1 + 2 * data_dim); - col_shape_vec[0] = input->dims()[1] / groups; - for (size_t j = 0; j < data_dim; ++j) { - col_shape_vec[j + 1] = filter_shape_vec[j + 2]; - col_shape_vec[j + 1 + data_dim] = output_shape_vec[j + 2]; - } - framework::DDim col_shape(framework::make_ddim(col_shape_vec)); - - // use col_matrix_shape in the gemm calculation - // size: (i_c/g * k_h * k_w, o_h * o_w) or (i_c/g * k_d * k_h * k_w, - // o_d * - // o_h * o_w) - framework::DDim col_matrix_shape = - framework::flatten_to_2d(col_shape, data_dim + 1); - - bool is_expand = - IsExpand(filter_shape_vec, strides, paddings, dilations); - Tensor col; - // col_matrix shares the same piece of data with col, - // but will be reshaped into a two-dimensional matrix shape - // to call the matrix multiplication interface. - Tensor col_matrix; - if (is_expand) { - col.mutable_data(col_shape); - col_matrix.ShareDataWith(col); - col_matrix.Resize(col_matrix_shape); - } - - framework::DDim input_shape = framework::slice_ddim( - input->dims(), 1, static_cast(input->dims().size())); - - framework::DDim filter_matrix_shape = { - filter.dims()[0], filter.numel() / filter.dims()[0]}; - filter.Resize(filter_matrix_shape); - - framework::DDim output_matrix_shape = { - output->dims()[1], - output->numel() / (output->dims()[0] * output->dims()[1])}; - - // convolution operator: im2col(or vol2col) + gemm - int in_step = static_cast(input->dims()[1]) / groups; - int out_step = static_cast(output->dims()[1]) / groups; - - math::Vol2ColFunctor vol2col; - math::Im2ColFunctor im2col; - - // auto& dev_ctx = context.template - // device_context(); - for (int i = 0; i < batch_size; i++) { - Tensor in_batch = input->Slice(i, i + 1).Resize(input_shape); - Tensor out_batch = - output->Slice(i, i + 1).Resize(output_matrix_shape); - - for (int g = 0; g < groups; g++) { - Tensor in_slice = - in_batch.Slice(g * in_step, (g + 1) * in_step); - - if (!is_expand) { - col.ShareDataWith(in_slice); - col_matrix.ShareDataWith(col); - col_matrix.Resize(col_matrix_shape); - } else if (data_dim == 2U) { - // im2col - im2col(in_slice, dilations, strides, - std::vector{paddings[0], paddings[1], - paddings[0], paddings[1]}, - &col); - } else if (data_dim == 3U) { - // vol2col - vol2col(in_slice, dilations, strides, paddings, &col); - } - - // gemm - Tensor out_slice = - out_batch.Slice(g * out_step, (g + 1) * out_step); - Tensor filter_slice = - filter.Slice(g * out_step, (g + 1) * out_step); - math::matmul(filter_slice, false, col_matrix, false, - float(1.0), &out_slice, float(0.0)); - } - } - } - - template class ConvKernel; - - } // namespace operators +namespace operators { + +bool IsExpand(const std::vector &filter_dim, + const std::vector &strides, + const std::vector &paddings, + const std::vector &dilations) { + bool filter_1 = true, strides_1 = true, padding_0 = true, + dilation_1 = true; + for (size_t j = 0; j < strides.size(); ++j) { + filter_1 = + filter_1 && (static_cast(filter_dim[j + 2]) == 1); + strides_1 = strides_1 && (strides[j] == 1); + padding_0 = padding_0 && (paddings[j] == 0); + dilation_1 = dilation_1 && (dilations[j] == 1); + } + return !(filter_1 && strides_1 && padding_0 && dilation_1); +} + +template<> +void ConvKernel::Compute( + const ConvParam ¶m) const { + LOG(kLOG_DEBUG) << param; + + const Tensor *input = param.Input(); + + // The filter will be reshaped in the calculations, + // so here use an assignment operation, + // that avoids modifying the variable in the Scope. + Tensor filter = *param.Filter(); + + Tensor *output = param.Output(); + // output->mutable_data(context.GetPlace()); + + int groups = param.Groups(); + std::vector strides = param.Strides(); + std::vector paddings = param.Paddings(); + std::vector dilations = param.Dilations(); + + DLOG << " compute end get Attrs " << strides[0]; + + const int batch_size = static_cast(input->dims()[0]); + + // filter_shape_vec: {k_o, k_i, k_h, k_w} or {k_o, k_i, k_d, k_h, + // k_w} + std::vector filter_shape_vec( + framework::vectorize(filter.dims())); + // output_shape_vec: {o_n, o_c, o_h, o_w} or {o_n, o_c, o_d, o_h, + // o_w} + std::vector output_shape_vec( + framework::vectorize(output->dims())); + + // use col_shape in the im2col calculation + // col_shape_vec: {i_c/g, k_h, k_w, o_h, o_w} or {i_c/g, k_d, k_h, + // k_w, o_d, + // o_h, o_w} + size_t data_dim = filter_shape_vec.size() - 2; + std::vector col_shape_vec(1 + 2 * data_dim); + col_shape_vec[0] = input->dims()[1] / groups; + for (size_t j = 0; j < data_dim; ++j) { + col_shape_vec[j + 1] = filter_shape_vec[j + 2]; + col_shape_vec[j + 1 + data_dim] = output_shape_vec[j + 2]; + } + framework::DDim col_shape(framework::make_ddim(col_shape_vec)); + + // use col_matrix_shape in the gemm calculation + // size: (i_c/g * k_h * k_w, o_h * o_w) or (i_c/g * k_d * k_h * k_w, + // o_d * + // o_h * o_w) + framework::DDim col_matrix_shape = + framework::flatten_to_2d(col_shape, data_dim + 1); + + bool is_expand = + IsExpand(filter_shape_vec, strides, paddings, dilations); + Tensor col; + // col_matrix shares the same piece of data with col, + // but will be reshaped into a two-dimensional matrix shape + // to call the matrix multiplication interface. + Tensor col_matrix; + if (is_expand) { + col.mutable_data(col_shape); + col_matrix.ShareDataWith(col); + col_matrix.Resize(col_matrix_shape); + } + + framework::DDim input_shape = framework::slice_ddim( + input->dims(), 1, static_cast(input->dims().size())); + + framework::DDim filter_matrix_shape = { + filter.dims()[0], filter.numel() / filter.dims()[0]}; + filter.Resize(filter_matrix_shape); + + framework::DDim output_matrix_shape = { + output->dims()[1], + output->numel() / (output->dims()[0] * output->dims()[1])}; + + // convolution operator: im2col(or vol2col) + gemm + int in_step = static_cast(input->dims()[1]) / groups; + int out_step = static_cast(output->dims()[1]) / groups; + + math::Vol2ColFunctor vol2col; + math::Im2ColFunctor im2col; + + // auto& dev_ctx = context.template + // device_context(); + for (int i = 0; i < batch_size; i++) { + Tensor in_batch = input->Slice(i, i + 1).Resize(input_shape); + Tensor out_batch = + output->Slice(i, i + 1).Resize(output_matrix_shape); + + for (int g = 0; g < groups; g++) { + Tensor in_slice = + in_batch.Slice(g * in_step, (g + 1) * in_step); + + if (!is_expand) { + col.ShareDataWith(in_slice); + col_matrix.ShareDataWith(col); + col_matrix.Resize(col_matrix_shape); + } else if (data_dim == 2U) { + // im2col + im2col(in_slice, dilations, strides, + std::vector{paddings[0], paddings[1], + paddings[0], paddings[1]}, + &col); + } else if (data_dim == 3U) { + // vol2col + vol2col(in_slice, dilations, strides, paddings, &col); + } + + // gemm + Tensor out_slice = + out_batch.Slice(g * out_step, (g + 1) * out_step); + Tensor filter_slice = + filter.Slice(g * out_step, (g + 1) * out_step); + math::matmul(filter_slice, false, col_matrix, false, + float(1.0), &out_slice, float(0.0)); + } + } +} + +template class ConvKernel; + +} // namespace operators } // namespace paddle_mobile diff --git a/src/operators/kernel/arm/elementwise_add_kernel.cpp b/src/operators/kernel/arm/elementwise_add_kernel.cpp index 4eba2ed100..8dfdbc6e86 100644 --- a/src/operators/kernel/arm/elementwise_add_kernel.cpp +++ b/src/operators/kernel/arm/elementwise_add_kernel.cpp @@ -17,25 +17,25 @@ limitations under the License. */ #include "operators/kernel/elementwise_add_kernel.h" namespace paddle_mobile { - namespace operators { - - template struct AddFunctor { - inline T operator()(T a, T b) const { return a + b; } - }; - - template <> - void ElementwiseAddKernel::Compute( - const ElementwiseAddParam ¶m) const { - const Tensor *input_x = param.InputX(); - const Tensor *input_y = param.InputY(); - Tensor *Out = param.Out(); - Out->mutable_data(); - const int axis = param.Axis(); - ElementwiseComputeEx, float>( - input_x, input_y, axis, AddFunctor(), Out); - } - - template class ElementwiseAddKernel; - - } // namespace operators +namespace operators { + +template struct AddFunctor { + inline T operator()(T a, T b) const { return a + b; } +}; + +template<> +void ElementwiseAddKernel::Compute( + const ElementwiseAddParam ¶m) const { + const Tensor *input_x = param.InputX(); + const Tensor *input_y = param.InputY(); + Tensor *Out = param.Out(); + Out->mutable_data(); + const int axis = param.Axis(); + ElementwiseComputeEx, float>( + input_x, input_y, axis, AddFunctor(), Out); +} + +template class ElementwiseAddKernel; + +} // namespace operators } // namespace paddle diff --git a/src/operators/kernel/arm/mul_kernel.cpp b/src/operators/kernel/arm/mul_kernel.cpp index 4fa39031d4..8e1d7a43ce 100644 --- a/src/operators/kernel/arm/mul_kernel.cpp +++ b/src/operators/kernel/arm/mul_kernel.cpp @@ -21,36 +21,36 @@ SOFTWARE. #include "operators/kernel/mul_kernel.h" namespace paddle_mobile { - namespace operators { +namespace operators { - template <> - void - MulKernel::Compute(const MulParam ¶m) const { - const Tensor *input_x = param.InputX(); - const Tensor *input_y = param.InputY(); - Tensor *out = param.Out(); - out->mutable_data(); - const Tensor x_matrix = - input_x->dims().size() > 2 - ? framework::ReshapeToMatrix(*input_x, param.XNumColDims()) - : *input_x; - const Tensor y_matrix = - input_y->dims().size() > 2 - ? framework::ReshapeToMatrix(*input_y, param.YNumColDims()) - : *input_y; - auto out_dim = out->dims(); - if (out_dim.size() != 2) { - out->Resize({x_matrix.dims()[0], y_matrix.dims()[1]}); - } - math::matmul(x_matrix, false, y_matrix, false, - static_cast(1), out, - static_cast(0)); - if (out_dim.size() != 2) { - out->Resize(out_dim); - } - } +template<> +void +MulKernel::Compute(const MulParam ¶m) const { + const Tensor *input_x = param.InputX(); + const Tensor *input_y = param.InputY(); + Tensor *out = param.Out(); + out->mutable_data(); + const Tensor x_matrix = + input_x->dims().size() > 2 + ? framework::ReshapeToMatrix(*input_x, param.XNumColDims()) + : *input_x; + const Tensor y_matrix = + input_y->dims().size() > 2 + ? framework::ReshapeToMatrix(*input_y, param.YNumColDims()) + : *input_y; + auto out_dim = out->dims(); + if (out_dim.size() != 2) { + out->Resize({x_matrix.dims()[0], y_matrix.dims()[1]}); + } + math::matmul(x_matrix, false, y_matrix, false, + static_cast(1), out, + static_cast(0)); + if (out_dim.size() != 2) { + out->Resize(out_dim); + } +} - template class MulKernel; +template class MulKernel; - } // namespace operators +} // namespace operators } // namespace paddle diff --git a/src/operators/kernel/conv_kernel.h b/src/operators/kernel/conv_kernel.h index 28c2621ff8..2dfc917268 100644 --- a/src/operators/kernel/conv_kernel.h +++ b/src/operators/kernel/conv_kernel.h @@ -25,15 +25,15 @@ SOFTWARE. #pragma once; namespace paddle_mobile { - namespace operators { +namespace operators { - using namespace framework; +using namespace framework; - template - class ConvKernel - : public framework::OpKernelBase { - public: - void Compute(const ConvParam ¶m) const; - }; - } +template +class ConvKernel + : public framework::OpKernelBase { +public: + void Compute(const ConvParam ¶m) const; +}; +} } diff --git a/src/operators/kernel/elementwise_add_kernel.h b/src/operators/kernel/elementwise_add_kernel.h index 74aeb4f16d..ddc2f396a7 100644 --- a/src/operators/kernel/elementwise_add_kernel.h +++ b/src/operators/kernel/elementwise_add_kernel.h @@ -22,15 +22,15 @@ SOFTWARE. #include "operators/op_param.h" namespace paddle_mobile { - namespace operators { +namespace operators { - using namespace framework; +using namespace framework; - template - class ElementwiseAddKernel - : public framework::OpKernelBase { - public: - void Compute(const ElementwiseAddParam ¶m) const; - }; - } +template +class ElementwiseAddKernel + : public framework::OpKernelBase { +public: + void Compute(const ElementwiseAddParam ¶m) const; +}; +} } diff --git a/src/operators/kernel/fpga/conv_kernel.cpp b/src/operators/kernel/fpga/conv_kernel.cpp index 1c4fc9bca4..265c32ed63 100644 --- a/src/operators/kernel/fpga/conv_kernel.cpp +++ b/src/operators/kernel/fpga/conv_kernel.cpp @@ -16,15 +16,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ==============================================================================*/ -#include "operators/kernel/conv_kernel.h" - namespace paddle_mobile { - namespace operators { +namespace operators { - // template<> - // void ConvKernel::Compute(const ConvParam ¶m) const - // {} - // - // template class ConvKernel; - } +// template<> +// void ConvKernel::Compute(const ConvParam ¶m) const +// {} +// +// template class ConvKernel; +} } diff --git a/src/operators/kernel/mul_kernel.h b/src/operators/kernel/mul_kernel.h index da38542cb7..e22211c33a 100644 --- a/src/operators/kernel/mul_kernel.h +++ b/src/operators/kernel/mul_kernel.h @@ -22,14 +22,14 @@ SOFTWARE. #pragma once; namespace paddle_mobile { - namespace operators { +namespace operators { - using namespace framework; +using namespace framework; - template - class MulKernel : public framework::OpKernelBase { - public: - void Compute(const MulParam ¶m) const; - }; - } +template +class MulKernel : public framework::OpKernelBase { +public: + void Compute(const MulParam ¶m) const; +}; +} } diff --git a/src/operators/math/elementwise_op_function.h b/src/operators/math/elementwise_op_function.h index 3f5c02de22..aa1f9ab9e8 100644 --- a/src/operators/math/elementwise_op_function.h +++ b/src/operators/math/elementwise_op_function.h @@ -18,194 +18,194 @@ limitations under the License. */ #define UNLIKELY(condition) __builtin_expect(static_cast(condition), 0) namespace paddle_mobile { - namespace operators { - - /* - * Out = X ⊙ Y - * If Y's shape does not match X' shape, they will be reshaped. - * For example: - * 1. shape(X) = (2, 3, 4, 5), shape(Y) = (3, 4), with axis=1 - * pre=2, n=3*4, post=5 - * x.shape(2, 12, 5) * y.shape(1, 12, 1).broadcast(2, 12, 5) - * 2. shape(X) = (2, 3, 4, 5), shape(Y) = (4,5) - * pre=2*3, n=4*5, post=1 - * x.shape(6, 20, 1) * y.shape(1, 20, 1).broadcast(6, 20, 1) - */ - inline void get_mid_dims(const framework::DDim &x_dims, - const framework::DDim &y_dims, const int axis, - int *pre, int *n, int *post) { - *pre = 1; - *n = 1; - *post = 1; - // compute pre - for (int i = 0; i < axis; ++i) { - (*pre) *= x_dims[i]; - } - - for (int i = 0; i < y_dims.size(); ++i) { - assert(x_dims[i + axis] == y_dims[i]); - /// "Broadcast dimension mismatch."); - (*n) *= y_dims[i]; - } - - for (int i = axis + y_dims.size(); i < x_dims.size(); ++i) { - (*post) *= x_dims[i]; - } - } - - /// remove dims tail 1. (4,20,1,1) -> (4,20) - inline void trim_trailing_singular_dims(framework::DDim *dims) { - // Remove trailing dimensions of size 1 for y - auto actual_dims_size = dims->size(); - for (; actual_dims_size != 0; --actual_dims_size) { - if ((*dims)[actual_dims_size - 1] != 1) - break; - } - if (actual_dims_size != dims->size()) { - auto actual_dims = framework::vectorize(*dims); - actual_dims.resize(actual_dims_size); - *dims = framework::make_ddim(actual_dims); - } - } - - template class RowwiseTransformIterator { - public: - RowwiseTransformIterator(const T *ptr, int n) - : ptr_(ptr), i_(0), n_(n) {} - - RowwiseTransformIterator &operator++() { - ++i_; - if (UNLIKELY(i_ == n_)) { - i_ = 0; - } - return *this; - } - - bool operator==(const RowwiseTransformIterator &rhs) const { - return (ptr_ + i_) == &(*rhs); - } - - bool operator!=(const RowwiseTransformIterator &rhs) const { - return (ptr_ + i_) != &(*rhs); - } - - const T &operator*() { return ptr_[i_]; } - - private: - const T *ptr_; - int i_; - int64_t n_; - }; - - /// (4,20,2)+(20,): (20,) just as (20,1), when move 2 strides in last - /// dimension - /// in (4,20,2) is 2 , - /// (20,1) move 1 stride , to fill(add) 2 element with the same number. - template class MidWiseTransformIterator { - public: - MidWiseTransformIterator(const T *ptr, int n, int post) - : ptr_(ptr), i_(0), j_(0), n_(n), post_(post) {} - - MidWiseTransformIterator &operator++() { - ++j_; - if (UNLIKELY(j_ == post_)) { - ++i_; - j_ = 0; - if (UNLIKELY(i_ == n_)) { - i_ = 0; - } - } - return *this; - } - - bool operator==(const MidWiseTransformIterator &rhs) const { - return (ptr_ + i_) == &(*rhs); - } - - bool operator!=(const MidWiseTransformIterator &rhs) const { - return (ptr_ + i_) != &(*rhs); - } - - const T &operator*() { return ptr_[i_]; } - - private: - const T *ptr_; - int64_t i_; - int64_t j_; - int64_t n_; - int64_t post_; - }; - - template - class TransformFunctor { - public: - TransformFunctor(const framework::Tensor *x, - const framework::Tensor *y, framework::Tensor *z, - Functor func) - : x_(x->data()), y_(y->data()), - z_(z->mutable_data()), nx_(x->numel()), func_(func) { - } - - inline void Run() const { - math::Transform trans; - // 同时执行func(x_, y_)传入z_。 - trans(x_, x_ + nx_, y_, z_, func_); - } - - inline void RunRowWise(int n, int pre) const { - math::Transform trans; - trans(x_, x_ + nx_, RowwiseTransformIterator(y_, n), z_, - func_); - } - - inline void RunMidWise(int n, int pre, int post) const { - math::Transform trans; - trans(x_, x_ + nx_, MidWiseTransformIterator(y_, n, post), - z_, func_); - } - - private: - const T *x_; - const T *y_; - OutType *z_; - int64_t nx_; - Functor func_; - }; - - template - void ElementwiseComputeEx(const framework::Tensor *x, - const framework::Tensor *y, int axis, - Functor func, framework::Tensor *z) { - TransformFunctor functor(x, y, z, func); - - auto x_dims = x->dims(); - auto y_dims = y->dims(); - // PADDLE_ENFORCE_GE(x_dims.size(), y_dims.size(), - // "Rank of first input must >= rank of second - // input."); - - if (x_dims == y_dims) { - functor.Run(); - return; - } - - /// axis = -1 represent the last dimension. - axis = (axis == -1 ? x_dims.size() - y_dims.size() : axis); - // PADDLE_ENFORCE(axis >= 0 && axis < x_dims.size(), - // "Axis should be in range [0, x_dims)"); - trim_trailing_singular_dims(&y_dims); - axis = (y_dims.size() == 0) ? x_dims.size() : axis; - - int pre, n, post; - get_mid_dims(x_dims, y_dims, axis, &pre, &n, &post); - if (post == 1) { - functor.RunRowWise(n, pre); - return; - } else { - functor.RunMidWise(n, pre, post); - return; - } - } - - } // namespace operators +namespace operators { + +/* + * Out = X ⊙ Y + * If Y's shape does not match X' shape, they will be reshaped. + * For example: + * 1. shape(X) = (2, 3, 4, 5), shape(Y) = (3, 4), with axis=1 + * pre=2, n=3*4, post=5 + * x.shape(2, 12, 5) * y.shape(1, 12, 1).broadcast(2, 12, 5) + * 2. shape(X) = (2, 3, 4, 5), shape(Y) = (4,5) + * pre=2*3, n=4*5, post=1 + * x.shape(6, 20, 1) * y.shape(1, 20, 1).broadcast(6, 20, 1) + */ +inline void get_mid_dims(const framework::DDim &x_dims, + const framework::DDim &y_dims, const int axis, + int *pre, int *n, int *post) { + *pre = 1; + *n = 1; + *post = 1; + // compute pre + for (int i = 0; i < axis; ++i) { + (*pre) *= x_dims[i]; + } + + for (int i = 0; i < y_dims.size(); ++i) { + assert(x_dims[i + axis] == y_dims[i]); + /// "Broadcast dimension mismatch."); + (*n) *= y_dims[i]; + } + + for (int i = axis + y_dims.size(); i < x_dims.size(); ++i) { + (*post) *= x_dims[i]; + } +} + +/// remove dims tail 1. (4,20,1,1) -> (4,20) +inline void trim_trailing_singular_dims(framework::DDim *dims) { + // Remove trailing dimensions of size 1 for y + auto actual_dims_size = dims->size(); + for (; actual_dims_size != 0; --actual_dims_size) { + if ((*dims)[actual_dims_size - 1] != 1) + break; + } + if (actual_dims_size != dims->size()) { + auto actual_dims = framework::vectorize(*dims); + actual_dims.resize(actual_dims_size); + *dims = framework::make_ddim(actual_dims); + } +} + +template class RowwiseTransformIterator { +public: + RowwiseTransformIterator(const T *ptr, int n) + : ptr_(ptr), i_(0), n_(n) {} + + RowwiseTransformIterator &operator++() { + ++i_; + if (UNLIKELY(i_ == n_)) { + i_ = 0; + } + return *this; + } + + bool operator==(const RowwiseTransformIterator &rhs) const { + return (ptr_ + i_) == &(*rhs); + } + + bool operator!=(const RowwiseTransformIterator &rhs) const { + return (ptr_ + i_) != &(*rhs); + } + + const T &operator*() { return ptr_[i_]; } + +private: + const T *ptr_; + int i_; + int64_t n_; +}; + +/// (4,20,2)+(20,): (20,) just as (20,1), when move 2 strides in last +/// dimension +/// in (4,20,2) is 2 , +/// (20,1) move 1 stride , to fill(add) 2 element with the same number. +template class MidWiseTransformIterator { +public: + MidWiseTransformIterator(const T *ptr, int n, int post) + : ptr_(ptr), i_(0), j_(0), n_(n), post_(post) {} + + MidWiseTransformIterator &operator++() { + ++j_; + if (UNLIKELY(j_ == post_)) { + ++i_; + j_ = 0; + if (UNLIKELY(i_ == n_)) { + i_ = 0; + } + } + return *this; + } + + bool operator==(const MidWiseTransformIterator &rhs) const { + return (ptr_ + i_) == &(*rhs); + } + + bool operator!=(const MidWiseTransformIterator &rhs) const { + return (ptr_ + i_) != &(*rhs); + } + + const T &operator*() { return ptr_[i_]; } + +private: + const T *ptr_; + int64_t i_; + int64_t j_; + int64_t n_; + int64_t post_; +}; + +template +class TransformFunctor { +public: + TransformFunctor(const framework::Tensor *x, + const framework::Tensor *y, framework::Tensor *z, + Functor func) + : x_(x->data()), y_(y->data()), + z_(z->mutable_data()), nx_(x->numel()), func_(func) { + } + + inline void Run() const { + math::Transform trans; + // 同时执行func(x_, y_)传入z_。 + trans(x_, x_ + nx_, y_, z_, func_); + } + + inline void RunRowWise(int n, int pre) const { + math::Transform trans; + trans(x_, x_ + nx_, RowwiseTransformIterator(y_, n), z_, + func_); + } + + inline void RunMidWise(int n, int pre, int post) const { + math::Transform trans; + trans(x_, x_ + nx_, MidWiseTransformIterator(y_, n, post), + z_, func_); + } + +private: + const T *x_; + const T *y_; + OutType *z_; + int64_t nx_; + Functor func_; +}; + +template +void ElementwiseComputeEx(const framework::Tensor *x, + const framework::Tensor *y, int axis, + Functor func, framework::Tensor *z) { + TransformFunctor functor(x, y, z, func); + + auto x_dims = x->dims(); + auto y_dims = y->dims(); + // PADDLE_ENFORCE_GE(x_dims.size(), y_dims.size(), + // "Rank of first input must >= rank of second + // input."); + + if (x_dims == y_dims) { + functor.Run(); + return; + } + + /// axis = -1 represent the last dimension. + axis = (axis == -1 ? x_dims.size() - y_dims.size() : axis); + // PADDLE_ENFORCE(axis >= 0 && axis < x_dims.size(), + // "Axis should be in range [0, x_dims)"); + trim_trailing_singular_dims(&y_dims); + axis = (y_dims.size() == 0) ? x_dims.size() : axis; + + int pre, n, post; + get_mid_dims(x_dims, y_dims, axis, &pre, &n, &post); + if (post == 1) { + functor.RunRowWise(n, pre); + return; + } else { + functor.RunMidWise(n, pre, post); + return; + } +} + +} // namespace operators } // namespace paddle diff --git a/src/operators/math/im2col.cc b/src/operators/math/im2col.cc index b54a0694d6..800e87383b 100644 --- a/src/operators/math/im2col.cc +++ b/src/operators/math/im2col.cc @@ -16,349 +16,349 @@ limitations under the License. */ #include "common/types.h" namespace paddle_mobile { - namespace operators { - namespace math { +namespace operators { +namespace math { - /* - * im = [input_channels, input_height, input_width] - * col = - * [input_channels, filter_height, filter_width, output_height, - * output_width] - */ - template class Im2ColFunctor { - public: - void operator()(const framework::Tensor &im, - const std::vector &dilation, - const std::vector &stride, - const std::vector &padding, - framework::Tensor *col) { - // PADDLE_ENFORCE(im.dims().size() == 3); - // PADDLE_ENFORCE(col->dims().size() == 5); +/* + * im = [input_channels, input_height, input_width] + * col = + * [input_channels, filter_height, filter_width, output_height, + * output_width] + */ +template class Im2ColFunctor { +public: + void operator()(const framework::Tensor &im, + const std::vector &dilation, + const std::vector &stride, + const std::vector &padding, + framework::Tensor *col) { + // PADDLE_ENFORCE(im.dims().size() == 3); + // PADDLE_ENFORCE(col->dims().size() == 5); - int im_channels = im.dims()[0]; - int im_height = im.dims()[1]; - int im_width = im.dims()[2]; - int filter_height = col->dims()[1]; - int filter_width = col->dims()[2]; - int col_height = col->dims()[3]; - int col_width = col->dims()[4]; + int im_channels = im.dims()[0]; + int im_height = im.dims()[1]; + int im_width = im.dims()[2]; + int filter_height = col->dims()[1]; + int filter_width = col->dims()[2]; + int col_height = col->dims()[3]; + int col_width = col->dims()[4]; - // PADDLE_ENFORCE_EQ((im_height + padding[0] + padding[2] - // - - // ((dilation[0] * (filter_height - 1) - // + 1))) / - // stride[0] + - // 1, - // col_height, - // "Output_height and - // padding(padding_up, padding_down) - // are " "inconsistent."); - // PADDLE_ENFORCE_EQ((im_width + padding[1] + padding[3] - // - - // ((dilation[1] * (filter_width - 1) - // + 1))) / - // stride[1] + - // 1, - // col_width, - // "Output_height and - // padding(padding_up, padding_down) - // are " "inconsistent."); + // PADDLE_ENFORCE_EQ((im_height + padding[0] + padding[2] + // - + // ((dilation[0] * (filter_height - 1) + // + 1))) / + // stride[0] + + // 1, + // col_height, + // "Output_height and + // padding(padding_up, padding_down) + // are " "inconsistent."); + // PADDLE_ENFORCE_EQ((im_width + padding[1] + padding[3] + // - + // ((dilation[1] * (filter_width - 1) + // + 1))) / + // stride[1] + + // 1, + // col_width, + // "Output_height and + // padding(padding_up, padding_down) + // are " "inconsistent."); - int channels_col = - im_channels * filter_height * filter_width; + int channels_col = + im_channels * filter_height * filter_width; - const T *im_data = im.data(); - T *col_data = col->data(); - for (int c = 0; c < channels_col; ++c) { - int w_offset = c % filter_width; - int h_offset = (c / filter_width) % filter_height; - int c_im = c / (filter_width * filter_height); - for (int h = 0; h < col_height; ++h) { - int im_row_idx = h * stride[0] - padding[0] + - h_offset * dilation[0]; - for (int w = 0; w < col_width; ++w) { - int im_col_idx = w * stride[1] - padding[1] + - w_offset * dilation[1]; - int col_idx = - (c * col_height + h) * col_width + w; - int im_idx = - (im_row_idx + c_im * im_height) * im_width + - im_col_idx; + const T *im_data = im.data(); + T *col_data = col->data(); + for (int c = 0; c < channels_col; ++c) { + int w_offset = c % filter_width; + int h_offset = (c / filter_width) % filter_height; + int c_im = c / (filter_width * filter_height); + for (int h = 0; h < col_height; ++h) { + int im_row_idx = h * stride[0] - padding[0] + + h_offset * dilation[0]; + for (int w = 0; w < col_width; ++w) { + int im_col_idx = w * stride[1] - padding[1] + + w_offset * dilation[1]; + int col_idx = + (c * col_height + h) * col_width + w; + int im_idx = + (im_row_idx + c_im * im_height) * im_width + + im_col_idx; - col_data[col_idx] = - (im_row_idx < 0 || - im_row_idx >= im_height || - im_col_idx < 0 || im_col_idx >= im_width) - ? static_cast(0) - : im_data[im_idx]; - } - } - } - } - }; + col_data[col_idx] = + (im_row_idx < 0 || + im_row_idx >= im_height || + im_col_idx < 0 || im_col_idx >= im_width) + ? static_cast(0) + : im_data[im_idx]; + } + } + } + } +}; - /* - * im = [input_channels, input_height, input_width] - * col = - * [input_channels, filter_height, filter_width, output_height, - * output_width] - */ - template class Col2ImFunctor { - public: - void operator()(const framework::Tensor &col, - const std::vector &dilation, - const std::vector &stride, - const std::vector &padding, - framework::Tensor *im) { - // PADDLE_ENFORCE(im->dims().size() == 3); - // PADDLE_ENFORCE(col.dims().size() == 5); - int im_channels = im->dims()[0]; - int im_height = im->dims()[1]; - int im_width = im->dims()[2]; - int filter_height = col.dims()[1]; - int filter_width = col.dims()[2]; - int col_height = col.dims()[3]; - int col_width = col.dims()[4]; +/* + * im = [input_channels, input_height, input_width] + * col = + * [input_channels, filter_height, filter_width, output_height, + * output_width] + */ +template class Col2ImFunctor { +public: + void operator()(const framework::Tensor &col, + const std::vector &dilation, + const std::vector &stride, + const std::vector &padding, + framework::Tensor *im) { + // PADDLE_ENFORCE(im->dims().size() == 3); + // PADDLE_ENFORCE(col.dims().size() == 5); + int im_channels = im->dims()[0]; + int im_height = im->dims()[1]; + int im_width = im->dims()[2]; + int filter_height = col.dims()[1]; + int filter_width = col.dims()[2]; + int col_height = col.dims()[3]; + int col_width = col.dims()[4]; - // PADDLE_ENFORCE_EQ((im_height + padding[0] + padding[2] - // - - // ((dilation[0] * (filter_height - 1) - // + 1))) / - // stride[0] + - // 1, - // col_height, - // "Output_height and - // padding(padding_up, padding_down) - // are " "inconsistent."); - // PADDLE_ENFORCE_EQ((im_width + padding[1] + padding[3] - // - - // ((dilation[1] * (filter_width - 1) - // + 1))) / - // stride[1] + - // 1, - // col_width, - // "Output_height and - // padding(padding_up, padding_down) - // are " "inconsistent."); + // PADDLE_ENFORCE_EQ((im_height + padding[0] + padding[2] + // - + // ((dilation[0] * (filter_height - 1) + // + 1))) / + // stride[0] + + // 1, + // col_height, + // "Output_height and + // padding(padding_up, padding_down) + // are " "inconsistent."); + // PADDLE_ENFORCE_EQ((im_width + padding[1] + padding[3] + // - + // ((dilation[1] * (filter_width - 1) + // + 1))) / + // stride[1] + + // 1, + // col_width, + // "Output_height and + // padding(padding_up, padding_down) + // are " "inconsistent."); - int channels_col = - im_channels * filter_height * filter_width; + int channels_col = + im_channels * filter_height * filter_width; - T *im_data = im->data(); - const T *col_data = col.data(); + T *im_data = im->data(); + const T *col_data = col.data(); - for (int c = 0; c < channels_col; ++c) { - int w_offset = c % filter_width; - int h_offset = (c / filter_width) % filter_height; - int c_im = c / (filter_width * filter_height); - for (int h = 0; h < col_height; ++h) { - int im_row_idx = h * stride[0] - padding[0] + - h_offset * dilation[0]; - for (int w = 0; w < col_width; ++w) { - int im_col_idx = w * stride[1] - padding[1] + - w_offset * dilation[1]; - if ((im_row_idx) >= 0 && - (im_row_idx) < im_height && - (im_col_idx) >= 0 && - (im_col_idx) < im_width) { - im_data[(im_row_idx + c_im * im_height) * - im_width + - im_col_idx] += - col_data[(c * col_height + h) * - col_width + - w]; - } - } - } - } - } - }; + for (int c = 0; c < channels_col; ++c) { + int w_offset = c % filter_width; + int h_offset = (c / filter_width) % filter_height; + int c_im = c / (filter_width * filter_height); + for (int h = 0; h < col_height; ++h) { + int im_row_idx = h * stride[0] - padding[0] + + h_offset * dilation[0]; + for (int w = 0; w < col_width; ++w) { + int im_col_idx = w * stride[1] - padding[1] + + w_offset * dilation[1]; + if ((im_row_idx) >= 0 && + (im_row_idx) < im_height && + (im_col_idx) >= 0 && + (im_col_idx) < im_width) { + im_data[(im_row_idx + c_im * im_height) * + im_width + + im_col_idx] += + col_data[(c * col_height + h) * + col_width + + w]; + } + } + } + } + } +}; - template class Im2ColFunctor; - template class Im2ColFunctor; - template class Col2ImFunctor; - template class Col2ImFunctor; +template class Im2ColFunctor; +template class Im2ColFunctor; +template class Col2ImFunctor; +template class Col2ImFunctor; - /* - * im = [input_channels, input_height, input_width] - * col = - * [output_height, output_width, input_channels, filter_height, - * filter_width] - */ - template class Im2ColFunctor { - public: - void operator()(const framework::Tensor &im, - const std::vector &dilation, - const std::vector &stride, - const std::vector &padding, - framework::Tensor *col) { - // PADDLE_ENFORCE(im.dims().size() == 3); - // PADDLE_ENFORCE(col->dims().size() == 5); - int im_channels = im.dims()[0]; - int im_height = im.dims()[1]; - int im_width = im.dims()[2]; - int filter_height = col->dims()[3]; - int filter_width = col->dims()[4]; - int col_height = col->dims()[0]; - int col_width = col->dims()[1]; +/* + * im = [input_channels, input_height, input_width] + * col = + * [output_height, output_width, input_channels, filter_height, + * filter_width] + */ +template class Im2ColFunctor { +public: + void operator()(const framework::Tensor &im, + const std::vector &dilation, + const std::vector &stride, + const std::vector &padding, + framework::Tensor *col) { + // PADDLE_ENFORCE(im.dims().size() == 3); + // PADDLE_ENFORCE(col->dims().size() == 5); + int im_channels = im.dims()[0]; + int im_height = im.dims()[1]; + int im_width = im.dims()[2]; + int filter_height = col->dims()[3]; + int filter_width = col->dims()[4]; + int col_height = col->dims()[0]; + int col_width = col->dims()[1]; - // PADDLE_ENFORCE_EQ( - // (im_height + padding[0] + padding[2] - - // filter_height) / stride[0] - // + 1, col_height, "Output_height and - // padding(padding_up, - // padding_down) are " "inconsistent."); - // PADDLE_ENFORCE_EQ( - // (im_width + padding[1] + padding[3] - - // filter_width) / stride[1] + - // 1, col_width, "col_width and padding(padding_left, - // padding_right) - // are " "inconsistent."); + // PADDLE_ENFORCE_EQ( + // (im_height + padding[0] + padding[2] - + // filter_height) / stride[0] + // + 1, col_height, "Output_height and + // padding(padding_up, + // padding_down) are " "inconsistent."); + // PADDLE_ENFORCE_EQ( + // (im_width + padding[1] + padding[3] - + // filter_width) / stride[1] + + // 1, col_width, "col_width and padding(padding_left, + // padding_right) + // are " "inconsistent."); - const T *im_data = im.data(); - T *col_data = col->data(); + const T *im_data = im.data(); + T *col_data = col->data(); - for (int col_row_idx = 0; col_row_idx < col_height; - ++col_row_idx) { - for (int col_col_idx = 0; col_col_idx < col_width; - ++col_col_idx) { - for (int channel = 0; channel < im_channels; - ++channel) { - for (int filter_row_idx = 0; - filter_row_idx < filter_height; - ++filter_row_idx) { - int im_row_offset = - col_row_idx * stride[0] + - filter_row_idx - padding[0]; - for (int filter_col_idx = 0; - filter_col_idx < filter_width; - ++filter_col_idx) { - int im_col_offset = - col_col_idx * stride[1] + - filter_col_idx - padding[1]; + for (int col_row_idx = 0; col_row_idx < col_height; + ++col_row_idx) { + for (int col_col_idx = 0; col_col_idx < col_width; + ++col_col_idx) { + for (int channel = 0; channel < im_channels; + ++channel) { + for (int filter_row_idx = 0; + filter_row_idx < filter_height; + ++filter_row_idx) { + int im_row_offset = + col_row_idx * stride[0] + + filter_row_idx - padding[0]; + for (int filter_col_idx = 0; + filter_col_idx < filter_width; + ++filter_col_idx) { + int im_col_offset = + col_col_idx * stride[1] + + filter_col_idx - padding[1]; - int col_offset = - ((((col_row_idx)*col_width + - col_col_idx) * - im_channels + - channel) * - filter_height + - filter_row_idx) * - filter_width + - filter_col_idx; + int col_offset = + ((((col_row_idx) * col_width + + col_col_idx) * + im_channels + + channel) * + filter_height + + filter_row_idx) * + filter_width + + filter_col_idx; - int im_offset = (channel * im_height + - im_row_offset) * - im_width + - im_col_offset; - col_data[col_offset] = - (im_row_offset < 0 || - im_row_offset >= im_height || - im_col_offset < 0 || - im_col_offset >= im_width) - ? static_cast(0) - : im_data[im_offset]; - } - } - } - } - } - } - }; + int im_offset = (channel * im_height + + im_row_offset) * + im_width + + im_col_offset; + col_data[col_offset] = + (im_row_offset < 0 || + im_row_offset >= im_height || + im_col_offset < 0 || + im_col_offset >= im_width) + ? static_cast(0) + : im_data[im_offset]; + } + } + } + } + } + } +}; - /* - * im = [input_channels, input_height, input_width] - * col = - * [output_height, output_width, input_channels, filter_height, - * filter_width] - */ - template class Col2ImFunctor { - public: - void operator()(const framework::Tensor &col, - const std::vector &dilation, - const std::vector &stride, - const std::vector &padding, - framework::Tensor *im) { - // PADDLE_ENFORCE(im->dims().size() == 3); - // PADDLE_ENFORCE(col.dims().size() == 5); - int im_channels = im->dims()[0]; - int im_height = im->dims()[1]; - int im_width = im->dims()[2]; - int filter_height = col.dims()[3]; - int filter_width = col.dims()[4]; - int col_height = col.dims()[0]; - int col_width = col.dims()[1]; +/* + * im = [input_channels, input_height, input_width] + * col = + * [output_height, output_width, input_channels, filter_height, + * filter_width] + */ +template class Col2ImFunctor { +public: + void operator()(const framework::Tensor &col, + const std::vector &dilation, + const std::vector &stride, + const std::vector &padding, + framework::Tensor *im) { + // PADDLE_ENFORCE(im->dims().size() == 3); + // PADDLE_ENFORCE(col.dims().size() == 5); + int im_channels = im->dims()[0]; + int im_height = im->dims()[1]; + int im_width = im->dims()[2]; + int filter_height = col.dims()[3]; + int filter_width = col.dims()[4]; + int col_height = col.dims()[0]; + int col_width = col.dims()[1]; - // PADDLE_ENFORCE_EQ( - // (im_height + padding[0] + padding[2] - - // filter_height) / stride[0] - // + 1, col_height, "Output_height and - // padding(padding_up, - // padding_down) are " "inconsistent."); - // PADDLE_ENFORCE_EQ( - // (im_width + padding[1] + padding[3] - - // filter_width) / stride[1] + - // 1, col_width, "col_width and padding(padding_left, - // padding_right) - // are " "inconsistent."); + // PADDLE_ENFORCE_EQ( + // (im_height + padding[0] + padding[2] - + // filter_height) / stride[0] + // + 1, col_height, "Output_height and + // padding(padding_up, + // padding_down) are " "inconsistent."); + // PADDLE_ENFORCE_EQ( + // (im_width + padding[1] + padding[3] - + // filter_width) / stride[1] + + // 1, col_width, "col_width and padding(padding_left, + // padding_right) + // are " "inconsistent."); - T *im_data = im->data(); - const T *col_data = col.data(); + T *im_data = im->data(); + const T *col_data = col.data(); - for (int col_row_idx = 0; col_row_idx < col_height; - ++col_row_idx) { - for (int col_col_idx = 0; col_col_idx < col_width; - ++col_col_idx) { - for (int channel = 0; channel < im_channels; - ++channel) { - for (int filter_row_idx = 0; - filter_row_idx < filter_height; - ++filter_row_idx) { - int im_row_offset = - col_row_idx * stride[0] + - filter_row_idx - padding[0]; - for (int filter_col_idx = 0; - filter_col_idx < filter_width; - ++filter_col_idx) { - int im_col_offset = - col_col_idx * stride[1] + - filter_col_idx - padding[1]; + for (int col_row_idx = 0; col_row_idx < col_height; + ++col_row_idx) { + for (int col_col_idx = 0; col_col_idx < col_width; + ++col_col_idx) { + for (int channel = 0; channel < im_channels; + ++channel) { + for (int filter_row_idx = 0; + filter_row_idx < filter_height; + ++filter_row_idx) { + int im_row_offset = + col_row_idx * stride[0] + + filter_row_idx - padding[0]; + for (int filter_col_idx = 0; + filter_col_idx < filter_width; + ++filter_col_idx) { + int im_col_offset = + col_col_idx * stride[1] + + filter_col_idx - padding[1]; - int col_offset = - (((col_row_idx * col_width + - col_col_idx) * - im_channels + - channel) * - filter_height + - filter_row_idx) * - filter_width + - filter_col_idx; + int col_offset = + (((col_row_idx * col_width + + col_col_idx) * + im_channels + + channel) * + filter_height + + filter_row_idx) * + filter_width + + filter_col_idx; - if (im_row_offset >= 0 && - im_row_offset < im_height && - im_col_offset >= 0 && - im_col_offset < im_width) { - int im_offset = - (channel * im_height + - im_row_offset) * - im_width + - im_col_offset; - im_data[im_offset] += - col_data[col_offset]; - } - } - } - } - } - } - } - }; + if (im_row_offset >= 0 && + im_row_offset < im_height && + im_col_offset >= 0 && + im_col_offset < im_width) { + int im_offset = + (channel * im_height + + im_row_offset) * + im_width + + im_col_offset; + im_data[im_offset] += + col_data[col_offset]; + } + } + } + } + } + } + } +}; - template class Im2ColFunctor; - template class Im2ColFunctor; - template class Col2ImFunctor; - template class Col2ImFunctor; +template class Im2ColFunctor; +template class Im2ColFunctor; +template class Col2ImFunctor; +template class Col2ImFunctor; - } // namespace math - } // namespace operators +} // namespace math +} // namespace operators } // namespace paddle_mobile diff --git a/src/operators/math/im2col.h b/src/operators/math/im2col.h index e9657e84cd..c197a204e1 100644 --- a/src/operators/math/im2col.h +++ b/src/operators/math/im2col.h @@ -17,96 +17,96 @@ limitations under the License. */ #include "framework/tensor.h" namespace paddle_mobile { - namespace operators { - namespace math { +namespace operators { +namespace math { - /* The storage format of the coldata in the Im2ColFunctor and - * Col2ImFunctor. */ - enum class ColFormat { kCFO = 0, kOCF = 1 }; +/* The storage format of the coldata in the Im2ColFunctor and + * Col2ImFunctor. */ +enum class ColFormat { kCFO = 0, kOCF = 1 }; - /* - * \brief Converts the image data of three dimensions(CHW) into a - * colData of - * five dimensions in the Im2ColFunctor calculation, - * And in the Col2ImFunctor calculation, it is reversed. - * - * \param imData Image data. - * \param imShape The shape of imData, - * [input_channels, input_height, input_width]. - * \param colData Column data. - * \param colShape The shape of colData. - * - * \param dilations dilation data. - * \param 2-dimension [dilation_height, dilation_width]. - * - * \param strides stride data. - * \param 2-dimension [stride_height, stride_width]. - * - * \param paddings padding data. - * \param 4-dimension [up_pad, left_pad, down_pad, right_pad]. - * - * If the template argument Format is kCFO, the shape of colData is: - * [input_channels, filter_height, filter_width, output_height, - * output_width] - * So, it is easy to reshape into a convolution matrix for - * convolution - * calculation based on matrix multiplication. - * The shape of convolution matrix is [height, width], where the - * height is equal - * input_channels * filter_height * filter_width, and the width is - * equal - * output_height * output_width. - * - * Reshape: - * shape of colData shape of convolution matrix - * [input_channels, - * filter_height, - * filter_width, ======> [height, width] - * output_height, - * output_width] - * - * If the template argument Format is kOCF, the shape of colData is: - * [output_height, output_width, input_channels, filter_height, - * filter_width] - * So, it is easy to reshape into a sequence matrix for rnn - * calculation. - * The shape of sequence matrix is [seq_length, step_size], where - * the seq_length - * is equal output_height * output_width, and the step_size is equal - * input_channels * filter_height * filter_width. - * - * Reshape: - * shape of colData shape of sequence matrix - * [output_height, - * output_width, - * input_channels, ======> [seqLength, stepSize] - * filter_height, - * filter_width] - * - * \note The caller needs to ensure that imShape.inputChannels is - * equal to - * colShape.inputChannels. - */ - template - class Im2ColFunctor { - public: - void operator()(const framework::Tensor &im, - const std::vector &dilation, - const std::vector &stride, - const std::vector &padding, - framework::Tensor *col); - }; +/* + * \brief Converts the image data of three dimensions(CHW) into a + * colData of + * five dimensions in the Im2ColFunctor calculation, + * And in the Col2ImFunctor calculation, it is reversed. + * + * \param imData Image data. + * \param imShape The shape of imData, + * [input_channels, input_height, input_width]. + * \param colData Column data. + * \param colShape The shape of colData. + * + * \param dilations dilation data. + * \param 2-dimension [dilation_height, dilation_width]. + * + * \param strides stride data. + * \param 2-dimension [stride_height, stride_width]. + * + * \param paddings padding data. + * \param 4-dimension [up_pad, left_pad, down_pad, right_pad]. + * + * If the template argument Format is kCFO, the shape of colData is: + * [input_channels, filter_height, filter_width, output_height, + * output_width] + * So, it is easy to reshape into a convolution matrix for + * convolution + * calculation based on matrix multiplication. + * The shape of convolution matrix is [height, width], where the + * height is equal + * input_channels * filter_height * filter_width, and the width is + * equal + * output_height * output_width. + * + * Reshape: + * shape of colData shape of convolution matrix + * [input_channels, + * filter_height, + * filter_width, ======> [height, width] + * output_height, + * output_width] + * + * If the template argument Format is kOCF, the shape of colData is: + * [output_height, output_width, input_channels, filter_height, + * filter_width] + * So, it is easy to reshape into a sequence matrix for rnn + * calculation. + * The shape of sequence matrix is [seq_length, step_size], where + * the seq_length + * is equal output_height * output_width, and the step_size is equal + * input_channels * filter_height * filter_width. + * + * Reshape: + * shape of colData shape of sequence matrix + * [output_height, + * output_width, + * input_channels, ======> [seqLength, stepSize] + * filter_height, + * filter_width] + * + * \note The caller needs to ensure that imShape.inputChannels is + * equal to + * colShape.inputChannels. + */ +template +class Im2ColFunctor { +public: + void operator()(const framework::Tensor &im, + const std::vector &dilation, + const std::vector &stride, + const std::vector &padding, + framework::Tensor *col); +}; - template - class Col2ImFunctor { - public: - void operator()(const framework::Tensor &col, - const std::vector &dilation, - const std::vector &stride, - const std::vector &padding, - framework::Tensor *im); - }; +template +class Col2ImFunctor { +public: + void operator()(const framework::Tensor &col, + const std::vector &dilation, + const std::vector &stride, + const std::vector &padding, + framework::Tensor *im); +}; - } // namespace math - } // namespace operators +} // namespace math +} // namespace operators } // namespace paddle_mobile diff --git a/src/operators/math/math_function.cc b/src/operators/math/math_function.cc index 4fa5470710..47ac4705e3 100644 --- a/src/operators/math/math_function.cc +++ b/src/operators/math/math_function.cc @@ -15,125 +15,125 @@ limitations under the License. */ #include "math_function.h" namespace paddle_mobile { - namespace operators { - namespace math { - - template <> - void gemm(const CBLAS_TRANSPOSE transA, - const CBLAS_TRANSPOSE transB, const int M, - const int N, const int K, const float alpha, - const float *A, const float *B, const float beta, - float *C) { - int lda = (transA == CblasNoTrans) ? K : M; - int ldb = (transB == CblasNoTrans) ? N : K; - int ldc = N; - cblas_sgemm(CblasRowMajor, transA, transB, M, N, K, alpha, A, - lda, B, ldb, beta, C, ldc); - } - - template <> - void gemm(const CBLAS_TRANSPOSE transA, - const CBLAS_TRANSPOSE transB, const int M, - const int N, const int K, const double alpha, - const double *A, const double *B, - const double beta, double *C) { - int lda = (transA == CblasNoTrans) ? K : M; - int ldb = (transB == CblasNoTrans) ? N : K; - int ldc = N; - cblas_dgemm(CblasRowMajor, transA, transB, M, N, K, alpha, A, - lda, B, ldb, beta, C, ldc); - } - - template <> - void gemm(const bool transA, const bool transB, const int M, - const int N, const int K, const float alpha, - const float *A, const int lda, const float *B, - const int ldb, const float beta, float *C, - const int ldc) { - cblas_sgemm(CblasRowMajor, - transA == false ? CblasNoTrans : CblasTrans, - transB == false ? CblasNoTrans : CblasTrans, M, N, - K, alpha, A, lda, B, ldb, beta, C, ldc); - } - - template <> - void gemm(const bool transA, const bool transB, const int M, - const int N, const int K, const double alpha, - const double *A, const int lda, const double *B, - const int ldb, const double beta, double *C, - const int ldc) { - cblas_dgemm(CblasRowMajor, - transA == false ? CblasNoTrans : CblasTrans, - transB == false ? CblasNoTrans : CblasTrans, M, N, - K, alpha, A, lda, B, ldb, beta, C, ldc); - } - - template <> - void matmul(const framework::Tensor &matrix_a, bool trans_a, - const framework::Tensor &matrix_b, bool trans_b, - float alpha, framework::Tensor *matrix_out, - float beta) { - auto dim_a = matrix_a.dims(); - auto dim_b = matrix_b.dims(); - auto dim_out = matrix_out->dims(); - // PADDLE_ENFORCE(dim_a.size() == 2 && dim_b.size() == 2 && - // dim_out.size() == - // 2, - // "The input and output of matmul be matrix"); - // - // PADDLE_ENFORCE(platform::is_cpu_place(matrix_a.place()) && - // platform::is_cpu_place(matrix_b.place()) - // && - // platform::is_cpu_place(matrix_out->place()), - // "Matrix must all be in CPUPlace"); - - int M = dim_out[0]; - int N = dim_out[1]; - int K = (trans_a == false) ? dim_a[1] : dim_a[0]; - - CBLAS_TRANSPOSE transA = - (trans_a == false) ? CblasNoTrans : CblasTrans; - CBLAS_TRANSPOSE transB = - (trans_b == false) ? CblasNoTrans : CblasTrans; - - gemm(transA, transB, M, N, K, alpha, - matrix_a.data(), matrix_b.data(), - beta, matrix_out->data()); - } - - template <> - void matmul(const framework::Tensor &matrix_a, bool trans_a, - const framework::Tensor &matrix_b, bool trans_b, - double alpha, framework::Tensor *matrix_out, - double beta) { - auto dim_a = matrix_a.dims(); - auto dim_b = matrix_b.dims(); - auto dim_out = matrix_out->dims(); - // PADDLE_ENFORCE(dim_a.size() == 2 && dim_b.size() == 2 && - // dim_out.size() == - // 2, - // "The input and output of matmul be matrix"); - // - // PADDLE_ENFORCE(platform::is_cpu_place(matrix_a.place()) && - // platform::is_cpu_place(matrix_b.place()) - // && - // platform::is_cpu_place(matrix_out->place()), - // "Matrix must all be in CPUPlace"); - - int M = dim_out[0]; - int N = dim_out[1]; - int K = (trans_a == false) ? dim_a[1] : dim_a[0]; - - CBLAS_TRANSPOSE transA = - (trans_a == false) ? CblasNoTrans : CblasTrans; - CBLAS_TRANSPOSE transB = - (trans_b == false) ? CblasNoTrans : CblasTrans; - - gemm(transA, transB, M, N, K, alpha, - matrix_a.data(), matrix_b.data(), - beta, matrix_out->data()); - } - - } // namespace math - } // namespace operators +namespace operators { +namespace math { + +template<> +void gemm(const CBLAS_TRANSPOSE transA, + const CBLAS_TRANSPOSE transB, const int M, + const int N, const int K, const float alpha, + const float *A, const float *B, const float beta, + float *C) { + int lda = (transA == CblasNoTrans) ? K : M; + int ldb = (transB == CblasNoTrans) ? N : K; + int ldc = N; + cblas_sgemm(CblasRowMajor, transA, transB, M, N, K, alpha, A, + lda, B, ldb, beta, C, ldc); +} + +template<> +void gemm(const CBLAS_TRANSPOSE transA, + const CBLAS_TRANSPOSE transB, const int M, + const int N, const int K, const double alpha, + const double *A, const double *B, + const double beta, double *C) { + int lda = (transA == CblasNoTrans) ? K : M; + int ldb = (transB == CblasNoTrans) ? N : K; + int ldc = N; + cblas_dgemm(CblasRowMajor, transA, transB, M, N, K, alpha, A, + lda, B, ldb, beta, C, ldc); +} + +template<> +void gemm(const bool transA, const bool transB, const int M, + const int N, const int K, const float alpha, + const float *A, const int lda, const float *B, + const int ldb, const float beta, float *C, + const int ldc) { + cblas_sgemm(CblasRowMajor, + transA == false ? CblasNoTrans : CblasTrans, + transB == false ? CblasNoTrans : CblasTrans, M, N, + K, alpha, A, lda, B, ldb, beta, C, ldc); +} + +template<> +void gemm(const bool transA, const bool transB, const int M, + const int N, const int K, const double alpha, + const double *A, const int lda, const double *B, + const int ldb, const double beta, double *C, + const int ldc) { + cblas_dgemm(CblasRowMajor, + transA == false ? CblasNoTrans : CblasTrans, + transB == false ? CblasNoTrans : CblasTrans, M, N, + K, alpha, A, lda, B, ldb, beta, C, ldc); +} + +template<> +void matmul(const framework::Tensor &matrix_a, bool trans_a, + const framework::Tensor &matrix_b, bool trans_b, + float alpha, framework::Tensor *matrix_out, + float beta) { + auto dim_a = matrix_a.dims(); + auto dim_b = matrix_b.dims(); + auto dim_out = matrix_out->dims(); + // PADDLE_ENFORCE(dim_a.size() == 2 && dim_b.size() == 2 && + // dim_out.size() == + // 2, + // "The input and output of matmul be matrix"); + // + // PADDLE_ENFORCE(platform::is_cpu_place(matrix_a.place()) && + // platform::is_cpu_place(matrix_b.place()) + // && + // platform::is_cpu_place(matrix_out->place()), + // "Matrix must all be in CPUPlace"); + + int M = dim_out[0]; + int N = dim_out[1]; + int K = (trans_a == false) ? dim_a[1] : dim_a[0]; + + CBLAS_TRANSPOSE transA = + (trans_a == false) ? CblasNoTrans : CblasTrans; + CBLAS_TRANSPOSE transB = + (trans_b == false) ? CblasNoTrans : CblasTrans; + + gemm(transA, transB, M, N, K, alpha, + matrix_a.data(), matrix_b.data(), + beta, matrix_out->data()); +} + +template<> +void matmul(const framework::Tensor &matrix_a, bool trans_a, + const framework::Tensor &matrix_b, bool trans_b, + double alpha, framework::Tensor *matrix_out, + double beta) { + auto dim_a = matrix_a.dims(); + auto dim_b = matrix_b.dims(); + auto dim_out = matrix_out->dims(); + // PADDLE_ENFORCE(dim_a.size() == 2 && dim_b.size() == 2 && + // dim_out.size() == + // 2, + // "The input and output of matmul be matrix"); + // + // PADDLE_ENFORCE(platform::is_cpu_place(matrix_a.place()) && + // platform::is_cpu_place(matrix_b.place()) + // && + // platform::is_cpu_place(matrix_out->place()), + // "Matrix must all be in CPUPlace"); + + int M = dim_out[0]; + int N = dim_out[1]; + int K = (trans_a == false) ? dim_a[1] : dim_a[0]; + + CBLAS_TRANSPOSE transA = + (trans_a == false) ? CblasNoTrans : CblasTrans; + CBLAS_TRANSPOSE transB = + (trans_b == false) ? CblasNoTrans : CblasTrans; + + gemm(transA, transB, M, N, K, alpha, + matrix_a.data(), matrix_b.data(), + beta, matrix_out->data()); +} + +} // namespace math +} // namespace operators } // namespace paddle_mobile diff --git a/src/operators/math/math_function.h b/src/operators/math/math_function.h index 0db08aa6b1..1ab975c3e2 100644 --- a/src/operators/math/math_function.h +++ b/src/operators/math/math_function.h @@ -19,26 +19,26 @@ limitations under the License. */ #include namespace paddle_mobile { - namespace operators { - namespace math { - - template - void gemm(const CBLAS_TRANSPOSE transA, - const CBLAS_TRANSPOSE transB, const int M, const int N, - const int K, const T alpha, const T *A, const T *B, - const T beta, T *C); - - template - void gemm(const bool transA, const bool transB, const int M, - const int N, const int K, const T alpha, const T *A, - const int lda, const T *B, const int ldb, const T beta, - T *C, const int ldc); - - // matrix multiply with continuous memory - template - void matmul(const framework::Tensor &matrix_a, bool trans_a, - const framework::Tensor &matrix_b, bool trans_b, - T alpha, framework::Tensor *matrix_out, T beta); - } // namespace math - } // namespace operators +namespace operators { +namespace math { + +template +void gemm(const CBLAS_TRANSPOSE transA, + const CBLAS_TRANSPOSE transB, const int M, const int N, + const int K, const T alpha, const T *A, const T *B, + const T beta, T *C); + +template +void gemm(const bool transA, const bool transB, const int M, + const int N, const int K, const T alpha, const T *A, + const int lda, const T *B, const int ldb, const T beta, + T *C, const int ldc); + +// matrix multiply with continuous memory +template +void matmul(const framework::Tensor &matrix_a, bool trans_a, + const framework::Tensor &matrix_b, bool trans_b, + T alpha, framework::Tensor *matrix_out, T beta); +} // namespace math +} // namespace operators } // namespace paddle_mobile diff --git a/src/operators/math/transform.h b/src/operators/math/transform.h index 55a351c90d..954058962c 100644 --- a/src/operators/math/transform.h +++ b/src/operators/math/transform.h @@ -17,41 +17,41 @@ limitations under the License. */ #include namespace paddle_mobile { - namespace operators { - namespace math { - - // Transform applys a unary or a binary functor on each element in a - // range defined by a pair of iterators. - // - // - The specialization for CPU calls std::transform. - // - The specialization for CUDA calls thrust::tranform. - // - // NOTE: We need to define InputIter and OutputIter defined as - // different types, because the InputIter points op's inputs - // and - // OutputIter pints to op's outputs. - // - // NOTE: We don't assume that InputIter to be const InputType* and - // OutputIter to be OutputType*, because we might use a - // iterator - // class, paddle::fluid::operators::RowwiseTRansformIterator. - - struct Transform { - template - void operator()(InputIter first, InputIter last, - OutputIter result, UnaryOperation op) { - std::transform(first, last, result, op); - } - - template - void operator()(InputIter1 first1, InputIter1 last1, - InputIter2 first2, OutputIter result, - BinaryOperation op) { - std::transform(first1, last1, first2, result, op); - } - }; - } - } // namespace platform +namespace operators { +namespace math { + +// Transform applys a unary or a binary functor on each element in a +// range defined by a pair of iterators. +// +// - The specialization for CPU calls std::transform. +// - The specialization for CUDA calls thrust::tranform. +// +// NOTE: We need to define InputIter and OutputIter defined as +// different types, because the InputIter points op's inputs +// and +// OutputIter pints to op's outputs. +// +// NOTE: We don't assume that InputIter to be const InputType* and +// OutputIter to be OutputType*, because we might use a +// iterator +// class, paddle::fluid::operators::RowwiseTRansformIterator. + +struct Transform { + template + void operator()(InputIter first, InputIter last, + OutputIter result, UnaryOperation op) { + std::transform(first, last, result, op); + } + + template + void operator()(InputIter1 first1, InputIter1 last1, + InputIter2 first2, OutputIter result, + BinaryOperation op) { + std::transform(first1, last1, first2, result, op); + } +}; +} +} // namespace platform } // namespace paddle diff --git a/src/operators/math/vol2col.cc b/src/operators/math/vol2col.cc index 485b94e437..c15715bfde 100644 --- a/src/operators/math/vol2col.cc +++ b/src/operators/math/vol2col.cc @@ -15,212 +15,212 @@ limitations under the License. */ #include "vol2col.h" namespace paddle_mobile { - namespace operators { - namespace math { - - using Tensor = paddle_mobile::framework::Tensor; - /* - * vol = [input_channels, input_depth, input_height, input_width] - * col = - * [input_channels, filter_depth, filter_height, filter_width, - * output_depth, output_height, output_width] - */ - template class Vol2ColFunctor { - public: - void operator()(const Tensor &vol, - const std::vector &dilations, - const std::vector &strides, - const std::vector &paddings, - Tensor *col) const { - // PADDLE_ENFORCE(vol.dims().size() == 4); - // PADDLE_ENFORCE(col->dims().size() == 7); - - int input_channels = vol.dims()[0]; - int input_depth = vol.dims()[1]; - int input_height = vol.dims()[2]; - int input_width = vol.dims()[3]; - int filter_depth = col->dims()[1]; - int filter_height = col->dims()[2]; - int filter_width = col->dims()[3]; - int output_depth = col->dims()[4]; - int output_height = col->dims()[5]; - int output_width = col->dims()[6]; - int channels_col = input_channels * filter_depth * - filter_height * filter_width; - - // PADDLE_ENFORCE_EQ((input_depth + 2 * paddings[0] - - // ((dilations[0] * (filter_depth - 1) - // + 1))) / - // strides[0] + - // 1, - // output_depth, - // "input_depth and output_depth are " - // "mismatching."); - // PADDLE_ENFORCE_EQ((input_height + 2 * paddings[1] - - // ((dilations[1] * (filter_height - - // 1) + 1))) / - // strides[1] + - // 1, - // output_height, - // "input_height and output_height are - // " - // "mismatching."); - // PADDLE_ENFORCE_EQ((input_width + 2 * paddings[2] - - // ((dilations[2] * (filter_width - 1) - // + 1))) / - // strides[2] + - // 1, - // output_width, - // "input_width and output_width are " - // "mismatching."); - - const T *vol_data = vol.data(); - T *col_data = col->data(); - - for (int c = 0; c < channels_col; ++c) { - int w_offset = c % filter_width; - int h_offset = (c / filter_width) % filter_height; - int d_offset = - (c / filter_width / filter_height) % filter_depth; - int c_in = - c / filter_width / filter_height / filter_depth; - for (int d = 0; d < output_depth; ++d) { - int d_pad = d * strides[0] - paddings[0] + - d_offset * dilations[0]; - for (int h = 0; h < output_height; ++h) { - int h_pad = h * strides[1] - paddings[1] + - h_offset * dilations[1]; - for (int w = 0; w < output_width; ++w) { - int w_pad = w * strides[2] - paddings[2] + - w_offset * dilations[2]; - - int col_idx = ((c * output_depth + d) * - output_height + - h) * - output_width + - w; - int vol_idx = - ((c_in * input_depth + d_pad) * - input_height + - h_pad) * - input_width + - w_pad; - col_data[col_idx] = - (h_pad < 0 || h_pad >= input_height || - w_pad < 0 || w_pad >= input_width || - d_pad < 0 || d_pad >= input_depth) - ? static_cast(0) - : vol_data[vol_idx]; - } - } - } - } - } - }; - - /* - * vol = [input_channels,input_depth, input_height, input_width] - * col = - * [input_channels, filter_depth, filter_height, filter_width, - * output_depth, output_height, output_width] - */ - template class Col2VolFunctor { - public: - void operator()(const Tensor &col, - const std::vector &dilations, - const std::vector &strides, - const std::vector &paddings, - Tensor *vol) const { - // PADDLE_ENFORCE(vol->dims().size() == 4); - // PADDLE_ENFORCE(col.dims().size() == 7); - - int input_channels = vol->dims()[0]; - int input_depth = vol->dims()[1]; - int input_height = vol->dims()[2]; - int input_width = vol->dims()[3]; - int filter_depth = col.dims()[1]; - int filter_height = col.dims()[2]; - int filter_width = col.dims()[3]; - int output_depth = col.dims()[4]; - int output_height = col.dims()[5]; - int output_width = col.dims()[6]; - int channels_col = input_channels * filter_depth * - filter_height * filter_width; - - // PADDLE_ENFORCE_EQ((input_depth + 2 * paddings[0] - - // ((dilations[0] * (filter_depth - 1) - // + 1))) / - // strides[0] + - // 1, - // output_depth, - // "input_depth and output_depth are " - // "mismatching."); - // PADDLE_ENFORCE_EQ((input_height + 2 * paddings[1] - - // ((dilations[1] * (filter_height - - // 1) + 1))) / - // strides[1] + - // 1, - // output_height, - // "input_height and output_height are - // " - // "mismatching."); - // PADDLE_ENFORCE_EQ((input_width + 2 * paddings[2] - - // ((dilations[2] * (filter_width - 1) - // + 1))) / - // strides[2] + - // 1, - // output_width, - // "input_width and output_width are " - // "mismatching."); - T *vol_data = vol->data(); - const T *col_data = col.data(); - - for (int c = 0; c < channels_col; ++c) { - int w_offset = c % filter_width; - int h_offset = (c / filter_width) % filter_height; - int d_offset = - (c / filter_width / filter_height) % filter_depth; - int cIm = - c / filter_width / filter_height / filter_depth; - for (int d = 0; d < output_depth; ++d) { - int d_pad = d * strides[0] - paddings[0] + - d_offset * dilations[0]; - for (int h = 0; h < output_height; ++h) { - int h_pad = h * strides[1] - paddings[1] + - h_offset * dilations[1]; - for (int w = 0; w < output_width; ++w) { - int w_pad = w * strides[2] - paddings[2] + - w_offset * dilations[2]; - - if (h_pad >= 0 && h_pad < input_height && - w_pad >= 0 && w_pad < input_width && - d_pad >= 0 && d_pad < input_depth) { - int vol_idx = - ((cIm * input_depth + d_pad) * - input_height + - h_pad) * - input_width + - w_pad; - - int col_idx = ((c * output_depth + d) * - output_height + - h) * - output_width + - w; - vol_data[vol_idx] += col_data[col_idx]; - } - } - } - } - } - } - }; - - template class Vol2ColFunctor; - template class Vol2ColFunctor; - template class Col2VolFunctor; - template class Col2VolFunctor; - - } // namespace math - } // namespace operators +namespace operators { +namespace math { + +using Tensor = paddle_mobile::framework::Tensor; +/* + * vol = [input_channels, input_depth, input_height, input_width] + * col = + * [input_channels, filter_depth, filter_height, filter_width, + * output_depth, output_height, output_width] + */ +template class Vol2ColFunctor { +public: + void operator()(const Tensor &vol, + const std::vector &dilations, + const std::vector &strides, + const std::vector &paddings, + Tensor *col) const { + // PADDLE_ENFORCE(vol.dims().size() == 4); + // PADDLE_ENFORCE(col->dims().size() == 7); + + int input_channels = vol.dims()[0]; + int input_depth = vol.dims()[1]; + int input_height = vol.dims()[2]; + int input_width = vol.dims()[3]; + int filter_depth = col->dims()[1]; + int filter_height = col->dims()[2]; + int filter_width = col->dims()[3]; + int output_depth = col->dims()[4]; + int output_height = col->dims()[5]; + int output_width = col->dims()[6]; + int channels_col = input_channels * filter_depth * + filter_height * filter_width; + + // PADDLE_ENFORCE_EQ((input_depth + 2 * paddings[0] - + // ((dilations[0] * (filter_depth - 1) + // + 1))) / + // strides[0] + + // 1, + // output_depth, + // "input_depth and output_depth are " + // "mismatching."); + // PADDLE_ENFORCE_EQ((input_height + 2 * paddings[1] - + // ((dilations[1] * (filter_height - + // 1) + 1))) / + // strides[1] + + // 1, + // output_height, + // "input_height and output_height are + // " + // "mismatching."); + // PADDLE_ENFORCE_EQ((input_width + 2 * paddings[2] - + // ((dilations[2] * (filter_width - 1) + // + 1))) / + // strides[2] + + // 1, + // output_width, + // "input_width and output_width are " + // "mismatching."); + + const T *vol_data = vol.data(); + T *col_data = col->data(); + + for (int c = 0; c < channels_col; ++c) { + int w_offset = c % filter_width; + int h_offset = (c / filter_width) % filter_height; + int d_offset = + (c / filter_width / filter_height) % filter_depth; + int c_in = + c / filter_width / filter_height / filter_depth; + for (int d = 0; d < output_depth; ++d) { + int d_pad = d * strides[0] - paddings[0] + + d_offset * dilations[0]; + for (int h = 0; h < output_height; ++h) { + int h_pad = h * strides[1] - paddings[1] + + h_offset * dilations[1]; + for (int w = 0; w < output_width; ++w) { + int w_pad = w * strides[2] - paddings[2] + + w_offset * dilations[2]; + + int col_idx = ((c * output_depth + d) * + output_height + + h) * + output_width + + w; + int vol_idx = + ((c_in * input_depth + d_pad) * + input_height + + h_pad) * + input_width + + w_pad; + col_data[col_idx] = + (h_pad < 0 || h_pad >= input_height || + w_pad < 0 || w_pad >= input_width || + d_pad < 0 || d_pad >= input_depth) + ? static_cast(0) + : vol_data[vol_idx]; + } + } + } + } + } +}; + +/* + * vol = [input_channels,input_depth, input_height, input_width] + * col = + * [input_channels, filter_depth, filter_height, filter_width, + * output_depth, output_height, output_width] + */ +template class Col2VolFunctor { +public: + void operator()(const Tensor &col, + const std::vector &dilations, + const std::vector &strides, + const std::vector &paddings, + Tensor *vol) const { + // PADDLE_ENFORCE(vol->dims().size() == 4); + // PADDLE_ENFORCE(col.dims().size() == 7); + + int input_channels = vol->dims()[0]; + int input_depth = vol->dims()[1]; + int input_height = vol->dims()[2]; + int input_width = vol->dims()[3]; + int filter_depth = col.dims()[1]; + int filter_height = col.dims()[2]; + int filter_width = col.dims()[3]; + int output_depth = col.dims()[4]; + int output_height = col.dims()[5]; + int output_width = col.dims()[6]; + int channels_col = input_channels * filter_depth * + filter_height * filter_width; + + // PADDLE_ENFORCE_EQ((input_depth + 2 * paddings[0] - + // ((dilations[0] * (filter_depth - 1) + // + 1))) / + // strides[0] + + // 1, + // output_depth, + // "input_depth and output_depth are " + // "mismatching."); + // PADDLE_ENFORCE_EQ((input_height + 2 * paddings[1] - + // ((dilations[1] * (filter_height - + // 1) + 1))) / + // strides[1] + + // 1, + // output_height, + // "input_height and output_height are + // " + // "mismatching."); + // PADDLE_ENFORCE_EQ((input_width + 2 * paddings[2] - + // ((dilations[2] * (filter_width - 1) + // + 1))) / + // strides[2] + + // 1, + // output_width, + // "input_width and output_width are " + // "mismatching."); + T *vol_data = vol->data(); + const T *col_data = col.data(); + + for (int c = 0; c < channels_col; ++c) { + int w_offset = c % filter_width; + int h_offset = (c / filter_width) % filter_height; + int d_offset = + (c / filter_width / filter_height) % filter_depth; + int cIm = + c / filter_width / filter_height / filter_depth; + for (int d = 0; d < output_depth; ++d) { + int d_pad = d * strides[0] - paddings[0] + + d_offset * dilations[0]; + for (int h = 0; h < output_height; ++h) { + int h_pad = h * strides[1] - paddings[1] + + h_offset * dilations[1]; + for (int w = 0; w < output_width; ++w) { + int w_pad = w * strides[2] - paddings[2] + + w_offset * dilations[2]; + + if (h_pad >= 0 && h_pad < input_height && + w_pad >= 0 && w_pad < input_width && + d_pad >= 0 && d_pad < input_depth) { + int vol_idx = + ((cIm * input_depth + d_pad) * + input_height + + h_pad) * + input_width + + w_pad; + + int col_idx = ((c * output_depth + d) * + output_height + + h) * + output_width + + w; + vol_data[vol_idx] += col_data[col_idx]; + } + } + } + } + } + } +}; + +template class Vol2ColFunctor; +template class Vol2ColFunctor; +template class Col2VolFunctor; +template class Col2VolFunctor; + +} // namespace math +} // namespace operators } // namespace paddle_mobile diff --git a/src/operators/math/vol2col.h b/src/operators/math/vol2col.h index 900906d1c4..887b3f436f 100644 --- a/src/operators/math/vol2col.h +++ b/src/operators/math/vol2col.h @@ -18,78 +18,78 @@ limitations under the License. */ #include "framework/tensor.h" namespace paddle_mobile { - namespace operators { - namespace math { - /* - * \brief Converts the feature data of four dimensions(CDHW) into a - * colData of - * seven dimensions in the Vol2ColFunctor calculation, - * And in the Col2VolFunctor calculation, it is reversed. - * - * \param volData Vol data. - * \param volShape The shape of volData, - * [input_channels, input_depth, input_height, - * input_width]. - * \param colData Column data. - * \param colShape The shape of colData. - * - * \param dilations dilation data. - * \param 3-dimension [dilation_depth, dilation_height, - * dilation_width]. - * - * \param strides stride data. - * \param 3-dimension [stride_depth, stride_height, stride_width]. - * - * \param paddings padding data. - * \param 3-dimension [d_pad, h_pad, w_pad]. - * - * The shape of colData is: - * [input_channels, filter_depth, filter_height, filter_width, - * output_depth, - * output_height, output_width] - * So, it is easy to reshape into a convolution matrix for - * convolution - * calculation based on matrix multiplication. - * The shape of convolution matrix is [height, width], where the - * height is equal - * input_channels * filter_depth * filter_height * filter_width, and - * the width - * is equal output_depth * output_height * output_width. - * - * Reshape: - * shape of colData shape of convolution matrix - * [input_channels, - * filter_depth, - * filter_height, - * filter_width, ======> [height, width] - * output_depth, - * output_height, - * output_width] - * - * \note The caller needs to ensure that volShape.inputChannels is - * equal to - * colShape.inputChannels. - */ - using Tensor = paddle_mobile::framework::Tensor; +namespace operators { +namespace math { +/* + * \brief Converts the feature data of four dimensions(CDHW) into a + * colData of + * seven dimensions in the Vol2ColFunctor calculation, + * And in the Col2VolFunctor calculation, it is reversed. + * + * \param volData Vol data. + * \param volShape The shape of volData, + * [input_channels, input_depth, input_height, + * input_width]. + * \param colData Column data. + * \param colShape The shape of colData. + * + * \param dilations dilation data. + * \param 3-dimension [dilation_depth, dilation_height, + * dilation_width]. + * + * \param strides stride data. + * \param 3-dimension [stride_depth, stride_height, stride_width]. + * + * \param paddings padding data. + * \param 3-dimension [d_pad, h_pad, w_pad]. + * + * The shape of colData is: + * [input_channels, filter_depth, filter_height, filter_width, + * output_depth, + * output_height, output_width] + * So, it is easy to reshape into a convolution matrix for + * convolution + * calculation based on matrix multiplication. + * The shape of convolution matrix is [height, width], where the + * height is equal + * input_channels * filter_depth * filter_height * filter_width, and + * the width + * is equal output_depth * output_height * output_width. + * + * Reshape: + * shape of colData shape of convolution matrix + * [input_channels, + * filter_depth, + * filter_height, + * filter_width, ======> [height, width] + * output_depth, + * output_height, + * output_width] + * + * \note The caller needs to ensure that volShape.inputChannels is + * equal to + * colShape.inputChannels. + */ +using Tensor = paddle_mobile::framework::Tensor; - template class Vol2ColFunctor { - public: - void operator()(const Tensor &vol, - const std::vector &dilations, - const std::vector &strides, - const std::vector &paddings, - Tensor *col) const; - }; +template class Vol2ColFunctor { +public: + void operator()(const Tensor &vol, + const std::vector &dilations, + const std::vector &strides, + const std::vector &paddings, + Tensor *col) const; +}; - template class Col2VolFunctor { - public: - void operator()(const Tensor &col, - const std::vector &dilations, - const std::vector &strides, - const std::vector &paddings, - Tensor *vol) const; - }; +template class Col2VolFunctor { +public: + void operator()(const Tensor &col, + const std::vector &dilations, + const std::vector &strides, + const std::vector &paddings, + Tensor *vol) const; +}; - } // namespace math - } // namespace operators +} // namespace math +} // namespace operators } // namespace paddle_mobile diff --git a/src/operators/mul_op.cpp b/src/operators/mul_op.cpp index f2f90b760b..cbdc22f97e 100644 --- a/src/operators/mul_op.cpp +++ b/src/operators/mul_op.cpp @@ -19,39 +19,39 @@ SOFTWARE. #include "mul_op.h" namespace paddle_mobile { - namespace operators { +namespace operators { - template - void MulOp::InferShape() const { - auto x_dims = param_.InputX()->dims(); - auto y_dims = param_.InputY()->dims(); - int x_num_col_dims = param_.XNumColDims(); - int y_num_col_dims = param_.YNumColDims(); +template +void MulOp::InferShape() const { + auto x_dims = param_.InputX()->dims(); + auto y_dims = param_.InputY()->dims(); + int x_num_col_dims = param_.XNumColDims(); + int y_num_col_dims = param_.YNumColDims(); - assert(x_dims.size() > x_num_col_dims); - assert(y_dims.size() > y_num_col_dims); + assert(x_dims.size() > x_num_col_dims); + assert(y_dims.size() > y_num_col_dims); - /// (1,2,3,4) , x_num_col_dims = 2 -> (2,12) - auto x_mat_dims = framework::flatten_to_2d(x_dims, x_num_col_dims); - auto y_mat_dims = framework::flatten_to_2d(y_dims, y_num_col_dims); + /// (1,2,3,4) , x_num_col_dims = 2 -> (2,12) + auto x_mat_dims = framework::flatten_to_2d(x_dims, x_num_col_dims); + auto y_mat_dims = framework::flatten_to_2d(y_dims, y_num_col_dims); - assert(x_mat_dims[1] == y_mat_dims[0]); + assert(x_mat_dims[1] == y_mat_dims[0]); - std::vector output_dims; - output_dims.reserve(static_cast( - x_num_col_dims + y_dims.size() - y_num_col_dims)); + std::vector output_dims; + output_dims.reserve(static_cast( + x_num_col_dims + y_dims.size() - y_num_col_dims)); - for (int i = 0; i < x_num_col_dims; ++i) { - output_dims.push_back(x_dims[i]); - } + for (int i = 0; i < x_num_col_dims; ++i) { + output_dims.push_back(x_dims[i]); + } - for (int i = y_num_col_dims; i < y_dims.size(); ++i) { - output_dims.push_back(y_dims[i]); - } + for (int i = y_num_col_dims; i < y_dims.size(); ++i) { + output_dims.push_back(y_dims[i]); + } - framework::DDim ddim = framework::make_ddim(output_dims); - param_.Out()->Resize(ddim); - } - template class MulOp; - } + framework::DDim ddim = framework::make_ddim(output_dims); + param_.Out()->Resize(ddim); +} +template class MulOp; +} } diff --git a/src/operators/mul_op.h b/src/operators/mul_op.h index 8fcb84ffcc..d78ca3db82 100644 --- a/src/operators/mul_op.h +++ b/src/operators/mul_op.h @@ -21,32 +21,32 @@ SOFTWARE. #include "operators/op_param.h" namespace paddle_mobile { - namespace operators { - - using namespace framework; - - template - class MulOp : public framework::OperatorWithKernel { - public: - MulOp(const std::string &type, const VariableNameMap &inputs, - const VariableNameMap &outputs, - const framework::AttributeMap attrs, - std::shared_ptr scope) - : framework::OperatorWithKernel( - type, inputs, outputs, attrs, scope), - param_(inputs, outputs, attrs, *scope) {} - - void Run() const { - operators::MulKernel kernel; - kernel.Compute(param_); - } - - using framework::OperatorWithKernel::OperatorWithKernel; - void InferShape() const override; - - protected: - MulParam param_; - }; - - } // namespace operators +namespace operators { + +using namespace framework; + +template +class MulOp : public framework::OperatorWithKernel { +public: + MulOp(const std::string &type, const VariableNameMap &inputs, + const VariableNameMap &outputs, + const framework::AttributeMap attrs, + std::shared_ptr scope) + : framework::OperatorWithKernel( + type, inputs, outputs, attrs, scope), + param_(inputs, outputs, attrs, *scope) {} + + void Run() const { + operators::MulKernel kernel; + kernel.Compute(param_); + } + + using framework::OperatorWithKernel::OperatorWithKernel; + void InferShape() const override; + +protected: + MulParam param_; +}; + +} // namespace operators } // namespace paddle diff --git a/src/operators/op_param.cpp b/src/operators/op_param.cpp index cb46ff37ef..529a096194 100644 --- a/src/operators/op_param.cpp +++ b/src/operators/op_param.cpp @@ -19,27 +19,27 @@ SOFTWARE. #include "op_param.h" namespace paddle_mobile { - namespace operators { - Print &operator<<(Print &printer, const ConvParam &conv_param) { - printer << "parameter of conv: " - << "\n"; - printer << " stride: " - << " (" << conv_param.Strides()[0] - << conv_param.Strides()[1] << ") " - << "\n"; - printer << " paddings: " - << " (" << conv_param.Paddings()[0] - << conv_param.Paddings()[1] << ") " - << "\n"; - printer << " dilations: " - << " (" << conv_param.Dilations()[0] - << conv_param.Dilations()[1] << ") " - << "\n"; - printer << " groups: " << conv_param.Groups() << "\n"; - printer << " input dims: " << conv_param.Input()->dims() << "\n"; - printer << " filter dims: " << conv_param.Filter()->dims() << "\n"; - printer << " output dims: " << conv_param.Output()->dims(); - return printer; - } - } // namespace operators +namespace operators { +Print &operator<<(Print &printer, const ConvParam &conv_param) { + printer << "parameter of conv: " + << "\n"; + printer << " stride: " + << " (" << conv_param.Strides()[0] + << conv_param.Strides()[1] << ") " + << "\n"; + printer << " paddings: " + << " (" << conv_param.Paddings()[0] + << conv_param.Paddings()[1] << ") " + << "\n"; + printer << " dilations: " + << " (" << conv_param.Dilations()[0] + << conv_param.Dilations()[1] << ") " + << "\n"; + printer << " groups: " << conv_param.Groups() << "\n"; + printer << " input dims: " << conv_param.Input()->dims() << "\n"; + printer << " filter dims: " << conv_param.Filter()->dims() << "\n"; + printer << " output dims: " << conv_param.Output()->dims(); + return printer; +} +} // namespace operators } // namespace paddle_mobile diff --git a/src/operators/op_param.h b/src/operators/op_param.h index 7f419bdb61..a059b332b2 100644 --- a/src/operators/op_param.h +++ b/src/operators/op_param.h @@ -26,211 +26,211 @@ SOFTWARE. #include "framework/variable.h" namespace paddle_mobile { - namespace operators { - - using namespace framework; - - class OpParam : PaddleMobileObject { - public: - protected: - template - static T *InputFrom(const VariableNameMap &inputs, - const Scope &scope) { - return GetVarValue("Input", inputs, scope); - } - - template - static T *InputXFrom(const VariableNameMap &inputs, - const Scope &scope) { - return GetVarValue("X", inputs, scope); - } - - template - static T *InputYFrom(const VariableNameMap &inputs, - const Scope &scope) { - return GetVarValue("Y", inputs, scope); - } - - template - static std::vector - InputMultiFrom(const VariableNameMap &inputs, const Scope &scope) { - return GetMultiVarValue("Input", inputs, scope); - } - - template - static T *OutputFrom(const VariableNameMap &outputs, - const Scope &scope) { - return GetVarValue("Output", outputs, scope); - } - - template - static T *OutFrom(const VariableNameMap &outputs, - const Scope &scope) { - return GetVarValue("Out", outputs, scope); - } - - template - static T *FilterFrom(const VariableNameMap &inputs, - const Scope &scope) { - return GetVarValue("Filter", inputs, scope); - } - - template - static const T GetAttr(std::string key, const AttributeMap &map) { - return ((Attribute)map.at(key)).Get(); - } - - template - static T *GetVarValue(std::string key, - const VariableNameMap &var_map, - const Scope &scope) { - auto var_vec = var_map.at(key); - if (var_vec.size()) { - // std::cout << " get var value -- " << var_vec[0] << - // std::endl; - auto var = scope.FindVar(var_vec[0]); - return var->GetMutable(); - } else { - return nullptr; - } - } - - template - static std::vector - GetMultiVarValue(std::string key, const VariableNameMap &var_map, - const Scope &scope) { - auto var_vecs = var_map.at(key); - assert(var_vecs.size() > 1); - std::vector var_res; - for (auto &var_vec : var_vecs) { - auto var = scope.FindVar(var_vec); - var_res.push_back(var->GetMutable()); - } - return var_res; - } - }; - - class ConvParam : OpParam { - public: - ConvParam(const VariableNameMap &inputs, +namespace operators { + +using namespace framework; + +class OpParam : PaddleMobileObject { +public: +protected: + template + static T *InputFrom(const VariableNameMap &inputs, + const Scope &scope) { + return GetVarValue("Input", inputs, scope); + } + + template + static T *InputXFrom(const VariableNameMap &inputs, + const Scope &scope) { + return GetVarValue("X", inputs, scope); + } + + template + static T *InputYFrom(const VariableNameMap &inputs, + const Scope &scope) { + return GetVarValue("Y", inputs, scope); + } + + template + static std::vector + InputMultiFrom(const VariableNameMap &inputs, const Scope &scope) { + return GetMultiVarValue("Input", inputs, scope); + } + + template + static T *OutputFrom(const VariableNameMap &outputs, + const Scope &scope) { + return GetVarValue("Output", outputs, scope); + } + + template + static T *OutFrom(const VariableNameMap &outputs, + const Scope &scope) { + return GetVarValue("Out", outputs, scope); + } + + template + static T *FilterFrom(const VariableNameMap &inputs, + const Scope &scope) { + return GetVarValue("Filter", inputs, scope); + } + + template + static const T GetAttr(std::string key, const AttributeMap &map) { + return ((Attribute) map.at(key)).Get(); + } + + template + static T *GetVarValue(std::string key, + const VariableNameMap &var_map, + const Scope &scope) { + auto var_vec = var_map.at(key); + if (var_vec.size()) { + // std::cout << " get var value -- " << var_vec[0] << + // std::endl; + auto var = scope.FindVar(var_vec[0]); + return var->GetMutable(); + } else { + return nullptr; + } + } + + template + static std::vector + GetMultiVarValue(std::string key, const VariableNameMap &var_map, + const Scope &scope) { + auto var_vecs = var_map.at(key); + assert(var_vecs.size() > 1); + std::vector var_res; + for (auto &var_vec : var_vecs) { + auto var = scope.FindVar(var_vec); + var_res.push_back(var->GetMutable()); + } + return var_res; + } +}; + +class ConvParam : OpParam { +public: + ConvParam(const VariableNameMap &inputs, + const VariableNameMap &outputs, + const framework::AttributeMap &attrs, + const framework::Scope &scope) { + filter_ = FilterFrom(inputs, scope); + input_ = InputFrom(inputs, scope); + output_ = OutputFrom(outputs, scope); + strides_ = GetAttr>("strides", attrs); + paddings_ = GetAttr>("paddings", attrs); + dilations_ = GetAttr>("dilations", attrs); + groups = GetAttr("groups", attrs); + } + + const Tensor *Input() const { return input_; } + + const LoDTensor *Filter() const { return filter_; } + + Tensor *Output() const { return output_; } + + const std::vector &Strides() const { return strides_; } + + const std::vector &Paddings() const { return paddings_; } + + const std::vector &Dilations() const { return dilations_; } + + const int &Groups() const { return groups; } + +private: + Tensor *input_; + Tensor *output_; + LoDTensor *filter_; + std::vector strides_; + std::vector paddings_; + std::vector dilations_; + int groups; +}; + +Print &operator<<(Print &printer, const ConvParam &conv_param); + +class ElementwiseAddParam : OpParam { +public: + ElementwiseAddParam(const VariableNameMap &inputs, const VariableNameMap &outputs, const framework::AttributeMap &attrs, const framework::Scope &scope) { - filter_ = FilterFrom(inputs, scope); - input_ = InputFrom(inputs, scope); - output_ = OutputFrom(outputs, scope); - strides_ = GetAttr>("strides", attrs); - paddings_ = GetAttr>("paddings", attrs); - dilations_ = GetAttr>("dilations", attrs); - groups = GetAttr("groups", attrs); - } - - const Tensor *Input() const { return input_; } - - const LoDTensor *Filter() const { return filter_; } - - Tensor *Output() const { return output_; } - - const std::vector &Strides() const { return strides_; } - - const std::vector &Paddings() const { return paddings_; } - - const std::vector &Dilations() const { return dilations_; } - - const int &Groups() const { return groups; } - - private: - Tensor *input_; - Tensor *output_; - LoDTensor *filter_; - std::vector strides_; - std::vector paddings_; - std::vector dilations_; - int groups; - }; - - Print &operator<<(Print &printer, const ConvParam &conv_param); - - class ElementwiseAddParam : OpParam { - public: - ElementwiseAddParam(const VariableNameMap &inputs, - const VariableNameMap &outputs, - const framework::AttributeMap &attrs, - const framework::Scope &scope) { - input_x_ = InputXFrom(inputs, scope); - input_y_ = InputYFrom(inputs, scope); - out_ = OutFrom(outputs, scope); - axis_ = GetAttr("axis", attrs); - } - - const Tensor *InputX() const { return input_x_; } - - const Tensor *InputY() const { return input_y_; } - - Tensor *Out() const { return out_; } - - const int &Axis() const { return axis_; } - - private: - Tensor *input_x_; - Tensor *input_y_; - Tensor *out_; - int axis_; - }; - - class MulParam : OpParam { - public: - MulParam(const VariableNameMap &inputs, - const VariableNameMap &outputs, - const framework::AttributeMap &attrs, - const framework::Scope &scope) { - input_x_ = InputXFrom(inputs, scope); - input_y_ = InputYFrom(inputs, scope); - out_ = OutFrom(outputs, scope); - x_num_col_dims_ = GetAttr("x_num_col_dims", attrs); - y_num_col_dims_ = GetAttr("y_num_col_dims", attrs); - } - - const Tensor *InputX() const { return input_x_; } - - const Tensor *InputY() const { return input_y_; } - - Tensor *Out() const { return out_; } - - const int &XNumColDims() const { return x_num_col_dims_; } - - const int &YNumColDims() const { return y_num_col_dims_; } - - private: - Tensor *input_x_; - Tensor *input_y_; - Tensor *out_; - int x_num_col_dims_; - int y_num_col_dims_; - }; - - class ConcatParam : public OpParam { - public: - ConcatParam(const VariableNameMap &inputs, - const VariableNameMap &outputs, - const framework::AttributeMap &attrs, - const framework::Scope &scope) { - inputs_ = InputMultiFrom(inputs, scope); - out_ = OutFrom(outputs, scope); - axis_ = GetAttr("axis", attrs); - } - - std::vector Inputs() const { return inputs_; } - - Tensor *Out() const { return out_; } - - const int &Axis() const { return axis_; } - - private: - std::vector inputs_; - Tensor *out_; - int axis_; - }; - - } // namespace operators + input_x_ = InputXFrom(inputs, scope); + input_y_ = InputYFrom(inputs, scope); + out_ = OutFrom(outputs, scope); + axis_ = GetAttr("axis", attrs); + } + + const Tensor *InputX() const { return input_x_; } + + const Tensor *InputY() const { return input_y_; } + + Tensor *Out() const { return out_; } + + const int &Axis() const { return axis_; } + +private: + Tensor *input_x_; + Tensor *input_y_; + Tensor *out_; + int axis_; +}; + +class MulParam : OpParam { +public: + MulParam(const VariableNameMap &inputs, + const VariableNameMap &outputs, + const framework::AttributeMap &attrs, + const framework::Scope &scope) { + input_x_ = InputXFrom(inputs, scope); + input_y_ = InputYFrom(inputs, scope); + out_ = OutFrom(outputs, scope); + x_num_col_dims_ = GetAttr("x_num_col_dims", attrs); + y_num_col_dims_ = GetAttr("y_num_col_dims", attrs); + } + + const Tensor *InputX() const { return input_x_; } + + const Tensor *InputY() const { return input_y_; } + + Tensor *Out() const { return out_; } + + const int &XNumColDims() const { return x_num_col_dims_; } + + const int &YNumColDims() const { return y_num_col_dims_; } + +private: + Tensor *input_x_; + Tensor *input_y_; + Tensor *out_; + int x_num_col_dims_; + int y_num_col_dims_; +}; + +class ConcatParam : public OpParam { +public: + ConcatParam(const VariableNameMap &inputs, + const VariableNameMap &outputs, + const framework::AttributeMap &attrs, + const framework::Scope &scope) { + inputs_ = InputMultiFrom(inputs, scope); + out_ = OutFrom(outputs, scope); + axis_ = GetAttr("axis", attrs); + } + + std::vector Inputs() const { return inputs_; } + + Tensor *Out() const { return out_; } + + const int &Axis() const { return axis_; } + +private: + std::vector inputs_; + Tensor *out_; + int axis_; +}; + +} // namespace operators } // namespace paddle_mobile diff --git a/tools/pre-commit.hooks/cpplint.bash b/tools/pre-commit.hooks/.clang-tidy.hook similarity index 67% rename from tools/pre-commit.hooks/cpplint.bash rename to tools/pre-commit.hooks/.clang-tidy.hook index d3ec20f13f..079d41f48e 100755 --- a/tools/pre-commit.hooks/cpplint.bash +++ b/tools/pre-commit.hooks/.clang-tidy.hook @@ -1,13 +1,13 @@ #!/bin/bash +set -e TOTAL_ERRORS=0 -#iclang-tidy *.[ch]pp -checks=* # The trick to remove deleted files: https://stackoverflow.com/a/2413151 -for file in $(git diff --cached --name-status | awk '$1 != "D" {print $2}'|grep -v ".pb." | grep -v "third-party/"); do - cpplint $file +for file in $(git diff --cached --name-status | awk '$1 != "D" {print $2}' | grep "src" | grep -v ".pb."); do + echo "clang-tidy formating $file" + clang-tidy $file TOTAL_ERRORS=$(expr $TOTAL_ERRORS + $?); done exit $TOTAL_ERRORS - diff --git a/tools/pre-commit.hooks/.clang_format.hook b/tools/pre-commit.hooks/.clang_format.hook deleted file mode 100755 index 1d92821686..0000000000 --- a/tools/pre-commit.hooks/.clang_format.hook +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -set -e - -readonly VERSION="3.8" - -version=$(clang-format -version) - -if ! [[ $version == *"$VERSION"* ]]; then - echo "clang-format version check failed." - echo "a version contains '$VERSION' is needed, but get '$version'" - echo "you can install the right version, and make an soft-link to '\$PATH' env" - exit -1 -fi - -clang-format $@ -- GitLab