提交 45de1e84 编写于 作者: 朔-望's avatar 朔-望 提交者: GitHub

Merge pull request #198 from allonli/develop

Add clang-tidy and clang-format hook
...@@ -3,5 +3,4 @@ Language: Cpp ...@@ -3,5 +3,4 @@ Language: Cpp
BasedOnStyle: LLVM BasedOnStyle: LLVM
Standard: Cpp11 Standard: Cpp11
IndentWidth: 4 IndentWidth: 4
NamespaceIndentation: All
... ...
Checks: >
*
-android-*
-bugprone-bool-pointer-implicit-conversion
-cert-env33-c
-cert-dcl50-cpp
-cert-dcl59-cpp
-cppcoreguidelines-*
-fuchsia-*
-google-*
google-default-arguments
google-explicit-constructor
google-runtime-member-string-references
google-runtime-operator
-hicpp-braces-around-statements
-hicpp-named-parameter
-hicpp-no-array-decay
-hicpp-no-assembler
-hicpp-no-malloc
-hicpp-function-size
-hicpp-special-member-functions
-hicpp-vararg
-llvm-*
-objc-*
-readability-else-after-return
-readability-implicit-bool-conversion
-readability-named-parameter
-readability-simplify-boolean-expr
-readability-braces-around-statements
-readability-identifier-naming
-readability-function-size
-readability-redundant-member-init
-misc-bool-pointer-implicit-conversion
-misc-definitions-in-headers
-misc-unused-alias-decls
-misc-unused-parameters
-misc-unused-using-decls
-modernize-use-using
-modernize-use-default-member-init
-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'
...@@ -22,13 +22,22 @@ repos: ...@@ -22,13 +22,22 @@ repos:
- repo: local - repo: local
hooks: hooks:
- id: clang-format-with-version-check - id: clang-format
name: clang-format name: clang-format
description: Format files with ClangFormat. description: Format files with ClangFormat.
entry: bash ./tools/pre-commit.hooks/.clang_format.hook -i entry: bash ./tools/pre-commit.hooks/.clang-format.hook -i
language: system language: system
files: (src).*\.(c|cc|cxx|cpp|h|hpp|hxx)$ files: \.(c|cc|cxx|cpp|h|hpp|hxx)$
- repo: local
hooks:
- id: clang-tidy
name: clang-tidy
description: Check C++ code style using clang-tidy.
entry: bash ./tools/pre-commit.hooks/.clang-tidy.hook -i
language: system
files: (src).*\.(c|cc|cxx|cpp|h|hpp|hxx)$
#
#- repo: local #- repo: local
# hooks: # hooks:
# - id: copyright_checker # - id: copyright_checker
......
...@@ -6,26 +6,54 @@ dist: trusty ...@@ -6,26 +6,54 @@ dist: trusty
os: os:
- linux - linux
env: env:
- JOB=check_style global:
- CMAKE_URL=https://cmake.org/files/v3.11/cmake-3.11.1-Linux-x86_64.tar.gz
addons: addons:
apt: apt:
sources:
- llvm-toolchain-trusty-6.0
- ubuntu-toolchain-r-test
packages: packages:
- git - git
- python - python
- python-pip - python-pip
- python2.7-dev - python2.7-dev
- clang-format-3.8 - libc6-i386
- clang-6.0
- libclang-6.0
- llvm-6.0
- llvm-6.0-dev
- curl
compiler:
- clang
before_install: before_install:
- sudo pip install -U virtualenv pre-commit pip - sudo pip install -U virtualenv pre-commit pip
# Download and install recent cmake
- |
if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then
CMAKE_URL=${CMAKE_URL}
mkdir -p ${DEPS_DIR}/cmake
travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR}/cmake
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
fi
#install:
# - if [ "$CXX" = "g++" ]; then export CXX="g++-5" CC="gcc-5"; fi
# - if [ "$CXX" = "clang++" ]; then export CXX="clang++-6.0" CC="clang-6.0"; fi
before_script:
- |
echo "cmake generate compile_commands.json for clang-tidy"
ls -l -a
clang-tidy -version
clang-format -version
script: script:
- if [[ "$JOB" == "check_style" ]]; then sudo ln -s /usr/bin/clang-format-3.8 /usr/bin/clang-format; fi
- | - |
function timeout() { perl -e 'alarm shift; exec @ARGV' "$@"; } function timeout() { perl -e 'alarm shift; exec @ARGV' "$@"; }
- | - |
timeout 600 .travis/${JOB}.sh # 10min timeout timeout 600 .travis/pre-commit-job.sh # 10min timeout
RESULT=$?; if [ $RESULT -eq 0 ] || [ $RESULT -eq 142 ]; then true; else exit 1; fi; RESULT=$?; if [ $RESULT -eq 0 ] || [ $RESULT -eq 142 ]; then true; else exit 1; fi;
notifications: notifications:
......
#!/bin/bash #!/bin/bash
function abort(){ function abort(){
echo "Your change doesn't follow PaddlePaddle's code style" 1>&2 echo "Your change doesn't follow Paddle-Moible's code style" 1>&2
echo "Please use pre-commit to auto-format your code." 1>&2 echo "Please use pre-commit to auto-format your code." 1>&2
exit 1 exit 1
} }
...@@ -11,7 +11,6 @@ cd `dirname $0` ...@@ -11,7 +11,6 @@ cd `dirname $0`
cd .. cd ..
export PATH=/usr/bin:$PATH export PATH=/usr/bin:$PATH
pre-commit install pre-commit install
clang-format --version
if ! pre-commit run -a ; then if ! pre-commit run -a ; then
ls -lh ls -lh
......
...@@ -5,7 +5,8 @@ add_definitions(-DPADDLE_MOBILE_DEBUG="true") ...@@ -5,7 +5,8 @@ add_definitions(-DPADDLE_MOBILE_DEBUG="true")
set(CMAKE_BUILD_TYPE RelWithDebInfo) set(CMAKE_BUILD_TYPE RelWithDebInfo)
set(CMAKE_VERBOSE_MAKEFILE on) set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY build) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY build)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY build) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY build)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY build) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY build)
......
#!/bin/bash #!/bin/bash
build_for_linux() { build_for_linux() {
echo "linux" if [ ! `which brew` ]; then
echo "building failed! homebrew not found, please install homebrew."
return
fi
if [ ! `which cmake` ]; then
echo "installing cmake."
brew install cmake
if [ ! $? ]; then
echo "cmake install failed."
return
fi
fi
PLATFORM="x86"
MODE="Release"
CXX_FLAGS="-std=c++11 -O3 -s"
BUILD_DIR=build/release/"${PLATFORM}"
mkdir -p ${BUILD_DIR}/build
mkdir -p ${BUILD_DIR}/test
cp -r test/models ${BUILD_DIR}/test/models
cmake . \
-B"${BUILD_DIR}" \
-DCMAKE_BUILD_TYPE="${MODE}" \
-DCMAKE_CXX_FLAGS="${CXX_FLAGS}" \
-DIS_MAC=true
cd ${BUILD_DIR}
make -j 8
} }
build_for_mac() { build_for_mac() {
......
此差异已折叠。
...@@ -27,7 +27,7 @@ SOFTWARE. ...@@ -27,7 +27,7 @@ SOFTWARE.
namespace paddle_mobile { namespace paddle_mobile {
enum LogLevel { enum LogLevel {
kNO_LOG, kNO_LOG,
kLOG_ERROR, kLOG_ERROR,
kLOG_WARNING, kLOG_WARNING,
...@@ -37,18 +37,18 @@ namespace paddle_mobile { ...@@ -37,18 +37,18 @@ namespace paddle_mobile {
kLOG_DEBUG2, kLOG_DEBUG2,
kLOG_DEBUG3, kLOG_DEBUG3,
kLOG_DEBUG4 kLOG_DEBUG4
}; };
// log level // log level
static LogLevel log_level = kLOG_DEBUG4; static LogLevel log_level = kLOG_DEBUG4;
static std::vector<std::string> logs{"NO", "ERROR ", "WARNING", static std::vector<std::string> logs{"NO", "ERROR ", "WARNING",
"INFO ", "DEBUG ", "DEBUG1 ", "INFO ", "DEBUG ", "DEBUG1 ",
"DEBUG2 ", "DEBUG3 ", "DEBUG4 "}; "DEBUG2 ", "DEBUG3 ", "DEBUG4 "};
struct ToLog; struct ToLog;
struct Print; struct Print;
struct Print { struct Print {
friend struct ToLog; friend struct ToLog;
template <typename T> Print &operator<<(T const &value) { template <typename T> Print &operator<<(T const &value) {
...@@ -66,9 +66,9 @@ namespace paddle_mobile { ...@@ -66,9 +66,9 @@ namespace paddle_mobile {
} }
} }
std::ostringstream buffer_; std::ostringstream buffer_;
}; };
struct ToLog { struct ToLog {
ToLog(LogLevel level = kLOG_DEBUG, const std::string &info = "") ToLog(LogLevel level = kLOG_DEBUG, const std::string &info = "")
: level_(level) { : level_(level) {
unsigned blanks = unsigned blanks =
...@@ -87,16 +87,16 @@ namespace paddle_mobile { ...@@ -87,16 +87,16 @@ namespace paddle_mobile {
private: private:
LogLevel level_; LogLevel level_;
Print printer_; Print printer_;
}; };
#define LOG(level) \ #define LOG(level) \
if (level > paddle_mobile::log_level) { \ if (level > paddle_mobile::log_level) { \
} else \ } else \
paddle_mobile::ToLog( \ paddle_mobile::ToLog( \
level, \ level, (std::stringstream() \
(std::stringstream() \
<< "[file: " \ << "[file: " \
<< (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1) : __FILE__) \ << (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1) \
: __FILE__) \
<< "] [line: " << __LINE__ << "] ") \ << "] [line: " << __LINE__ << "] ") \
.str()) .str())
...@@ -107,10 +107,11 @@ namespace paddle_mobile { ...@@ -107,10 +107,11 @@ namespace paddle_mobile {
paddle_mobile::kLOG_DEBUG, \ paddle_mobile::kLOG_DEBUG, \
(std::stringstream() \ (std::stringstream() \
<< "[file: " \ << "[file: " \
<< (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1) : __FILE__) \ << (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1) \
: __FILE__) \
<< "] [line: " << __LINE__ << "] ") \ << "] [line: " << __LINE__ << "] ") \
.str()) .str())
} } // namespace paddle_mobile
#define LOGF(level, format, ...) \ #define LOGF(level, format, ...) \
if (level > paddle_mobile::log_level) { \ if (level > paddle_mobile::log_level) { \
...@@ -126,7 +127,7 @@ namespace paddle_mobile { ...@@ -126,7 +127,7 @@ namespace paddle_mobile {
namespace paddle_mobile { namespace paddle_mobile {
enum LogLevel { enum LogLevel {
kNO_LOG, kNO_LOG,
kLOG_ERROR, kLOG_ERROR,
kLOG_WARNING, kLOG_WARNING,
...@@ -136,23 +137,21 @@ namespace paddle_mobile { ...@@ -136,23 +137,21 @@ namespace paddle_mobile {
kLOG_DEBUG2, kLOG_DEBUG2,
kLOG_DEBUG3, kLOG_DEBUG3,
kLOG_DEBUG4 kLOG_DEBUG4
}; };
struct ToLog; struct ToLog;
struct Print { struct Print {
friend struct ToLog; friend struct ToLog;
template <typename T> Print &operator<<(T const &value) {} template <typename T> Print &operator<<(T const &value) {}
private: private:
}; };
struct ToLog { struct ToLog {
ToLog(LogLevel level) {} ToLog(LogLevel level) {}
template <typename T> ToLog &operator<<(T const &value) { template <typename T> ToLog &operator<<(T const &value) { return *this; }
return *this; };
}
};
#define LOG(level) \ #define LOG(level) \
if (true) { \ if (true) { \
...@@ -167,6 +166,6 @@ namespace paddle_mobile { ...@@ -167,6 +166,6 @@ namespace paddle_mobile {
#define LOGF(level, format, ...) #define LOGF(level, format, ...)
#define DLOGF(format, ...) #define DLOGF(format, ...)
} } // namespace paddle_mobile
#endif #endif
...@@ -23,31 +23,30 @@ SOFTWARE. ...@@ -23,31 +23,30 @@ SOFTWARE.
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
template <typename Dtype> class OperatorBase; template <typename Dtype> class OperatorBase;
class OpDesc; class OpDesc;
class BlockDesc; class BlockDesc;
class InferShapeContext; class InferShapeContext;
} } // namespace framework
using VariableNameMap = std::map<std::string, std::vector<std::string>>; using VariableNameMap = std::map<std::string, std::vector<std::string>>;
template <typename Dtype> template <typename Dtype>
using OpCreator = std::function<framework::OperatorBase<Dtype> *( using OpCreator = std::function<framework::OperatorBase<Dtype> *(
const std::string & /*type*/, const VariableNameMap & /*inputs*/, const std::string & /*type*/, const VariableNameMap & /*inputs*/,
const VariableNameMap & /*outputs*/, const VariableNameMap & /*outputs*/,
const framework::AttributeMap & /*attrs*/)>; const framework::AttributeMap & /*attrs*/)>;
using GradOpMakerFN = using GradOpMakerFN =
std::function<std::vector<std::unique_ptr<framework::OpDesc>>( std::function<std::vector<std::unique_ptr<framework::OpDesc>>(
const framework::OpDesc &, const framework::OpDesc &,
const std::unordered_set<std::string> & /*no_grad_set*/, const std::unordered_set<std::string> & /*no_grad_set*/,
std::unordered_map<std::string, std::string> * /*grad_to_var*/, std::unordered_map<std::string, std::string> * /*grad_to_var*/,
const std::vector<framework::BlockDesc *> &grad_block)>; const std::vector<framework::BlockDesc *> &grad_block)>;
using InferVarTypeFN = using InferVarTypeFN = std::function<void(const framework::OpDesc & /*op_desc*/,
std::function<void(const framework::OpDesc & /*op_desc*/,
framework::BlockDesc * /*block*/)>; framework::BlockDesc * /*block*/)>;
using InferShapeFN = std::function<void(framework::InferShapeContext *)>; using InferShapeFN = std::function<void(framework::InferShapeContext *)>;
}; }; // namespace paddle_mobile
...@@ -19,19 +19,19 @@ SOFTWARE. ...@@ -19,19 +19,19 @@ SOFTWARE.
#pragma once; #pragma once;
namespace paddle_mobile { namespace paddle_mobile {
enum class Precision : int { FP32 = 0 }; enum class Precision : int { FP32 = 0 };
//! device type //! device type
enum DeviceTypeEnum { kINVALID = -1, kCPU = 0, kFPGA = 1, kGPU_MALI = 2 }; enum DeviceTypeEnum { kINVALID = -1, kCPU = 0, kFPGA = 1, kGPU_MALI = 2 };
template <DeviceTypeEnum T> struct DeviceType {}; template <DeviceTypeEnum T> struct DeviceType {};
typedef DeviceType<kCPU> CPU; typedef DeviceType<kCPU> CPU;
typedef DeviceType<kFPGA> FPGA; typedef DeviceType<kFPGA> FPGA;
typedef DeviceType<kGPU_MALI> GPU_MALI; typedef DeviceType<kGPU_MALI> GPU_MALI;
//! data type //! data type
enum DataType { enum DataType {
PM_INVALID = -1, PM_INVALID = -1,
PM_HALF = 0, PM_HALF = 0,
PM_FLOAT = 1, PM_FLOAT = 1,
...@@ -47,9 +47,9 @@ namespace paddle_mobile { ...@@ -47,9 +47,9 @@ namespace paddle_mobile {
PM_BOOL = 11, PM_BOOL = 11,
PM_SHAPE = 12, PM_SHAPE = 12,
PM_TENSOR = 13 PM_TENSOR = 13
}; };
//! //!
enum PMStatus { enum PMStatus {
PMSuccess = 0xFF, /*!< No errors */ PMSuccess = 0xFF, /*!< No errors */
PMNotInitialized = 0x01, /*!< Data not initialized. */ PMNotInitialized = 0x01, /*!< Data not initialized. */
PMInvalidValue = 0x02, /*!< Incorrect variable value. */ PMInvalidValue = 0x02, /*!< Incorrect variable value. */
...@@ -59,5 +59,5 @@ namespace paddle_mobile { ...@@ -59,5 +59,5 @@ namespace paddle_mobile {
PMOutOfMem = 0x06, /*!< OOM error*/ PMOutOfMem = 0x06, /*!< OOM error*/
PMUnImplError = 0x07, /*!< Unimplement error. */ PMUnImplError = 0x07, /*!< Unimplement error. */
PMWrongDevice = 0x08 /*!< un-correct device. */ PMWrongDevice = 0x08 /*!< un-correct device. */
}; };
} } // namespace paddle_mobile
...@@ -15,5 +15,3 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ...@@ -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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
==============================================================================*/ ==============================================================================*/
#include "variant.h"
...@@ -21,9 +21,9 @@ SOFTWARE. ...@@ -21,9 +21,9 @@ SOFTWARE.
#pragma once #pragma once
namespace paddle_mobile { namespace paddle_mobile {
template <int ID, typename Type> struct IDToType { typedef Type type_t; }; template <int ID, typename Type> struct IDToType { typedef Type type_t; };
template <typename F, typename... Ts> struct VariantHelper { template <typename F, typename... Ts> struct VariantHelper {
static const size_t size = sizeof(F) > VariantHelper<Ts...>::size static const size_t size = sizeof(F) > VariantHelper<Ts...>::size
? sizeof(F) ? sizeof(F)
: VariantHelper<Ts...>::size; : VariantHelper<Ts...>::size;
...@@ -35,9 +35,9 @@ namespace paddle_mobile { ...@@ -35,9 +35,9 @@ namespace paddle_mobile {
VariantHelper<Ts...>::Destroy(id, data); VariantHelper<Ts...>::Destroy(id, data);
} }
} }
}; };
template <typename F> struct VariantHelper<F> { template <typename F> struct VariantHelper<F> {
static const size_t size = sizeof(F); static const size_t size = sizeof(F);
inline static void Destroy(size_t id, void *data) { inline static void Destroy(size_t id, void *data) {
if (id == typeid(F).hash_code()) { if (id == typeid(F).hash_code()) {
...@@ -46,9 +46,9 @@ namespace paddle_mobile { ...@@ -46,9 +46,9 @@ namespace paddle_mobile {
// std::cout << "未匹配到 " << std::endl; // std::cout << "未匹配到 " << std::endl;
} }
} }
}; };
template <size_t size> class RawData { template <size_t size> class RawData {
public: public:
char data[size]; char data[size];
RawData() {} RawData() {}
...@@ -56,9 +56,9 @@ namespace paddle_mobile { ...@@ -56,9 +56,9 @@ namespace paddle_mobile {
// void operator=(const RawData &raw_data){ // void operator=(const RawData &raw_data){
// strcpy(data, raw_data.data); // strcpy(data, raw_data.data);
// } // }
}; };
template <typename... Ts> struct Variant { template <typename... Ts> struct Variant {
Variant(const Variant &variant) { Variant(const Variant &variant) {
// std::cout << " 赋值构造函数 " << std::endl; // std::cout << " 赋值构造函数 " << std::endl;
type_id = variant.type_id; type_id = variant.type_id;
...@@ -92,8 +92,8 @@ namespace paddle_mobile { ...@@ -92,8 +92,8 @@ namespace paddle_mobile {
typedef VariantHelper<Ts...> helper; typedef VariantHelper<Ts...> helper;
size_t type_id; size_t type_id;
RawData<helper::size> data; RawData<helper::size> data;
}; };
template <typename T> struct Vistor { typedef T type_t; }; template <typename T> struct Vistor { typedef T type_t; };
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -16,8 +16,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ...@@ -16,8 +16,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
==============================================================================*/ ==============================================================================*/
#include "attribute.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework {} namespace framework {}
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -22,14 +22,13 @@ SOFTWARE. ...@@ -22,14 +22,13 @@ SOFTWARE.
#include "framework.pb.h" #include "framework.pb.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
class BlockDesc; class BlockDesc;
class Attribute { class Attribute {
public: public:
static Attribute static Attribute GetAttrValue(const proto::OpDesc::Attr &attr_desc) {
GetAttrValue(const proto::OpDesc::Attr &attr_desc) {
// std::cout << "begin get attr value" << std::endl; // std::cout << "begin get attr value" << std::endl;
Attribute attr; Attribute attr;
switch (attr_desc.type()) { switch (attr_desc.type()) {
...@@ -94,8 +93,7 @@ namespace paddle_mobile { ...@@ -94,8 +93,7 @@ namespace paddle_mobile {
} }
Attribute() {} Attribute() {}
template <typename T, typename... Args> template <typename T, typename... Args> Attribute &Set(Args &&... args) {
Attribute &Set(Args &&... args) {
variant_.Set<T>(args...); variant_.Set<T>(args...);
return *this; return *this;
} }
...@@ -103,15 +101,15 @@ namespace paddle_mobile { ...@@ -103,15 +101,15 @@ namespace paddle_mobile {
template <typename T> T &Get() const { return variant_.Get<T>(); } template <typename T> T &Get() const { return variant_.Get<T>(); }
private: private:
Variant<int, float, std::string, std::vector<int>, Variant<int, float, std::string, std::vector<int>, std::vector<float>,
std::vector<float>, std::vector<std::string>, bool, std::vector<std::string>, bool, std::vector<bool>, BlockDesc *,
std::vector<bool>, BlockDesc *, int64_t> int64_t>
variant_; variant_;
}; };
using AttributeMap = std::unordered_map<std::string, Attribute>; using AttributeMap = std::unordered_map<std::string, Attribute>;
class AttrReader { class AttrReader {
public: public:
explicit AttrReader(const AttributeMap &attrs) : attrs_(attrs) {} explicit AttrReader(const AttributeMap &attrs) : attrs_(attrs) {}
...@@ -125,7 +123,7 @@ namespace paddle_mobile { ...@@ -125,7 +123,7 @@ namespace paddle_mobile {
private: private:
const AttributeMap &attrs_; const AttributeMap &attrs_;
}; };
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -19,32 +19,32 @@ SOFTWARE. ...@@ -19,32 +19,32 @@ SOFTWARE.
#include "block_desc.h" #include "block_desc.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
std::vector<std::shared_ptr<VarDesc>> BlockDesc::Vars() const { std::vector<std::shared_ptr<VarDesc>> BlockDesc::Vars() const {
std::vector<std::shared_ptr<VarDesc>> res; std::vector<std::shared_ptr<VarDesc>> res;
for (const auto &p : vars_) { for (const auto &p : vars_) {
res.push_back(p.second); res.push_back(p.second);
} }
return res; return res;
} }
std::vector<std::shared_ptr<OpDesc>> BlockDesc::Ops() const { std::vector<std::shared_ptr<OpDesc>> BlockDesc::Ops() const {
std::vector<std::shared_ptr<OpDesc>> res; std::vector<std::shared_ptr<OpDesc>> res;
for (const auto &op : ops_) { for (const auto &op : ops_) {
res.push_back(op); res.push_back(op);
} }
return res; return res;
} }
BlockDesc::BlockDesc(const proto::BlockDesc &desc) : desc_(desc) { BlockDesc::BlockDesc(const proto::BlockDesc &desc) : desc_(desc) {
for (const proto::VarDesc &var_desc : desc_.vars()) { for (const proto::VarDesc &var_desc : desc_.vars()) {
vars_[var_desc.name()].reset(new VarDesc(var_desc)); vars_[var_desc.name()].reset(new VarDesc(var_desc));
} }
for (const proto::OpDesc &op_desc : desc_.ops()) { for (const proto::OpDesc &op_desc : desc_.ops()) {
ops_.emplace_back(new framework::OpDesc(op_desc)); ops_.emplace_back(new framework::OpDesc(op_desc));
} }
} }
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -24,9 +24,9 @@ SOFTWARE. ...@@ -24,9 +24,9 @@ SOFTWARE.
#include "var_desc.h" #include "var_desc.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
class BlockDesc : PaddleMobileObject { class BlockDesc : PaddleMobileObject {
public: public:
BlockDesc(const proto::BlockDesc &desc); BlockDesc(const proto::BlockDesc &desc);
...@@ -34,16 +34,13 @@ namespace paddle_mobile { ...@@ -34,16 +34,13 @@ namespace paddle_mobile {
const int &Parent() const { return desc_.parent_idx(); } const int &Parent() const { return desc_.parent_idx(); }
bool operator==( bool operator==(const paddle_mobile::framework::BlockDesc &in_block) const {
const paddle_mobile::framework::BlockDesc &in_block) const {
return this->ID() == in_block.ID() && return this->ID() == in_block.ID() &&
this->Parent() == in_block.Parent(); this->Parent() == in_block.Parent();
} }
bool operator<( bool operator<(const paddle_mobile::framework::BlockDesc &in_block) const {
const paddle_mobile::framework::BlockDesc &in_block) const { return this->ID() < in_block.ID() && this->Parent() < in_block.Parent();
return this->ID() < in_block.ID() &&
this->Parent() < in_block.Parent();
} }
std::vector<std::shared_ptr<VarDesc>> Vars() const; std::vector<std::shared_ptr<VarDesc>> Vars() const;
...@@ -53,14 +50,14 @@ namespace paddle_mobile { ...@@ -53,14 +50,14 @@ namespace paddle_mobile {
proto::BlockDesc desc_; proto::BlockDesc desc_;
std::vector<std::shared_ptr<OpDesc>> ops_; std::vector<std::shared_ptr<OpDesc>> ops_;
std::unordered_map<std::string, std::shared_ptr<VarDesc>> vars_; std::unordered_map<std::string, std::shared_ptr<VarDesc>> vars_;
}; };
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
namespace std { namespace std {
template <> struct hash<paddle_mobile::framework::BlockDesc> { template <> struct hash<paddle_mobile::framework::BlockDesc> {
typedef paddle_mobile::framework::BlockDesc argument_type; typedef paddle_mobile::framework::BlockDesc argument_type;
typedef std::size_t result_type; typedef std::size_t result_type;
result_type operator()(argument_type const &s) const noexcept { result_type operator()(argument_type const &s) const noexcept {
...@@ -68,6 +65,6 @@ namespace std { ...@@ -68,6 +65,6 @@ namespace std {
result_type const h2(std::hash<int>{}(s.ID())); result_type const h2(std::hash<int>{}(s.ID()));
return h1 ^ (h2 << 1); return h1 ^ (h2 << 1);
} }
}; };
} // namespace std } // namespace std
...@@ -19,15 +19,15 @@ limitations under the License. */ ...@@ -19,15 +19,15 @@ limitations under the License. */
#include <string> #include <string>
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
enum class DataLayout { enum class DataLayout {
kNHWC = 0, kNHWC = 0,
kNCHW = 1, kNCHW = 1,
kAnyLayout = 2, kAnyLayout = 2,
}; };
inline DataLayout StringToDataLayout(const std::string &str) { inline DataLayout StringToDataLayout(const std::string &str) {
std::string s(str); std::string s(str);
for (size_t i = 0; i < s.size(); ++i) { for (size_t i = 0; i < s.size(); ++i) {
s[i] = toupper(s[i]); s[i] = toupper(s[i]);
...@@ -42,9 +42,9 @@ namespace paddle_mobile { ...@@ -42,9 +42,9 @@ namespace paddle_mobile {
} else { } else {
// std::cout << "Unknown storage order string: %s", s; // std::cout << "Unknown storage order string: %s", s;
} }
} }
inline std::string DataLayoutToString(const DataLayout &data_layout) { inline std::string DataLayoutToString(const DataLayout &data_layout) {
switch (data_layout) { switch (data_layout) {
case DataLayout::kNHWC: case DataLayout::kNHWC:
return "NHWC"; return "NHWC";
...@@ -56,13 +56,12 @@ namespace paddle_mobile { ...@@ -56,13 +56,12 @@ namespace paddle_mobile {
break; break;
// std::cout << "unknown DataLayou %d", data_layout; // std::cout << "unknown DataLayou %d", data_layout;
} }
} }
inline std::ostream &operator<<(std::ostream &out, inline std::ostream &operator<<(std::ostream &out, const DataLayout &l) {
const DataLayout &l) {
out << DataLayoutToString(l); out << DataLayoutToString(l);
return out; return out;
} }
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -21,14 +21,14 @@ SOFTWARE. ...@@ -21,14 +21,14 @@ SOFTWARE.
#include "data_transform.h" #include "data_transform.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
static void PassTensorData(Tensor *from, Tensor *to) { static void PassTensorData(Tensor *from, Tensor *to) {
to->ShareDataWith(*from); to->ShareDataWith(*from);
*from = Tensor(); *from = Tensor();
} }
void DataTransform(const OpKernelType &expected_kernel_type, void DataTransform(const OpKernelType &expected_kernel_type,
const OpKernelType &kernel_type_for_var, const OpKernelType &kernel_type_for_var,
const Tensor &input_tensor, Tensor *output_tensor) { const Tensor &input_tensor, Tensor *output_tensor) {
bool transformed = false; bool transformed = false;
...@@ -66,10 +66,10 @@ namespace paddle_mobile { ...@@ -66,10 +66,10 @@ namespace paddle_mobile {
// check!"); // check!");
// get output data // get output data
output_tensor->ShareDataWith(in); output_tensor->ShareDataWith(in);
} }
void CopyVariableWithTensor(const Variable &in_var, void CopyVariableWithTensor(const Variable &in_var, const Tensor &tensor,
const Tensor &tensor, Variable &out_var) { Variable &out_var) {
// if (in_var.IsType<LoDTensor>()) { // if (in_var.IsType<LoDTensor>()) {
// auto& in_lod_tensor = in_var.Get<LoDTensor>(); // auto& in_lod_tensor = in_var.Get<LoDTensor>();
// auto* tran_lod_tensor = out_var.GetMutable<LoDTensor>(); // auto* tran_lod_tensor = out_var.GetMutable<LoDTensor>();
...@@ -86,7 +86,7 @@ namespace paddle_mobile { ...@@ -86,7 +86,7 @@ namespace paddle_mobile {
// } else { // } else {
// PADDLE_THROW("unknown var type"); // PADDLE_THROW("unknown var type");
// } // }
} }
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -28,14 +28,14 @@ SOFTWARE. ...@@ -28,14 +28,14 @@ SOFTWARE.
#include "variable.h" #include "variable.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
void DataTransform(const OpKernelType &expected_kernel_type, void DataTransform(const OpKernelType &expected_kernel_type,
const OpKernelType &kernel_type_for_var, const OpKernelType &kernel_type_for_var,
const Tensor &input_tensor, Tensor *out); const Tensor &input_tensor, Tensor *out);
void CopyVariableWithTensor(const Variable &in_var, void CopyVariableWithTensor(const Variable &in_var, const Tensor &tensor,
const Tensor &tensor, Variable &out_var); Variable &out_var);
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -21,23 +21,23 @@ SOFTWARE. ...@@ -21,23 +21,23 @@ SOFTWARE.
#include "framework.pb.h" #include "framework.pb.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
// inline proto::VarType::Type ToDataType(std::type_index type) { // inline proto::VarType::Type ToDataType(std::type_index type) {
// using namespace paddle_mobile::framework::proto; // using namespace paddle_mobile::framework::proto;
// if (typeid(float).hash_code() == type.hash_code()) { // if (typeid(float).hash_code() == type.hash_code()) {
// return proto::VarType::FP32; // return proto::VarType::FP32;
// } else if (typeid(double).hash_code() == type.hash_code()) { // } else if (typeid(double).hash_code() == type.hash_code()) {
// return proto::VarType::FP64; // return proto::VarType::FP64;
// } else if (typeid(int).hash_code() == type.hash_code()) { // } else if (typeid(int).hash_code() == type.hash_code()) {
// return proto::VarType::INT32; // return proto::VarType::INT32;
// } else if (typeid(int64_t).hash_code() == type.hash_code()) { // } else if (typeid(int64_t).hash_code() == type.hash_code()) {
// return proto::VarType::INT64; // return proto::VarType::INT64;
// } else if (typeid(bool).hash_code() == type.hash_code()) { // } else if (typeid(bool).hash_code() == type.hash_code()) {
// return proto::VarType::BOOL; // return proto::VarType::BOOL;
// } else { // } else {
//// PADDLE_THROW("Not supported"); //// PADDLE_THROW("Not supported");
// } // }
// } // }
} }
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -15,17 +15,17 @@ limitations under the License. */ ...@@ -15,17 +15,17 @@ limitations under the License. */
#include "ddim.h" #include "ddim.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
/// @cond HIDDEN /// @cond HIDDEN
template <int i> Dim<i> make_dim(const int64_t *d) { template <int i> Dim<i> make_dim(const int64_t *d) {
return Dim<i>(*d, make_dim<i - 1>(d + 1)); return Dim<i>(*d, make_dim<i - 1>(d + 1));
} }
template <> Dim<0> make_dim<0>(const int64_t *d) { return Dim<0>(*d); } template <> Dim<0> make_dim<0>(const int64_t *d) { return Dim<0>(*d); }
void make_ddim(DDim &ddim, const int64_t *dims, int n) { void make_ddim(DDim &ddim, const int64_t *dims, int n) {
switch (n) { switch (n) {
case 0: case 0:
ddim = make_dim<0>(dims); ddim = make_dim<0>(dims);
...@@ -63,33 +63,33 @@ namespace paddle_mobile { ...@@ -63,33 +63,33 @@ namespace paddle_mobile {
// dimensions."; // dimensions.";
break; break;
} }
} }
/// @endcond /// @endcond
DDim make_ddim(std::initializer_list<int64_t> dims) { DDim make_ddim(std::initializer_list<int64_t> dims) {
DDim result(make_dim(0)); DDim result(make_dim(0));
make_ddim(result, dims.begin(), dims.size()); make_ddim(result, dims.begin(), dims.size());
return result; return result;
} }
DDim make_ddim(const std::vector<int64_t> &dims) { DDim make_ddim(const std::vector<int64_t> &dims) {
DDim result(make_dim(0)); DDim result(make_dim(0));
make_ddim(result, &dims[0], dims.size()); make_ddim(result, &dims[0], dims.size());
return result; return result;
} }
DDim make_ddim(const std::vector<int> &dims) { DDim make_ddim(const std::vector<int> &dims) {
std::vector<int64_t> res(dims.size()); std::vector<int64_t> res(dims.size());
std::transform(dims.begin(), dims.end(), res.begin(), std::transform(dims.begin(), dims.end(), res.begin(),
[](int d) { return static_cast<int64_t>(d); }); [](int d) { return static_cast<int64_t>(d); });
return make_ddim(res); return make_ddim(res);
} }
/// @cond HIDDEN /// @cond HIDDEN
// XXX For some reason, putting this in an anonymous namespace causes // XXX For some reason, putting this in an anonymous namespace causes
// errors // errors
struct DynamicMutableIndexer : Vistor<int64_t &> { struct DynamicMutableIndexer : Vistor<int64_t &> {
public: public:
explicit DynamicMutableIndexer(int idx) : idx_(idx) {} explicit DynamicMutableIndexer(int idx) : idx_(idx) {}
...@@ -99,9 +99,9 @@ namespace paddle_mobile { ...@@ -99,9 +99,9 @@ namespace paddle_mobile {
private: private:
int idx_; int idx_;
}; };
struct DynamicConstIndexer : public Vistor<int64_t> { struct DynamicConstIndexer : public Vistor<int64_t> {
public: public:
explicit DynamicConstIndexer(int idx) : idx_(idx) {} explicit DynamicConstIndexer(int idx) : idx_(idx) {}
...@@ -111,21 +111,21 @@ namespace paddle_mobile { ...@@ -111,21 +111,21 @@ namespace paddle_mobile {
private: private:
int idx_; int idx_;
}; };
/// @endcond /// @endcond
int64_t &DDim::operator[](int idx) { int64_t &DDim::operator[](int idx) {
return DDim::ApplyVistor(DynamicMutableIndexer(idx), *this); return DDim::ApplyVistor(DynamicMutableIndexer(idx), *this);
} }
int64_t DDim::operator[](int idx) const { int64_t DDim::operator[](int idx) const {
return DDim::ApplyVistor(DynamicConstIndexer(idx), *this); return DDim::ApplyVistor(DynamicConstIndexer(idx), *this);
} }
int DDim::size() const { return arity(*this); } int DDim::size() const { return arity(*this); }
bool DDim::operator==(DDim d) const { bool DDim::operator==(DDim d) const {
// if (var.which() != d.getVar().which()) { // if (var.which() != d.getVar().which()) {
// return false; // return false;
// } else { // } else {
...@@ -140,11 +140,11 @@ namespace paddle_mobile { ...@@ -140,11 +140,11 @@ namespace paddle_mobile {
return true; return true;
// } // }
} }
bool DDim::operator!=(DDim d) const { return !(*this == d); } bool DDim::operator!=(DDim d) const { return !(*this == d); }
DDim DDim::operator+(DDim d) const { DDim DDim::operator+(DDim d) const {
std::vector<int64_t> v1 = vectorize(*this); std::vector<int64_t> v1 = vectorize(*this);
std::vector<int64_t> v2 = vectorize(d); std::vector<int64_t> v2 = vectorize(d);
...@@ -157,9 +157,9 @@ namespace paddle_mobile { ...@@ -157,9 +157,9 @@ namespace paddle_mobile {
} }
return make_ddim(v3); return make_ddim(v3);
} }
DDim DDim::operator*(DDim d) const { DDim DDim::operator*(DDim d) const {
std::vector<int64_t> v1 = vectorize(*this); std::vector<int64_t> v1 = vectorize(*this);
std::vector<int64_t> v2 = vectorize(d); std::vector<int64_t> v2 = vectorize(d);
...@@ -172,14 +172,14 @@ namespace paddle_mobile { ...@@ -172,14 +172,14 @@ namespace paddle_mobile {
} }
return make_ddim(v3); return make_ddim(v3);
} }
int64_t get(const DDim &ddim, int idx) { return ddim[idx]; } int64_t get(const DDim &ddim, int idx) { return ddim[idx]; }
void set(DDim &ddim, int idx, int value) { ddim[idx] = value; } void set(DDim &ddim, int idx, int value) { ddim[idx] = value; }
/// @cond HIDDEN /// @cond HIDDEN
struct VectorizeVisitor : Vistor<void> { struct VectorizeVisitor : Vistor<void> {
std::vector<int64_t> &vector; std::vector<int64_t> &vector;
explicit VectorizeVisitor(std::vector<int64_t> &v) : vector(v) {} explicit VectorizeVisitor(std::vector<int64_t> &v) : vector(v) {}
...@@ -190,36 +190,36 @@ namespace paddle_mobile { ...@@ -190,36 +190,36 @@ namespace paddle_mobile {
} }
void operator()(const Dim<0> &t) {} void operator()(const Dim<0> &t) {}
}; };
/// @endcond /// @endcond
std::vector<int64_t> vectorize(const DDim &ddim) { std::vector<int64_t> vectorize(const DDim &ddim) {
std::vector<int64_t> result; std::vector<int64_t> result;
VectorizeVisitor visitor(result); VectorizeVisitor visitor(result);
DDim::ApplyVistor(visitor, ddim); DDim::ApplyVistor(visitor, ddim);
return result; return result;
} }
// NOTE: framework::vectorize converts to type int64_t // NOTE: framework::vectorize converts to type int64_t
// which does not fit cudnn inputs. // which does not fit cudnn inputs.
std::vector<int> vectorize2int(const DDim &ddim) { std::vector<int> vectorize2int(const DDim &ddim) {
std::vector<int64_t> temp = vectorize(ddim); std::vector<int64_t> temp = vectorize(ddim);
std::vector<int> result(temp.begin(), temp.end()); std::vector<int> result(temp.begin(), temp.end());
return result; return result;
} }
struct ProductVisitor : Vistor<int64_t> { struct ProductVisitor : Vistor<int64_t> {
template <int D> int64_t operator()(const Dim<D> &dim) { template <int D> int64_t operator()(const Dim<D> &dim) {
return product(dim); return product(dim);
} }
}; };
int64_t product(const DDim &ddim) { int64_t product(const DDim &ddim) {
ProductVisitor visitor; ProductVisitor visitor;
return DDim::ApplyVistor(visitor, ddim); return DDim::ApplyVistor(visitor, ddim);
} }
struct SliceVectorizeVisitor : Vistor<void> { struct SliceVectorizeVisitor : Vistor<void> {
std::vector<int64_t> &vector; std::vector<int64_t> &vector;
int begin; int begin;
int end; int end;
...@@ -251,9 +251,9 @@ namespace paddle_mobile { ...@@ -251,9 +251,9 @@ namespace paddle_mobile {
// PADDLE_ENFORCE(end == 0, "End index in ddim slice is out // PADDLE_ENFORCE(end == 0, "End index in ddim slice is out
// of bound."); // of bound.");
} }
}; };
DDim slice_ddim(const DDim &ddim, int begin, int end) { DDim slice_ddim(const DDim &ddim, int begin, int end) {
std::vector<int64_t> vec; std::vector<int64_t> vec;
vec.reserve(end - begin); vec.reserve(end - begin);
SliceVectorizeVisitor visitor(vec, begin, end); SliceVectorizeVisitor visitor(vec, begin, end);
...@@ -261,27 +261,27 @@ namespace paddle_mobile { ...@@ -261,27 +261,27 @@ namespace paddle_mobile {
DDim::ApplyVistor(visitor, ddim); DDim::ApplyVistor(visitor, ddim);
// visitor(ddim.var.Get<Dim<4>>()); // visitor(ddim.var.Get<Dim<4>>());
return make_ddim(vec); return make_ddim(vec);
} }
/// \cond HIDDEN /// \cond HIDDEN
struct ArityVisitor : Vistor<int> { struct ArityVisitor : Vistor<int> {
template <int D> int operator()(Dim<D>) const { return D; } template <int D> int operator()(Dim<D>) const { return D; }
}; };
/// \endcond /// \endcond
int arity(const DDim &d) { int arity(const DDim &d) {
ArityVisitor arityVisitor = ArityVisitor(); ArityVisitor arityVisitor = ArityVisitor();
return DDim::ApplyVistor(arityVisitor, d); return DDim::ApplyVistor(arityVisitor, d);
// return arityVisitor(d.var.Get<Dim<4>>()); // return arityVisitor(d.var.Get<Dim<4>>());
// return boost::apply_visitor(ArityVisitor(), d); } // return boost::apply_visitor(ArityVisitor(), d); }
} }
/// \cond HIDDEN /// \cond HIDDEN
/// \endcond /// \endcond
struct OSVistor : Vistor<std::ostream &> { struct OSVistor : Vistor<std::ostream &> {
OSVistor(std::ostream &os) : os_(os) {} OSVistor(std::ostream &os) : os_(os) {}
template <int D> std::ostream &operator()(Dim<D> dim) const { template <int D> std::ostream &operator()(Dim<D> dim) const {
...@@ -290,45 +290,43 @@ namespace paddle_mobile { ...@@ -290,45 +290,43 @@ namespace paddle_mobile {
private: private:
std::ostream &os_; std::ostream &os_;
}; };
std::ostream &operator<<(std::ostream &os, const DDim &ddim) { std::ostream &operator<<(std::ostream &os, const DDim &ddim) {
auto vistor = OSVistor(os); auto vistor = OSVistor(os);
DDim::ApplyVistor(vistor, ddim); DDim::ApplyVistor(vistor, ddim);
return os; return os;
} }
DDim::DDim(std::initializer_list<int64_t> init_list) { DDim::DDim(std::initializer_list<int64_t> init_list) {
*this = make_ddim(init_list); *this = make_ddim(init_list);
} }
DDim flatten_to_2d(const DDim &src, int num_col_dims) { DDim flatten_to_2d(const DDim &src, int num_col_dims) {
int rank = src.size(); int rank = src.size();
return make_ddim({product(slice_ddim(src, 0, num_col_dims)), return make_ddim({product(slice_ddim(src, 0, num_col_dims)),
product(slice_ddim(src, num_col_dims, rank))}); product(slice_ddim(src, num_col_dims, rank))});
} }
DDim flatten_to_1d(const DDim &src) { DDim flatten_to_1d(const DDim &src) { return make_ddim({product(src)}); }
return make_ddim({product(src)});
}
DDim stride(const DDim &ddim) { DDim stride(const DDim &ddim) {
std::vector<int64_t> strides(ddim.size()); std::vector<int64_t> strides(ddim.size());
strides[ddim.size() - 1] = 1; strides[ddim.size() - 1] = 1;
for (int i = ddim.size() - 2; i >= 0; --i) { for (int i = ddim.size() - 2; i >= 0; --i) {
strides[i] = strides[i + 1] * ddim[i + 1]; strides[i] = strides[i + 1] * ddim[i + 1];
} }
return framework::make_ddim(strides); return framework::make_ddim(strides);
} }
DDim stride_numel(const framework::DDim &ddim) { DDim stride_numel(const framework::DDim &ddim) {
std::vector<int64_t> strides(ddim.size()); std::vector<int64_t> strides(ddim.size());
strides[ddim.size() - 1] = ddim[ddim.size() - 1]; strides[ddim.size() - 1] = ddim[ddim.size() - 1];
for (int i = ddim.size() - 2; i >= 0; --i) { for (int i = ddim.size() - 2; i >= 0; --i) {
strides[i] = strides[i + 1] * ddim[i]; strides[i] = strides[i + 1] * ddim[i];
} }
return framework::make_ddim(strides); return framework::make_ddim(strides);
} }
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -22,22 +22,21 @@ limitations under the License. */ ...@@ -22,22 +22,21 @@ limitations under the License. */
#include <vector> #include <vector>
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
/** /**
* \brief A dynamically sized dimension. * \brief A dynamically sized dimension.
* *
* The number of dimensions must be between [1, 9]. * The number of dimensions must be between [1, 9].
*/ */
struct DDim { struct DDim {
typedef Variant<Dim<0>, Dim<1>, Dim<2>, Dim<3>, Dim<4>, Dim<5>, typedef Variant<Dim<0>, Dim<1>, Dim<2>, Dim<3>, Dim<4>, Dim<5>, Dim<6>,
Dim<6>, Dim<7>, Dim<8>, Dim<9>> Dim<7>, Dim<8>, Dim<9>>
DDimVar; DDimVar;
DDimVar var; DDimVar var;
template <typename Vistor> template <typename Vistor>
static typename Vistor::type_t ApplyVistor(Vistor vistor, static typename Vistor::type_t ApplyVistor(Vistor vistor, const DDim &d) {
const DDim &d) {
if (d.var.TypeId() == typeid(Dim<0>).hash_code()) { if (d.var.TypeId() == typeid(Dim<0>).hash_code()) {
return vistor(d.var.Get<Dim<0>>()); return vistor(d.var.Get<Dim<0>>());
} else if (d.var.TypeId() == typeid(Dim<1>).hash_code()) { } else if (d.var.TypeId() == typeid(Dim<1>).hash_code()) {
...@@ -67,9 +66,7 @@ namespace paddle_mobile { ...@@ -67,9 +66,7 @@ namespace paddle_mobile {
DDim() { var.Set<Dim<1>>(Dim<1>()); } DDim() { var.Set<Dim<1>>(Dim<1>()); }
template <int D> explicit DDim(const Dim<D> &in) { template <int D> explicit DDim(const Dim<D> &in) { var.Set<Dim<D>>(in); }
var.Set<Dim<D>>(in);
}
/*implicit*/ DDim(std::initializer_list<int64_t> init_list); /*implicit*/ DDim(std::initializer_list<int64_t> init_list);
...@@ -104,63 +101,63 @@ namespace paddle_mobile { ...@@ -104,63 +101,63 @@ namespace paddle_mobile {
DDim operator*(DDim d) const; DDim operator*(DDim d) const;
int size() const; int size() const;
}; };
/** /**
* \brief Make a DDim from std::vector<int64_t> * \brief Make a DDim from std::vector<int64_t>
* *
* \param dims An vector of ints. Must be sized between [1, 9] * \param dims An vector of ints. Must be sized between [1, 9]
*/ */
DDim make_ddim(const std::vector<int64_t> &dims); DDim make_ddim(const std::vector<int64_t> &dims);
DDim make_ddim(const std::vector<int> &dims); DDim make_ddim(const std::vector<int> &dims);
/** /**
* \brief Make a DDim from an initializer list * \brief Make a DDim from an initializer list
* *
* \param dims An initializer list of ints. Must be sized between [1, 9] * \param dims An initializer list of ints. Must be sized between [1, 9]
* *
*/ */
DDim make_ddim(std::initializer_list<int64_t> dims); DDim make_ddim(std::initializer_list<int64_t> dims);
int64_t get(const DDim &dim, int idx); int64_t get(const DDim &dim, int idx);
void set(DDim &dim, int idx, int val); void set(DDim &dim, int idx, int val);
std::vector<int64_t> vectorize(const DDim &ddim); std::vector<int64_t> vectorize(const DDim &ddim);
std::vector<int> vectorize2int(const DDim &ddim); std::vector<int> vectorize2int(const DDim &ddim);
int64_t product(const DDim &ddim); int64_t product(const DDim &ddim);
/** /**
* \brief Slice a ddim * \brief Slice a ddim
* *
* Slice dim with [begin, end). * Slice dim with [begin, end).
* e.g. DDim d = make_ddim({1,2,3,4,5}); * e.g. DDim d = make_ddim({1,2,3,4,5});
* slice_ddim(d, 1, 3); ====> {2,3} * slice_ddim(d, 1, 3); ====> {2,3}
*/ */
DDim slice_ddim(const DDim &dim, int begin, int end); DDim slice_ddim(const DDim &dim, int begin, int end);
/** /**
* \brief What is the length of this dimension? * \brief What is the length of this dimension?
* *
* \param Dynamic dimension to inspect * \param Dynamic dimension to inspect
*/ */
int arity(const DDim &ddim); int arity(const DDim &ddim);
std::ostream &operator<<(std::ostream &, const DDim &); std::ostream &operator<<(std::ostream &, const DDim &);
// Reshape a tensor to a matrix. The matrix's first dimension(column // Reshape a tensor to a matrix. The matrix's first dimension(column
// length) // length)
// will be the product of tensor's first `num_col_dims` dimensions. // will be the product of tensor's first `num_col_dims` dimensions.
DDim flatten_to_2d(const DDim &src, int num_col_dims); DDim flatten_to_2d(const DDim &src, int num_col_dims);
DDim flatten_to_1d(const DDim &src); DDim flatten_to_1d(const DDim &src);
DDim stride(const DDim &ddim); DDim stride(const DDim &ddim);
DDim stride_numel(const DDim &ddim); DDim stride_numel(const DDim &ddim);
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -21,23 +21,20 @@ ...@@ -21,23 +21,20 @@
#include "platform/hostdevice.h" #include "platform/hostdevice.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
// Statically sized, statically indexed dimension // Statically sized, statically indexed dimension
template <int i> struct Dim { template <int i> struct Dim {
static constexpr int dimensions = i; static constexpr int dimensions = i;
template <typename... Args> template <typename... Args>
HOSTDEVICE Dim(int64_t _head, Args... _tail) HOSTDEVICE Dim(int64_t _head, Args... _tail) : head(_head), tail(_tail...) {
: head(_head), tail(_tail...) { static_assert(sizeof...(_tail) == i - 1,
static_assert(
sizeof...(_tail) == i - 1,
"Dim initialized with the wrong number of parameters"); "Dim initialized with the wrong number of parameters");
} }
HOSTDEVICE HOSTDEVICE
Dim(int64_t _head, const Dim<i - 1> &_tail) Dim(int64_t _head, const Dim<i - 1> &_tail) : head(_head), tail(_tail) {}
: head(_head), tail(_tail) {}
HOSTDEVICE HOSTDEVICE
Dim() : head(0), tail() {} Dim() : head(0), tail() {}
...@@ -70,10 +67,10 @@ namespace paddle_mobile { ...@@ -70,10 +67,10 @@ namespace paddle_mobile {
int64_t head; int64_t head;
Dim<i - 1> tail; Dim<i - 1> tail;
}; };
// Base case specialization // Base case specialization
template <> struct Dim<0> { template <> struct Dim<0> {
static constexpr int dimensions = 0; static constexpr int dimensions = 0;
HOSTDEVICE HOSTDEVICE
...@@ -103,41 +100,38 @@ namespace paddle_mobile { ...@@ -103,41 +100,38 @@ namespace paddle_mobile {
int64_t &operator[](int idx); int64_t &operator[](int idx);
HOSTDEVICE HOSTDEVICE
int64_t operator[](int idx) const; int64_t operator[](int idx) const;
}; };
namespace { namespace {
// Helper for accessing Dim classes // Helper for accessing Dim classes
template <int i> struct DimGetter { template <int i> struct DimGetter {
// Return a copy if Dim is const // Return a copy if Dim is const
template <typename D> template <typename D> HOSTDEVICE static int64_t impl(const D &d) {
HOSTDEVICE static int64_t impl(const D &d) {
return DimGetter<i - 1>::impl(d.tail); return DimGetter<i - 1>::impl(d.tail);
} }
// Return a reference if Dim is mutable // Return a reference if Dim is mutable
template <typename D> HOSTDEVICE static int64_t &impl(D &d) { template <typename D> HOSTDEVICE static int64_t &impl(D &d) {
return DimGetter<i - 1>::impl(d.tail); return DimGetter<i - 1>::impl(d.tail);
} }
}; };
// Eureka! We found the element! // Eureka! We found the element!
template <> struct DimGetter<0> { template <> struct DimGetter<0> {
// Return a copy if Dim is const // Return a copy if Dim is const
template <typename D> template <typename D> HOSTDEVICE static int64_t impl(const D &d) {
HOSTDEVICE static int64_t impl(const D &d) {
return d.head; return d.head;
} }
// Return a reference if Dim is mutable // Return a reference if Dim is mutable
template <typename D> HOSTDEVICE static int64_t &impl(D &d) { template <typename D> HOSTDEVICE static int64_t &impl(D &d) {
return d.head; return d.head;
} }
}; };
template <int D> HOSTDEVICE int64_t &indexer(Dim<D> &dim, int idx) { template <int D> HOSTDEVICE int64_t &indexer(Dim<D> &dim, int idx) {
#ifndef __CUDA_ARCH__ #ifndef __CUDA_ARCH__
if (idx < 0) { if (idx < 0) {
throw std::invalid_argument( throw std::invalid_argument("Tried to access a negative dimension");
"Tried to access a negative dimension");
} }
#else #else
PADDLE_ASSERT(idx >= 0); PADDLE_ASSERT(idx >= 0);
...@@ -146,9 +140,9 @@ namespace paddle_mobile { ...@@ -146,9 +140,9 @@ namespace paddle_mobile {
return dim.head; return dim.head;
} }
return indexer(dim.tail, idx - 1); return indexer(dim.tail, idx - 1);
} }
template <> HOSTDEVICE int64_t &indexer<0>(Dim<0> &dim, int idx) { template <> HOSTDEVICE int64_t &indexer<0>(Dim<0> &dim, int idx) {
#ifndef __CUDA_ARCH__ #ifndef __CUDA_ARCH__
throw std::invalid_argument("Invalid index"); throw std::invalid_argument("Invalid index");
#else #else
...@@ -162,14 +156,12 @@ namespace paddle_mobile { ...@@ -162,14 +156,12 @@ namespace paddle_mobile {
#endif #endif
return head; return head;
#endif #endif
} }
template <int D> template <int D> HOSTDEVICE int64_t indexer(const Dim<D> &dim, int idx) {
HOSTDEVICE int64_t indexer(const Dim<D> &dim, int idx) {
#ifndef __CUDA_ARCH__ #ifndef __CUDA_ARCH__
if (idx < 0) { if (idx < 0) {
throw std::invalid_argument( throw std::invalid_argument("Tried to access a negative dimension");
"Tried to access a negative dimension");
} }
#else #else
PADDLE_ASSERT(idx >= 0); PADDLE_ASSERT(idx >= 0);
...@@ -178,10 +170,9 @@ namespace paddle_mobile { ...@@ -178,10 +170,9 @@ namespace paddle_mobile {
return dim.head; return dim.head;
} }
return indexer(dim.tail, idx - 1); return indexer(dim.tail, idx - 1);
} }
template <> template <> HOSTDEVICE int64_t indexer<0>(const Dim<0> &dim, int idx) {
HOSTDEVICE int64_t indexer<0>(const Dim<0> &dim, int idx) {
#ifndef __CUDA_ARCH__ #ifndef __CUDA_ARCH__
throw std::invalid_argument("Invalid index"); throw std::invalid_argument("Invalid index");
#else #else
...@@ -195,152 +186,146 @@ namespace paddle_mobile { ...@@ -195,152 +186,146 @@ namespace paddle_mobile {
#endif #endif
return head; return head;
#endif #endif
} }
} // namespace } // namespace
// Static access to constant Dim // Static access to constant Dim
template <int i, int l> HOSTDEVICE int64_t get(const Dim<l> &d) { template <int i, int l> HOSTDEVICE int64_t get(const Dim<l> &d) {
return DimGetter<i>::impl(d); return DimGetter<i>::impl(d);
} }
// Static access to mutable Dim // Static access to mutable Dim
template <int i, int l> HOSTDEVICE int64_t &get(Dim<l> &d) { template <int i, int l> HOSTDEVICE int64_t &get(Dim<l> &d) {
return DimGetter<i>::impl(d); return DimGetter<i>::impl(d);
} }
// Dynamic access to constant Dim // Dynamic access to constant Dim
template <int l> HOSTDEVICE int64_t Dim<l>::operator[](int i) const { template <int l> HOSTDEVICE int64_t Dim<l>::operator[](int i) const {
// std::cout << "l: " << l << std::endl; // std::cout << "l: " << l << std::endl;
return indexer(*this, i); return indexer(*this, i);
} }
// Dynamic access to mutable Dim // Dynamic access to mutable Dim
template <int l> HOSTDEVICE int64_t &Dim<l>::operator[](int i) { template <int l> HOSTDEVICE int64_t &Dim<l>::operator[](int i) {
return indexer(*this, i); return indexer(*this, i);
} }
// Dynamic access to constant Dim // Dynamic access to constant Dim
inline HOSTDEVICE int64_t Dim<0>::operator[](int i) const { inline HOSTDEVICE int64_t Dim<0>::operator[](int i) const {
return indexer(*this, i); return indexer(*this, i);
} }
// Dynamic access to mutable Dim // Dynamic access to mutable Dim
inline HOSTDEVICE int64_t &Dim<0>::operator[](int i) { inline HOSTDEVICE int64_t &Dim<0>::operator[](int i) {
return indexer(*this, i); return indexer(*this, i);
} }
// Dynamic access to constant Dim // Dynamic access to constant Dim
// without std::enable_if will try to instantiate this on get<0>(d) // without std::enable_if will try to instantiate this on get<0>(d)
template <int l> template <int l>
HOSTDEVICE typename std::enable_if<(l > 0), int64_t>::type HOSTDEVICE typename std::enable_if<(l > 0), int64_t>::type get(const Dim<l> &d,
get(const Dim<l> &d, int i) { int i) {
return d[i]; return d[i];
} }
// Dynamic access to mutable Dim // Dynamic access to mutable Dim
template <int l> template <int l>
HOSTDEVICE typename std::enable_if<(l > 0), int64_t &>::type HOSTDEVICE typename std::enable_if<(l > 0), int64_t &>::type get(Dim<l> &d,
get(Dim<l> &d, int i) { int i) {
return d[i]; return d[i];
} }
// Dot product of two dims // Dot product of two dims
template <int i> template <int i>
HOSTDEVICE int64_t linearize(const Dim<i> &a, const Dim<i> &b) { HOSTDEVICE int64_t linearize(const Dim<i> &a, const Dim<i> &b) {
return a.head * b.head + linearize(a.tail, b.tail); return a.head * b.head + linearize(a.tail, b.tail);
} }
// Base case dot product of two Dims // Base case dot product of two Dims
// Notice it is inline because it is no longer a template // Notice it is inline because it is no longer a template
template <> template <>
HOSTDEVICE inline int64_t linearize(const Dim<0> &a, const Dim<0> &b) { HOSTDEVICE inline int64_t linearize(const Dim<0> &a, const Dim<0> &b) {
return 0; return 0;
} }
// Product of a Dim // Product of a Dim
template <int i> template <int i> HOSTDEVICE int64_t product(const Dim<i> &a, int prod = 1) {
HOSTDEVICE int64_t product(const Dim<i> &a, int prod = 1) {
return prod * a.head * product(a.tail); return prod * a.head * product(a.tail);
} }
// Base case product of a Dim // Base case product of a Dim
// Notice it is inline because it is no longer a template // Notice it is inline because it is no longer a template
template <> template <> HOSTDEVICE inline int64_t product(const Dim<0> &a, int prod) {
HOSTDEVICE inline int64_t product(const Dim<0> &a, int prod) {
return prod; return prod;
} }
// Is 0 <= idx_i < size_i for all i? // Is 0 <= idx_i < size_i for all i?
template <int i> template <int i>
HOSTDEVICE bool contained(const Dim<i> &idx, const Dim<i> &size) { HOSTDEVICE bool contained(const Dim<i> &idx, const Dim<i> &size) {
return ((0 <= idx.head) && (idx.head < size.head) && return ((0 <= idx.head) && (idx.head < size.head) &&
contained(idx.tail, size.tail)); contained(idx.tail, size.tail));
} }
// Base case of is 0 <= idx_i < size_i ? // Base case of is 0 <= idx_i < size_i ?
// Notice it is inline because it is no longer a template // Notice it is inline because it is no longer a template
template <> template <>
HOSTDEVICE inline bool contained(const Dim<0> &idx, HOSTDEVICE inline bool contained(const Dim<0> &idx, const Dim<0> &size) {
const Dim<0> &size) {
return true; return true;
} }
/** /**
* \brief Compute exclusive prefix-multiply of a Dim. * \brief Compute exclusive prefix-multiply of a Dim.
*/ */
template <int i> template <int i>
HOSTDEVICE Dim<i> ex_prefix_mul(const Dim<i> &src, int mul = 1) { HOSTDEVICE Dim<i> ex_prefix_mul(const Dim<i> &src, int mul = 1) {
return Dim<i>(mul, ex_prefix_mul(src.tail, mul * src.head)); return Dim<i>(mul, ex_prefix_mul(src.tail, mul * src.head));
} }
///\cond HIDDEN ///\cond HIDDEN
// Base case of ex_prefix_mul // Base case of ex_prefix_mul
// Notice it is inline because it is no longer a template // Notice it is inline because it is no longer a template
template <> template <> HOSTDEVICE inline Dim<0> ex_prefix_mul(const Dim<0> &src, int mul) {
HOSTDEVICE inline Dim<0> ex_prefix_mul(const Dim<0> &src, int mul) {
return Dim<0>(); return Dim<0>();
} }
///\endcond ///\endcond
/** /**
* Add two dimensions together * Add two dimensions together
*/ */
template <int i> template <int i> HOSTDEVICE Dim<i> dim_plus(const Dim<i> &a, const Dim<i> &b) {
HOSTDEVICE Dim<i> dim_plus(const Dim<i> &a, const Dim<i> &b) {
return Dim<i>(a.head + b.head, dim_plus(a.tail, b.tail)); return Dim<i>(a.head + b.head, dim_plus(a.tail, b.tail));
} }
// Base case // Base case
template <> template <>
HOSTDEVICE inline Dim<0> dim_plus(const Dim<0> &a, const Dim<0> &b) { HOSTDEVICE inline Dim<0> dim_plus(const Dim<0> &a, const Dim<0> &b) {
return Dim<0>(); return Dim<0>();
} }
template <int i> template <int i>
HOSTDEVICE Dim<i> operator+(const Dim<i> &lhs, const Dim<i> &rhs) { HOSTDEVICE Dim<i> operator+(const Dim<i> &lhs, const Dim<i> &rhs) {
return dim_plus(lhs, rhs); return dim_plus(lhs, rhs);
} }
/** /**
* Multiply two dimensions together * Multiply two dimensions together
*/ */
template <int i> template <int i> HOSTDEVICE Dim<i> dim_mult(const Dim<i> &a, const Dim<i> &b) {
HOSTDEVICE Dim<i> dim_mult(const Dim<i> &a, const Dim<i> &b) {
return Dim<i>(a.head * b.head, dim_mult(a.tail, b.tail)); return Dim<i>(a.head * b.head, dim_mult(a.tail, b.tail));
} }
// Base case // Base case
template <> template <>
HOSTDEVICE inline Dim<0> dim_mult(const Dim<0> &a, const Dim<0> &b) { HOSTDEVICE inline Dim<0> dim_mult(const Dim<0> &a, const Dim<0> &b) {
return Dim<0>(); return Dim<0>();
} }
template <int i> template <int i>
HOSTDEVICE Dim<i> operator*(const Dim<i> &lhs, const Dim<i> &rhs) { HOSTDEVICE Dim<i> operator*(const Dim<i> &lhs, const Dim<i> &rhs) {
return dim_mult(lhs, rhs); return dim_mult(lhs, rhs);
} }
/** /**
* \brief Normalize strides to ensure any dimension with extent 1 * \brief Normalize strides to ensure any dimension with extent 1
* has stride 0. * has stride 0.
* *
...@@ -350,25 +335,23 @@ namespace paddle_mobile { ...@@ -350,25 +335,23 @@ namespace paddle_mobile {
* *
*/ */
template <int i> template <int i>
HOSTDEVICE Dim<i> normalize_strides(const Dim<i> &size, HOSTDEVICE Dim<i> normalize_strides(const Dim<i> &size, const Dim<i> &stride) {
const Dim<i> &stride) {
int norm_stride = size.head == 1 ? 0 : stride.head; int norm_stride = size.head == 1 ? 0 : stride.head;
return Dim<i>(norm_stride, return Dim<i>(norm_stride, normalize_strides(size.tail, stride.tail));
normalize_strides(size.tail, stride.tail)); }
}
///\cond HIDDEN ///\cond HIDDEN
template <> template <>
HOSTDEVICE inline Dim<0> normalize_strides(const Dim<0> &size, HOSTDEVICE inline Dim<0> normalize_strides(const Dim<0> &size,
const Dim<0> &stride) { const Dim<0> &stride) {
return Dim<0>(); return Dim<0>();
} }
///\endcond ///\endcond
/** /**
* Helper function to create a Dim * Helper function to create a Dim
* *
* \param idxes The type of Dim constructed depends on the number of * \param idxes The type of Dim constructed depends on the number of
...@@ -376,44 +359,43 @@ namespace paddle_mobile { ...@@ -376,44 +359,43 @@ namespace paddle_mobile {
* *
*/ */
template <typename... Args> template <typename... Args>
HOSTDEVICE Dim<sizeof...(Args)> make_dim(Args... idxes) { HOSTDEVICE Dim<sizeof...(Args)> make_dim(Args... idxes) {
return Dim<sizeof...(Args)>(idxes...); return Dim<sizeof...(Args)>(idxes...);
} }
// Allows us to output a Dim // Allows us to output a Dim
// XXX For some reason, overloading fails to resolve this correctly // XXX For some reason, overloading fails to resolve this correctly
template <int i> template <int i>
typename std::enable_if<(i > 1), std::ostream &>::type typename std::enable_if<(i > 1), std::ostream &>::type
operator<<(std::ostream &os, const Dim<i> &d) { operator<<(std::ostream &os, const Dim<i> &d) {
os << d.head << ", " << d.tail; os << d.head << ", " << d.tail;
return os; return os;
} }
// Base case that allows us to output a Dim // Base case that allows us to output a Dim
// XXX I wish this could be an overload instead of a template // XXX I wish this could be an overload instead of a template
template <int i> template <int i>
typename std::enable_if<(i == 1), std::ostream &>::type typename std::enable_if<(i == 1), std::ostream &>::type
operator<<(std::ostream &os, const Dim<i> &d) { operator<<(std::ostream &os, const Dim<i> &d) {
os << d.head; os << d.head;
return os; return os;
} }
inline std::ostream &operator<<(std::ostream &os, const Dim<0> &d) { inline std::ostream &operator<<(std::ostream &os, const Dim<0> &d) {
return os; return os;
} }
template <int i> HOST std::string Dim<i>::to_string() const { template <int i> HOST std::string Dim<i>::to_string() const {
std::stringstream stream; std::stringstream stream;
stream << *this; stream << *this;
return stream.str(); return stream.str();
} }
template <int D> template <int D>
HOSTDEVICE Dim<D> linear_to_dimension(int linear_index, HOSTDEVICE Dim<D> linear_to_dimension(int linear_index, Dim<D> extents) {
Dim<D> extents) {
Dim<D> result; Dim<D> result;
for (int i = 0; i < D - 1; ++i) { for (int i = 0; i < D - 1; ++i) {
...@@ -424,7 +406,7 @@ namespace paddle_mobile { ...@@ -424,7 +406,7 @@ namespace paddle_mobile {
result[D - 1] = linear_index; result[D - 1] = linear_index;
return result; return result;
} }
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -20,13 +20,12 @@ SOFTWARE. ...@@ -20,13 +20,12 @@ SOFTWARE.
#include "executor.h" #include "executor.h"
#include "lod_tensor.h" #include "lod_tensor.h"
#include "operators/conv_op.h" #include "operators/conv_op.h"
#include "variable.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
template <typename Dtype> template <typename Dtype>
Executor<Dtype>::Executor(const Program<Dtype> p) : program_(p) { Executor<Dtype>::Executor(const Program<Dtype> p) : program_(p) {
if (use_optimize_) { if (use_optimize_) {
to_predict_program_ = program_.optimizeProgram; to_predict_program_ = program_.optimizeProgram;
} else { } else {
...@@ -40,11 +39,9 @@ namespace paddle_mobile { ...@@ -40,11 +39,9 @@ namespace paddle_mobile {
std::vector<std::shared_ptr<OpDesc>> ops = block_desc->Ops(); std::vector<std::shared_ptr<OpDesc>> ops = block_desc->Ops();
for (int j = 0; j < ops.size(); ++j) { for (int j = 0; j < ops.size(); ++j) {
std::shared_ptr<OpDesc> op = ops[j]; std::shared_ptr<OpDesc> op = ops[j];
if (op->Type() == "conv2d" && if (op->Type() == "conv2d" && op->Input("Input")[0] == "pixel") {
op->Input("Input")[0] == "pixel") {
Attribute strides_attr = op->GetAttrMap().at("strides"); Attribute strides_attr = op->GetAttrMap().at("strides");
std::vector<int> stride = std::vector<int> stride = strides_attr.Get<std::vector<int>>();
strides_attr.Get<std::vector<int>>();
for (int k = 0; k < stride.size(); ++k) { for (int k = 0; k < stride.size(); ++k) {
} }
std::shared_ptr<operators::ConvOp<Dtype, float>> conv = std::shared_ptr<operators::ConvOp<Dtype, float>> conv =
...@@ -55,10 +52,10 @@ namespace paddle_mobile { ...@@ -55,10 +52,10 @@ namespace paddle_mobile {
} }
} }
} }
} }
template <typename Dtype> template <typename Dtype>
std::shared_ptr<Tensor> Executor<Dtype>::predict(Tensor &t) { std::shared_ptr<Tensor> Executor<Dtype>::predict(Tensor &t) {
// feed // feed
auto scope = program_.scope; auto scope = program_.scope;
Variable *g_feed_value = scope->Var("pixel"); Variable *g_feed_value = scope->Var("pixel");
...@@ -77,21 +74,20 @@ namespace paddle_mobile { ...@@ -77,21 +74,20 @@ namespace paddle_mobile {
predict(t, 0); predict(t, 0);
return out_tensor; return out_tensor;
} }
template <typename Dtype> template <typename Dtype>
void Executor<Dtype>::predict(const Tensor &t, int block_id) { void Executor<Dtype>::predict(const Tensor &t, int block_id) {
std::shared_ptr<BlockDesc> to_predict_block = std::shared_ptr<BlockDesc> to_predict_block =
to_predict_program_->Block(block_id); to_predict_program_->Block(block_id);
for (int j = 0; j < ops_of_block_[*to_predict_block.get()].size(); for (int j = 0; j < ops_of_block_[*to_predict_block.get()].size(); ++j) {
++j) {
auto op = ops_of_block_[*to_predict_block.get()][j]; auto op = ops_of_block_[*to_predict_block.get()][j];
// std::cout << "开始run" << std::endl; // std::cout << "开始run" << std::endl;
op->Run(); op->Run();
} }
} }
template class Executor<CPU>; template class Executor<CPU>;
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -32,9 +32,9 @@ SOFTWARE. ...@@ -32,9 +32,9 @@ SOFTWARE.
#include "variable.h" #include "variable.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
template <typename Dtype> class Executor { template <typename Dtype> class Executor {
public: public:
Executor(const Program<Dtype> p); Executor(const Program<Dtype> p);
std::shared_ptr<Tensor> predict(Tensor &t); std::shared_ptr<Tensor> predict(Tensor &t);
...@@ -47,7 +47,7 @@ namespace paddle_mobile { ...@@ -47,7 +47,7 @@ namespace paddle_mobile {
std::vector<std::shared_ptr<OperatorBase<Dtype>>>> std::vector<std::shared_ptr<OperatorBase<Dtype>>>>
ops_of_block_; ops_of_block_;
bool use_optimize_ = false; bool use_optimize_ = false;
}; };
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
此差异已折叠。
此差异已折叠。
...@@ -19,9 +19,9 @@ limitations under the License. */ ...@@ -19,9 +19,9 @@ limitations under the License. */
#include <string.h> #include <string.h>
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
std::ostream &operator<<(std::ostream &os, const LoD &lod) { std::ostream &operator<<(std::ostream &os, const LoD &lod) {
os << "{"; os << "{";
for (auto &v : lod) { for (auto &v : lod) {
os << "{"; os << "{";
...@@ -39,9 +39,9 @@ namespace paddle_mobile { ...@@ -39,9 +39,9 @@ namespace paddle_mobile {
os << "}"; os << "}";
return os; return os;
} }
std::ostream &operator<<(std::ostream &os, const LoDTensor &t) { std::ostream &operator<<(std::ostream &os, const LoDTensor &t) {
// PADDLE_ENFORCE(t.type().hash_code() == // PADDLE_ENFORCE(t.type().hash_code() ==
// typeid(float).hash_code()); // typeid(float).hash_code());
...@@ -66,15 +66,15 @@ namespace paddle_mobile { ...@@ -66,15 +66,15 @@ namespace paddle_mobile {
} }
return os; return os;
} }
std::string LoDToString(const LoD &lod) { std::string LoDToString(const LoD &lod) {
std::ostringstream stream; std::ostringstream stream;
stream << lod; stream << lod;
return stream.str(); return stream.str();
} }
LoD SliceInLevel(const LoD &in, size_t level, size_t elem_begin, LoD SliceInLevel(const LoD &in, size_t level, size_t elem_begin,
size_t elem_end) { size_t elem_end) {
// PADDLE_ENFORCE_LT(level, in.size()); // PADDLE_ENFORCE_LT(level, in.size());
// PADDLE_ENFORCE_LT(elem_end, in[level].size()); // PADDLE_ENFORCE_LT(elem_end, in[level].size());
...@@ -101,24 +101,23 @@ namespace paddle_mobile { ...@@ -101,24 +101,23 @@ namespace paddle_mobile {
} }
} }
return res; return res;
} }
LoD ToAbsOffset(const LoD &in) { LoD ToAbsOffset(const LoD &in) {
// the lowest level stores relative offsets // the lowest level stores relative offsets
if (in.empty() || in.size() == 1) if (in.empty() || in.size() == 1)
return in; return in;
LoD result = in; LoD result = in;
for (auto level = static_cast<int>(in.size() - 2); level >= 0; for (auto level = static_cast<int>(in.size() - 2); level >= 0; level--) {
level--) {
for (size_t i = 0; i < in[level].size(); ++i) { for (size_t i = 0; i < in[level].size(); ++i) {
size_t index = in[level][i]; size_t index = in[level][i];
result[level][i] = result[level + 1][index]; result[level][i] = result[level + 1][index];
} }
} }
return result; return result;
} }
bool operator==(const LoD &a, const LoD &b) { bool operator==(const LoD &a, const LoD &b) {
if (a.size() != b.size()) { if (a.size() != b.size()) {
return false; return false;
} }
...@@ -136,9 +135,9 @@ namespace paddle_mobile { ...@@ -136,9 +135,9 @@ namespace paddle_mobile {
} }
} }
return true; return true;
} }
bool CheckLoD(const LoD &in, int tensor_height) { bool CheckLoD(const LoD &in, int tensor_height) {
if (in.empty()) if (in.empty())
return true; return true;
for (const auto &level : in) { for (const auto &level : in) {
...@@ -180,9 +179,9 @@ namespace paddle_mobile { ...@@ -180,9 +179,9 @@ namespace paddle_mobile {
return false; return false;
} }
return true; return true;
} }
bool CheckAbsLoD(const LoD &in, int tensor_height) { bool CheckAbsLoD(const LoD &in, int tensor_height) {
if (in.empty()) if (in.empty())
return true; return true;
for (const auto &level : in) { for (const auto &level : in) {
...@@ -215,24 +214,20 @@ namespace paddle_mobile { ...@@ -215,24 +214,20 @@ namespace paddle_mobile {
} }
} }
return true; return true;
} }
using LoDAndOffset = std::pair<LoD, std::pair<size_t, size_t>>; using LoDAndOffset = std::pair<LoD, std::pair<size_t, size_t>>;
LoDAndOffset GetSubLoDAndAbsoluteOffset(const LoD &lod, LoDAndOffset GetSubLoDAndAbsoluteOffset(const LoD &lod, size_t start_idx,
size_t start_idx, size_t end_idx, size_t start_level) {
size_t end_idx,
size_t start_level) {
LoD sub_lod; LoD sub_lod;
for (size_t level_idx = start_level; level_idx < lod.size(); for (size_t level_idx = start_level; level_idx < lod.size(); ++level_idx) {
++level_idx) {
// PADDLE_ENFORCE_LE(start_idx, end_idx); // PADDLE_ENFORCE_LE(start_idx, end_idx);
// PADDLE_ENFORCE_LT(end_idx, lod[level_idx].size()); // PADDLE_ENFORCE_LT(end_idx, lod[level_idx].size());
std::vector<size_t> level_lens; std::vector<size_t> level_lens;
for (size_t i = start_idx; i < end_idx; ++i) { for (size_t i = start_idx; i < end_idx; ++i) {
level_lens.push_back(lod[level_idx][i + 1] - level_lens.push_back(lod[level_idx][i + 1] - lod[level_idx][i]);
lod[level_idx][i]);
} }
sub_lod.emplace_back(level_lens); sub_lod.emplace_back(level_lens);
start_idx = lod[level_idx][start_idx]; start_idx = lod[level_idx][start_idx];
...@@ -240,9 +235,9 @@ namespace paddle_mobile { ...@@ -240,9 +235,9 @@ namespace paddle_mobile {
} }
return LoDAndOffset{sub_lod, {start_idx, end_idx}}; return LoDAndOffset{sub_lod, {start_idx, end_idx}};
} }
void AppendLoD(LoD *lod, const LoD &lod_length) { void AppendLoD(LoD *lod, const LoD &lod_length) {
// PADDLE_ENFORCE( // PADDLE_ENFORCE(
// lod->empty() || lod->size() == lod_length.size(), // lod->empty() || lod->size() == lod_length.size(),
// "The lod_length should has the same size with the appended // "The lod_length should has the same size with the appended
...@@ -259,13 +254,12 @@ namespace paddle_mobile { ...@@ -259,13 +254,12 @@ namespace paddle_mobile {
level.push_back(level.back() + len); level.push_back(level.back() + len);
} }
} }
} }
void SerializeToStream(std::ostream &os, const LoDTensor &tensor) { void SerializeToStream(std::ostream &os, const LoDTensor &tensor) {
{ // the 1st field, uint32_t version for LoDTensor { // the 1st field, uint32_t version for LoDTensor
constexpr uint32_t version = 0; constexpr uint32_t version = 0;
os.write(reinterpret_cast<const char *>(&version), os.write(reinterpret_cast<const char *>(&version), sizeof(version));
sizeof(version));
} }
{ {
// the 2st field, LoD information // the 2st field, LoD information
...@@ -278,19 +272,17 @@ namespace paddle_mobile { ...@@ -278,19 +272,17 @@ namespace paddle_mobile {
os.write(reinterpret_cast<const char *>(&size), sizeof(size)); os.write(reinterpret_cast<const char *>(&size), sizeof(size));
for (auto &each : lod) { for (auto &each : lod) {
size = each.size() * size = each.size() * sizeof(framework::LoD::value_type::value_type);
sizeof(framework::LoD::value_type::value_type); os.write(reinterpret_cast<const char *>(&size), sizeof(size));
os.write(reinterpret_cast<const char *>(&size),
sizeof(size));
os.write(reinterpret_cast<const char *>(each.data()), os.write(reinterpret_cast<const char *>(each.data()),
static_cast<std::streamsize>(size)); static_cast<std::streamsize>(size));
} }
} }
// the 3st field, Tensor // the 3st field, Tensor
TensorToStream(os, static_cast<Tensor>(tensor)); TensorToStream(os, static_cast<Tensor>(tensor));
} }
void DeserializeFromStream(std::istream &is, LoDTensor *tensor) { void DeserializeFromStream(std::istream &is, LoDTensor *tensor) {
{ {
// the 1st field, unit32_t version for LoDTensor // the 1st field, unit32_t version for LoDTensor
uint32_t version; uint32_t version;
...@@ -301,8 +293,7 @@ namespace paddle_mobile { ...@@ -301,8 +293,7 @@ namespace paddle_mobile {
{ {
// the 2st field, LoD information // the 2st field, LoD information
uint64_t lod_level; uint64_t lod_level;
is.read(reinterpret_cast<char *>(&lod_level), is.read(reinterpret_cast<char *>(&lod_level), sizeof(lod_level));
sizeof(lod_level));
auto &lod = *tensor->mutable_lod(); auto &lod = *tensor->mutable_lod();
lod.resize(lod_level); lod.resize(lod_level);
for (uint64_t i = 0; i < lod_level; ++i) { for (uint64_t i = 0; i < lod_level; ++i) {
...@@ -316,7 +307,7 @@ namespace paddle_mobile { ...@@ -316,7 +307,7 @@ namespace paddle_mobile {
} }
// the 3st filed, Tensor // the 3st filed, Tensor
TensorFromStream(is, static_cast<Tensor *>(tensor)); TensorFromStream(is, static_cast<Tensor *>(tensor));
} }
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -23,9 +23,9 @@ limitations under the License. */ ...@@ -23,9 +23,9 @@ limitations under the License. */
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
/* /*
* LoD is short for Level of Details. * LoD is short for Level of Details.
* *
* - in a level, each element indicates relative offset of the lower * - in a level, each element indicates relative offset of the lower
...@@ -42,25 +42,25 @@ namespace paddle_mobile { ...@@ -42,25 +42,25 @@ namespace paddle_mobile {
* 0 2 4 7 * 0 2 4 7
* 0 2 5 7 10 12 15 20 * 0 2 5 7 10 12 15 20
*/ */
using LoD = std::vector<std::vector<size_t>>; using LoD = std::vector<std::vector<size_t>>;
std::ostream &operator<<(std::ostream &os, const LoD &lod); std::ostream &operator<<(std::ostream &os, const LoD &lod);
std::ostream &operator<<(std::ostream &os, const LoDTensor &t); std::ostream &operator<<(std::ostream &os, const LoDTensor &t);
std::string LoDToString(const LoD &lod); std::string LoDToString(const LoD &lod);
LoD SliceInLevel(const LoD &in, size_t level, size_t elem_begin, LoD SliceInLevel(const LoD &in, size_t level, size_t elem_begin,
size_t elem_end); size_t elem_end);
/* /*
* Transform an LoD from relative offsets to absolute offsets. * Transform an LoD from relative offsets to absolute offsets.
*/ */
LoD ToAbsOffset(const LoD &in); LoD ToAbsOffset(const LoD &in);
bool operator==(const LoD &a, const LoD &b); bool operator==(const LoD &a, const LoD &b);
/* /*
* Check whether this lod's format is valid. * Check whether this lod's format is valid.
* *
* ATTENTION: * ATTENTION:
...@@ -78,9 +78,9 @@ namespace paddle_mobile { ...@@ -78,9 +78,9 @@ namespace paddle_mobile {
* tensor_height>0. * tensor_height>0.
*/ */
bool CheckLoD(const LoD &in, int tensor_height = -1); bool CheckLoD(const LoD &in, int tensor_height = -1);
/* /*
* Check whether this absolute lod's format is valid. * Check whether this absolute lod's format is valid.
* *
* ATTENTION: * ATTENTION:
...@@ -95,13 +95,13 @@ namespace paddle_mobile { ...@@ -95,13 +95,13 @@ namespace paddle_mobile {
* same(the height of underlying tensor) or `tensor_height` if * same(the height of underlying tensor) or `tensor_height` if
* tensor_height>0. * tensor_height>0.
*/ */
bool CheckAbsLoD(const LoD &in, int tensor_height = -1); bool CheckAbsLoD(const LoD &in, int tensor_height = -1);
/* /*
* LoDTensor (Level of details Tensor) * LoDTensor (Level of details Tensor)
* see https://en.wikipedia.org/wiki/Level_of_details for reference. * see https://en.wikipedia.org/wiki/Level_of_details for reference.
*/ */
class LoDTensor : public Tensor { class LoDTensor : public Tensor {
public: public:
LoDTensor() : Tensor() {} LoDTensor() : Tensor() {}
...@@ -116,12 +116,10 @@ namespace paddle_mobile { ...@@ -116,12 +116,10 @@ namespace paddle_mobile {
/* /*
* Get the start offset and end offset of an element from LoD. * Get the start offset and end offset of an element from LoD.
*/ */
std::pair<size_t, size_t> lod_element(size_t level, std::pair<size_t, size_t> lod_element(size_t level, size_t elem) const {
size_t elem) const {
// PADDLE_ENFORCE_LT(level, NumLevels()); // PADDLE_ENFORCE_LT(level, NumLevels());
// PADDLE_ENFORCE_LT(elem, NumElements(level)); // PADDLE_ENFORCE_LT(elem, NumElements(level));
return std::make_pair((lod_)[level][elem], return std::make_pair((lod_)[level][elem], (lod_)[level][elem + 1]);
(lod_)[level][elem + 1]);
} }
/* /*
...@@ -143,9 +141,9 @@ namespace paddle_mobile { ...@@ -143,9 +141,9 @@ namespace paddle_mobile {
private: private:
LoD lod_; LoD lod_;
}; };
/* /*
* Expand the `source` to fit the LoD of `lod`. For example, a `source` * Expand the `source` to fit the LoD of `lod`. For example, a `source`
* LoDTensor is * LoDTensor is
* - LoD: [0, 2] * - LoD: [0, 2]
...@@ -155,9 +153,8 @@ namespace paddle_mobile { ...@@ -155,9 +153,8 @@ namespace paddle_mobile {
* returns a new LoDTensor * returns a new LoDTensor
* - [a0 a0 a0 a1 a1] * - [a0 a0 a0 a1 a1]
*/ */
template <typename T> template <typename T>
LoDTensor LodExpand(const LoDTensor &source, const LoD &lod, LoDTensor LodExpand(const LoDTensor &source, const LoD &lod, size_t level) {
size_t level) {
LoD abs_lod = ToAbsOffset(lod); LoD abs_lod = ToAbsOffset(lod);
const auto &lod_level = lod[level]; const auto &lod_level = lod[level];
size_t num_instances = source.dims()[0]; size_t num_instances = source.dims()[0];
...@@ -172,41 +169,40 @@ namespace paddle_mobile { ...@@ -172,41 +169,40 @@ namespace paddle_mobile {
// PADDLE_ENFORCE_EQ(num_instances, lod_level.size() - 1); // PADDLE_ENFORCE_EQ(num_instances, lod_level.size() - 1);
for (size_t ins = 0; ins < num_instances; ins++) { for (size_t ins = 0; ins < num_instances; ins++) {
for (size_t elem = lod_level[ins]; elem < lod_level[ins + 1]; for (size_t elem = lod_level[ins]; elem < lod_level[ins + 1]; elem++) {
elem++) {
auto slice = tensor.Slice(elem, elem + 1); auto slice = tensor.Slice(elem, elem + 1);
TensorCopy(source.Slice(ins, ins + 1), &slice); TensorCopy(source.Slice(ins, ins + 1), &slice);
} }
} }
return tensor; return tensor;
} }
// Get the absolute offset of a lod[start_level][start_idx:end_idx] and // Get the absolute offset of a lod[start_level][start_idx:end_idx] and
// relative length of details for every levels(i.e., [start_level: ]). // relative length of details for every levels(i.e., [start_level: ]).
// //
// For example, // For example,
// lod = [[0, 3, 4, 8], [0, 9, 10, 11, 13, 17, 19, 22, 24]] // lod = [[0, 3, 4, 8], [0, 9, 10, 11, 13, 17, 19, 22, 24]]
// start_level = 0 // start_level = 0
// start_idx = 1 // start_idx = 1
// end_idx = 3 // end_idx = 3
// //
// Returns: // Returns:
// LoD = [[1, 4], [2, 4, 2, 3, 2]] // LoD = [[1, 4], [2, 4, 2, 3, 2]]
// pair<size_t, size_t> = {11, 24} // pair<size_t, size_t> = {11, 24}
std::pair<LoD, std::pair<size_t, size_t>> std::pair<LoD, std::pair<size_t, size_t>>
GetSubLoDAndAbsoluteOffset(const LoD &lod, size_t start_idx, GetSubLoDAndAbsoluteOffset(const LoD &lod, size_t start_idx, size_t end_idx,
size_t end_idx, size_t start_level); size_t start_level);
void AppendLoD(LoD *lod, const LoD &lod_length); void AppendLoD(LoD *lod, const LoD &lod_length);
/* /*
* Serialize/Desiralize LoDTensor to std::ostream * Serialize/Desiralize LoDTensor to std::ostream
* You can pass ofstream or ostringstream to serilize to file * You can pass ofstream or ostringstream to serilize to file
* or to a in memory string. GPU tensor will be copied to CPU. * or to a in memory string. GPU tensor will be copied to CPU.
*/ */
void SerializeToStream(std::ostream &os, const LoDTensor &tensor); void SerializeToStream(std::ostream &os, const LoDTensor &tensor);
void DeserializeFromStream(std::istream &is, LoDTensor *tensor); void DeserializeFromStream(std::istream &is, LoDTensor *tensor);
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
#include "op_desc.h" #include "op_desc.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
OpDesc::OpDesc(const proto::OpDesc &desc) : desc_(desc) { OpDesc::OpDesc(const proto::OpDesc &desc) : desc_(desc) {
for (int i = 0; i < desc_.inputs_size(); ++i) { for (int i = 0; i < desc_.inputs_size(); ++i) {
const proto::OpDesc::Var &var = desc_.inputs(i); const proto::OpDesc::Var &var = desc_.inputs(i);
std::vector<std::string> &args = inputs_[var.parameter()]; std::vector<std::string> &args = inputs_[var.parameter()];
...@@ -36,27 +36,24 @@ namespace paddle_mobile { ...@@ -36,27 +36,24 @@ namespace paddle_mobile {
// } // }
} }
} }
} }
const std::vector<std::string> & const std::vector<std::string> &OpDesc::Input(const std::string &name) const {
OpDesc::Input(const std::string &name) const {
return inputs_.find(name)->second; return inputs_.find(name)->second;
} }
const std::vector<std::string> & const std::vector<std::string> &OpDesc::Output(const std::string &name) const {
OpDesc::Output(const std::string &name) const {
return outputs_.find(name)->second; return outputs_.find(name)->second;
} }
Attribute OpDesc::GetAttr(const std::string &name) const { Attribute OpDesc::GetAttr(const std::string &name) const {
auto it = attrs_.find(name); auto it = attrs_.find(name);
return it->second; return it->second;
} }
const std::unordered_map<std::string, Attribute> & const std::unordered_map<std::string, Attribute> &OpDesc::GetAttrMap() const {
OpDesc::GetAttrMap() const {
return attrs_; return attrs_;
} }
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -23,15 +23,13 @@ SOFTWARE. ...@@ -23,15 +23,13 @@ SOFTWARE.
#include "paddle_mobile_object.h" #include "paddle_mobile_object.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
class OpDesc : PaddleMobileObject { class OpDesc : PaddleMobileObject {
public: public:
OpDesc(const proto::OpDesc &desc); OpDesc(const proto::OpDesc &desc);
const std::vector<std::string> & const std::vector<std::string> &Input(const std::string &name) const;
Input(const std::string &name) const; const std::vector<std::string> &Output(const std::string &name) const;
const std::vector<std::string> &
Output(const std::string &name) const;
Attribute GetAttr(const std::string &name) const; Attribute GetAttr(const std::string &name) const;
const VariableNameMap &GetInputs() { return inputs_; } const VariableNameMap &GetInputs() { return inputs_; }
...@@ -47,7 +45,7 @@ namespace paddle_mobile { ...@@ -47,7 +45,7 @@ namespace paddle_mobile {
VariableNameMap inputs_; VariableNameMap inputs_;
VariableNameMap outputs_; VariableNameMap outputs_;
AttributeMap attrs_; AttributeMap attrs_;
}; };
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -22,9 +22,9 @@ SOFTWARE. ...@@ -22,9 +22,9 @@ SOFTWARE.
#include "framework.pb.h" #include "framework.pb.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
template <typename Dtype> struct OpInfo { template <typename Dtype> struct OpInfo {
OpCreator<Dtype> creator_; OpCreator<Dtype> creator_;
const OpCreator<Dtype> &Creator() const { const OpCreator<Dtype> &Creator() const {
// PADDLE_ENFORCE_NOT_NULL(creator_, // PADDLE_ENFORCE_NOT_NULL(creator_,
...@@ -32,14 +32,13 @@ namespace paddle_mobile { ...@@ -32,14 +32,13 @@ namespace paddle_mobile {
// registered"); // registered");
return creator_; return creator_;
} }
}; };
template <typename Dtype> class OpInfoMap; template <typename Dtype> class OpInfoMap;
template <typename Dtype> template <typename Dtype> static OpInfoMap<Dtype> *g_op_info_map = nullptr;
static OpInfoMap<Dtype> *g_op_info_map = nullptr;
template <typename Dtype> class OpInfoMap { template <typename Dtype> class OpInfoMap {
public: public:
static OpInfoMap &Instance() { static OpInfoMap &Instance() {
if (g_op_info_map<Dtype> == nullptr) { if (g_op_info_map<Dtype> == nullptr) {
...@@ -89,7 +88,7 @@ namespace paddle_mobile { ...@@ -89,7 +88,7 @@ namespace paddle_mobile {
std::unordered_map<std::string, OpInfo<Dtype>> map_; std::unordered_map<std::string, OpInfo<Dtype>> map_;
// DISABLE_COPY_AND_ASSIGN(OpInfoMap); // DISABLE_COPY_AND_ASSIGN(OpInfoMap);
}; };
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -22,12 +22,11 @@ SOFTWARE. ...@@ -22,12 +22,11 @@ SOFTWARE.
#include "framework.pb.h" #include "framework.pb.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
struct OpKernelType { struct OpKernelType {
struct Hash { struct Hash {
size_t operator()(const OpKernelType &key) const { size_t operator()(const OpKernelType &key) const {
int data_type = static_cast<int>(key.data_type_) int data_type = static_cast<int>(key.data_type_) << LEFT_SHIFT;
<< LEFT_SHIFT;
int data_layout = static_cast<int>(key.data_layout_) int data_layout = static_cast<int>(key.data_layout_)
<< (LEFT_SHIFT * 2); << (LEFT_SHIFT * 2);
...@@ -47,26 +46,20 @@ namespace paddle_mobile { ...@@ -47,26 +46,20 @@ namespace paddle_mobile {
: data_type_(data_type), data_layout_(data_layout) {} : data_type_(data_type), data_layout_(data_layout) {}
bool operator==(const OpKernelType &o) const { bool operator==(const OpKernelType &o) const {
return data_type_ == o.data_type_ && return data_type_ == o.data_type_ && data_layout_ == o.data_layout_;
data_layout_ == o.data_layout_;
} }
bool operator!=(const OpKernelType &o) const { bool operator!=(const OpKernelType &o) const { return !(*this == o); }
return !(*this == o); };
}
};
inline bool NeedTransformLayout(const DataLayout &l, inline bool NeedTransformLayout(const DataLayout &l, const DataLayout &r) {
const DataLayout &r) { return l != DataLayout::kAnyLayout && r != DataLayout::kAnyLayout && l != r;
return l != DataLayout::kAnyLayout && r != DataLayout::kAnyLayout && }
l != r;
}
inline bool TransFromNeeded(const OpKernelType &l, inline bool TransFromNeeded(const OpKernelType &l, const OpKernelType &r) {
const OpKernelType &r) {
return (l.data_type_ != r.data_type_) || return (l.data_type_ != r.data_type_) ||
NeedTransformLayout(l.data_layout_, r.data_layout_); NeedTransformLayout(l.data_layout_, r.data_layout_);
} }
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -19,8 +19,8 @@ SOFTWARE. ...@@ -19,8 +19,8 @@ SOFTWARE.
#pragma once #pragma once
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
// this class not only make proto but also init attribute checkers. // this class not only make proto but also init attribute checkers.
class OpProtoAndCheckerMaker {}; class OpProtoAndCheckerMaker {};
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -20,10 +20,10 @@ SOFTWARE. ...@@ -20,10 +20,10 @@ SOFTWARE.
#include "op_info.h" #include "op_info.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
template <typename Dtype> template <typename Dtype>
OperatorBase<Dtype>::OperatorBase(const std::string &type, OperatorBase<Dtype>::OperatorBase(const std::string &type,
const VariableNameMap &inputs, const VariableNameMap &inputs,
const VariableNameMap &outputs, const VariableNameMap &outputs,
const AttributeMap &attrs, const AttributeMap &attrs,
...@@ -31,12 +31,12 @@ namespace paddle_mobile { ...@@ -31,12 +31,12 @@ namespace paddle_mobile {
: type_(type), inputs_(inputs), outputs_(outputs), attrs_(attrs), : type_(type), inputs_(inputs), outputs_(outputs), attrs_(attrs),
scope_(scope) { scope_(scope) {
CheckAllInputOutputSet(); CheckAllInputOutputSet();
} }
template <typename Dtype> template <typename Dtype>
void OperatorBase<Dtype>::CheckAllInputOutputSet() const {} void OperatorBase<Dtype>::CheckAllInputOutputSet() const {}
template class OperatorBase<CPU>; template class OperatorBase<CPU>;
template class OperatorWithKernel<CPU>; template class OperatorWithKernel<CPU>;
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -33,8 +33,8 @@ SOFTWARE. ...@@ -33,8 +33,8 @@ SOFTWARE.
#include "variable.h" #include "variable.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
static std::unordered_map<std::string, std::vector<std::string>> static std::unordered_map<std::string, std::vector<std::string>>
op_input_output_key = { op_input_output_key = {
{"conv2d", {"Input", "Output"}}, {"relu", {"X", "Out"}}, {"conv2d", {"Input", "Output"}}, {"relu", {"X", "Out"}},
{"softmax", {"X", "Out"}}, {"mul", {"X", "Out"}}, {"softmax", {"X", "Out"}}, {"mul", {"X", "Out"}},
...@@ -42,13 +42,12 @@ namespace paddle_mobile { ...@@ -42,13 +42,12 @@ namespace paddle_mobile {
{"batch_norm", {"X", "Y"}}, {"lrn", {"X", "Out"}}, {"batch_norm", {"X", "Y"}}, {"lrn", {"X", "Out"}},
{"concat", {"X", "Out"}}, {"concat", {"X", "Out"}},
}; };
template <typename Dtype> class OperatorBase : PaddleMobileObject { template <typename Dtype> class OperatorBase : PaddleMobileObject {
public: public:
OperatorBase(const std::string &type, const VariableNameMap &inputs, OperatorBase(const std::string &type, const VariableNameMap &inputs,
const VariableNameMap &outputs, const VariableNameMap &outputs, const AttributeMap &attrs,
const AttributeMap &attrs,
std::shared_ptr<Scope> scope); std::shared_ptr<Scope> scope);
virtual ~OperatorBase() {} virtual ~OperatorBase() {}
virtual void Run() const = 0; virtual void Run() const = 0;
...@@ -73,28 +72,25 @@ namespace paddle_mobile { ...@@ -73,28 +72,25 @@ namespace paddle_mobile {
private: private:
void CheckAllInputOutputSet() const; void CheckAllInputOutputSet() const;
}; };
template <typename Dtype> template <typename Dtype>
class OperatorWithKernel : public OperatorBase<Dtype> { class OperatorWithKernel : public OperatorBase<Dtype> {
public: public:
OperatorWithKernel(const std::string &type, OperatorWithKernel(const std::string &type, const VariableNameMap &inputs,
const VariableNameMap &inputs,
const VariableNameMap &outputs, const VariableNameMap &outputs,
const AttributeMap &attrs, const AttributeMap &attrs, std::shared_ptr<Scope> scope)
std::shared_ptr<Scope> scope)
: OperatorBase<Dtype>(type, inputs, outputs, attrs, scope) {} : OperatorBase<Dtype>(type, inputs, outputs, attrs, scope) {}
virtual void InferShape() const = 0; virtual void InferShape() const = 0;
virtual void Run() const = 0; virtual void Run() const = 0;
}; };
template <typename Dtype, typename P> template <typename Dtype, typename P> class OpKernelBase : PaddleMobileObject {
class OpKernelBase : PaddleMobileObject {
public: public:
virtual void Compute(const P &para) const = 0; virtual void Compute(const P &para) const = 0;
virtual ~OpKernelBase() = default; virtual ~OpKernelBase() = default;
}; };
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -23,7 +23,7 @@ SOFTWARE. ...@@ -23,7 +23,7 @@ SOFTWARE.
namespace paddle_mobile { namespace paddle_mobile {
class PaddleMobileObject { class PaddleMobileObject {
public: public:
virtual std::string ToString() { virtual std::string ToString() {
char address[128] = {0}; char address[128] = {0};
...@@ -32,5 +32,5 @@ namespace paddle_mobile { ...@@ -32,5 +32,5 @@ namespace paddle_mobile {
} }
private: private:
}; };
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -21,14 +21,14 @@ SOFTWARE. ...@@ -21,14 +21,14 @@ SOFTWARE.
#include "node.h" #include "node.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
Node &Node::operator>(const Node &out) { Node &Node::operator>(const Node &out) {
std::shared_ptr<Node> node = std::make_shared<Node>(Node(out)); std::shared_ptr<Node> node = std::make_shared<Node>(Node(out));
outputs_.push_back(node); outputs_.push_back(node);
return *node; return *node;
} }
bool Node::operator==(const Node &in) { bool Node::operator==(const Node &in) {
if (in.type_ == this->type_) { if (in.type_ == this->type_) {
if (this->outputs_.size() == in.outputs_.size()) { if (this->outputs_.size() == in.outputs_.size()) {
for (int i = 0; i < outputs_.size(); ++i) { for (int i = 0; i < outputs_.size(); ++i) {
...@@ -43,22 +43,22 @@ namespace paddle_mobile { ...@@ -43,22 +43,22 @@ namespace paddle_mobile {
return false; return false;
} }
return true; return true;
} }
std::string Node::ToString(std::string blank) const { std::string Node::ToString(std::string blank) const {
std::stringstream ss; std::stringstream ss;
ss << type_ << ": \n"; ss << type_ << ": \n";
for (int i = 0; i < outputs_.size(); ++i) { for (int i = 0; i < outputs_.size(); ++i) {
ss << blank << outputs_[i]->ToString(blank + " ") << ""; ss << blank << outputs_[i]->ToString(blank + " ") << "";
} }
return ss.str(); return ss.str();
} }
std::string Node::ToString() const { return this->ToString(" "); } std::string Node::ToString() const { return this->ToString(" "); }
Print &operator<<(Print &printer, const Node &node) { Print &operator<<(Print &printer, const Node &node) {
printer << node.ToString(); printer << node.ToString();
return printer; return printer;
}
}
} }
} // namespace framework
} // namespace paddle_mobile
...@@ -25,9 +25,9 @@ SOFTWARE. ...@@ -25,9 +25,9 @@ SOFTWARE.
#include "framework/paddle_mobile_object.h" #include "framework/paddle_mobile_object.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
class Node : PaddleMobileObject { class Node : PaddleMobileObject {
public: public:
Node(const std::string &type) : type_(type) {} Node(const std::string &type) : type_(type) {}
...@@ -39,8 +39,8 @@ namespace paddle_mobile { ...@@ -39,8 +39,8 @@ namespace paddle_mobile {
std::string ToString(std::string blank) const; std::string ToString(std::string blank) const;
std::vector<std::shared_ptr<Node>> outputs_; std::vector<std::shared_ptr<Node>> outputs_;
std::string type_; std::string type_;
}; };
Print &operator<<(Print &printer, const Node &node); Print &operator<<(Print &printer, const Node &node);
} } // namespace framework
} } // namespace paddle_mobile
...@@ -19,7 +19,7 @@ SOFTWARE. ...@@ -19,7 +19,7 @@ SOFTWARE.
#include "program_optimize.h" #include "program_optimize.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
std::shared_ptr<ProgramDesc> ProgramOptimize::Optimize() {} std::shared_ptr<ProgramDesc> ProgramOptimize::Optimize() {}
} } // namespace framework
} } // namespace paddle_mobile
...@@ -21,8 +21,8 @@ SOFTWARE. ...@@ -21,8 +21,8 @@ SOFTWARE.
#include "framework/program_desc.h" #include "framework/program_desc.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
class ProgramOptimize { class ProgramOptimize {
public: public:
ProgramOptimize(std::shared_ptr<ProgramDesc> ori_desc) ProgramOptimize(std::shared_ptr<ProgramDesc> ori_desc)
: ori_desc_(ori_desc) {} : ori_desc_(ori_desc) {}
...@@ -30,6 +30,6 @@ namespace paddle_mobile { ...@@ -30,6 +30,6 @@ namespace paddle_mobile {
private: private:
std::shared_ptr<ProgramDesc> ori_desc_; std::shared_ptr<ProgramDesc> ori_desc_;
}; };
} } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -17,5 +17,5 @@ SOFTWARE. ...@@ -17,5 +17,5 @@ SOFTWARE.
==============================================================================*/ ==============================================================================*/
namespace paddle_mobile { namespace paddle_mobile {
namespace framework {} namespace framework {}
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -24,17 +24,17 @@ SOFTWARE. ...@@ -24,17 +24,17 @@ SOFTWARE.
#include "scope.h" #include "scope.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
template <typename Dtype, Precision P = Precision::FP32> template <typename Dtype, Precision P = Precision::FP32>
class Program : PaddleMobileObject { class Program : PaddleMobileObject {
public: public:
std::shared_ptr<ProgramDesc> originProgram; std::shared_ptr<ProgramDesc> originProgram;
std::shared_ptr<ProgramDesc> optimizeProgram; std::shared_ptr<ProgramDesc> optimizeProgram;
std::shared_ptr<Scope> scope; std::shared_ptr<Scope> scope;
private: private:
}; };
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -5,18 +5,18 @@ ...@@ -5,18 +5,18 @@
#include "program_desc.h" #include "program_desc.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
ProgramDesc::ProgramDesc(const proto::ProgramDesc &desc) : desc_(desc) { ProgramDesc::ProgramDesc(const proto::ProgramDesc &desc) : desc_(desc) {
for (auto &block_desc : *desc_.mutable_blocks()) { for (auto &block_desc : *desc_.mutable_blocks()) {
// new framework::BlockDesc(block_desc) // new framework::BlockDesc(block_desc)
blocks_.emplace_back(std::make_shared<BlockDesc>(block_desc)); blocks_.emplace_back(std::make_shared<BlockDesc>(block_desc));
} }
} }
std::shared_ptr<BlockDesc> ProgramDesc::Block(size_t idx) { std::shared_ptr<BlockDesc> ProgramDesc::Block(size_t idx) {
return blocks_[idx]; return blocks_[idx];
} }
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -25,20 +25,18 @@ SOFTWARE. ...@@ -25,20 +25,18 @@ SOFTWARE.
#include "paddle_mobile_object.h" #include "paddle_mobile_object.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
class ProgramDesc : PaddleMobileObject { class ProgramDesc : PaddleMobileObject {
public: public:
ProgramDesc(const proto::ProgramDesc &desc); ProgramDesc(const proto::ProgramDesc &desc);
std::shared_ptr<BlockDesc> Block(size_t idx); std::shared_ptr<BlockDesc> Block(size_t idx);
const std::vector<std::shared_ptr<BlockDesc>> &Blocks() { const std::vector<std::shared_ptr<BlockDesc>> &Blocks() { return blocks_; };
return blocks_;
};
private: private:
std::vector<std::shared_ptr<BlockDesc>> blocks_; std::vector<std::shared_ptr<BlockDesc>> blocks_;
proto::ProgramDesc desc_; proto::ProgramDesc desc_;
}; };
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -4,15 +4,15 @@ ...@@ -4,15 +4,15 @@
#include <vector> #include <vector>
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
Scope &Scope::NewScope() const { Scope &Scope::NewScope() const {
std::unique_lock<std::mutex> lock(mutex_); std::unique_lock<std::mutex> lock(mutex_);
kids_.push_back(new Scope(this)); kids_.push_back(new Scope(this));
return *kids_.back(); return *kids_.back();
} }
Variable *Scope::Var(const std::string &name) { Variable *Scope::Var(const std::string &name) {
auto *pvar = FindVarLocally(name); auto *pvar = FindVarLocally(name);
if (pvar != nullptr) { if (pvar != nullptr) {
return pvar; return pvar;
...@@ -21,59 +21,59 @@ namespace paddle_mobile { ...@@ -21,59 +21,59 @@ namespace paddle_mobile {
vars_[name] = pvar; vars_[name] = pvar;
pvar->name_ = &(vars_.find(name)->first); pvar->name_ = &(vars_.find(name)->first);
return pvar; return pvar;
} }
// Variable* Scope::Var(std::string* name) { // Variable* Scope::Var(std::string* name) {
// auto var_name = string::Sprintf("%p.%d", this, // auto var_name = string::Sprintf("%p.%d", this,
// vars_.size()); // vars_.size());
// if (name != nullptr) { // if (name != nullptr) {
// *name = var_name; // *name = var_name;
// } // }
// return Var(var_name); // return Var(var_name);
// } // }
Variable *Scope::FindVar(const std::string &name) const { Variable *Scope::FindVar(const std::string &name) const {
auto *pvar = FindVarLocally(name); auto *pvar = FindVarLocally(name);
if (pvar != nullptr) { if (pvar != nullptr) {
return pvar; return pvar;
} }
return (parent_ == nullptr) ? nullptr : parent_->FindVar(name); return (parent_ == nullptr) ? nullptr : parent_->FindVar(name);
} }
const Scope *Scope::FindScope(const Variable *var) const { const Scope *Scope::FindScope(const Variable *var) const {
for (auto &name_var : vars_) { for (auto &name_var : vars_) {
if (name_var.second == var) { if (name_var.second == var) {
return this; return this;
} }
} }
return (parent_ == nullptr) ? nullptr : parent_->FindScope(var); return (parent_ == nullptr) ? nullptr : parent_->FindScope(var);
} }
void Scope::DropKids() { void Scope::DropKids() {
for (Scope *s : kids_) { for (Scope *s : kids_) {
delete s; delete s;
} }
kids_.clear(); kids_.clear();
} }
std::vector<std::string> Scope::LocalVarNames() const { std::vector<std::string> Scope::LocalVarNames() const {
std::vector<std::string> known_vars; std::vector<std::string> known_vars;
known_vars.reserve(vars_.size()); known_vars.reserve(vars_.size());
for (auto &name_var : vars_) { for (auto &name_var : vars_) {
known_vars.emplace_back(name_var.first); known_vars.emplace_back(name_var.first);
} }
return known_vars; return known_vars;
} }
void Scope::DeleteScope(Scope *scope) const { void Scope::DeleteScope(Scope *scope) const {
std::unique_lock<std::mutex> lock(mutex_); std::unique_lock<std::mutex> lock(mutex_);
auto it = std::find(kids_.begin(), kids_.end(), scope); auto it = std::find(kids_.begin(), kids_.end(), scope);
kids_.erase(it); kids_.erase(it);
delete scope; delete scope;
// deferent // deferent
} }
void Scope::EraseVars(const std::vector<std::string> &var_names) { void Scope::EraseVars(const std::vector<std::string> &var_names) {
std::set<std::string> var_set(var_names.begin(), var_names.end()); std::set<std::string> var_set(var_names.begin(), var_names.end());
for (auto it = vars_.begin(); it != vars_.end();) { for (auto it = vars_.begin(); it != vars_.end();) {
if (var_set.find(it->first) != var_set.end()) { if (var_set.find(it->first) != var_set.end()) {
...@@ -83,9 +83,9 @@ namespace paddle_mobile { ...@@ -83,9 +83,9 @@ namespace paddle_mobile {
++it; ++it;
} }
} }
} }
void Scope::Rename(const std::string &origin_name, void Scope::Rename(const std::string &origin_name,
const std::string &new_name) const { const std::string &new_name) const {
auto origin_it = vars_.find(origin_name); auto origin_it = vars_.find(origin_name);
if (origin_it == vars_.end()) { if (origin_it == vars_.end()) {
...@@ -97,23 +97,23 @@ namespace paddle_mobile { ...@@ -97,23 +97,23 @@ namespace paddle_mobile {
} }
vars_[new_name] = origin_it->second; vars_[new_name] = origin_it->second;
vars_.erase(origin_it); vars_.erase(origin_it);
} }
// //
// std::string Scope::Rename(const std::string& origin_name) // std::string Scope::Rename(const std::string& origin_name)
// const { // const {
// auto var_name = string::Sprintf("%p.%d", this, // auto var_name = string::Sprintf("%p.%d", this,
// vars_.size()); // vars_.size());
// Rename(origin_name, var_name); // Rename(origin_name, var_name);
// return var_name; // return var_name;
// } // }
Variable *Scope::FindVarLocally(const std::string &name) const { Variable *Scope::FindVarLocally(const std::string &name) const {
auto it = vars_.find(name); auto it = vars_.find(name);
if (it != vars_.end()) { if (it != vars_.end()) {
return it->second; return it->second;
} }
return nullptr; return nullptr;
} }
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -24,8 +24,8 @@ SOFTWARE. ...@@ -24,8 +24,8 @@ SOFTWARE.
#include <unordered_map> //std::unordered_map #include <unordered_map> //std::unordered_map
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
class Scope { class Scope {
public: public:
Scope() {} Scope() {}
~Scope() {} ~Scope() {}
...@@ -76,6 +76,6 @@ namespace paddle_mobile { ...@@ -76,6 +76,6 @@ namespace paddle_mobile {
Scope const *parent_{nullptr}; Scope const *parent_{nullptr};
mutable std::mutex mutex_; mutable std::mutex mutex_;
}; };
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -24,12 +24,11 @@ SOFTWARE. ...@@ -24,12 +24,11 @@ SOFTWARE.
#include "tensor.h" #include "tensor.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
class SelectedRows { class SelectedRows {
public: public:
SelectedRows(const std::vector<int64_t> &rows, SelectedRows(const std::vector<int64_t> &rows, const int64_t &height)
const int64_t &height)
: rows_(rows), height_(height) { : rows_(rows), height_(height) {
value_.reset(new Tensor()); value_.reset(new Tensor());
} }
...@@ -76,7 +75,7 @@ namespace paddle_mobile { ...@@ -76,7 +75,7 @@ namespace paddle_mobile {
std::vector<int64_t> rows_; std::vector<int64_t> rows_;
std::unique_ptr<Tensor> value_{nullptr}; std::unique_ptr<Tensor> value_{nullptr};
int64_t height_; int64_t height_;
}; };
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -25,10 +25,10 @@ limitations under the License. */ ...@@ -25,10 +25,10 @@ limitations under the License. */
#include "memory/t_malloc.h" #include "memory/t_malloc.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
template <typename... T> struct SizeOfTypeFunctor; template <typename... T> struct SizeOfTypeFunctor;
template <typename T> struct SizeOfTypeFunctor<T> { template <typename T> struct SizeOfTypeFunctor<T> {
size_t operator()(std::type_index type) const { size_t operator()(std::type_index type) const {
if (typeid(T).hash_code() == type.hash_code()) { if (typeid(T).hash_code() == type.hash_code()) {
return sizeof(T); return sizeof(T);
...@@ -36,14 +36,14 @@ namespace paddle_mobile { ...@@ -36,14 +36,14 @@ namespace paddle_mobile {
return 0UL; return 0UL;
} }
} }
}; };
template <> struct SizeOfTypeFunctor<> { template <> struct SizeOfTypeFunctor<> {
size_t operator()(std::type_index type) const { return 0UL; } size_t operator()(std::type_index type) const { return 0UL; }
}; };
template <typename HEAD, typename... TAIL> template <typename HEAD, typename... TAIL>
struct SizeOfTypeFunctor<HEAD, TAIL...> { struct SizeOfTypeFunctor<HEAD, TAIL...> {
size_t operator()(std::type_index type) const { size_t operator()(std::type_index type) const {
SizeOfTypeFunctor<HEAD> head; SizeOfTypeFunctor<HEAD> head;
size_t head_size = head(type); size_t head_size = head(type);
...@@ -53,21 +53,20 @@ namespace paddle_mobile { ...@@ -53,21 +53,20 @@ namespace paddle_mobile {
SizeOfTypeFunctor<TAIL...> tail; SizeOfTypeFunctor<TAIL...> tail;
return tail(type); return tail(type);
} }
}; };
static inline size_t SizeOfType(std::type_index type) { static inline size_t SizeOfType(std::type_index type) {
SizeOfTypeFunctor<int, float, double, int16_t, int64_t, bool, SizeOfTypeFunctor<int, float, double, int16_t, int64_t, bool, size_t>
size_t>
functor; functor;
size_t size = functor(type); size_t size = functor(type);
// PADDLE_ENFORCE(size != 0UL, "Cannot get size of type %s", // PADDLE_ENFORCE(size != 0UL, "Cannot get size of type %s",
// type.name()); // type.name());
return size; return size;
} }
class LoDTensor; class LoDTensor;
class Tensor { class Tensor {
public: public:
Tensor() : offset_(0) {} Tensor() : offset_(0) {}
...@@ -200,8 +199,7 @@ namespace paddle_mobile { ...@@ -200,8 +199,7 @@ namespace paddle_mobile {
DDim dst_dims = dims_; DDim dst_dims = dims_;
dst_dims[0] = end_idx - begin_idx; dst_dims[0] = end_idx - begin_idx;
dst.Resize(dst_dims); dst.Resize(dst_dims);
dst.offset_ = dst.offset_ = offset_ + begin_idx * base * SizeOfType(type());
offset_ + begin_idx * base * SizeOfType(type());
return dst; return dst;
} }
} }
...@@ -236,9 +234,7 @@ namespace paddle_mobile { ...@@ -236,9 +234,7 @@ namespace paddle_mobile {
inline DataLayout layout() const { return layout_; } inline DataLayout layout() const { return layout_; }
inline void set_layout(const DataLayout layout) { inline void set_layout(const DataLayout layout) { layout_ = layout; }
layout_ = layout;
}
private: private:
/** /**
...@@ -274,9 +270,7 @@ namespace paddle_mobile { ...@@ -274,9 +270,7 @@ namespace paddle_mobile {
virtual size_t size() const { return size_; } virtual size_t size() const { return size_; }
virtual void *ptr() const { virtual void *ptr() const { return static_cast<void *>(ptr_.get()); }
return static_cast<void *>(ptr_.get());
}
virtual std::type_index type() const { return type_; } virtual std::type_index type() const { return type_; }
...@@ -327,14 +321,14 @@ namespace paddle_mobile { ...@@ -327,14 +321,14 @@ namespace paddle_mobile {
* begins. * begins.
*/ */
size_t offset_; size_t offset_;
}; };
inline Tensor ReshapeToMatrix(const Tensor &src, int num_col_dims) { inline Tensor ReshapeToMatrix(const Tensor &src, int num_col_dims) {
Tensor res; Tensor res;
res.ShareDataWith(src); res.ShareDataWith(src);
res.Resize(flatten_to_2d(src.dims(), num_col_dims)); res.Resize(flatten_to_2d(src.dims(), num_col_dims));
return res; return res;
} }
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
#include <vector> #include <vector>
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
void TensorCopy(const Tensor &src, Tensor *dst) { void TensorCopy(const Tensor &src, Tensor *dst) {
// VLOG(3) << "TensorCopy " << src.dims() << " from " << // VLOG(3) << "TensorCopy " << src.dims() << " from " <<
// src.place() << " to // src.place() << " to
// " // "
...@@ -36,9 +36,9 @@ namespace paddle_mobile { ...@@ -36,9 +36,9 @@ namespace paddle_mobile {
auto size = src.numel() * SizeOfType(src.type()); auto size = src.numel() * SizeOfType(src.type());
memory::Copy(dst_ptr, src_ptr, size); memory::Copy(dst_ptr, src_ptr, size);
} }
void TensorCopySync(const Tensor &src, Tensor *dst) { void TensorCopySync(const Tensor &src, Tensor *dst) {
// VLOG(3) << "TensorCopySync " << src.dims() << " from " << // VLOG(3) << "TensorCopySync " << src.dims() << " from " <<
// src.place() // src.place()
// << " to " << dst_place; // << " to " << dst_place;
...@@ -49,15 +49,14 @@ namespace paddle_mobile { ...@@ -49,15 +49,14 @@ namespace paddle_mobile {
auto dst_ptr = dst->mutable_data(src.type()); auto dst_ptr = dst->mutable_data(src.type());
auto size = src.numel() * SizeOfType(src.type()); auto size = src.numel() * SizeOfType(src.type());
memory::Copy(dst_ptr, src_ptr, size); memory::Copy(dst_ptr, src_ptr, size);
} }
template <typename Predicate> struct AnyDTypeVisitor { template <typename Predicate> struct AnyDTypeVisitor {
Predicate predicate_; Predicate predicate_;
const Tensor &tensor_; const Tensor &tensor_;
Tensor *out_; Tensor *out_;
AnyDTypeVisitor(Predicate predicate, const Tensor &tensor, AnyDTypeVisitor(Predicate predicate, const Tensor &tensor, Tensor *out)
Tensor *out)
: predicate_(predicate), tensor_(tensor), out_(out) {} : predicate_(predicate), tensor_(tensor), out_(out) {}
template <typename T> void operator()() const { template <typename T> void operator()() const {
...@@ -66,16 +65,16 @@ namespace paddle_mobile { ...@@ -66,16 +65,16 @@ namespace paddle_mobile {
// return any of predicate_(t) is true. // return any of predicate_(t) is true.
// o.device(*ctx_.eigen_device()) = predicate_(t).any(); // o.device(*ctx_.eigen_device()) = predicate_(t).any();
} }
}; };
template <typename Predicate> template <typename Predicate>
inline void AnyImpl(Predicate predicate, const Tensor &tensor, inline void AnyImpl(Predicate predicate, const Tensor &tensor,
framework::Tensor *out) { framework::Tensor *out) {
VisitDataType(ToDataType(tensor.type()), VisitDataType(ToDataType(tensor.type()),
AnyDTypeVisitor<Predicate>(predicate, tensor, out)); AnyDTypeVisitor<Predicate>(predicate, tensor, out));
} }
template <typename Predicate> struct AnyVisitor { template <typename Predicate> struct AnyVisitor {
const framework::Tensor &tensor_; const framework::Tensor &tensor_;
Predicate predicate_; Predicate predicate_;
...@@ -93,48 +92,47 @@ namespace paddle_mobile { ...@@ -93,48 +92,47 @@ namespace paddle_mobile {
bool GetResult(const framework::Tensor &out) const { bool GetResult(const framework::Tensor &out) const {
return *out.data<bool>(); return *out.data<bool>();
} }
}; };
template <typename Predicate> template <typename Predicate>
inline bool Any(const framework::Tensor &tensor, Predicate predicate) { inline bool Any(const framework::Tensor &tensor, Predicate predicate) {
AnyVisitor<Predicate> visitor(tensor, predicate); AnyVisitor<Predicate> visitor(tensor, predicate);
// return platform::VisitPlace(visitor); // return platform::VisitPlace(visitor);
return visitor(); return visitor();
} }
struct ContainsNANPredicate { struct ContainsNANPredicate {
template <typename T> template <typename T>
auto operator()(const T &eigen_vec) const auto operator()(const T &eigen_vec) const
-> decltype(std::declval<T>().isnan()) { -> decltype(std::declval<T>().isnan()) {
// Cast eigen_vector to vector of bool. true if is inf. // Cast eigen_vector to vector of bool. true if is inf.
return eigen_vec.isnan(); return eigen_vec.isnan();
} }
}; };
bool TensorContainsNAN(const framework::Tensor &tensor) { bool TensorContainsNAN(const framework::Tensor &tensor) {
ContainsNANPredicate predicate; ContainsNANPredicate predicate;
return Any(tensor, predicate); return Any(tensor, predicate);
} }
struct ContainsInfPredicate { struct ContainsInfPredicate {
template <typename T> template <typename T>
auto operator()(const T &eigen_vec) const auto operator()(const T &eigen_vec) const
-> decltype(std::declval<T>().isinf()) { -> decltype(std::declval<T>().isinf()) {
// Cast eigen_vector to vector of bool. true if is inf. // Cast eigen_vector to vector of bool. true if is inf.
return eigen_vec.isinf(); return eigen_vec.isinf();
} }
}; };
bool TensorContainsInf(const framework::Tensor &tensor) { bool TensorContainsInf(const framework::Tensor &tensor) {
ContainsInfPredicate predicate; ContainsInfPredicate predicate;
return Any(tensor, predicate); return Any(tensor, predicate);
} }
void TensorToStream(std::ostream &os, const Tensor &tensor) { void TensorToStream(std::ostream &os, const Tensor &tensor) {
{ // the 1st field, uint32_t version { // the 1st field, uint32_t version
constexpr uint32_t version = 0; constexpr uint32_t version = 0;
os.write(reinterpret_cast<const char *>(&version), os.write(reinterpret_cast<const char *>(&version), sizeof(version));
sizeof(version));
} }
{ // the 2nd field, tensor description { // the 2nd field, tensor description
// int32_t size // int32_t size
...@@ -160,9 +158,9 @@ namespace paddle_mobile { ...@@ -160,9 +158,9 @@ namespace paddle_mobile {
os.write(static_cast<const char *>(data_ptr), os.write(static_cast<const char *>(data_ptr),
static_cast<std::streamsize>(size)); static_cast<std::streamsize>(size));
} }
} }
struct DeserializedDataFunctor { struct DeserializedDataFunctor {
DeserializedDataFunctor(void **buf, Tensor *tensor) DeserializedDataFunctor(void **buf, Tensor *tensor)
: buf_(buf), tensor_(tensor) {} : buf_(buf), tensor_(tensor) {}
...@@ -172,9 +170,9 @@ namespace paddle_mobile { ...@@ -172,9 +170,9 @@ namespace paddle_mobile {
void **buf_; void **buf_;
Tensor *tensor_; Tensor *tensor_;
}; };
void TensorFromStream(std::istream &is, framework::Tensor *tensor) { void TensorFromStream(std::istream &is, framework::Tensor *tensor) {
uint32_t version; uint32_t version;
is.read(reinterpret_cast<char *>(&version), sizeof(version)); is.read(reinterpret_cast<char *>(&version), sizeof(version));
// PADDLE_ENFORCE_EQ(version, 0U, "Only version 0 is supported"); // PADDLE_ENFORCE_EQ(version, 0U, "Only version 0 is supported");
...@@ -200,7 +198,7 @@ namespace paddle_mobile { ...@@ -200,7 +198,7 @@ namespace paddle_mobile {
DeserializedDataFunctor(&buf, tensor)); DeserializedDataFunctor(&buf, tensor));
is.read(static_cast<char *>(buf), tensor->memory_size()); is.read(static_cast<char *>(buf), tensor->memory_size());
} }
} }
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -20,39 +20,39 @@ limitations under the License. */ ...@@ -20,39 +20,39 @@ limitations under the License. */
#include <vector> #include <vector>
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
void TensorCopy(const Tensor &src, Tensor *dst); void TensorCopy(const Tensor &src, Tensor *dst);
void TensorCopySync(const Tensor &src, Tensor *dst); void TensorCopySync(const Tensor &src, Tensor *dst);
template <typename T> template <typename T>
void TensorFromVector(const std::vector<T> &src, Tensor *dst); void TensorFromVector(const std::vector<T> &src, Tensor *dst);
template <typename T> template <typename T>
void TesnorToVector(const Tensor &src, std::vector<T> *dst); void TesnorToVector(const Tensor &src, std::vector<T> *dst);
bool TensorContainsNAN(const framework::Tensor &tensor); bool TensorContainsNAN(const framework::Tensor &tensor);
bool TensorContainsInf(const framework::Tensor &tensor); bool TensorContainsInf(const framework::Tensor &tensor);
void TensorToStream(std::ostream &os, const Tensor &tensor); void TensorToStream(std::ostream &os, const Tensor &tensor);
void TensorFromStream(std::istream &is, Tensor *tensor); void TensorFromStream(std::istream &is, Tensor *tensor);
// //
// The implementation of template functions. // The implementation of template functions.
// //
template <typename T> template <typename T>
void TensorFromVector(const std::vector<T> &src, Tensor *dst) { void TensorFromVector(const std::vector<T> &src, Tensor *dst) {
auto src_ptr = static_cast<const void *>(src.data()); auto src_ptr = static_cast<const void *>(src.data());
dst->Resize({static_cast<int64_t>(src.size())}); dst->Resize({static_cast<int64_t>(src.size())});
auto dst_ptr = static_cast<void *>(dst->mutable_data<T>()); auto dst_ptr = static_cast<void *>(dst->mutable_data<T>());
auto size = src.size() * sizeof(T); auto size = src.size() * sizeof(T);
memory::Copy(dst_ptr, src_ptr, size); memory::Copy(dst_ptr, src_ptr, size);
} }
template <typename T> template <typename T>
void TensorToVector(const Tensor &src, std::vector<T> *dst) { void TensorToVector(const Tensor &src, std::vector<T> *dst) {
auto src_ptr = static_cast<const void *>(src.data<T>()); auto src_ptr = static_cast<const void *>(src.data<T>());
auto size = src.numel() * sizeof(T); auto size = src.numel() * sizeof(T);
...@@ -60,7 +60,7 @@ namespace paddle_mobile { ...@@ -60,7 +60,7 @@ namespace paddle_mobile {
auto dst_ptr = static_cast<void *>(dst->data()); auto dst_ptr = static_cast<void *>(dst->data());
memory::Copy(dst_ptr, src_ptr, size); memory::Copy(dst_ptr, src_ptr, size);
} }
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -20,9 +20,9 @@ SOFTWARE. ...@@ -20,9 +20,9 @@ SOFTWARE.
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
VarDesc::VarDesc(const proto::VarDesc &desc) : desc_(desc) {} VarDesc::VarDesc(const proto::VarDesc &desc) : desc_(desc) {}
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -22,9 +22,9 @@ SOFTWARE. ...@@ -22,9 +22,9 @@ SOFTWARE.
#include "paddle_mobile_object.h" #include "paddle_mobile_object.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
class VarDesc { class VarDesc {
public: public:
VarDesc(const proto::VarDesc &desc); VarDesc(const proto::VarDesc &desc);
...@@ -68,8 +68,7 @@ namespace paddle_mobile { ...@@ -68,8 +68,7 @@ namespace paddle_mobile {
template <typename T> template <typename T>
std::vector<T> RepeatedToVector( std::vector<T> RepeatedToVector(
const google::protobuf::RepeatedField<T> &repeated_field) const google::protobuf::RepeatedField<T> &repeated_field) const {
const {
std::vector<T> ret; std::vector<T> ret;
ret.reserve(repeated_field.size()); ret.reserve(repeated_field.size());
std::copy(repeated_field.begin(), repeated_field.end(), std::copy(repeated_field.begin(), repeated_field.end(),
...@@ -83,7 +82,7 @@ namespace paddle_mobile { ...@@ -83,7 +82,7 @@ namespace paddle_mobile {
private: private:
proto::VarDesc desc_; proto::VarDesc desc_;
}; };
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -23,8 +23,8 @@ SOFTWARE. ...@@ -23,8 +23,8 @@ SOFTWARE.
#include "variable.h" #include "variable.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
inline proto::VarType::Type ToVarType(std::type_index type) { inline proto::VarType::Type ToVarType(std::type_index type) {
if (type.hash_code() == typeid(LoDTensor).hash_code()) { if (type.hash_code() == typeid(LoDTensor).hash_code()) {
return proto::VarType_Type_LOD_TENSOR; return proto::VarType_Type_LOD_TENSOR;
} else if (type.hash_code() == typeid(SelectedRows).hash_code()) { } else if (type.hash_code() == typeid(SelectedRows).hash_code()) {
...@@ -33,7 +33,7 @@ namespace paddle_mobile { ...@@ -33,7 +33,7 @@ namespace paddle_mobile {
// PADDLE_THROW("ToVarType:Unsupported type %s", // PADDLE_THROW("ToVarType:Unsupported type %s",
// type.name()); // type.name());
} }
} }
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -26,8 +26,8 @@ SOFTWARE. ...@@ -26,8 +26,8 @@ SOFTWARE.
#include <typeinfo> #include <typeinfo>
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
class Variable : public PaddleMobileObject { class Variable : public PaddleMobileObject {
public: public:
template <typename T> const T *Get() const { template <typename T> const T *Get() const {
return static_cast<const T *>(holder_->Ptr()); return static_cast<const T *>(holder_->Ptr());
...@@ -51,8 +51,8 @@ namespace paddle_mobile { ...@@ -51,8 +51,8 @@ namespace paddle_mobile {
template <typename T> bool IsType() const { template <typename T> bool IsType() const {
if (holder_) { if (holder_) {
// printf("not null \n"); // printf("not null \n");
printf(" holder type : %s, this type %s \n", printf(" holder type : %s, this type %s \n", holder_->Type().name(),
holder_->Type().name(), typeid(T).name()); typeid(T).name());
} }
// std::cout << " " << holder_->Type() << " " << // std::cout << " " << holder_->Type() << " " <<
...@@ -91,6 +91,6 @@ namespace paddle_mobile { ...@@ -91,6 +91,6 @@ namespace paddle_mobile {
std::unique_ptr<Placeholder> holder_; std::unique_ptr<Placeholder> holder_;
friend class Scope; friend class Scope;
const std::string *name_; const std::string *name_;
}; };
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -28,7 +28,7 @@ SOFTWARE. ...@@ -28,7 +28,7 @@ SOFTWARE.
namespace paddle_mobile { namespace paddle_mobile {
void ReadBinaryFile(const std::string &filename, std::string *contents) { void ReadBinaryFile(const std::string &filename, std::string *contents) {
std::ifstream fin(filename, std::ios::in | std::ios::binary); std::ifstream fin(filename, std::ios::in | std::ios::binary);
fin.seekg(0, std::ios::end); fin.seekg(0, std::ios::end);
contents->clear(); contents->clear();
...@@ -36,10 +36,10 @@ namespace paddle_mobile { ...@@ -36,10 +36,10 @@ namespace paddle_mobile {
fin.seekg(0, std::ios::beg); fin.seekg(0, std::ios::beg);
fin.read(&(contents->at(0)), contents->size()); fin.read(&(contents->at(0)), contents->size());
fin.close(); fin.close();
} }
template <typename Dtype, Precision P> template <typename Dtype, Precision P>
void Loader<Dtype, P>::LoadVar(framework::LoDTensor *tensor, void Loader<Dtype, P>::LoadVar(framework::LoDTensor *tensor,
const std::string &file_path) { const std::string &file_path) {
// LOG(kLOG_DEBUG) << " to load " << file_path; // LOG(kLOG_DEBUG) << " to load " << file_path;
// Log(kLOG_DEBUG) << "123"; // Log(kLOG_DEBUG) << "123";
...@@ -77,8 +77,7 @@ namespace paddle_mobile { ...@@ -77,8 +77,7 @@ namespace paddle_mobile {
// 3. tensor version // 3. tensor version
uint32_t tensor_version; uint32_t tensor_version;
is.read(reinterpret_cast<char *>(&tensor_version), is.read(reinterpret_cast<char *>(&tensor_version), sizeof(tensor_version));
sizeof(tensor_version));
// std::cout << " tensor_version: " << tensor_version << std::endl; // std::cout << " tensor_version: " << tensor_version << std::endl;
// 4. tensor desc // 4. tensor desc
...@@ -103,8 +102,7 @@ namespace paddle_mobile { ...@@ -103,8 +102,7 @@ namespace paddle_mobile {
std::vector<int64_t> dims; std::vector<int64_t> dims;
dims.reserve(static_cast<size_t>(desc.dims().size())); dims.reserve(static_cast<size_t>(desc.dims().size()));
std::copy(desc.dims().begin(), desc.dims().end(), std::copy(desc.dims().begin(), desc.dims().end(), std::back_inserter(dims));
std::back_inserter(dims));
tensor->Resize(framework::make_ddim(dims)); tensor->Resize(framework::make_ddim(dims));
void *memory; void *memory;
...@@ -146,11 +144,11 @@ namespace paddle_mobile { ...@@ -146,11 +144,11 @@ namespace paddle_mobile {
is.read(static_cast<char *>(memory), memory_size * type_size); is.read(static_cast<char *>(memory), memory_size * type_size);
// std::cout << " memory: " << memory << std::endl; // std::cout << " memory: " << memory << std::endl;
is.close(); is.close();
}; };
template <typename Dtype, Precision P> template <typename Dtype, Precision P>
const framework::Program<Dtype, P> const framework::Program<Dtype, P>
Loader<Dtype, P>::Load(const std::string &dirname) { Loader<Dtype, P>::Load(const std::string &dirname) {
std::string model_filename = dirname + "/__model__"; std::string model_filename = dirname + "/__model__";
std::string program_desc_str; std::string program_desc_str;
ReadBinaryFile(model_filename, &program_desc_str); ReadBinaryFile(model_filename, &program_desc_str);
...@@ -174,8 +172,7 @@ namespace paddle_mobile { ...@@ -174,8 +172,7 @@ namespace paddle_mobile {
for (int i = 0; i < block->Vars().size(); ++i) { for (int i = 0; i < block->Vars().size(); ++i) {
std::shared_ptr<framework::VarDesc> var_desc = block->Vars()[i]; std::shared_ptr<framework::VarDesc> var_desc = block->Vars()[i];
auto var = scope->Var(var_desc->Name()); auto var = scope->Var(var_desc->Name());
if (var_desc->GetType() == if (var_desc->GetType() == framework::proto::VarType::LOD_TENSOR) {
framework::proto::VarType::LOD_TENSOR) {
if (var_desc->Persistable() && if (var_desc->Persistable() &&
var_desc->GetType() != var_desc->GetType() !=
framework::proto::VarType::FEED_MINIBATCH && framework::proto::VarType::FEED_MINIBATCH &&
...@@ -201,11 +198,9 @@ namespace paddle_mobile { ...@@ -201,11 +198,9 @@ namespace paddle_mobile {
LOG(kLOG_DEBUG1) << " op: " << op.type(); LOG(kLOG_DEBUG1) << " op: " << op.type();
for (int m = 0; m < op.inputs_size(); ++m) { for (int m = 0; m < op.inputs_size(); ++m) {
const framework::proto::OpDesc::Var &var = op.inputs(m); const framework::proto::OpDesc::Var &var = op.inputs(m);
LOG(kLOG_DEBUG2) << " input parameter: " LOG(kLOG_DEBUG2) << " input parameter: " << var.parameter();
<< var.parameter();
for (int n = 0; n < var.arguments().size(); ++n) { for (int n = 0; n < var.arguments().size(); ++n) {
LOG(kLOG_DEBUG3) << " argument - " LOG(kLOG_DEBUG3) << " argument - " << var.arguments()[n];
<< var.arguments()[n];
} }
} }
...@@ -213,8 +208,7 @@ namespace paddle_mobile { ...@@ -213,8 +208,7 @@ namespace paddle_mobile {
const framework::proto::OpDesc::Var &var = op.outputs(y); const framework::proto::OpDesc::Var &var = op.outputs(y);
LOG(kLOG_DEBUG2) << " out parameter: " << var.parameter(); LOG(kLOG_DEBUG2) << " out parameter: " << var.parameter();
for (int z = 0; z < var.arguments().size(); ++z) { for (int z = 0; z < var.arguments().size(); ++z) {
LOG(kLOG_DEBUG3) << " argument - " LOG(kLOG_DEBUG3) << " argument - " << var.arguments()[z];
<< var.arguments()[z];
} }
} }
...@@ -278,8 +272,7 @@ namespace paddle_mobile { ...@@ -278,8 +272,7 @@ namespace paddle_mobile {
for (int k = 0; k < block.vars().size(); ++k) { for (int k = 0; k < block.vars().size(); ++k) {
framework::proto::VarDesc var = block.vars()[k]; framework::proto::VarDesc var = block.vars()[k];
if (var.type().type() == if (var.type().type() == framework::proto::VarType::LOD_TENSOR) {
framework::proto::VarType::LOD_TENSOR) {
// std::cout << " var name: " << var.name() << // std::cout << " var name: " << var.name() <<
// std::endl; // std::endl;
const framework::proto::VarType::TensorDesc &tensor_desc = const framework::proto::VarType::TensorDesc &tensor_desc =
...@@ -299,14 +292,12 @@ namespace paddle_mobile { ...@@ -299,14 +292,12 @@ namespace paddle_mobile {
if (var.persistable() && if (var.persistable() &&
var.type().type() != var.type().type() !=
framework::proto::VarType::FEED_MINIBATCH && framework::proto::VarType::FEED_MINIBATCH &&
var.type().type() != var.type().type() != framework::proto::VarType::FETCH_LIST) {
framework::proto::VarType::FETCH_LIST) {
// std::cout << " to load " << var.name() << // std::cout << " to load " << var.name() <<
// std::endl; // std::endl;
std::string file_path = dirname + "/" + var.name(); std::string file_path = dirname + "/" + var.name();
std::ifstream is(file_path); std::ifstream is(file_path);
std::streampos pos = std::streampos pos = is.tellg(); // save current position
is.tellg(); // save current position
is.seekg(0, std::ios::end); is.seekg(0, std::ios::end);
// std::cout << " file length = " << is.tellg() << // std::cout << " file length = " << is.tellg() <<
// std::endl; // std::endl;
...@@ -314,8 +305,7 @@ namespace paddle_mobile { ...@@ -314,8 +305,7 @@ namespace paddle_mobile {
// 1. version // 1. version
uint32_t version; uint32_t version;
is.read(reinterpret_cast<char *>(&version), is.read(reinterpret_cast<char *>(&version), sizeof(version));
sizeof(version));
// std::cout << " version: " << version << // std::cout << " version: " << version <<
// std::endl; // std::endl;
...@@ -339,8 +329,7 @@ namespace paddle_mobile { ...@@ -339,8 +329,7 @@ namespace paddle_mobile {
} }
uint32_t tensor_version; uint32_t tensor_version;
is.read(reinterpret_cast<char *>(&version), is.read(reinterpret_cast<char *>(&version), sizeof(version));
sizeof(version));
// std::cout << " tensor_version: " << // std::cout << " tensor_version: " <<
// tensor_version << // tensor_version <<
// std::endl; // std::endl;
...@@ -404,8 +393,7 @@ namespace paddle_mobile { ...@@ -404,8 +393,7 @@ namespace paddle_mobile {
// type_size // type_size
// << std::endl; // << std::endl;
void *memory = malloc(memory_size * type_size); void *memory = malloc(memory_size * type_size);
is.read(static_cast<char *>(memory), is.read(static_cast<char *>(memory), memory_size * type_size);
memory_size * type_size);
// std::cout << " memory: " << memory << // std::cout << " memory: " << memory <<
// std::endl; // std::endl;
is.close(); is.close();
...@@ -418,8 +406,8 @@ namespace paddle_mobile { ...@@ -418,8 +406,8 @@ namespace paddle_mobile {
#endif #endif
return program; return program;
} }
template class Loader<CPU, Precision::FP32>; template class Loader<CPU, Precision::FP32>;
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -27,14 +27,13 @@ SOFTWARE. ...@@ -27,14 +27,13 @@ SOFTWARE.
namespace paddle_mobile { namespace paddle_mobile {
template <typename Dtype, Precision P = Precision::FP32> template <typename Dtype, Precision P = Precision::FP32>
class Loader : PaddleMobileObject { class Loader : PaddleMobileObject {
public: public:
const framework::Program<Dtype, P> Load(const std::string &dirname); const framework::Program<Dtype, P> Load(const std::string &dirname);
private: private:
void LoadVar(framework::LoDTensor *tensor, void LoadVar(framework::LoDTensor *tensor, const std::string &file_path);
const std::string &file_path); };
};
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -22,30 +22,30 @@ SOFTWARE. ...@@ -22,30 +22,30 @@ SOFTWARE.
#include <cstring> #include <cstring>
namespace paddle_mobile { namespace paddle_mobile {
namespace memory { namespace memory {
const int MALLOC_ALIGN = 16; const int MALLOC_ALIGN = 16;
void Copy(void *dst, const void *src, size_t num) { void Copy(void *dst, const void *src, size_t num) {
std::memcpy(dst, src, num); std::memcpy(dst, src, num);
}; };
void *Alloc(size_t size) { void *Alloc(size_t size) {
size_t offset = sizeof(void *) + MALLOC_ALIGN - 1; size_t offset = sizeof(void *) + MALLOC_ALIGN - 1;
char *p = static_cast<char *>(malloc(offset + size)); char *p = static_cast<char *>(malloc(offset + size));
if (!p) { if (!p) {
return nullptr; return nullptr;
} }
void *r = reinterpret_cast<void *>( void *r = reinterpret_cast<void *>(reinterpret_cast<size_t>(p + offset) &
reinterpret_cast<size_t>(p + offset) & (~(MALLOC_ALIGN - 1))); (~(MALLOC_ALIGN - 1)));
static_cast<void **>(r)[-1] = p; static_cast<void **>(r)[-1] = p;
return r; return r;
} }
void Free(void *ptr) { void Free(void *ptr) {
if (ptr) { if (ptr) {
free(static_cast<void **>(ptr)[-1]); free(static_cast<void **>(ptr)[-1]);
} }
} }
} // namespace memory } // namespace memory
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -21,15 +21,15 @@ SOFTWARE. ...@@ -21,15 +21,15 @@ SOFTWARE.
#include <type_traits> #include <type_traits>
namespace paddle_mobile { namespace paddle_mobile {
namespace memory { namespace memory {
void Copy(void *dst, const void *src, size_t num); void Copy(void *dst, const void *src, size_t num);
void *Alloc(size_t size); void *Alloc(size_t size);
void Free(void *ptr); void Free(void *ptr);
/** /**
* \brief Free memory block in one place. * \brief Free memory block in one place.
* *
* \note In some cases, custom deleter is used to * \note In some cases, custom deleter is used to
...@@ -37,16 +37,16 @@ namespace paddle_mobile { ...@@ -37,16 +37,16 @@ namespace paddle_mobile {
* std::unique_ptr<T> in tensor.h. * std::unique_ptr<T> in tensor.h.
* static_cast * static_cast
*/ */
template <typename T> class PODDeleter { template <typename T> class PODDeleter {
static_assert(std::is_pod<T>::value, "T must be POD"); static_assert(std::is_pod<T>::value, "T must be POD");
public: public:
explicit PODDeleter(){}; explicit PODDeleter(){};
void operator()(T *ptr) { Free(static_cast<void *>(ptr)); } void operator()(T *ptr) { Free(static_cast<void *>(ptr)); }
}; };
/** /**
* \brief Free memory block in one place does not meet POD * \brief Free memory block in one place does not meet POD
* *
* \note In some cases, custom deleter is used to * \note In some cases, custom deleter is used to
...@@ -54,11 +54,11 @@ namespace paddle_mobile { ...@@ -54,11 +54,11 @@ namespace paddle_mobile {
* std::unique_ptr<T> in tensor.h. * std::unique_ptr<T> in tensor.h.
* reinterpret_cast * reinterpret_cast
*/ */
template <typename T> class PlainDeleter { template <typename T> class PlainDeleter {
public: public:
explicit PlainDeleter(){}; explicit PlainDeleter(){};
void operator()(T *ptr) { Free(reinterpret_cast<void *>(ptr)); } void operator()(T *ptr) { Free(reinterpret_cast<void *>(ptr)); }
}; };
} // namespace memory } // namespace memory
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -19,20 +19,19 @@ SOFTWARE. ...@@ -19,20 +19,19 @@ SOFTWARE.
#include "conv_op.h" #include "conv_op.h"
#include "framework/data_type.h" #include "framework/data_type.h"
#include "framework/op_proto_maker.h" #include "framework/op_proto_maker.h"
#include "framework/operator.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
int ConvOutputSize(int input_size, int filter_size, int dilation, int ConvOutputSize(int input_size, int filter_size, int dilation, int padding,
int padding, int stride) { int stride) {
const int dkernel = dilation * (filter_size - 1) + 1; const int dkernel = dilation * (filter_size - 1) + 1;
int output_size = (input_size + 2 * padding - dkernel) / stride + 1; int output_size = (input_size + 2 * padding - dkernel) / stride + 1;
return output_size; return output_size;
} }
template <typename Dtype, typename T> template <typename Dtype, typename T>
void ConvOp<Dtype, T>::InferShape() const { void ConvOp<Dtype, T>::InferShape() const {
// std::cout << " begin get dims: " << std::endl; // std::cout << " begin get dims: " << std::endl;
auto in_dims = param_.Input()->dims(); auto in_dims = param_.Input()->dims();
...@@ -61,16 +60,16 @@ namespace paddle_mobile { ...@@ -61,16 +60,16 @@ namespace paddle_mobile {
std::vector<int64_t> output_shape({in_dims[0], filter_dims[0]}); std::vector<int64_t> output_shape({in_dims[0], filter_dims[0]});
for (size_t i = 0; i < strides.size(); ++i) { for (size_t i = 0; i < strides.size(); ++i) {
output_shape.push_back( output_shape.push_back(ConvOutputSize(in_dims[i + 2],
ConvOutputSize(in_dims[i + 2], filter_dims[i + 2], filter_dims[i + 2], dilations[i],
dilations[i], paddings[i], strides[i])); paddings[i], strides[i]));
} }
framework::DDim ddim = framework::make_ddim(output_shape); framework::DDim ddim = framework::make_ddim(output_shape);
param_.Output()->Resize(ddim); param_.Output()->Resize(ddim);
} }
template class ConvOp<CPU, float>; template class ConvOp<CPU, float>;
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -22,19 +22,18 @@ SOFTWARE. ...@@ -22,19 +22,18 @@ SOFTWARE.
#include "operators/kernel/conv_kernel.h" #include "operators/kernel/conv_kernel.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
using namespace framework; using namespace framework;
template <typename DeviceType, typename T> template <typename DeviceType, typename T>
class ConvOp : public framework::OperatorWithKernel<DeviceType> { class ConvOp : public framework::OperatorWithKernel<DeviceType> {
public: public:
ConvOp(const std::string &type, const VariableNameMap &inputs, ConvOp(const std::string &type, const VariableNameMap &inputs,
const VariableNameMap &outputs, const VariableNameMap &outputs, const framework::AttributeMap &attrs,
const framework::AttributeMap &attrs,
std::shared_ptr<framework::Scope> scope) std::shared_ptr<framework::Scope> scope)
: framework::OperatorWithKernel<DeviceType>( : framework::OperatorWithKernel<DeviceType>(type, inputs, outputs,
type, inputs, outputs, attrs, scope), attrs, scope),
param_(inputs, outputs, attrs, *scope) {} param_(inputs, outputs, attrs, *scope) {}
using framework::OperatorWithKernel<DeviceType>::OperatorWithKernel; using framework::OperatorWithKernel<DeviceType>::OperatorWithKernel;
...@@ -48,7 +47,7 @@ namespace paddle_mobile { ...@@ -48,7 +47,7 @@ namespace paddle_mobile {
private: private:
ConvParam param_; ConvParam param_;
}; };
} // operators } // namespace operators
} // paddle_mobile } // namespace paddle_mobile
...@@ -19,13 +19,13 @@ SOFTWARE. ...@@ -19,13 +19,13 @@ SOFTWARE.
#include "elementwise_add_op.h" #include "elementwise_add_op.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
template <typename Dtype, typename T> template <typename Dtype, typename T>
void ElementwiseAddOp<Dtype, T>::InferShape() const { void ElementwiseAddOp<Dtype, T>::InferShape() const {
auto x_dim = param_.InputX()->dims(); auto x_dim = param_.InputX()->dims();
param_.Out()->Resize(x_dim); param_.Out()->Resize(x_dim);
}
template class ElementwiseAddOp<CPU, float>;
}
} }
template class ElementwiseAddOp<CPU, float>;
} // namespace operators
} // namespace paddle_mobile
...@@ -21,26 +21,23 @@ SOFTWARE. ...@@ -21,26 +21,23 @@ SOFTWARE.
#include "op_param.h" #include "op_param.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
using namespace framework; using namespace framework;
template <typename DeviceType, typename T> template <typename DeviceType, typename T>
class ElementwiseAddOp class ElementwiseAddOp : public framework::OperatorWithKernel<DeviceType> {
: public framework::OperatorWithKernel<DeviceType> {
public: public:
ElementwiseAddOp(const std::string &type, ElementwiseAddOp(const std::string &type, const VariableNameMap &inputs,
const VariableNameMap &inputs,
const VariableNameMap &outputs, const VariableNameMap &outputs,
const framework::AttributeMap attrs, const framework::AttributeMap attrs,
std::shared_ptr<framework::Scope> scope) std::shared_ptr<framework::Scope> scope)
: framework::OperatorWithKernel<DeviceType>( : framework::OperatorWithKernel<DeviceType>(type, inputs, outputs,
type, inputs, outputs, attrs, scope), attrs, scope),
param_(inputs, outputs, attrs, *scope) {} param_(inputs, outputs, attrs, *scope) {}
void Run() const { void Run() const {
operators::ElementwiseAddKernel<DeviceType, T, operators::ElementwiseAddKernel<DeviceType, T, ElementwiseAddParam>
ElementwiseAddParam>
kernel; kernel;
kernel.Compute(param_); kernel.Compute(param_);
} }
...@@ -50,6 +47,6 @@ namespace paddle_mobile { ...@@ -50,6 +47,6 @@ namespace paddle_mobile {
protected: protected:
ElementwiseAddParam param_; ElementwiseAddParam param_;
}; };
} } // namespace operators
} } // namespace paddle_mobile
...@@ -19,27 +19,23 @@ SOFTWARE. ...@@ -19,27 +19,23 @@ SOFTWARE.
#include "operators/kernel/conv_kernel.h" #include "operators/kernel/conv_kernel.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
bool IsExpand(const std::vector<int64_t> &filter_dim, bool IsExpand(const std::vector<int64_t> &filter_dim,
const std::vector<int> &strides, const std::vector<int> &strides, const std::vector<int> &paddings,
const std::vector<int> &paddings,
const std::vector<int> &dilations) { const std::vector<int> &dilations) {
bool filter_1 = true, strides_1 = true, padding_0 = true, bool filter_1 = true, strides_1 = true, padding_0 = true, dilation_1 = true;
dilation_1 = true;
for (size_t j = 0; j < strides.size(); ++j) { for (size_t j = 0; j < strides.size(); ++j) {
filter_1 = filter_1 = filter_1 && (static_cast<int>(filter_dim[j + 2]) == 1);
filter_1 && (static_cast<int>(filter_dim[j + 2]) == 1);
strides_1 = strides_1 && (strides[j] == 1); strides_1 = strides_1 && (strides[j] == 1);
padding_0 = padding_0 && (paddings[j] == 0); padding_0 = padding_0 && (paddings[j] == 0);
dilation_1 = dilation_1 && (dilations[j] == 1); dilation_1 = dilation_1 && (dilations[j] == 1);
} }
return !(filter_1 && strides_1 && padding_0 && dilation_1); return !(filter_1 && strides_1 && padding_0 && dilation_1);
} }
template <> template <>
void ConvKernel<CPU, float, ConvParam>::Compute( void ConvKernel<CPU, float, ConvParam>::Compute(const ConvParam &param) const {
const ConvParam &param) const {
LOG(kLOG_DEBUG) << param; LOG(kLOG_DEBUG) << param;
const Tensor *input = param.Input(); const Tensor *input = param.Input();
...@@ -63,12 +59,10 @@ namespace paddle_mobile { ...@@ -63,12 +59,10 @@ namespace paddle_mobile {
// filter_shape_vec: {k_o, k_i, k_h, k_w} or {k_o, k_i, k_d, k_h, // filter_shape_vec: {k_o, k_i, k_h, k_w} or {k_o, k_i, k_d, k_h,
// k_w} // k_w}
std::vector<int64_t> filter_shape_vec( std::vector<int64_t> filter_shape_vec(framework::vectorize(filter.dims()));
framework::vectorize(filter.dims()));
// output_shape_vec: {o_n, o_c, o_h, o_w} or {o_n, o_c, o_d, o_h, // output_shape_vec: {o_n, o_c, o_h, o_w} or {o_n, o_c, o_d, o_h,
// o_w} // o_w}
std::vector<int64_t> output_shape_vec( std::vector<int64_t> output_shape_vec(framework::vectorize(output->dims()));
framework::vectorize(output->dims()));
// use col_shape in the im2col calculation // 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, // col_shape_vec: {i_c/g, k_h, k_w, o_h, o_w} or {i_c/g, k_d, k_h,
...@@ -90,8 +84,7 @@ namespace paddle_mobile { ...@@ -90,8 +84,7 @@ namespace paddle_mobile {
framework::DDim col_matrix_shape = framework::DDim col_matrix_shape =
framework::flatten_to_2d(col_shape, data_dim + 1); framework::flatten_to_2d(col_shape, data_dim + 1);
bool is_expand = bool is_expand = IsExpand(filter_shape_vec, strides, paddings, dilations);
IsExpand(filter_shape_vec, strides, paddings, dilations);
Tensor col; Tensor col;
// col_matrix shares the same piece of data with col, // col_matrix shares the same piece of data with col,
// but will be reshaped into a two-dimensional matrix shape // but will be reshaped into a two-dimensional matrix shape
...@@ -106,8 +99,8 @@ namespace paddle_mobile { ...@@ -106,8 +99,8 @@ namespace paddle_mobile {
framework::DDim input_shape = framework::slice_ddim( framework::DDim input_shape = framework::slice_ddim(
input->dims(), 1, static_cast<int>(input->dims().size())); input->dims(), 1, static_cast<int>(input->dims().size()));
framework::DDim filter_matrix_shape = { framework::DDim filter_matrix_shape = {filter.dims()[0],
filter.dims()[0], filter.numel() / filter.dims()[0]}; filter.numel() / filter.dims()[0]};
filter.Resize(filter_matrix_shape); filter.Resize(filter_matrix_shape);
framework::DDim output_matrix_shape = { framework::DDim output_matrix_shape = {
...@@ -125,12 +118,10 @@ namespace paddle_mobile { ...@@ -125,12 +118,10 @@ namespace paddle_mobile {
// device_context<DeviceContext>(); // device_context<DeviceContext>();
for (int i = 0; i < batch_size; i++) { for (int i = 0; i < batch_size; i++) {
Tensor in_batch = input->Slice(i, i + 1).Resize(input_shape); Tensor in_batch = input->Slice(i, i + 1).Resize(input_shape);
Tensor out_batch = Tensor out_batch = output->Slice(i, i + 1).Resize(output_matrix_shape);
output->Slice(i, i + 1).Resize(output_matrix_shape);
for (int g = 0; g < groups; g++) { for (int g = 0; g < groups; g++) {
Tensor in_slice = Tensor in_slice = in_batch.Slice(g * in_step, (g + 1) * in_step);
in_batch.Slice(g * in_step, (g + 1) * in_step);
if (!is_expand) { if (!is_expand) {
col.ShareDataWith(in_slice); col.ShareDataWith(in_slice);
...@@ -139,8 +130,8 @@ namespace paddle_mobile { ...@@ -139,8 +130,8 @@ namespace paddle_mobile {
} else if (data_dim == 2U) { } else if (data_dim == 2U) {
// im2col // im2col
im2col(in_slice, dilations, strides, im2col(in_slice, dilations, strides,
std::vector<int>{paddings[0], paddings[1], std::vector<int>{paddings[0], paddings[1], paddings[0],
paddings[0], paddings[1]}, paddings[1]},
&col); &col);
} else if (data_dim == 3U) { } else if (data_dim == 3U) {
// vol2col // vol2col
...@@ -156,9 +147,9 @@ namespace paddle_mobile { ...@@ -156,9 +147,9 @@ namespace paddle_mobile {
float(1.0), &out_slice, float(0.0)); float(1.0), &out_slice, float(0.0));
} }
} }
} }
template class ConvKernel<CPU, float, ConvParam>; template class ConvKernel<CPU, float, ConvParam>;
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -17,25 +17,25 @@ limitations under the License. */ ...@@ -17,25 +17,25 @@ limitations under the License. */
#include "operators/kernel/elementwise_add_kernel.h" #include "operators/kernel/elementwise_add_kernel.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
template <typename T> struct AddFunctor { template <typename T> struct AddFunctor {
inline T operator()(T a, T b) const { return a + b; } inline T operator()(T a, T b) const { return a + b; }
}; };
template <> template <>
void ElementwiseAddKernel<CPU, float, ElementwiseAddParam>::Compute( void ElementwiseAddKernel<CPU, float, ElementwiseAddParam>::Compute(
const ElementwiseAddParam &param) const { const ElementwiseAddParam &param) const {
const Tensor *input_x = param.InputX(); const Tensor *input_x = param.InputX();
const Tensor *input_y = param.InputY(); const Tensor *input_y = param.InputY();
Tensor *Out = param.Out(); Tensor *Out = param.Out();
Out->mutable_data<float>(); Out->mutable_data<float>();
const int axis = param.Axis(); const int axis = param.Axis();
ElementwiseComputeEx<AddFunctor<float>, float>( ElementwiseComputeEx<AddFunctor<float>, float>(input_x, input_y, axis,
input_x, input_y, axis, AddFunctor<float>(), Out); AddFunctor<float>(), Out);
} }
template class ElementwiseAddKernel<CPU, float, ElementwiseAddParam>; template class ElementwiseAddKernel<CPU, float, ElementwiseAddParam>;
} // namespace operators } // namespace operators
} // namespace paddle } // namespace paddle_mobile
...@@ -21,11 +21,10 @@ SOFTWARE. ...@@ -21,11 +21,10 @@ SOFTWARE.
#include "operators/kernel/mul_kernel.h" #include "operators/kernel/mul_kernel.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
template <> template <>
void void MulKernel<CPU, float, MulParam>::Compute(const MulParam &param) const {
MulKernel<CPU, float, MulParam>::Compute(const MulParam &param) const {
const Tensor *input_x = param.InputX(); const Tensor *input_x = param.InputX();
const Tensor *input_y = param.InputY(); const Tensor *input_y = param.InputY();
Tensor *out = param.Out(); Tensor *out = param.Out();
...@@ -42,15 +41,14 @@ namespace paddle_mobile { ...@@ -42,15 +41,14 @@ namespace paddle_mobile {
if (out_dim.size() != 2) { if (out_dim.size() != 2) {
out->Resize({x_matrix.dims()[0], y_matrix.dims()[1]}); out->Resize({x_matrix.dims()[0], y_matrix.dims()[1]});
} }
math::matmul<float>(x_matrix, false, y_matrix, false, math::matmul<float>(x_matrix, false, y_matrix, false, static_cast<float>(1),
static_cast<float>(1), out, out, static_cast<float>(0));
static_cast<float>(0));
if (out_dim.size() != 2) { if (out_dim.size() != 2) {
out->Resize(out_dim); out->Resize(out_dim);
} }
} }
template class MulKernel<CPU, float, MulParam>; template class MulKernel<CPU, float, MulParam>;
} // namespace operators } // namespace operators
} // namespace paddle } // namespace paddle_mobile
...@@ -25,15 +25,14 @@ SOFTWARE. ...@@ -25,15 +25,14 @@ SOFTWARE.
#pragma once; #pragma once;
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
using namespace framework; using namespace framework;
template <typename DeviceType, typename T, typename P> template <typename DeviceType, typename T, typename P>
class ConvKernel class ConvKernel : public framework::OpKernelBase<DeviceType, ConvParam> {
: public framework::OpKernelBase<DeviceType, ConvParam> {
public: public:
void Compute(const ConvParam &param) const; void Compute(const ConvParam &param) const;
}; };
} } // namespace operators
} } // namespace paddle_mobile
...@@ -22,15 +22,15 @@ SOFTWARE. ...@@ -22,15 +22,15 @@ SOFTWARE.
#include "operators/op_param.h" #include "operators/op_param.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
using namespace framework; using namespace framework;
template <typename DeviceType, typename T, typename P> template <typename DeviceType, typename T, typename P>
class ElementwiseAddKernel class ElementwiseAddKernel
: public framework::OpKernelBase<DeviceType, ElementwiseAddParam> { : public framework::OpKernelBase<DeviceType, ElementwiseAddParam> {
public: public:
void Compute(const ElementwiseAddParam &param) const; void Compute(const ElementwiseAddParam &param) const;
}; };
} } // namespace operators
} } // namespace paddle_mobile
...@@ -16,15 +16,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ...@@ -16,15 +16,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
==============================================================================*/ ==============================================================================*/
#include "operators/kernel/conv_kernel.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
// template<> // template<>
// void ConvKernel<FPGA, float>::Compute(const ConvParam &param) const // void ConvKernel<FPGA, float>::Compute(const ConvParam &param) const
// {} // {}
// //
// template class ConvKernel<FPGA, float>; // template class ConvKernel<FPGA, float>;
}
} }
} // namespace paddle_mobile
...@@ -22,14 +22,14 @@ SOFTWARE. ...@@ -22,14 +22,14 @@ SOFTWARE.
#pragma once; #pragma once;
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
using namespace framework; using namespace framework;
template <typename DeviceType, typename T, typename P> template <typename DeviceType, typename T, typename P>
class MulKernel : public framework::OpKernelBase<DeviceType, MulParam> { class MulKernel : public framework::OpKernelBase<DeviceType, MulParam> {
public: public:
void Compute(const MulParam &param) const; void Compute(const MulParam &param) const;
}; };
} } // namespace operators
} } // namespace paddle_mobile
...@@ -18,9 +18,9 @@ limitations under the License. */ ...@@ -18,9 +18,9 @@ limitations under the License. */
#define UNLIKELY(condition) __builtin_expect(static_cast<bool>(condition), 0) #define UNLIKELY(condition) __builtin_expect(static_cast<bool>(condition), 0)
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
/* /*
* Out = X ⊙ Y * Out = X ⊙ Y
* If Y's shape does not match X' shape, they will be reshaped. * If Y's shape does not match X' shape, they will be reshaped.
* For example: * For example:
...@@ -31,7 +31,7 @@ namespace paddle_mobile { ...@@ -31,7 +31,7 @@ namespace paddle_mobile {
* pre=2*3, n=4*5, post=1 * pre=2*3, n=4*5, post=1
* x.shape(6, 20, 1) * y.shape(1, 20, 1).broadcast(6, 20, 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, inline void get_mid_dims(const framework::DDim &x_dims,
const framework::DDim &y_dims, const int axis, const framework::DDim &y_dims, const int axis,
int *pre, int *n, int *post) { int *pre, int *n, int *post) {
*pre = 1; *pre = 1;
...@@ -51,10 +51,10 @@ namespace paddle_mobile { ...@@ -51,10 +51,10 @@ namespace paddle_mobile {
for (int i = axis + y_dims.size(); i < x_dims.size(); ++i) { for (int i = axis + y_dims.size(); i < x_dims.size(); ++i) {
(*post) *= x_dims[i]; (*post) *= x_dims[i];
} }
} }
/// remove dims tail 1. (4,20,1,1) -> (4,20) /// remove dims tail 1. (4,20,1,1) -> (4,20)
inline void trim_trailing_singular_dims(framework::DDim *dims) { inline void trim_trailing_singular_dims(framework::DDim *dims) {
// Remove trailing dimensions of size 1 for y // Remove trailing dimensions of size 1 for y
auto actual_dims_size = dims->size(); auto actual_dims_size = dims->size();
for (; actual_dims_size != 0; --actual_dims_size) { for (; actual_dims_size != 0; --actual_dims_size) {
...@@ -66,12 +66,11 @@ namespace paddle_mobile { ...@@ -66,12 +66,11 @@ namespace paddle_mobile {
actual_dims.resize(actual_dims_size); actual_dims.resize(actual_dims_size);
*dims = framework::make_ddim(actual_dims); *dims = framework::make_ddim(actual_dims);
} }
} }
template <typename T> class RowwiseTransformIterator { template <typename T> class RowwiseTransformIterator {
public: public:
RowwiseTransformIterator(const T *ptr, int n) RowwiseTransformIterator(const T *ptr, int n) : ptr_(ptr), i_(0), n_(n) {}
: ptr_(ptr), i_(0), n_(n) {}
RowwiseTransformIterator<T> &operator++() { RowwiseTransformIterator<T> &operator++() {
++i_; ++i_;
...@@ -95,13 +94,13 @@ namespace paddle_mobile { ...@@ -95,13 +94,13 @@ namespace paddle_mobile {
const T *ptr_; const T *ptr_;
int i_; int i_;
int64_t n_; int64_t n_;
}; };
/// (4,20,2)+(20,): (20,) just as (20,1), when move 2 strides in last /// (4,20,2)+(20,): (20,) just as (20,1), when move 2 strides in last
/// dimension /// dimension
/// in (4,20,2) is 2 , /// in (4,20,2) is 2 ,
/// (20,1) move 1 stride , to fill(add) 2 element with the same number. /// (20,1) move 1 stride , to fill(add) 2 element with the same number.
template <typename T> class MidWiseTransformIterator { template <typename T> class MidWiseTransformIterator {
public: public:
MidWiseTransformIterator(const T *ptr, int n, int post) MidWiseTransformIterator(const T *ptr, int n, int post)
: ptr_(ptr), i_(0), j_(0), n_(n), post_(post) {} : ptr_(ptr), i_(0), j_(0), n_(n), post_(post) {}
...@@ -134,17 +133,15 @@ namespace paddle_mobile { ...@@ -134,17 +133,15 @@ namespace paddle_mobile {
int64_t j_; int64_t j_;
int64_t n_; int64_t n_;
int64_t post_; int64_t post_;
}; };
template <typename Functor, typename T, typename OutType = T> template <typename Functor, typename T, typename OutType = T>
class TransformFunctor { class TransformFunctor {
public: public:
TransformFunctor(const framework::Tensor *x, TransformFunctor(const framework::Tensor *x, const framework::Tensor *y,
const framework::Tensor *y, framework::Tensor *z, framework::Tensor *z, Functor func)
Functor func) : x_(x->data<T>()), y_(y->data<T>()), z_(z->mutable_data<OutType>()),
: x_(x->data<T>()), y_(y->data<T>()), nx_(x->numel()), func_(func) {}
z_(z->mutable_data<OutType>()), nx_(x->numel()), func_(func) {
}
inline void Run() const { inline void Run() const {
math::Transform trans; math::Transform trans;
...@@ -154,14 +151,13 @@ namespace paddle_mobile { ...@@ -154,14 +151,13 @@ namespace paddle_mobile {
inline void RunRowWise(int n, int pre) const { inline void RunRowWise(int n, int pre) const {
math::Transform trans; math::Transform trans;
trans(x_, x_ + nx_, RowwiseTransformIterator<T>(y_, n), z_, trans(x_, x_ + nx_, RowwiseTransformIterator<T>(y_, n), z_, func_);
func_);
} }
inline void RunMidWise(int n, int pre, int post) const { inline void RunMidWise(int n, int pre, int post) const {
math::Transform trans; math::Transform trans;
trans(x_, x_ + nx_, MidWiseTransformIterator<T>(y_, n, post), trans(x_, x_ + nx_, MidWiseTransformIterator<T>(y_, n, post), z_,
z_, func_); func_);
} }
private: private:
...@@ -170,12 +166,12 @@ namespace paddle_mobile { ...@@ -170,12 +166,12 @@ namespace paddle_mobile {
OutType *z_; OutType *z_;
int64_t nx_; int64_t nx_;
Functor func_; Functor func_;
}; };
template <typename Functor, typename T, typename OutType = T> template <typename Functor, typename T, typename OutType = T>
void ElementwiseComputeEx(const framework::Tensor *x, void ElementwiseComputeEx(const framework::Tensor *x,
const framework::Tensor *y, int axis, const framework::Tensor *y, int axis, Functor func,
Functor func, framework::Tensor *z) { framework::Tensor *z) {
TransformFunctor<Functor, T, OutType> functor(x, y, z, func); TransformFunctor<Functor, T, OutType> functor(x, y, z, func);
auto x_dims = x->dims(); auto x_dims = x->dims();
...@@ -205,7 +201,7 @@ namespace paddle_mobile { ...@@ -205,7 +201,7 @@ namespace paddle_mobile {
functor.RunMidWise(n, pre, post); functor.RunMidWise(n, pre, post);
return; return;
} }
} }
} // namespace operators } // namespace operators
} // namespace paddle } // namespace paddle_mobile
...@@ -16,22 +16,21 @@ limitations under the License. */ ...@@ -16,22 +16,21 @@ limitations under the License. */
#include "common/types.h" #include "common/types.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
namespace math { namespace math {
/* /*
* im = [input_channels, input_height, input_width] * im = [input_channels, input_height, input_width]
* col = * col =
* [input_channels, filter_height, filter_width, output_height, * [input_channels, filter_height, filter_width, output_height,
* output_width] * output_width]
*/ */
template <class T> class Im2ColFunctor<ColFormat::kCFO, CPU, T> { template <class T> class Im2ColFunctor<ColFormat::kCFO, CPU, T> {
public: public:
void operator()(const framework::Tensor &im, void operator()(const framework::Tensor &im,
const std::vector<int> &dilation, const std::vector<int> &dilation,
const std::vector<int> &stride, const std::vector<int> &stride,
const std::vector<int> &padding, const std::vector<int> &padding, framework::Tensor *col) {
framework::Tensor *col) {
// PADDLE_ENFORCE(im.dims().size() == 3); // PADDLE_ENFORCE(im.dims().size() == 3);
// PADDLE_ENFORCE(col->dims().size() == 5); // PADDLE_ENFORCE(col->dims().size() == 5);
...@@ -64,8 +63,7 @@ namespace paddle_mobile { ...@@ -64,8 +63,7 @@ namespace paddle_mobile {
// padding(padding_up, padding_down) // padding(padding_up, padding_down)
// are " "inconsistent."); // are " "inconsistent.");
int channels_col = int channels_col = im_channels * filter_height * filter_width;
im_channels * filter_height * filter_width;
const T *im_data = im.data<T>(); const T *im_data = im.data<T>();
T *col_data = col->data<T>(); T *col_data = col->data<T>();
...@@ -74,20 +72,17 @@ namespace paddle_mobile { ...@@ -74,20 +72,17 @@ namespace paddle_mobile {
int h_offset = (c / filter_width) % filter_height; int h_offset = (c / filter_width) % filter_height;
int c_im = c / (filter_width * filter_height); int c_im = c / (filter_width * filter_height);
for (int h = 0; h < col_height; ++h) { for (int h = 0; h < col_height; ++h) {
int im_row_idx = h * stride[0] - padding[0] + int im_row_idx =
h_offset * dilation[0]; h * stride[0] - padding[0] + h_offset * dilation[0];
for (int w = 0; w < col_width; ++w) { for (int w = 0; w < col_width; ++w) {
int im_col_idx = w * stride[1] - padding[1] + int im_col_idx =
w_offset * dilation[1]; w * stride[1] - padding[1] + w_offset * dilation[1];
int col_idx = int col_idx = (c * col_height + h) * col_width + w;
(c * col_height + h) * col_width + w;
int im_idx = int im_idx =
(im_row_idx + c_im * im_height) * im_width + (im_row_idx + c_im * im_height) * im_width + im_col_idx;
im_col_idx;
col_data[col_idx] = col_data[col_idx] =
(im_row_idx < 0 || (im_row_idx < 0 || im_row_idx >= im_height ||
im_row_idx >= im_height ||
im_col_idx < 0 || im_col_idx >= im_width) im_col_idx < 0 || im_col_idx >= im_width)
? static_cast<T>(0) ? static_cast<T>(0)
: im_data[im_idx]; : im_data[im_idx];
...@@ -95,21 +90,20 @@ namespace paddle_mobile { ...@@ -95,21 +90,20 @@ namespace paddle_mobile {
} }
} }
} }
}; };
/* /*
* im = [input_channels, input_height, input_width] * im = [input_channels, input_height, input_width]
* col = * col =
* [input_channels, filter_height, filter_width, output_height, * [input_channels, filter_height, filter_width, output_height,
* output_width] * output_width]
*/ */
template <class T> class Col2ImFunctor<ColFormat::kCFO, CPU, T> { template <class T> class Col2ImFunctor<ColFormat::kCFO, CPU, T> {
public: public:
void operator()(const framework::Tensor &col, void operator()(const framework::Tensor &col,
const std::vector<int> &dilation, const std::vector<int> &dilation,
const std::vector<int> &stride, const std::vector<int> &stride,
const std::vector<int> &padding, const std::vector<int> &padding, framework::Tensor *im) {
framework::Tensor *im) {
// PADDLE_ENFORCE(im->dims().size() == 3); // PADDLE_ENFORCE(im->dims().size() == 3);
// PADDLE_ENFORCE(col.dims().size() == 5); // PADDLE_ENFORCE(col.dims().size() == 5);
int im_channels = im->dims()[0]; int im_channels = im->dims()[0];
...@@ -141,8 +135,7 @@ namespace paddle_mobile { ...@@ -141,8 +135,7 @@ namespace paddle_mobile {
// padding(padding_up, padding_down) // padding(padding_up, padding_down)
// are " "inconsistent."); // are " "inconsistent.");
int channels_col = int channels_col = im_channels * filter_height * filter_width;
im_channels * filter_height * filter_width;
T *im_data = im->data<T>(); T *im_data = im->data<T>();
const T *col_data = col.data<T>(); const T *col_data = col.data<T>();
...@@ -152,46 +145,40 @@ namespace paddle_mobile { ...@@ -152,46 +145,40 @@ namespace paddle_mobile {
int h_offset = (c / filter_width) % filter_height; int h_offset = (c / filter_width) % filter_height;
int c_im = c / (filter_width * filter_height); int c_im = c / (filter_width * filter_height);
for (int h = 0; h < col_height; ++h) { for (int h = 0; h < col_height; ++h) {
int im_row_idx = h * stride[0] - padding[0] + int im_row_idx =
h_offset * dilation[0]; h * stride[0] - padding[0] + h_offset * dilation[0];
for (int w = 0; w < col_width; ++w) { for (int w = 0; w < col_width; ++w) {
int im_col_idx = w * stride[1] - padding[1] + int im_col_idx =
w_offset * dilation[1]; w * stride[1] - padding[1] + w_offset * dilation[1];
if ((im_row_idx) >= 0 && if ((im_row_idx) >= 0 && (im_row_idx) < im_height &&
(im_row_idx) < im_height && (im_col_idx) >= 0 && (im_col_idx) < im_width) {
(im_col_idx) >= 0 && im_data[(im_row_idx + c_im * im_height) * im_width +
(im_col_idx) < im_width) {
im_data[(im_row_idx + c_im * im_height) *
im_width +
im_col_idx] += im_col_idx] +=
col_data[(c * col_height + h) * col_data[(c * col_height + h) * col_width + w];
col_width +
w];
} }
} }
} }
} }
} }
}; };
template class Im2ColFunctor<ColFormat::kCFO, CPU, float>; template class Im2ColFunctor<ColFormat::kCFO, CPU, float>;
template class Im2ColFunctor<ColFormat::kCFO, CPU, double>; template class Im2ColFunctor<ColFormat::kCFO, CPU, double>;
template class Col2ImFunctor<ColFormat::kCFO, CPU, float>; template class Col2ImFunctor<ColFormat::kCFO, CPU, float>;
template class Col2ImFunctor<ColFormat::kCFO, CPU, double>; template class Col2ImFunctor<ColFormat::kCFO, CPU, double>;
/* /*
* im = [input_channels, input_height, input_width] * im = [input_channels, input_height, input_width]
* col = * col =
* [output_height, output_width, input_channels, filter_height, * [output_height, output_width, input_channels, filter_height,
* filter_width] * filter_width]
*/ */
template <class T> class Im2ColFunctor<ColFormat::kOCF, CPU, T> { template <class T> class Im2ColFunctor<ColFormat::kOCF, CPU, T> {
public: public:
void operator()(const framework::Tensor &im, void operator()(const framework::Tensor &im,
const std::vector<int> &dilation, const std::vector<int> &dilation,
const std::vector<int> &stride, const std::vector<int> &stride,
const std::vector<int> &padding, const std::vector<int> &padding, framework::Tensor *col) {
framework::Tensor *col) {
// PADDLE_ENFORCE(im.dims().size() == 3); // PADDLE_ENFORCE(im.dims().size() == 3);
// PADDLE_ENFORCE(col->dims().size() == 5); // PADDLE_ENFORCE(col->dims().size() == 5);
int im_channels = im.dims()[0]; int im_channels = im.dims()[0];
...@@ -218,28 +205,20 @@ namespace paddle_mobile { ...@@ -218,28 +205,20 @@ namespace paddle_mobile {
const T *im_data = im.data<T>(); const T *im_data = im.data<T>();
T *col_data = col->data<T>(); T *col_data = col->data<T>();
for (int col_row_idx = 0; col_row_idx < col_height; for (int col_row_idx = 0; col_row_idx < col_height; ++col_row_idx) {
++col_row_idx) { for (int col_col_idx = 0; col_col_idx < col_width; ++col_col_idx) {
for (int col_col_idx = 0; col_col_idx < col_width; for (int channel = 0; channel < im_channels; ++channel) {
++col_col_idx) { for (int filter_row_idx = 0; filter_row_idx < filter_height;
for (int channel = 0; channel < im_channels;
++channel) {
for (int filter_row_idx = 0;
filter_row_idx < filter_height;
++filter_row_idx) { ++filter_row_idx) {
int im_row_offset = int im_row_offset = col_row_idx * stride[0] +
col_row_idx * stride[0] +
filter_row_idx - padding[0]; filter_row_idx - padding[0];
for (int filter_col_idx = 0; for (int filter_col_idx = 0;
filter_col_idx < filter_width; filter_col_idx < filter_width; ++filter_col_idx) {
++filter_col_idx) { int im_col_offset = col_col_idx * stride[1] +
int im_col_offset =
col_col_idx * stride[1] +
filter_col_idx - padding[1]; filter_col_idx - padding[1];
int col_offset = int col_offset =
((((col_row_idx)*col_width + ((((col_row_idx)*col_width + col_col_idx) *
col_col_idx) *
im_channels + im_channels +
channel) * channel) *
filter_height + filter_height +
...@@ -247,15 +226,14 @@ namespace paddle_mobile { ...@@ -247,15 +226,14 @@ namespace paddle_mobile {
filter_width + filter_width +
filter_col_idx; filter_col_idx;
int im_offset = (channel * im_height + int im_offset =
im_row_offset) * (channel * im_height + im_row_offset) *
im_width + im_width +
im_col_offset; im_col_offset;
col_data[col_offset] = col_data[col_offset] =
(im_row_offset < 0 || (im_row_offset < 0 ||
im_row_offset >= im_height || im_row_offset >= im_height ||
im_col_offset < 0 || im_col_offset < 0 || im_col_offset >= im_width)
im_col_offset >= im_width)
? static_cast<T>(0) ? static_cast<T>(0)
: im_data[im_offset]; : im_data[im_offset];
} }
...@@ -264,21 +242,20 @@ namespace paddle_mobile { ...@@ -264,21 +242,20 @@ namespace paddle_mobile {
} }
} }
} }
}; };
/* /*
* im = [input_channels, input_height, input_width] * im = [input_channels, input_height, input_width]
* col = * col =
* [output_height, output_width, input_channels, filter_height, * [output_height, output_width, input_channels, filter_height,
* filter_width] * filter_width]
*/ */
template <class T> class Col2ImFunctor<ColFormat::kOCF, CPU, T> { template <class T> class Col2ImFunctor<ColFormat::kOCF, CPU, T> {
public: public:
void operator()(const framework::Tensor &col, void operator()(const framework::Tensor &col,
const std::vector<int> &dilation, const std::vector<int> &dilation,
const std::vector<int> &stride, const std::vector<int> &stride,
const std::vector<int> &padding, const std::vector<int> &padding, framework::Tensor *im) {
framework::Tensor *im) {
// PADDLE_ENFORCE(im->dims().size() == 3); // PADDLE_ENFORCE(im->dims().size() == 3);
// PADDLE_ENFORCE(col.dims().size() == 5); // PADDLE_ENFORCE(col.dims().size() == 5);
int im_channels = im->dims()[0]; int im_channels = im->dims()[0];
...@@ -305,28 +282,20 @@ namespace paddle_mobile { ...@@ -305,28 +282,20 @@ namespace paddle_mobile {
T *im_data = im->data<T>(); T *im_data = im->data<T>();
const T *col_data = col.data<T>(); const T *col_data = col.data<T>();
for (int col_row_idx = 0; col_row_idx < col_height; for (int col_row_idx = 0; col_row_idx < col_height; ++col_row_idx) {
++col_row_idx) { for (int col_col_idx = 0; col_col_idx < col_width; ++col_col_idx) {
for (int col_col_idx = 0; col_col_idx < col_width; for (int channel = 0; channel < im_channels; ++channel) {
++col_col_idx) { for (int filter_row_idx = 0; filter_row_idx < filter_height;
for (int channel = 0; channel < im_channels;
++channel) {
for (int filter_row_idx = 0;
filter_row_idx < filter_height;
++filter_row_idx) { ++filter_row_idx) {
int im_row_offset = int im_row_offset = col_row_idx * stride[0] +
col_row_idx * stride[0] +
filter_row_idx - padding[0]; filter_row_idx - padding[0];
for (int filter_col_idx = 0; for (int filter_col_idx = 0;
filter_col_idx < filter_width; filter_col_idx < filter_width; ++filter_col_idx) {
++filter_col_idx) { int im_col_offset = col_col_idx * stride[1] +
int im_col_offset =
col_col_idx * stride[1] +
filter_col_idx - padding[1]; filter_col_idx - padding[1];
int col_offset = int col_offset =
(((col_row_idx * col_width + (((col_row_idx * col_width + col_col_idx) *
col_col_idx) *
im_channels + im_channels +
channel) * channel) *
filter_height + filter_height +
...@@ -339,12 +308,10 @@ namespace paddle_mobile { ...@@ -339,12 +308,10 @@ namespace paddle_mobile {
im_col_offset >= 0 && im_col_offset >= 0 &&
im_col_offset < im_width) { im_col_offset < im_width) {
int im_offset = int im_offset =
(channel * im_height + (channel * im_height + im_row_offset) *
im_row_offset) *
im_width + im_width +
im_col_offset; im_col_offset;
im_data[im_offset] += im_data[im_offset] += col_data[col_offset];
col_data[col_offset];
} }
} }
} }
...@@ -352,13 +319,13 @@ namespace paddle_mobile { ...@@ -352,13 +319,13 @@ namespace paddle_mobile {
} }
} }
} }
}; };
template class Im2ColFunctor<ColFormat::kOCF, CPU, float>; template class Im2ColFunctor<ColFormat::kOCF, CPU, float>;
template class Im2ColFunctor<ColFormat::kOCF, CPU, double>; template class Im2ColFunctor<ColFormat::kOCF, CPU, double>;
template class Col2ImFunctor<ColFormat::kOCF, CPU, float>; template class Col2ImFunctor<ColFormat::kOCF, CPU, float>;
template class Col2ImFunctor<ColFormat::kOCF, CPU, double>; template class Col2ImFunctor<ColFormat::kOCF, CPU, double>;
} // namespace math } // namespace math
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -17,14 +17,14 @@ limitations under the License. */ ...@@ -17,14 +17,14 @@ limitations under the License. */
#include "framework/tensor.h" #include "framework/tensor.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
namespace math { namespace math {
/* The storage format of the coldata in the Im2ColFunctor and /* The storage format of the coldata in the Im2ColFunctor and
* Col2ImFunctor. */ * Col2ImFunctor. */
enum class ColFormat { kCFO = 0, kOCF = 1 }; enum class ColFormat { kCFO = 0, kOCF = 1 };
/* /*
* \brief Converts the image data of three dimensions(CHW) into a * \brief Converts the image data of three dimensions(CHW) into a
* colData of * colData of
* five dimensions in the Im2ColFunctor calculation, * five dimensions in the Im2ColFunctor calculation,
...@@ -87,26 +87,24 @@ namespace paddle_mobile { ...@@ -87,26 +87,24 @@ namespace paddle_mobile {
* equal to * equal to
* colShape.inputChannels. * colShape.inputChannels.
*/ */
template <ColFormat Format, typename DeviceType, typename T> template <ColFormat Format, typename DeviceType, typename T>
class Im2ColFunctor { class Im2ColFunctor {
public: public:
void operator()(const framework::Tensor &im, void operator()(const framework::Tensor &im,
const std::vector<int> &dilation, const std::vector<int> &dilation,
const std::vector<int> &stride, const std::vector<int> &stride,
const std::vector<int> &padding, const std::vector<int> &padding, framework::Tensor *col);
framework::Tensor *col); };
};
template <ColFormat Format, typename DeviceType, typename T> template <ColFormat Format, typename DeviceType, typename T>
class Col2ImFunctor { class Col2ImFunctor {
public: public:
void operator()(const framework::Tensor &col, void operator()(const framework::Tensor &col,
const std::vector<int> &dilation, const std::vector<int> &dilation,
const std::vector<int> &stride, const std::vector<int> &stride,
const std::vector<int> &padding, const std::vector<int> &padding, framework::Tensor *im);
framework::Tensor *im); };
};
} // namespace math } // namespace math
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -15,64 +15,56 @@ limitations under the License. */ ...@@ -15,64 +15,56 @@ limitations under the License. */
#include "math_function.h" #include "math_function.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
namespace math { namespace math {
template <> template <>
void gemm<float>(const CBLAS_TRANSPOSE transA, void gemm<float>(const CBLAS_TRANSPOSE transA, const CBLAS_TRANSPOSE transB,
const CBLAS_TRANSPOSE transB, const int M, const int M, const int N, const int K, const float alpha,
const int N, const int K, const float alpha, const float *A, const float *B, const float beta, float *C) {
const float *A, const float *B, const float beta,
float *C) {
int lda = (transA == CblasNoTrans) ? K : M; int lda = (transA == CblasNoTrans) ? K : M;
int ldb = (transB == CblasNoTrans) ? N : K; int ldb = (transB == CblasNoTrans) ? N : K;
int ldc = N; int ldc = N;
cblas_sgemm(CblasRowMajor, transA, transB, M, N, K, alpha, A, cblas_sgemm(CblasRowMajor, transA, transB, M, N, K, alpha, A, lda, B, ldb,
lda, B, ldb, beta, C, ldc); beta, C, ldc);
} }
template <> template <>
void gemm<double>(const CBLAS_TRANSPOSE transA, void gemm<double>(const CBLAS_TRANSPOSE transA, const CBLAS_TRANSPOSE transB,
const CBLAS_TRANSPOSE transB, const int M, const int M, const int N, const int K, const double alpha,
const int N, const int K, const double alpha, const double *A, const double *B, const double beta,
const double *A, const double *B, double *C) {
const double beta, double *C) {
int lda = (transA == CblasNoTrans) ? K : M; int lda = (transA == CblasNoTrans) ? K : M;
int ldb = (transB == CblasNoTrans) ? N : K; int ldb = (transB == CblasNoTrans) ? N : K;
int ldc = N; int ldc = N;
cblas_dgemm(CblasRowMajor, transA, transB, M, N, K, alpha, A, cblas_dgemm(CblasRowMajor, transA, transB, M, N, K, alpha, A, lda, B, ldb,
beta, C, ldc);
}
template <>
void gemm<float>(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<double>(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); lda, B, ldb, beta, C, ldc);
} }
template <> template <>
void gemm<float>(const bool transA, const bool transB, const int M, void matmul<float>(const framework::Tensor &matrix_a, bool trans_a,
const int N, const int K, const float alpha, const framework::Tensor &matrix_b, bool trans_b, float alpha,
const float *A, const int lda, const float *B, framework::Tensor *matrix_out, float beta) {
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<double>(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<float>(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_a = matrix_a.dims();
auto dim_b = matrix_b.dims(); auto dim_b = matrix_b.dims();
auto dim_out = matrix_out->dims(); auto dim_out = matrix_out->dims();
...@@ -91,21 +83,17 @@ namespace paddle_mobile { ...@@ -91,21 +83,17 @@ namespace paddle_mobile {
int N = dim_out[1]; int N = dim_out[1];
int K = (trans_a == false) ? dim_a[1] : dim_a[0]; int K = (trans_a == false) ? dim_a[1] : dim_a[0];
CBLAS_TRANSPOSE transA = CBLAS_TRANSPOSE transA = (trans_a == false) ? CblasNoTrans : CblasTrans;
(trans_a == false) ? CblasNoTrans : CblasTrans; CBLAS_TRANSPOSE transB = (trans_b == false) ? CblasNoTrans : CblasTrans;
CBLAS_TRANSPOSE transB =
(trans_b == false) ? CblasNoTrans : CblasTrans;
gemm<float>(transA, transB, M, N, K, alpha, gemm<float>(transA, transB, M, N, K, alpha, matrix_a.data<float>(),
matrix_a.data<float>(), matrix_b.data<float>(), matrix_b.data<float>(), beta, matrix_out->data<float>());
beta, matrix_out->data<float>()); }
}
template <> template <>
void matmul<double>(const framework::Tensor &matrix_a, bool trans_a, void matmul<double>(const framework::Tensor &matrix_a, bool trans_a,
const framework::Tensor &matrix_b, bool trans_b, const framework::Tensor &matrix_b, bool trans_b,
double alpha, framework::Tensor *matrix_out, double alpha, framework::Tensor *matrix_out, double beta) {
double beta) {
auto dim_a = matrix_a.dims(); auto dim_a = matrix_a.dims();
auto dim_b = matrix_b.dims(); auto dim_b = matrix_b.dims();
auto dim_out = matrix_out->dims(); auto dim_out = matrix_out->dims();
...@@ -124,16 +112,13 @@ namespace paddle_mobile { ...@@ -124,16 +112,13 @@ namespace paddle_mobile {
int N = dim_out[1]; int N = dim_out[1];
int K = (trans_a == false) ? dim_a[1] : dim_a[0]; int K = (trans_a == false) ? dim_a[1] : dim_a[0];
CBLAS_TRANSPOSE transA = CBLAS_TRANSPOSE transA = (trans_a == false) ? CblasNoTrans : CblasTrans;
(trans_a == false) ? CblasNoTrans : CblasTrans; CBLAS_TRANSPOSE transB = (trans_b == false) ? CblasNoTrans : CblasTrans;
CBLAS_TRANSPOSE transB =
(trans_b == false) ? CblasNoTrans : CblasTrans;
gemm<double>(transA, transB, M, N, K, alpha, gemm<double>(transA, transB, M, N, K, alpha, matrix_a.data<double>(),
matrix_a.data<double>(), matrix_b.data<double>(), matrix_b.data<double>(), beta, matrix_out->data<double>());
beta, matrix_out->data<double>()); }
}
} // namespace math } // namespace math
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -19,26 +19,24 @@ limitations under the License. */ ...@@ -19,26 +19,24 @@ limitations under the License. */
#include <cmath> #include <cmath>
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
namespace math { namespace math {
template <typename T> template <typename T>
void gemm(const CBLAS_TRANSPOSE transA, void gemm(const CBLAS_TRANSPOSE transA, const CBLAS_TRANSPOSE transB,
const CBLAS_TRANSPOSE transB, const int M, const int N, const int M, const int N, const int K, const T alpha, const T *A,
const int K, const T alpha, const T *A, const T *B, const T *B, const T beta, T *C);
const T beta, T *C);
template <typename T>
template <typename T> void gemm(const bool transA, const bool transB, const int M, const int N,
void gemm(const bool transA, const bool transB, const int M, const int K, const T alpha, const T *A, const int lda, const T *B,
const int N, const int K, const T alpha, const T *A, const int ldb, const T beta, T *C, const int ldc);
const int lda, const T *B, const int ldb, const T beta,
T *C, const int ldc); // matrix multiply with continuous memory
template <typename T>
// matrix multiply with continuous memory void matmul(const framework::Tensor &matrix_a, bool trans_a,
template <typename T> const framework::Tensor &matrix_b, bool trans_b, T alpha,
void matmul(const framework::Tensor &matrix_a, bool trans_a, framework::Tensor *matrix_out, T beta);
const framework::Tensor &matrix_b, bool trans_b, } // namespace math
T alpha, framework::Tensor *matrix_out, T beta); } // namespace operators
} // namespace math
} // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -17,41 +17,39 @@ limitations under the License. */ ...@@ -17,41 +17,39 @@ limitations under the License. */
#include <algorithm> #include <algorithm>
namespace paddle_mobile { namespace paddle_mobile {
namespace operators { namespace operators {
namespace math { namespace math {
// Transform applys a unary or a binary functor on each element in a // Transform applys a unary or a binary functor on each element in a
// range defined by a pair of iterators. // range defined by a pair of iterators.
// //
// - The specialization for CPU calls std::transform. // - The specialization for CPU calls std::transform.
// - The specialization for CUDA calls thrust::tranform. // - The specialization for CUDA calls thrust::tranform.
// //
// NOTE: We need to define InputIter and OutputIter defined as // NOTE: We need to define InputIter and OutputIter defined as
// different types, because the InputIter points op's inputs // different types, because the InputIter points op's inputs
// and // and
// OutputIter pints to op's outputs. // OutputIter pints to op's outputs.
// //
// NOTE: We don't assume that InputIter to be const InputType* and // NOTE: We don't assume that InputIter to be const InputType* and
// OutputIter to be OutputType*, because we might use a // OutputIter to be OutputType*, because we might use a
// iterator // iterator
// class, paddle::fluid::operators::RowwiseTRansformIterator. // class, paddle::fluid::operators::RowwiseTRansformIterator.
struct Transform { struct Transform {
template <typename InputIter, typename OutputIter, template <typename InputIter, typename OutputIter, typename UnaryOperation>
typename UnaryOperation> void operator()(InputIter first, InputIter last, OutputIter result,
void operator()(InputIter first, InputIter last, UnaryOperation op) {
OutputIter result, UnaryOperation op) {
std::transform(first, last, result, op); std::transform(first, last, result, op);
} }
template <typename InputIter1, typename InputIter2, template <typename InputIter1, typename InputIter2, typename OutputIter,
typename OutputIter, typename BinaryOperation> typename BinaryOperation>
void operator()(InputIter1 first1, InputIter1 last1, void operator()(InputIter1 first1, InputIter1 last1, InputIter2 first2,
InputIter2 first2, OutputIter result, OutputIter result, BinaryOperation op) {
BinaryOperation op) {
std::transform(first1, last1, first2, result, op); std::transform(first1, last1, first2, result, op);
} }
}; };
} } // namespace math
} // namespace platform } // namespace operators
} // namespace paddle } // namespace paddle_mobile
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -22,9 +22,10 @@ int main() { ...@@ -22,9 +22,10 @@ int main() {
DLOGF("DASJFDAFJ%d -- %f", 12345, 344.234); DLOGF("DASJFDAFJ%d -- %f", 12345, 344.234);
LOGF( paddle_mobile::kLOG_DEBUG, "DASJFDAFJ%d -- %f", 12345, 344.234); LOGF(paddle_mobile::kLOG_DEBUG, "DASJFDAFJ%d -- %f", 12345, 344.234);
LOG(paddle_mobile::kLOG_DEBUG) << "test debug" << " next log"; LOG(paddle_mobile::kLOG_DEBUG) << "test debug"
<< " next log";
LOG(paddle_mobile::kLOG_DEBUG1) << "test debug1" LOG(paddle_mobile::kLOG_DEBUG1) << "test debug1"
<< " next log"; << " next log";
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include "framework/scope.h" #include "framework/scope.h"
#include "framework/tensor.h" #include "framework/tensor.h"
#include "framework/variable.h" #include "framework/variable.h"
#include "framework/variable.h"
#include "io.h" #include "io.h"
#include "test_helper.h" #include "test_helper.h"
#include <map> #include <map>
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册