提交 913c8030 编写于 作者: 朔-望's avatar 朔-望 提交者: GitHub

Merge pull request #170 from allonli/develop

fix #171 update clang-format & update code stylee. 
---
Language: Cpp
BasedOnStyle: LLVM
Standard: Cpp11
IndentWidth: 4
NamespaceIndentation: All
...
...@@ -6,6 +6,7 @@ repos: ...@@ -6,6 +6,7 @@ repos:
files: (src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$ files: (src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$
- id: remove-tabs - id: remove-tabs
files: (src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$ files: (src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
sha: 5bf6c09bfa1297d3692cadd621ef95f1284e33c0 sha: 5bf6c09bfa1297d3692cadd621ef95f1284e33c0
hooks: hooks:
...@@ -18,11 +19,21 @@ repos: ...@@ -18,11 +19,21 @@ repos:
files: (src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$ files: (src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$
- id: trailing-whitespace - id: trailing-whitespace
files: (src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$ files: (src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$
- repo: local - repo: local
hooks: hooks:
- id: clang-format-with-version-check - id: clang-format-with-version-check
name: clang-format name: clang-format
description: Format files with ClangFormat. description: Format files with ClangFormat.
entry: bash .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: (src).*\.(c|cc|cxx|cpp|h|hpp|hxx)$
#- repo: local
# hooks:
# - id: copyright_checker
# name: copyright_checker
# entry: python ./tools/pre-commit.hooks/.copyright.hook
# language: system
# files: (src).*\.(c|cc|cxx|cpp|cu|h|hpp|hxx|proto|py)$
# exclude: (?!.*third_party)^.*$ | (?!.*book)^.*$
# Paddle-Mobile # Paddle-Mobile
![License MIT](https://img.shields.io/github/license/mashape/apistatus.svg) [![Build Status](https://travis-ci.org/PaddlePaddle/paddle-mobile.svg?branch=develop&longCache=true&style=flat-square)](https://travis-ci.org/PaddlePaddle/paddle-mobile)
This project is used to develop the next version deep learning freamwork for mobile device. This project is used to develop the next version deep learning freamwork for mobile device.
......
...@@ -23,30 +23,31 @@ SOFTWARE. ...@@ -23,30 +23,31 @@ 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;
} }
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 = std::function<void(const framework::OpDesc & /*op_desc*/, using InferVarTypeFN =
framework::BlockDesc * /*block*/)>; std::function<void(const framework::OpDesc & /*op_desc*/,
framework::BlockDesc * /*block*/)>;
using InferShapeFN = std::function<void(framework::InferShapeContext *)>;
using InferShapeFN = std::function<void(framework::InferShapeContext *)>;
}; };
...@@ -19,45 +19,45 @@ SOFTWARE. ...@@ -19,45 +19,45 @@ 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,
PM_DOUBLE = 2, PM_DOUBLE = 2,
PM_INT8 = 3, PM_INT8 = 3,
PM_INT16 = 4, PM_INT16 = 4,
PM_INT32 = 5, PM_INT32 = 5,
PM_INT64 = 6, PM_INT64 = 6,
PM_UINT8 = 7, PM_UINT8 = 7,
PM_UINT16 = 8, PM_UINT16 = 8,
PM_UINT32 = 9, PM_UINT32 = 9,
PM_STRING = 10, PM_STRING = 10,
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. */
PMMemAllocFailed = 0x03, /*!< Memory allocation error. */ PMMemAllocFailed = 0x03, /*!< Memory allocation error. */
PMUnKownError = 0x04, /*!< Unknown error. */ PMUnKownError = 0x04, /*!< Unknown error. */
PMOutOfAuthority = 0x05, /*!< Try to modified data not your own*/ PMOutOfAuthority = 0x05, /*!< Try to modified data not your own*/
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. */
}; };
} }
...@@ -21,79 +21,79 @@ SOFTWARE. ...@@ -21,79 +21,79 @@ 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;
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()) {
reinterpret_cast<F *>(data)->~F(); reinterpret_cast<F *>(data)->~F();
} else { } else {
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()) {
// reinterpret_cast<F*>(data)->~F(); // reinterpret_cast<F*>(data)->~F();
} else { } else {
// 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() {}
RawData(const RawData &raw_data) { strcpy(data, raw_data.data); } RawData(const RawData &raw_data) { strcpy(data, raw_data.data); }
// 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;
data = variant.data; data = variant.data;
} }
Variant() : type_id(invalid_type()) {} Variant() : type_id(invalid_type()) {}
~Variant() { ~Variant() {
// helper::Destroy(type_id, &data); // helper::Destroy(type_id, &data);
} }
template <typename T, typename... Args> void Set(Args &&... args) { template <typename T, typename... Args> void Set(Args &&... args) {
helper::Destroy(type_id, &data); helper::Destroy(type_id, &data);
new (&data) T(std::forward<Args>(args)...); new (&data) T(std::forward<Args>(args)...);
type_id = typeid(T).hash_code(); type_id = typeid(T).hash_code();
} }
template <typename T> T &Get() const { template <typename T> T &Get() const {
if (type_id == typeid(T).hash_code()) { if (type_id == typeid(T).hash_code()) {
return *const_cast<T *>(reinterpret_cast<const T *>(&data)); return *const_cast<T *>(reinterpret_cast<const T *>(&data));
} else { } else {
// std::cout << " bad cast in variant " << std::endl; // std::cout << " bad cast in variant " << std::endl;
throw std::bad_cast(); throw std::bad_cast();
} }
} }
size_t TypeId() const { return type_id; } size_t TypeId() const { return type_id; }
private: private:
static inline size_t invalid_type() { return typeid(void).hash_code(); } static inline size_t invalid_type() { return typeid(void).hash_code(); }
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
...@@ -19,5 +19,5 @@ SOFTWARE. ...@@ -19,5 +19,5 @@ SOFTWARE.
#include "attribute.h" #include "attribute.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework {} namespace framework {}
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -22,107 +22,110 @@ SOFTWARE. ...@@ -22,107 +22,110 @@ 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 GetAttrValue(const proto::OpDesc::Attr &attr_desc) { static Attribute
// std::cout << "begin get attr value" << std::endl; GetAttrValue(const proto::OpDesc::Attr &attr_desc) {
Attribute attr; // std::cout << "begin get attr value" << std::endl;
switch (attr_desc.type()) { Attribute attr;
case proto::AttrType::BOOLEAN: { switch (attr_desc.type()) {
attr.Set<bool>(attr_desc.b()); case proto::AttrType::BOOLEAN: {
break; attr.Set<bool>(attr_desc.b());
} break;
case proto::AttrType::INT: { }
attr.Set<int>(attr_desc.i()); case proto::AttrType::INT: {
break; attr.Set<int>(attr_desc.i());
} break;
case proto::AttrType::FLOAT: { }
attr.Set<float>(attr_desc.f()); case proto::AttrType::FLOAT: {
break; attr.Set<float>(attr_desc.f());
} break;
case proto::AttrType::STRING: { }
attr.Set<std::string>(attr_desc.s()); case proto::AttrType::STRING: {
break; attr.Set<std::string>(attr_desc.s());
} break;
case proto::AttrType::BOOLEANS: { }
std::vector<bool> val(attr_desc.bools_size()); case proto::AttrType::BOOLEANS: {
for (int i = 0; i < attr_desc.bools_size(); ++i) { std::vector<bool> val(attr_desc.bools_size());
val[i] = attr_desc.bools(i); for (int i = 0; i < attr_desc.bools_size(); ++i) {
} val[i] = attr_desc.bools(i);
attr.Set<std::vector<bool>>(val); }
break; attr.Set<std::vector<bool>>(val);
} break;
case proto::AttrType::INTS: { }
std::vector<int> val(attr_desc.ints_size()); case proto::AttrType::INTS: {
for (int i = 0; i < attr_desc.ints_size(); ++i) { std::vector<int> val(attr_desc.ints_size());
val[i] = attr_desc.ints(i); for (int i = 0; i < attr_desc.ints_size(); ++i) {
} val[i] = attr_desc.ints(i);
attr.Set<std::vector<int>>(val); }
break; attr.Set<std::vector<int>>(val);
} break;
case proto::AttrType::FLOATS: { }
std::vector<float> val(attr_desc.floats_size()); case proto::AttrType::FLOATS: {
for (int i = 0; i < attr_desc.floats_size(); ++i) { std::vector<float> val(attr_desc.floats_size());
val[i] = attr_desc.floats(i); for (int i = 0; i < attr_desc.floats_size(); ++i) {
} val[i] = attr_desc.floats(i);
attr.Set<std::vector<float>>(val); }
break; attr.Set<std::vector<float>>(val);
} break;
case proto::AttrType::STRINGS: { }
std::vector<std::string> val(attr_desc.strings_size()); case proto::AttrType::STRINGS: {
for (int i = 0; i < attr_desc.strings_size(); ++i) { std::vector<std::string> val(attr_desc.strings_size());
val[i] = attr_desc.strings(i); for (int i = 0; i < attr_desc.strings_size(); ++i) {
} val[i] = attr_desc.strings(i);
attr.Set<std::vector<std::string>>(val); }
break; attr.Set<std::vector<std::string>>(val);
} break;
case proto::AttrType::LONG: { }
attr.Set<int64_t>(attr_desc.l()); case proto::AttrType::LONG: {
break; attr.Set<int64_t>(attr_desc.l());
} break;
default: }
// std::cout << " not support " << std::endl; default:
break; // std::cout << " not support " << std::endl;
} break;
// std::cout << "end get attr value" << std::endl; }
return attr; // std::cout << "end get attr value" << std::endl;
} return attr;
}
Attribute() {} Attribute() {}
template <typename T, typename... Args> Attribute &Set(Args &&... args) { template <typename T, typename... Args>
variant_.Set<T>(args...); Attribute &Set(Args &&... args) {
return *this; variant_.Set<T>(args...);
} return *this;
}
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>, std::vector<float>, Variant<int, float, std::string, std::vector<int>,
std::vector<std::string>, bool, std::vector<bool>, BlockDesc *, std::vector<float>, std::vector<std::string>, bool,
int64_t> std::vector<bool>, BlockDesc *, 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) {}
template <typename T> inline T Get(const std::string &name) const { template <typename T> inline T Get(const std::string &name) const {
// PADDLE_ENFORCE(attrs_.count(name) != 0, "%s should be in // PADDLE_ENFORCE(attrs_.count(name) != 0, "%s should
// AttributeMap", // be in
// name); // AttributeMap",
return ((Attribute)attrs_.at(name)).Get<T>(); // name);
} return ((Attribute)attrs_.at(name)).Get<T>();
}
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,46 +24,50 @@ SOFTWARE. ...@@ -24,46 +24,50 @@ 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);
const int &ID() const { return desc_.idx(); } const int &ID() const { return desc_.idx(); }
const int &Parent() const { return desc_.parent_idx(); } const int &Parent() const { return desc_.parent_idx(); }
bool operator==(const paddle_mobile::framework::BlockDesc &in_block) const { bool operator==(
return this->ID() == in_block.ID() && this->Parent() == in_block.Parent(); const paddle_mobile::framework::BlockDesc &in_block) const {
} return this->ID() == in_block.ID() &&
this->Parent() == in_block.Parent();
}
bool operator<(const paddle_mobile::framework::BlockDesc &in_block) const { bool operator<(
return this->ID() < in_block.ID() && this->Parent() < in_block.Parent(); const paddle_mobile::framework::BlockDesc &in_block) const {
} 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;
std::vector<std::shared_ptr<OpDesc>> Ops() const; std::vector<std::shared_ptr<OpDesc>> Ops() const;
private: private:
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 {
result_type const h1(std::hash<int>{}(s.ID())); result_type const h1(std::hash<int>{}(s.ID()));
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,49 +19,50 @@ limitations under the License. */ ...@@ -19,49 +19,50 @@ 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]);
} }
if (s == "NHWC") { if (s == "NHWC") {
return DataLayout::kNHWC; return DataLayout::kNHWC;
} else if (s == "NCHW") { } else if (s == "NCHW") {
return DataLayout::kNCHW; return DataLayout::kNCHW;
} else if (s == "ANYLAYOUT") { } else if (s == "ANYLAYOUT") {
return DataLayout::kAnyLayout; return DataLayout::kAnyLayout;
} 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";
case DataLayout::kNCHW: case DataLayout::kNCHW:
return "NCHW"; return "NCHW";
case DataLayout::kAnyLayout: case DataLayout::kAnyLayout:
return "ANY_LAYOUT"; return "ANY_LAYOUT";
default: default:
break; break;
// std::cout << "unknown DataLayou %d", data_layout; // std::cout << "unknown DataLayou %d", data_layout;
} }
} }
inline std::ostream &operator<<(std::ostream &out, const DataLayout &l) { inline std::ostream &operator<<(std::ostream &out,
out << DataLayoutToString(l); const DataLayout &l) {
return out; out << DataLayoutToString(l);
} return out;
}
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -21,67 +21,72 @@ SOFTWARE. ...@@ -21,67 +21,72 @@ 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;
Tensor in; Tensor in;
in.ShareDataWith(input_tensor); in.ShareDataWith(input_tensor);
Tensor out; Tensor out;
// // do layout transform // // do layout transform
// if (NeedTransformLayout(expected_kernel_type.data_layout_, // if (NeedTransformLayout(expected_kernel_type.data_layout_,
// kernel_type_for_var.data_layout_)) { // kernel_type_for_var.data_layout_)) {
// TransDataLayout(kernel_type_for_var, expected_kernel_type, in, &out); // TransDataLayout(kernel_type_for_var, expected_kernel_type, in,
// transformed = true; // &out);
// PassTensorData(&out, &in); // transformed = true;
// } // PassTensorData(&out, &in);
// // }
// // do data type transform //
// if (expected_kernel_type.data_type_ != kernel_type_for_var.data_type_) { // // do data type transform
// TransDataType(kernel_type_for_var, expected_kernel_type, in, &out); // if (expected_kernel_type.data_type_ !=
// transformed = true; // kernel_type_for_var.data_type_) {
// PassTensorData(&out, &in); // TransDataType(kernel_type_for_var, expected_kernel_type, in,
// } // &out);
// // transformed = true;
// // do device transform // PassTensorData(&out, &in);
// if (!platform::is_same_place(kernel_type_for_var.place_, // }
// expected_kernel_type.place_)) { //
// TransDataDevice(in, expected_kernel_type.place_, &out); // // do device transform
// transformed = true; // if (!platform::is_same_place(kernel_type_for_var.place_,
// PassTensorData(&out, &in); // expected_kernel_type.place_)) {
// } // TransDataDevice(in, expected_kernel_type.place_, &out);
// // transformed = true;
// PADDLE_ENFORCE(transformed, "No transform is applied, please check!"); // PassTensorData(&out, &in);
// get output data // }
output_tensor->ShareDataWith(in); //
} // PADDLE_ENFORCE(transformed, "No transform is applied, please
// check!");
// get output data
output_tensor->ShareDataWith(in);
}
void CopyVariableWithTensor(const Variable &in_var, const Tensor &tensor, void CopyVariableWithTensor(const Variable &in_var,
Variable &out_var) { const Tensor &tensor, 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>();
// tran_lod_tensor->set_lod(in_lod_tensor.lod()); // tran_lod_tensor->set_lod(in_lod_tensor.lod());
// tran_lod_tensor->set_layout(in_lod_tensor.layout()); // tran_lod_tensor->set_layout(in_lod_tensor.layout());
// tran_lod_tensor->ShareDataWith(tensor); // tran_lod_tensor->ShareDataWith(tensor);
// } else if (in_var.IsType<SelectedRows>()) { // } else if (in_var.IsType<SelectedRows>()) {
// auto& in_selected_rows = in_var.Get<SelectedRows>(); // auto& in_selected_rows = in_var.Get<SelectedRows>();
// auto* trans_selected_rows = out_var.GetMutable<SelectedRows>(); // auto* trans_selected_rows =
// trans_selected_rows->set_height(in_selected_rows.height()); // out_var.GetMutable<SelectedRows>();
// trans_selected_rows->set_rows(in_selected_rows.rows()); // trans_selected_rows->set_height(in_selected_rows.height());
// trans_selected_rows->mutable_value()->ShareDataWith(tensor); // trans_selected_rows->set_rows(in_selected_rows.rows());
// } else { // trans_selected_rows->mutable_value()->ShareDataWith(tensor);
// PADDLE_THROW("unknown var type"); // } else {
// } // 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, const Tensor &tensor, void CopyVariableWithTensor(const Variable &in_var,
Variable &out_var); const Tensor &tensor, 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,311 +15,320 @@ limitations under the License. */ ...@@ -15,311 +15,320 @@ 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);
break; break;
case 1: case 1:
ddim = make_dim<1>(dims); ddim = make_dim<1>(dims);
break; break;
case 2: case 2:
ddim = make_dim<2>(dims); ddim = make_dim<2>(dims);
break; break;
case 3: case 3:
ddim = make_dim<3>(dims); ddim = make_dim<3>(dims);
break; break;
case 4: case 4:
ddim = make_dim<4>(dims); ddim = make_dim<4>(dims);
break; break;
case 5: case 5:
ddim = make_dim<5>(dims); ddim = make_dim<5>(dims);
break; break;
case 6: case 6:
ddim = make_dim<6>(dims); ddim = make_dim<6>(dims);
break; break;
case 7: case 7:
ddim = make_dim<7>(dims); ddim = make_dim<7>(dims);
break; break;
case 8: case 8:
ddim = make_dim<8>(dims); ddim = make_dim<8>(dims);
break; break;
case 9: case 9:
ddim = make_dim<9>(dims); ddim = make_dim<9>(dims);
break; break;
default: default:
// std::cout << "Dynamic dimensions must have between [1, 9] // std::cout << "Dynamic dimensions must have between [1,
// dimensions."; // 9]
break; // dimensions.";
} break;
} }
}
/// @endcond
/// @endcond
DDim make_ddim(std::initializer_list<int64_t> dims) {
DDim result(make_dim(0)); DDim make_ddim(std::initializer_list<int64_t> dims) {
make_ddim(result, dims.begin(), dims.size()); DDim result(make_dim(0));
return result; make_ddim(result, dims.begin(), dims.size());
} return result;
}
DDim make_ddim(const std::vector<int64_t> &dims) {
DDim result(make_dim(0)); DDim make_ddim(const std::vector<int64_t> &dims) {
make_ddim(result, &dims[0], dims.size()); DDim result(make_dim(0));
return result; make_ddim(result, &dims[0], dims.size());
} return result;
}
DDim make_ddim(const std::vector<int> &dims) {
std::vector<int64_t> res(dims.size()); DDim make_ddim(const std::vector<int> &dims) {
std::transform(dims.begin(), dims.end(), res.begin(), std::vector<int64_t> res(dims.size());
[](int d) { return static_cast<int64_t>(d); }); std::transform(dims.begin(), dims.end(), res.begin(),
return make_ddim(res); [](int d) { return static_cast<int64_t>(d); });
} return make_ddim(res);
}
/// @cond HIDDEN
// XXX For some reason, putting this in an anonymous namespace causes errors /// @cond HIDDEN
struct DynamicMutableIndexer : Vistor<int64_t &> { // XXX For some reason, putting this in an anonymous namespace causes
public: // errors
explicit DynamicMutableIndexer(int idx) : idx_(idx) {} struct DynamicMutableIndexer : Vistor<int64_t &> {
public:
template <int D> int64_t &operator()(Dim<D> &dim) const { return dim[idx_]; } explicit DynamicMutableIndexer(int idx) : idx_(idx) {}
private: template <int D> int64_t &operator()(Dim<D> &dim) const {
int idx_; return dim[idx_];
}; }
struct DynamicConstIndexer : public Vistor<int64_t> { private:
public: int idx_;
explicit DynamicConstIndexer(int idx) : idx_(idx) {} };
template <int D> int64_t operator()(const Dim<D> &dim) const { struct DynamicConstIndexer : public Vistor<int64_t> {
return dim[idx_]; public:
} explicit DynamicConstIndexer(int idx) : idx_(idx) {}
private: template <int D> int64_t operator()(const Dim<D> &dim) const {
int idx_; return dim[idx_];
}; }
/// @endcond private:
int idx_;
int64_t &DDim::operator[](int idx) { };
return DDim::ApplyVistor(DynamicMutableIndexer(idx), *this);
} /// @endcond
int64_t DDim::operator[](int idx) const { int64_t &DDim::operator[](int idx) {
return DDim::ApplyVistor(DynamicConstIndexer(idx), *this); return DDim::ApplyVistor(DynamicMutableIndexer(idx), *this);
} }
int DDim::size() const { return arity(*this); } int64_t DDim::operator[](int idx) const {
return DDim::ApplyVistor(DynamicConstIndexer(idx), *this);
bool DDim::operator==(DDim d) const { }
// if (var.which() != d.getVar().which()) {
// return false; int DDim::size() const { return arity(*this); }
// } else {
std::vector<int64_t> v1 = vectorize(*this); bool DDim::operator==(DDim d) const {
std::vector<int64_t> v2 = vectorize(d); // if (var.which() != d.getVar().which()) {
// return false;
for (unsigned int i = 0; i < v1.size(); i++) { // } else {
if (v1[i] != v2[i]) { std::vector<int64_t> v1 = vectorize(*this);
return false; std::vector<int64_t> v2 = vectorize(d);
}
} for (unsigned int i = 0; i < v1.size(); i++) {
if (v1[i] != v2[i]) {
return true; return false;
// } }
} }
bool DDim::operator!=(DDim d) const { return !(*this == d); } return true;
// }
DDim DDim::operator+(DDim d) const { }
std::vector<int64_t> v1 = vectorize(*this);
std::vector<int64_t> v2 = vectorize(d); bool DDim::operator!=(DDim d) const { return !(*this == d); }
std::vector<int64_t> v3; DDim DDim::operator+(DDim d) const {
std::vector<int64_t> v1 = vectorize(*this);
assert(v1.size() == v2.size()); std::vector<int64_t> v2 = vectorize(d);
for (unsigned int i = 0; i < v1.size(); i++) { std::vector<int64_t> v3;
v3.push_back(v1[i] + v2[i]);
} assert(v1.size() == v2.size());
return make_ddim(v3); for (unsigned int i = 0; i < v1.size(); i++) {
} v3.push_back(v1[i] + v2[i]);
}
DDim DDim::operator*(DDim d) const {
std::vector<int64_t> v1 = vectorize(*this); return make_ddim(v3);
std::vector<int64_t> v2 = vectorize(d); }
std::vector<int64_t> v3; DDim DDim::operator*(DDim d) const {
std::vector<int64_t> v1 = vectorize(*this);
assert(v1.size() == v2.size()); std::vector<int64_t> v2 = vectorize(d);
for (unsigned int i = 0; i < v1.size(); i++) { std::vector<int64_t> v3;
v3.push_back(v1[i] * v2[i]);
} assert(v1.size() == v2.size());
return make_ddim(v3); for (unsigned int i = 0; i < v1.size(); i++) {
} v3.push_back(v1[i] * v2[i]);
}
int64_t get(const DDim &ddim, int idx) { return ddim[idx]; }
return make_ddim(v3);
void set(DDim &ddim, int idx, int value) { ddim[idx] = value; } }
/// @cond HIDDEN int64_t get(const DDim &ddim, int idx) { return ddim[idx]; }
struct VectorizeVisitor : Vistor<void> {
std::vector<int64_t> &vector; void set(DDim &ddim, int idx, int value) { ddim[idx] = value; }
explicit VectorizeVisitor(std::vector<int64_t> &v) : vector(v) {} /// @cond HIDDEN
struct VectorizeVisitor : Vistor<void> {
template <typename T> void operator()(const T &t) { std::vector<int64_t> &vector;
vector.push_back(t.head);
this->operator()(t.tail); explicit VectorizeVisitor(std::vector<int64_t> &v) : vector(v) {}
}
template <typename T> void operator()(const T &t) {
void operator()(const Dim<0> &t) {} vector.push_back(t.head);
}; this->operator()(t.tail);
/// @endcond }
std::vector<int64_t> vectorize(const DDim &ddim) { void operator()(const Dim<0> &t) {}
std::vector<int64_t> result; };
VectorizeVisitor visitor(result); /// @endcond
DDim::ApplyVistor(visitor, ddim);
return result; std::vector<int64_t> vectorize(const DDim &ddim) {
} std::vector<int64_t> result;
VectorizeVisitor visitor(result);
// NOTE: framework::vectorize converts to type int64_t DDim::ApplyVistor(visitor, ddim);
// which does not fit cudnn inputs. return result;
std::vector<int> vectorize2int(const DDim &ddim) { }
std::vector<int64_t> temp = vectorize(ddim);
std::vector<int> result(temp.begin(), temp.end()); // NOTE: framework::vectorize converts to type int64_t
return result; // which does not fit cudnn inputs.
} std::vector<int> vectorize2int(const DDim &ddim) {
std::vector<int64_t> temp = vectorize(ddim);
struct ProductVisitor : Vistor<int64_t> { std::vector<int> result(temp.begin(), temp.end());
template <int D> int64_t operator()(const Dim<D> &dim) { return result;
return product(dim); }
}
}; struct ProductVisitor : Vistor<int64_t> {
template <int D> int64_t operator()(const Dim<D> &dim) {
int64_t product(const DDim &ddim) { return product(dim);
ProductVisitor visitor; }
return DDim::ApplyVistor(visitor, ddim); };
}
int64_t product(const DDim &ddim) {
struct SliceVectorizeVisitor : Vistor<void> { ProductVisitor visitor;
std::vector<int64_t> &vector; return DDim::ApplyVistor(visitor, ddim);
int begin; }
int end;
struct SliceVectorizeVisitor : Vistor<void> {
SliceVectorizeVisitor(std::vector<int64_t> &v, int b, int e) std::vector<int64_t> &vector;
: vector(v), begin(b), end(e) { int begin;
// PADDLE_ENFORCE(begin < end, int end;
// "Begin index must be less than end index in ddim
// slice."); SliceVectorizeVisitor(std::vector<int64_t> &v, int b, int e)
// PADDLE_ENFORCE(begin >= 0, : vector(v), begin(b), end(e) {
// "Begin index can't be less than zero in ddim slice."); // PADDLE_ENFORCE(begin < end,
} // "Begin index must be less than end index in
// ddim
template <int S> void operator()(const Dim<S> &dim) { // slice.");
if (begin == 0) { // PADDLE_ENFORCE(begin >= 0,
vector.push_back(dim.head); // "Begin index can't be less than zero in
} else { // ddim slice.");
--begin; }
}
--end; template <int S> void operator()(const Dim<S> &dim) {
if (end > 0) { if (begin == 0) {
this->operator()(dim.tail); vector.push_back(dim.head);
} } else {
} --begin;
}
void operator()(const Dim<0> &dim) { --end;
// PADDLE_ENFORCE(end == 0, "End index in ddim slice is out of bound."); if (end > 0) {
} this->operator()(dim.tail);
}; }
}
DDim slice_ddim(const DDim &ddim, int begin, int end) {
std::vector<int64_t> vec; void operator()(const Dim<0> &dim) {
vec.reserve(end - begin); // PADDLE_ENFORCE(end == 0, "End index in ddim slice is out
SliceVectorizeVisitor visitor(vec, begin, end); // of bound.");
// boost::apply_visitor(visitor, dim); }
DDim::ApplyVistor(visitor, ddim); };
// visitor(ddim.var.Get<Dim<4>>());
return make_ddim(vec); DDim slice_ddim(const DDim &ddim, int begin, int end) {
} std::vector<int64_t> vec;
vec.reserve(end - begin);
/// \cond HIDDEN SliceVectorizeVisitor visitor(vec, begin, end);
// boost::apply_visitor(visitor, dim);
struct ArityVisitor : Vistor<int> { DDim::ApplyVistor(visitor, ddim);
template <int D> int operator()(Dim<D>) const { return D; } // visitor(ddim.var.Get<Dim<4>>());
}; return make_ddim(vec);
}
/// \endcond
/// \cond HIDDEN
int arity(const DDim &d) {
ArityVisitor arityVisitor = ArityVisitor(); struct ArityVisitor : Vistor<int> {
return DDim::ApplyVistor(arityVisitor, d); template <int D> int operator()(Dim<D>) const { return D; }
// return arityVisitor(d.var.Get<Dim<4>>()); };
// return boost::apply_visitor(ArityVisitor(), d); }
} /// \endcond
/// \cond HIDDEN
int arity(const DDim &d) {
/// \endcond ArityVisitor arityVisitor = ArityVisitor();
return DDim::ApplyVistor(arityVisitor, d);
struct OSVistor : Vistor<std::ostream &> { // return arityVisitor(d.var.Get<Dim<4>>());
OSVistor(std::ostream &os) : os_(os) {} // return boost::apply_visitor(ArityVisitor(), d); }
}
template <int D> std::ostream &operator()(Dim<D> dim) const { /// \cond HIDDEN
return os_ << dim;
} /// \endcond
private: struct OSVistor : Vistor<std::ostream &> {
std::ostream &os_; OSVistor(std::ostream &os) : os_(os) {}
};
template <int D> std::ostream &operator()(Dim<D> dim) const {
std::ostream &operator<<(std::ostream &os, const DDim &ddim) { return os_ << dim;
auto vistor = OSVistor(os); }
DDim::ApplyVistor(vistor, ddim);
return os; private:
} std::ostream &os_;
};
DDim::DDim(std::initializer_list<int64_t> init_list) {
*this = make_ddim(init_list); std::ostream &operator<<(std::ostream &os, const DDim &ddim) {
} auto vistor = OSVistor(os);
DDim::ApplyVistor(vistor, ddim);
DDim flatten_to_2d(const DDim &src, int num_col_dims) { return os;
int rank = src.size(); }
return make_ddim({product(slice_ddim(src, 0, num_col_dims)),
product(slice_ddim(src, num_col_dims, rank))}); DDim::DDim(std::initializer_list<int64_t> init_list) {
} *this = make_ddim(init_list);
}
DDim flatten_to_1d(const DDim &src) { return make_ddim({product(src)}); }
DDim flatten_to_2d(const DDim &src, int num_col_dims) {
DDim stride(const DDim &ddim) { int rank = src.size();
std::vector<int64_t> strides(ddim.size()); return make_ddim({product(slice_ddim(src, 0, num_col_dims)),
strides[ddim.size() - 1] = 1; product(slice_ddim(src, num_col_dims, rank))});
for (int i = ddim.size() - 2; i >= 0; --i) { }
strides[i] = strides[i + 1] * ddim[i + 1];
} DDim flatten_to_1d(const DDim &src) {
return framework::make_ddim(strides); return make_ddim({product(src)});
} }
DDim stride_numel(const framework::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] = ddim[ddim.size() - 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]; strides[i] = strides[i + 1] * ddim[i + 1];
} }
return framework::make_ddim(strides); return framework::make_ddim(strides);
} }
} // namespace framework DDim stride_numel(const framework::DDim &ddim) {
std::vector<int64_t> strides(ddim.size());
strides[ddim.size() - 1] = ddim[ddim.size() - 1];
for (int i = ddim.size() - 2; i >= 0; --i) {
strides[i] = strides[i + 1] * ddim[i];
}
return framework::make_ddim(strides);
}
} // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -22,140 +22,145 @@ limitations under the License. */ ...@@ -22,140 +22,145 @@ 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>, Dim<6>, typedef Variant<Dim<0>, Dim<1>, Dim<2>, Dim<3>, Dim<4>, Dim<5>,
Dim<7>, Dim<8>, Dim<9>> Dim<6>, 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, const DDim &d) { static typename Vistor::type_t ApplyVistor(Vistor vistor,
if (d.var.TypeId() == typeid(Dim<0>).hash_code()) { const DDim &d) {
return vistor(d.var.Get<Dim<0>>()); if (d.var.TypeId() == typeid(Dim<0>).hash_code()) {
} else if (d.var.TypeId() == typeid(Dim<1>).hash_code()) { return vistor(d.var.Get<Dim<0>>());
return vistor(d.var.Get<Dim<1>>()); } else if (d.var.TypeId() == typeid(Dim<1>).hash_code()) {
} else if (d.var.TypeId() == typeid(Dim<2>).hash_code()) { return vistor(d.var.Get<Dim<1>>());
return vistor(d.var.Get<Dim<2>>()); } else if (d.var.TypeId() == typeid(Dim<2>).hash_code()) {
} else if (d.var.TypeId() == typeid(Dim<3>).hash_code()) { return vistor(d.var.Get<Dim<2>>());
return vistor(d.var.Get<Dim<3>>()); } else if (d.var.TypeId() == typeid(Dim<3>).hash_code()) {
} else if (d.var.TypeId() == typeid(Dim<4>).hash_code()) { return vistor(d.var.Get<Dim<3>>());
return vistor(d.var.Get<Dim<4>>()); } else if (d.var.TypeId() == typeid(Dim<4>).hash_code()) {
} else if (d.var.TypeId() == typeid(Dim<5>).hash_code()) { return vistor(d.var.Get<Dim<4>>());
return vistor(d.var.Get<Dim<5>>()); } else if (d.var.TypeId() == typeid(Dim<5>).hash_code()) {
} else if (d.var.TypeId() == typeid(Dim<6>).hash_code()) { return vistor(d.var.Get<Dim<5>>());
return vistor(d.var.Get<Dim<6>>()); } else if (d.var.TypeId() == typeid(Dim<6>).hash_code()) {
} else if (d.var.TypeId() == typeid(Dim<7>).hash_code()) { return vistor(d.var.Get<Dim<6>>());
return vistor(d.var.Get<Dim<7>>()); } else if (d.var.TypeId() == typeid(Dim<7>).hash_code()) {
} else if (d.var.TypeId() == typeid(Dim<8>).hash_code()) { return vistor(d.var.Get<Dim<7>>());
return vistor(d.var.Get<Dim<8>>()); } else if (d.var.TypeId() == typeid(Dim<8>).hash_code()) {
} else if (d.var.TypeId() == typeid(Dim<9>).hash_code()) { return vistor(d.var.Get<Dim<8>>());
return vistor(d.var.Get<Dim<9>>()); } else if (d.var.TypeId() == typeid(Dim<9>).hash_code()) {
} else { return vistor(d.var.Get<Dim<9>>());
printf(" dim not support \n"); } else {
throw std::bad_exception(); printf(" dim not support \n");
// return typename Vistor::type_t(); throw std::bad_exception();
} // return typename Vistor::type_t();
} }
}
DDim() { var.Set<Dim<1>>(Dim<1>()); }
DDim() { var.Set<Dim<1>>(Dim<1>()); }
template <int D> explicit DDim(const Dim<D> &in) { var.Set<Dim<D>>(in); }
template <int D> explicit DDim(const Dim<D> &in) {
/*implicit*/ DDim(std::initializer_list<int64_t> init_list); var.Set<Dim<D>>(in);
}
template <int D> DDim &operator=(const Dim<D> &in) {
var.Set<Dim<D>>(in); /*implicit*/ DDim(std::initializer_list<int64_t> init_list);
return *this;
} template <int D> DDim &operator=(const Dim<D> &in) {
var.Set<Dim<D>>(in);
int64_t &operator[](int idx); return *this;
}
int64_t operator[](int idx) const;
int64_t &operator[](int idx);
// template <typename Visitor>
// typename Visitor::result_type apply_visitor(Visitor& visitor) { int64_t operator[](int idx) const;
// return var.apply_visitor(visitor);
// } // template <typename Visitor>
// // typename Visitor::result_type apply_visitor(Visitor& visitor) {
// template <typename Visitor> // return var.apply_visitor(visitor);
// typename Visitor::result_type apply_visitor(Visitor& visitor) const { // }
// return var.apply_visitor(visitor); //
// } // template <typename Visitor>
// typename Visitor::result_type apply_visitor(Visitor& visitor)
DDimVar getVar() { return var; } // const {
// return var.apply_visitor(visitor);
bool operator==(DDim d) const; // }
bool operator!=(DDim d) const; DDimVar getVar() { return var; }
DDim operator+(DDim d) const; bool operator==(DDim d) const;
DDim operator*(DDim d) const; bool operator!=(DDim d) const;
int size() const; DDim operator+(DDim d) const;
};
DDim operator*(DDim d) const;
/**
* \brief Make a DDim from std::vector<int64_t> int size() const;
* };
* \param dims An vector of ints. Must be sized between [1, 9]
*/ /**
DDim make_ddim(const std::vector<int64_t> &dims); * \brief Make a DDim from std::vector<int64_t>
*
DDim make_ddim(const std::vector<int> &dims); * \param dims An vector of ints. Must be sized between [1, 9]
*/
/** DDim make_ddim(const std::vector<int64_t> &dims);
* \brief Make a DDim from an initializer list
* DDim make_ddim(const std::vector<int> &dims);
* \param dims An initializer list of ints. Must be sized between [1, 9]
* /**
*/ * \brief Make a DDim from an initializer list
DDim make_ddim(std::initializer_list<int64_t> dims); *
* \param dims An initializer list of ints. Must be sized between [1, 9]
int64_t get(const DDim &dim, int idx); *
*/
void set(DDim &dim, int idx, int val); DDim make_ddim(std::initializer_list<int64_t> dims);
std::vector<int64_t> vectorize(const DDim &ddim); int64_t get(const DDim &dim, int idx);
std::vector<int> vectorize2int(const DDim &ddim); void set(DDim &dim, int idx, int val);
int64_t product(const DDim &ddim); std::vector<int64_t> vectorize(const DDim &ddim);
/** std::vector<int> vectorize2int(const DDim &ddim);
* \brief Slice a ddim
* int64_t product(const DDim &ddim);
* Slice dim with [begin, end).
* e.g. DDim d = make_ddim({1,2,3,4,5}); /**
* slice_ddim(d, 1, 3); ====> {2,3} * \brief Slice a ddim
*/ *
DDim slice_ddim(const DDim &dim, int begin, int end); * Slice dim with [begin, end).
* e.g. DDim d = make_ddim({1,2,3,4,5});
/** * slice_ddim(d, 1, 3); ====> {2,3}
* \brief What is the length of this dimension? */
* DDim slice_ddim(const DDim &dim, int begin, int end);
* \param Dynamic dimension to inspect
*/ /**
* \brief What is the length of this dimension?
*
* \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 length) // Reshape a tensor to a matrix. The matrix's first dimension(column
// will be the product of tensor's first `num_col_dims` dimensions. // length)
DDim flatten_to_2d(const DDim &src, int num_col_dims); // 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_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
此差异已折叠。
...@@ -23,84 +23,93 @@ SOFTWARE. ...@@ -23,84 +23,93 @@ SOFTWARE.
#include "variable.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 {
to_predict_program_ = program_.originProgram; to_predict_program_ = program_.originProgram;
} }
const std::vector<std::shared_ptr<BlockDesc>> blocks = const std::vector<std::shared_ptr<BlockDesc>> blocks =
to_predict_program_->Blocks(); to_predict_program_->Blocks();
// std::cout << " **block size " << blocks.size() << std::endl; // std::cout << " **block size " << blocks.size() << std::endl;
for (int i = 0; i < blocks.size(); ++i) { for (int i = 0; i < blocks.size(); ++i) {
std::shared_ptr<BlockDesc> block_desc = blocks[i]; std::shared_ptr<BlockDesc> block_desc = blocks[i];
std::vector<std::shared_ptr<OpDesc>> ops = block_desc->Ops(); std::vector<std::shared_ptr<OpDesc>> ops = block_desc->Ops();
// std::cout << " ops " << ops.size() << std::endl; // std::cout << " ops " << ops.size() << std::endl;
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];
// std::cout << " input 0 " << op->Input("Input")[0] << std::endl; // std::cout << " input 0 " << op->Input("Input")[0]
if (op->Type() == "conv2d" && op->Input("Input")[0] == "pixel") { // << std::endl;
// std::cout << " conv2d attr size: " << op->GetAttrMap().size() if (op->Type() == "conv2d" &&
// << std::endl; op->Input("Input")[0] == "pixel") {
// std::cout << " input size: " << op->GetInputs().size() << // std::cout << " conv2d attr size: " <<
// std::endl; // op->GetAttrMap().size()
// << std::endl;
// std::cout << " input size: " <<
// op->GetInputs().size() <<
// std::endl;
// std::cout << " output size: " << op->GetOutputs().size() << // std::cout << " output size: " <<
// std::endl; // op->GetOutputs().size() <<
// std::endl;
Attribute strides_attr = op->GetAttrMap().at("strides"); Attribute strides_attr = op->GetAttrMap().at("strides");
std::vector<int> stride = strides_attr.Get<std::vector<int>>(); std::vector<int> stride =
for (int k = 0; k < stride.size(); ++k) { strides_attr.Get<std::vector<int>>();
// std::cout << " stride " << stride[k] << std::endl; for (int k = 0; k < stride.size(); ++k) {
} // std::cout << " stride " << stride[k] <<
// std::endl;
}
std::shared_ptr<operators::ConvOp<Dtype, float>> conv = std::shared_ptr<operators::ConvOp<Dtype, float>> conv =
std::make_shared<operators::ConvOp<Dtype, float>>( std::make_shared<operators::ConvOp<Dtype, float>>(
op->Type(), op->GetInputs(), op->GetOutputs(), op->GetAttrMap(), op->Type(), op->GetInputs(), op->GetOutputs(),
program_.scope); op->GetAttrMap(), program_.scope);
ops_of_block_[*block_desc.get()].push_back(conv); ops_of_block_[*block_desc.get()].push_back(conv);
} }
} }
} }
} }
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");
auto tensor = g_feed_value->GetMutable<Tensor>(); auto tensor = g_feed_value->GetMutable<Tensor>();
tensor->ShareDataWith(t); tensor->ShareDataWith(t);
Variable *con_output = scope->Var("conv2d_0.tmp_0"); Variable *con_output = scope->Var("conv2d_0.tmp_0");
Tensor *output_tensor = con_output->GetMutable<Tensor>(); Tensor *output_tensor = con_output->GetMutable<Tensor>();
output_tensor->mutable_data<float>({1, 16, 32, 32}); output_tensor->mutable_data<float>({1, 16, 32, 32});
// std::cout << typeid(output_tensor).name() << std::endl; // std::cout << typeid(output_tensor).name() << std::endl;
// std::cout << "output_tensor dims: " << output_tensor->dims() << std::endl; // std::cout << "output_tensor dims: " << output_tensor->dims() <<
// std::endl;
std::shared_ptr<Tensor> out_tensor = std::make_shared<LoDTensor>(); std::shared_ptr<Tensor> out_tensor = std::make_shared<LoDTensor>();
out_tensor.reset(output_tensor); out_tensor.reset(output_tensor);
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(); ++j) { for (int j = 0; j < ops_of_block_[*to_predict_block.get()].size();
auto op = ops_of_block_[*to_predict_block.get()][j]; ++j) {
// std::cout << "开始run" << std::endl; auto op = ops_of_block_[*to_predict_block.get()][j];
op->Run(); // std::cout << "开始run" << std::endl;
} op->Run();
} }
}
template class Executor<CPU>; template class Executor<CPU>;
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -32,22 +32,22 @@ SOFTWARE. ...@@ -32,22 +32,22 @@ 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);
private: private:
const framework::Program<Dtype> program_; const framework::Program<Dtype> program_;
std::shared_ptr<ProgramDesc> to_predict_program_; std::shared_ptr<ProgramDesc> to_predict_program_;
void predict(const Tensor &t, int block_id); void predict(const Tensor &t, int block_id);
std::map<framework::BlockDesc, std::map<framework::BlockDesc,
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
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -23,178 +23,190 @@ limitations under the License. */ ...@@ -23,178 +23,190 @@ 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 level * - in a level, each element indicates relative offset of the lower
* - the first element should be 0 and that indicates that this sequence start * level
* from 0 * - the first element should be 0 and that indicates that this sequence
* - each sequence's begin and end(no-inclusive) is level[id, id+1] * start
* * from 0
* For example: * - each sequence's begin and end(no-inclusive) is level[id, id+1]
* 3-level LoD stores *
* * For example:
* 0 2 3 * 3-level LoD stores
* 0 2 4 7 *
* 0 2 5 7 10 12 15 20 * 0 2 3
*/ * 0 2 4 7
using LoD = std::vector<std::vector<size_t>>; * 0 2 5 7 10 12 15 20
*/
std::ostream &operator<<(std::ostream &os, const LoD &lod); using LoD = std::vector<std::vector<size_t>>;
std::ostream &operator<<(std::ostream &os, const LoDTensor &t); std::ostream &operator<<(std::ostream &os, const LoD &lod);
std::string LoDToString(const LoD &lod); std::ostream &operator<<(std::ostream &os, const LoDTensor &t);
LoD SliceInLevel(const LoD &in, size_t level, size_t elem_begin, std::string LoDToString(const LoD &lod);
size_t elem_end);
LoD SliceInLevel(const LoD &in, size_t level, size_t elem_begin,
/* size_t elem_end);
* Transform an LoD from relative offsets to absolute offsets.
*/ /*
LoD ToAbsOffset(const LoD &in); * Transform an LoD from relative offsets to absolute offsets.
*/
bool operator==(const LoD &a, const LoD &b); LoD ToAbsOffset(const LoD &in);
/* bool operator==(const LoD &a, const LoD &b);
* Check whether this lod's format is valid.
* /*
* ATTENTION: * Check whether this lod's format is valid.
* - Empty lod is treated as valid. *
* * ATTENTION:
* It will check two things: * - Empty lod is treated as valid.
* *
* 1. all the offsets in a level should be ascending(no same items allows). * It will check two things:
* 2. there should be more than 2 offsets existing in each level. *
* 3. the higher level's last offset should equals the lower level's size-1. * 1. all the offsets in a level should be ascending(no same items
* 4. the first offset(the begin offset) of each level should be 0. * allows).
* 5. the lowest level's last offset should equals `tensor_height` if * 2. there should be more than 2 offsets existing in each level.
* tensor_height>0. * 3. the higher level's last offset should equals the lower level's
*/ * size-1.
* 4. the first offset(the begin offset) of each level should be 0.
bool CheckLoD(const LoD &in, int tensor_height = -1); * 5. the lowest level's last offset should equals `tensor_height` if
* tensor_height>0.
/* */
* Check whether this absolute lod's format is valid.
* bool CheckLoD(const LoD &in, int tensor_height = -1);
* ATTENTION:
* - Empty lod is treated as valid. /*
* * Check whether this absolute lod's format is valid.
* It will check two things: *
* 1. all the offsets in a level should be ascending(no same items allows) * ATTENTION:
* 2. there should be more than 2 offsets existing in each level. * - Empty lod is treated as valid.
* 3. the first offset of each level should be 0, and the last should be the *
* same(the height of underlying tensor) or `tensor_height` if * It will check two things:
* tensor_height>0. * 1. all the offsets in a level should be ascending(no same items
*/ * allows)
bool CheckAbsLoD(const LoD &in, int tensor_height = -1); * 2. there should be more than 2 offsets existing in each level.
* 3. the first offset of each level should be 0, and the last should
/* * be the
* LoDTensor (Level of details Tensor) * same(the height of underlying tensor) or `tensor_height` if
* see https://en.wikipedia.org/wiki/Level_of_details for reference. * tensor_height>0.
*/ */
class LoDTensor : public Tensor { bool CheckAbsLoD(const LoD &in, int tensor_height = -1);
public:
LoDTensor() : Tensor() {} /*
* LoDTensor (Level of details Tensor)
explicit LoDTensor(const LoD &lod) : lod_(lod) {} * see https://en.wikipedia.org/wiki/Level_of_details for reference.
*/
void set_lod(const LoD &lod) { lod_ = lod; } class LoDTensor : public Tensor {
public:
const LoD &lod() const { return lod_; } LoDTensor() : Tensor() {}
LoD *mutable_lod() { return &lod_; } explicit LoDTensor(const LoD &lod) : lod_(lod) {}
/* void set_lod(const LoD &lod) { lod_ = lod; }
* Get the start offset and end offset of an element from LoD.
*/ const LoD &lod() const { return lod_; }
std::pair<size_t, size_t> lod_element(size_t level, size_t elem) const {
// PADDLE_ENFORCE_LT(level, NumLevels()); LoD *mutable_lod() { return &lod_; }
// PADDLE_ENFORCE_LT(elem, NumElements(level));
return std::make_pair((lod_)[level][elem], (lod_)[level][elem + 1]); /*
} * Get the start offset and end offset of an element from LoD.
*/
/* std::pair<size_t, size_t> lod_element(size_t level,
* Number of LoDTensor's levels, each level has units of data, for example, size_t elem) const {
* in the sentence's view, article, paragraph, sentence are 3 levels. // PADDLE_ENFORCE_LT(level, NumLevels());
*/ // PADDLE_ENFORCE_LT(elem, NumElements(level));
size_t NumLevels() const { return lod_.size(); } return std::make_pair((lod_)[level][elem],
(lod_)[level][elem + 1]);
/* }
* Number of elements in a level.
*/ /*
size_t NumElements(size_t level = 0) const { * Number of LoDTensor's levels, each level has units of data, for
// PADDLE_ENFORCE_LT(level, NumLevels()); * example,
// the last offset is the end of last element * in the sentence's view, article, paragraph, sentence are 3
return (lod_)[level].size() - 1; * levels.
} */
size_t NumLevels() const { return lod_.size(); }
private:
LoD lod_; /*
}; * Number of elements in a level.
*/
/* size_t NumElements(size_t level = 0) const {
* Expand the `source` to fit the LoD of `lod`. For example, a `source` // PADDLE_ENFORCE_LT(level, NumLevels());
* LoDTensor is // the last offset is the end of last element
* - LoD: [0, 2] return (lod_)[level].size() - 1;
* - tensor: [a0, a1] }
* a `lod` is
* - LoD: [0 3 5] private:
* returns a new LoDTensor LoD lod_;
* - [a0 a0 a0 a1 a1] };
*/
template <typename T> /*
LoDTensor LodExpand(const LoDTensor &source, const LoD &lod, size_t level) { * Expand the `source` to fit the LoD of `lod`. For example, a `source`
LoD abs_lod = ToAbsOffset(lod); * LoDTensor is
const auto &lod_level = lod[level]; * - LoD: [0, 2]
size_t num_instances = source.dims()[0]; * - tensor: [a0, a1]
* a `lod` is
// new tensor * - LoD: [0 3 5]
LoDTensor tensor; * returns a new LoDTensor
tensor.set_lod(lod); * - [a0 a0 a0 a1 a1]
auto dims = source.dims(); */
dims[0] = lod_level.back(); template <typename T>
tensor.Resize(dims); LoDTensor LodExpand(const LoDTensor &source, const LoD &lod,
tensor.mutable_data<T>(); size_t level) {
LoD abs_lod = ToAbsOffset(lod);
// PADDLE_ENFORCE_EQ(num_instances, lod_level.size() - 1); const auto &lod_level = lod[level];
for (size_t ins = 0; ins < num_instances; ins++) { size_t num_instances = source.dims()[0];
for (size_t elem = lod_level[ins]; elem < lod_level[ins + 1]; elem++) {
auto slice = tensor.Slice(elem, elem + 1); // new tensor
TensorCopy(source.Slice(ins, ins + 1), &slice); LoDTensor tensor;
} tensor.set_lod(lod);
} auto dims = source.dims();
return tensor; dims[0] = lod_level.back();
} tensor.Resize(dims);
tensor.mutable_data<T>();
// 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: ]). // PADDLE_ENFORCE_EQ(num_instances, lod_level.size() - 1);
// for (size_t ins = 0; ins < num_instances; ins++) {
// For example, for (size_t elem = lod_level[ins]; elem < lod_level[ins + 1];
// lod = [[0, 3, 4, 8], [0, 9, 10, 11, 13, 17, 19, 22, 24]] elem++) {
// start_level = 0 auto slice = tensor.Slice(elem, elem + 1);
// start_idx = 1 TensorCopy(source.Slice(ins, ins + 1), &slice);
// end_idx = 3 }
// }
// Returns: return tensor;
// LoD = [[1, 4], [2, 4, 2, 3, 2]] }
// pair<size_t, size_t> = {11, 24}
std::pair<LoD, std::pair<size_t, size_t>> // Get the absolute offset of a lod[start_level][start_idx:end_idx] and
GetSubLoDAndAbsoluteOffset(const LoD &lod, size_t start_idx, size_t end_idx, // relative length of details for every levels(i.e., [start_level: ]).
size_t start_level); //
// For example,
void AppendLoD(LoD *lod, const LoD &lod_length); // lod = [[0, 3, 4, 8], [0, 9, 10, 11, 13, 17, 19, 22, 24]]
// start_level = 0
/* // start_idx = 1
* Serialize/Desiralize LoDTensor to std::ostream // end_idx = 3
* You can pass ofstream or ostringstream to serilize to file //
* or to a in memory string. GPU tensor will be copied to CPU. // Returns:
*/ // LoD = [[1, 4], [2, 4, 2, 3, 2]]
void SerializeToStream(std::ostream &os, const LoDTensor &tensor); // pair<size_t, size_t> = {11, 24}
std::pair<LoD, std::pair<size_t, size_t>>
void DeserializeFromStream(std::istream &is, LoDTensor *tensor); GetSubLoDAndAbsoluteOffset(const LoD &lod, size_t start_idx,
size_t end_idx, size_t start_level);
} // namespace framework
void AppendLoD(LoD *lod, const LoD &lod_length);
/*
* Serialize/Desiralize LoDTensor to std::ostream
* You can pass ofstream or ostringstream to serilize to file
* or to a in memory string. GPU tensor will be copied to CPU.
*/
void SerializeToStream(std::ostream &os, const LoDTensor &tensor);
void DeserializeFromStream(std::istream &is, LoDTensor *tensor);
} // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -5,55 +5,58 @@ ...@@ -5,55 +5,58 @@
#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()];
int arg_size = var.arguments_size(); int arg_size = var.arguments_size();
for (int j = 0; j < arg_size; ++j) { for (int j = 0; j < arg_size; ++j) {
args.push_back(var.arguments(j)); args.push_back(var.arguments(j));
} }
} }
for (int i = 0; i < desc_.outputs_size(); ++i) { for (int i = 0; i < desc_.outputs_size(); ++i) {
const proto::OpDesc::Var &var = desc_.outputs(i); const proto::OpDesc::Var &var = desc_.outputs(i);
std::vector<std::string> &args = outputs_[var.parameter()]; std::vector<std::string> &args = outputs_[var.parameter()];
int arg_size = var.arguments_size(); int arg_size = var.arguments_size();
for (int j = 0; j < arg_size; ++j) { for (int j = 0; j < arg_size; ++j) {
args.push_back(var.arguments(j)); args.push_back(var.arguments(j));
} }
} }
for (const proto::OpDesc::Attr &attr : desc_.attrs()) { for (const proto::OpDesc::Attr &attr : desc_.attrs()) {
std::string attr_name = attr.name(); std::string attr_name = attr.name();
if (attr.type() != proto::AttrType::BLOCK) { if (attr.type() != proto::AttrType::BLOCK) {
attrs_[attr_name] = Attribute::GetAttrValue(attr); attrs_[attr_name] = Attribute::GetAttrValue(attr);
// if (attr.type() == proto::AttrType::INT){ // if (attr.type() == proto::AttrType::INT){
// std::cout << " attrName " << attr_name << " " << // std::cout << " attrName " << attr_name << " " <<
// attrs_[attr_name].Get<int>() << std::endl; // attrs_[attr_name].Get<int>() << std::endl;
// } // }
} }
} }
} }
const std::vector<std::string> &OpDesc::Input(const std::string &name) const { const std::vector<std::string> &
return inputs_.find(name)->second; OpDesc::Input(const std::string &name) const {
} return inputs_.find(name)->second;
}
const std::vector<std::string> &OpDesc::Output(const std::string &name) const {
return outputs_.find(name)->second; const std::vector<std::string> &
} OpDesc::Output(const std::string &name) const {
return outputs_.find(name)->second;
Attribute OpDesc::GetAttr(const std::string &name) const { }
auto it = attrs_.find(name);
return it->second; Attribute OpDesc::GetAttr(const std::string &name) const {
} auto it = attrs_.find(name);
return it->second;
const std::unordered_map<std::string, Attribute> &OpDesc::GetAttrMap() const { }
return attrs_;
} const std::unordered_map<std::string, Attribute> &
OpDesc::GetAttrMap() const {
} // namespace framework return attrs_;
}
} // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -23,29 +23,31 @@ SOFTWARE. ...@@ -23,29 +23,31 @@ 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> &Input(const std::string &name) const; const std::vector<std::string> &
const std::vector<std::string> &Output(const std::string &name) const; Input(const std::string &name) const;
Attribute GetAttr(const std::string &name) const; const std::vector<std::string> &
Output(const std::string &name) const;
Attribute GetAttr(const std::string &name) const;
const VariableNameMap &GetInputs() { return inputs_; } const VariableNameMap &GetInputs() { return inputs_; }
const VariableNameMap &GetOutputs() { return outputs_; } const VariableNameMap &GetOutputs() { return outputs_; }
const AttributeMap &GetAttrMap() const; const AttributeMap &GetAttrMap() const;
const std::string &Type() { return desc_.type(); }; const std::string &Type() { return desc_.type(); };
private: private:
proto::OpDesc desc_; proto::OpDesc desc_;
VariableNameMap inputs_; VariableNameMap inputs_;
VariableNameMap outputs_; VariableNameMap outputs_;
AttributeMap attrs_; AttributeMap attrs_;
}; };
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -22,70 +22,74 @@ SOFTWARE. ...@@ -22,70 +22,74 @@ 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_,
// "Operator Creator has not been registered"); // "Operator Creator has not been
return creator_; // registered");
} return creator_;
}; }
};
template <typename Dtype> class OpInfoMap;
template <typename Dtype> class OpInfoMap;
template <typename Dtype> static OpInfoMap<Dtype> *g_op_info_map = nullptr;
template <typename Dtype>
template <typename Dtype> class OpInfoMap { static OpInfoMap<Dtype> *g_op_info_map = nullptr;
public:
static OpInfoMap &Instance() { template <typename Dtype> class OpInfoMap {
if (g_op_info_map<Dtype> == nullptr) { public:
g_op_info_map<Dtype> = new OpInfoMap(); static OpInfoMap &Instance() {
} if (g_op_info_map<Dtype> == nullptr) {
return *g_op_info_map<Dtype>; g_op_info_map<Dtype> = new OpInfoMap();
}; }
return *g_op_info_map<Dtype>;
bool Has(const std::string &op_type) const { };
return map_.find(op_type) != map_.end();
} bool Has(const std::string &op_type) const {
return map_.find(op_type) != map_.end();
void Insert(const std::string &type, const OpInfo<Dtype> &info) { }
// PADDLE_ENFORCE(!Has(type), "Operator %s has been registered", type);
map_.insert({type, info}); void Insert(const std::string &type, const OpInfo<Dtype> &info) {
} // PADDLE_ENFORCE(!Has(type), "Operator %s has been
// registered", type);
const OpInfo<Dtype> &Get(const std::string &type) const { map_.insert({type, info});
auto op_info_ptr = GetNullable(type); }
// PADDLE_ENFORCE_NOT_NULL(op_info_ptr, "Operator %s has not been
// registered", const OpInfo<Dtype> &Get(const std::string &type) const {
// type); auto op_info_ptr = GetNullable(type);
return *op_info_ptr; // PADDLE_ENFORCE_NOT_NULL(op_info_ptr, "Operator %s has not
} // been
// registered",
const OpInfo<Dtype> *GetNullable(const std::string &type) const { // type);
auto it = map_.find(type); return *op_info_ptr;
if (it == map_.end()) { }
return nullptr;
} else { const OpInfo<Dtype> *GetNullable(const std::string &type) const {
return &it->second; auto it = map_.find(type);
} if (it == map_.end()) {
} return nullptr;
} else {
const std::unordered_map<std::string, OpInfo<Dtype>> &map() const { return &it->second;
return map_; }
} }
std::unordered_map<std::string, OpInfo<Dtype>> *mutable_map() { const std::unordered_map<std::string, OpInfo<Dtype>> &map() const {
return &map_; return map_;
} }
private: std::unordered_map<std::string, OpInfo<Dtype>> *mutable_map() {
OpInfoMap() = default; return &map_;
std::unordered_map<std::string, OpInfo<Dtype>> map_; }
// DISABLE_COPY_AND_ASSIGN(OpInfoMap); private:
}; OpInfoMap() = default;
std::unordered_map<std::string, OpInfo<Dtype>> map_;
} // namespace framework
// DISABLE_COPY_AND_ASSIGN(OpInfoMap);
};
} // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -22,43 +22,51 @@ SOFTWARE. ...@@ -22,43 +22,51 @@ 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_) << LEFT_SHIFT; int data_type = static_cast<int>(key.data_type_)
int data_layout = static_cast<int>(key.data_layout_) << (LEFT_SHIFT * 2); << LEFT_SHIFT;
int data_layout = static_cast<int>(key.data_layout_)
<< (LEFT_SHIFT * 2);
std::hash<int> hasher; std::hash<int> hasher;
return hasher(data_type + data_layout); return hasher(data_type + data_layout);
} }
}; };
// place, data_type, library_type kinds less than 2^8 // place, data_type, library_type kinds less than 2^8
constexpr static int LEFT_SHIFT = 8; constexpr static int LEFT_SHIFT = 8;
proto::VarType::Type data_type_; proto::VarType::Type data_type_;
DataLayout data_layout_; DataLayout data_layout_;
OpKernelType(proto::VarType::Type data_type, OpKernelType(proto::VarType::Type data_type,
DataLayout data_layout = DataLayout::kAnyLayout) DataLayout data_layout = DataLayout::kAnyLayout)
: 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_ && data_layout_ == o.data_layout_; return data_type_ == o.data_type_ &&
} data_layout_ == o.data_layout_;
}
bool operator!=(const OpKernelType &o) const { return !(*this == o); } bool operator!=(const OpKernelType &o) const {
}; return !(*this == o);
}
};
inline bool NeedTransformLayout(const DataLayout &l, const DataLayout &r) { inline bool NeedTransformLayout(const DataLayout &l,
return l != DataLayout::kAnyLayout && r != DataLayout::kAnyLayout && l != r; const DataLayout &r) {
} return l != DataLayout::kAnyLayout && r != DataLayout::kAnyLayout &&
l != r;
}
inline bool TransFromNeeded(const OpKernelType &l, const OpKernelType &r) { inline bool TransFromNeeded(const OpKernelType &l,
return (l.data_type_ != r.data_type_) || const OpKernelType &r) {
NeedTransformLayout(l.data_layout_, r.data_layout_); return (l.data_type_ != r.data_type_) ||
} 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,26 +20,26 @@ SOFTWARE. ...@@ -20,26 +20,26 @@ 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,
std::shared_ptr<Scope> scope) std::shared_ptr<Scope> scope)
: 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> void OperatorBase<Dtype>::Run() { RunImpl(); } template <typename Dtype> void OperatorBase<Dtype>::Run() { RunImpl(); }
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,53 +33,57 @@ SOFTWARE. ...@@ -33,53 +33,57 @@ SOFTWARE.
#include "variable.h" #include "variable.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
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 AttributeMap &attrs, const VariableNameMap &outputs,
std::shared_ptr<Scope> scope); const AttributeMap &attrs,
virtual ~OperatorBase() {} std::shared_ptr<Scope> scope);
virtual void Run(); virtual ~OperatorBase() {}
const VariableNameMap &Inputs() const { return inputs_; } virtual void Run();
const VariableNameMap &Outputs() const { return outputs_; } const VariableNameMap &Inputs() const { return inputs_; }
const std::string &Type() const { return type_; } const VariableNameMap &Outputs() const { return outputs_; }
const AttributeMap &Attrs() const { return attrs_; } const std::string &Type() const { return type_; }
const AttributeMap &Attrs() const { return attrs_; }
protected: protected:
std::shared_ptr<Scope> scope_; std::shared_ptr<Scope> scope_;
std::string type_; std::string type_;
VariableNameMap inputs_; VariableNameMap inputs_;
VariableNameMap outputs_; VariableNameMap outputs_;
AttributeMap attrs_; AttributeMap attrs_;
private: private:
void CheckAllInputOutputSet() const; void CheckAllInputOutputSet() const;
virtual void RunImpl() const = 0; virtual void RunImpl() const = 0;
}; };
template <typename Dtype> template <typename Dtype>
class OperatorWithKernel : public OperatorBase<Dtype> { class OperatorWithKernel : public OperatorBase<Dtype> {
public: public:
OperatorWithKernel(const std::string &type, const VariableNameMap &inputs, OperatorWithKernel(const std::string &type,
const VariableNameMap &outputs, const AttributeMap &attrs, const VariableNameMap &inputs,
std::shared_ptr<Scope> scope) const VariableNameMap &outputs,
: OperatorBase<Dtype>(type, inputs, outputs, attrs, scope) {} const AttributeMap &attrs,
virtual void InferShape() const = 0; std::shared_ptr<Scope> scope)
: OperatorBase<Dtype>(type, inputs, outputs, attrs, scope) {}
virtual void InferShape() const = 0;
protected: protected:
virtual void RunImpl() const = 0; virtual void RunImpl() const = 0;
private: private:
}; };
template <typename Dtype, typename P> class OpKernelBase : PaddleMobileObject { template <typename Dtype, typename P>
public: class OpKernelBase : PaddleMobileObject {
virtual void Compute(const P &para) const = 0; public:
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,14 +23,14 @@ SOFTWARE. ...@@ -23,14 +23,14 @@ SOFTWARE.
namespace paddle_mobile { namespace paddle_mobile {
class PaddleMobileObject { class PaddleMobileObject {
public: public:
virtual inline const std::string &ToString() { virtual inline const std::string &ToString() {
char address[128] = {0}; char address[128] = {0};
sprintf(address, "%p", this); sprintf(address, "%p", this);
return std::string(address); return std::string(address);
} }
private: private:
}; };
} // 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,18 +25,20 @@ SOFTWARE. ...@@ -25,18 +25,20 @@ 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() { return blocks_; }; const std::vector<std::shared_ptr<BlockDesc>> &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,113 +4,116 @@ ...@@ -4,113 +4,116 @@
#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;
}; };
pvar = new Variable; pvar = new Variable;
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, vars_.size()); // auto var_name = string::Sprintf("%p.%d", this,
// if (name != nullptr) { // vars_.size());
// *name = var_name; // if (name != nullptr) {
// } // *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()) {
delete it->second; delete it->second;
it = vars_.erase(it); it = vars_.erase(it);
} else { } else {
++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()) {
return; return;
} }
auto new_it = vars_.find(new_name); auto new_it = vars_.find(new_name);
if (new_it != vars_.end()) { if (new_it != vars_.end()) {
return; return;
} }
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) const { // std::string Scope::Rename(const std::string& origin_name)
// auto var_name = string::Sprintf("%p.%d", this, vars_.size()); // const {
// Rename(origin_name, var_name); // auto var_name = string::Sprintf("%p.%d", this,
// return var_name; // vars_.size());
// } // Rename(origin_name, 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,57 +24,58 @@ SOFTWARE. ...@@ -24,57 +24,58 @@ 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() {}
Scope &NewScope() const; Scope &NewScope() const;
/// Create a variable with given name if it doesn't exist. /// Create a variable with given name if it doesn't exist.
Variable *Var(const std::string &name); Variable *Var(const std::string &name);
/// Create a variable with a scope-unique name. /// Create a variable with a scope-unique name.
Variable *Var(std::string *name = nullptr); Variable *Var(std::string *name = nullptr);
void EraseVars(const std::vector<std::string> &var_names); void EraseVars(const std::vector<std::string> &var_names);
/// Find a variable in the scope or any of its ancestors. Returns /// Find a variable in the scope or any of its ancestors. Returns
/// nullptr if cannot find. /// nullptr if cannot find.
Variable *FindVar(const std::string &name) const; Variable *FindVar(const std::string &name) const;
const Scope *parent() const { return parent_; } const Scope *parent() const { return parent_; }
/// Find the scope or an ancestor scope that contains the given variable. /// Find the scope or an ancestor scope that contains the given
const Scope *FindScope(const Variable *var) const; /// variable.
const Scope *FindScope(const Variable *var) const;
void DeleteScope(Scope *scope) const; void DeleteScope(Scope *scope) const;
/// Drop all kids scopes belonged to this scope. /// Drop all kids scopes belonged to this scope.
void DropKids(); void DropKids();
// enumerate all the variables current contains. // enumerate all the variables current contains.
std::vector<std::string> LocalVarNames() const; std::vector<std::string> LocalVarNames() const;
// Rename variable to a new name // Rename variable to a new name
void Rename(const std::string &origin_name, void Rename(const std::string &origin_name,
const std::string &new_name) const; const std::string &new_name) const;
// Rename variable to a new name and return the new name // Rename variable to a new name and return the new name
std::string Rename(const std::string &origin_name) const; std::string Rename(const std::string &origin_name) const;
Variable *FindVarLocally(const std::string &name) const; Variable *FindVarLocally(const std::string &name) const;
private: private:
// Call Scope::NewScope for a sub-scope. // Call Scope::NewScope for a sub-scope.
explicit Scope(Scope const *parent) : parent_(parent) {} explicit Scope(Scope const *parent) : parent_(parent) {}
mutable std::unordered_map<std::string, Variable *> vars_; mutable std::unordered_map<std::string, Variable *> vars_;
mutable std::list<Scope *> kids_; mutable std::list<Scope *> kids_;
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,57 +24,59 @@ SOFTWARE. ...@@ -24,57 +24,59 @@ 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, const int64_t &height) SelectedRows(const std::vector<int64_t> &rows,
: rows_(rows), height_(height) { const int64_t &height)
value_.reset(new Tensor()); : rows_(rows), height_(height) {
} value_.reset(new Tensor());
}
SelectedRows() { SelectedRows() {
height_ = 0; height_ = 0;
value_.reset(new Tensor()); value_.reset(new Tensor());
} }
const Tensor &value() const { return *value_; } const Tensor &value() const { return *value_; }
Tensor *mutable_value() { return value_.get(); } Tensor *mutable_value() { return value_.get(); }
int64_t height() const { return height_; } int64_t height() const { return height_; }
void set_height(int64_t height) { height_ = height; } void set_height(int64_t height) { height_ = height; }
const std::vector<int64_t> &rows() const { return rows_; } const std::vector<int64_t> &rows() const { return rows_; }
std::vector<int64_t> *mutable_rows() { return &rows_; } std::vector<int64_t> *mutable_rows() { return &rows_; }
void set_rows(const std::vector<int64_t> &rows) { rows_ = rows; } void set_rows(const std::vector<int64_t> &rows) { rows_ = rows; }
/** /**
* get the index of id in rows * get the index of id in rows
*/ */
int64_t index(int64_t id) const { int64_t index(int64_t id) const {
auto it = std::find(rows_.begin(), rows_.end(), id); auto it = std::find(rows_.begin(), rows_.end(), id);
// PADDLE_ENFORCE(it != rows_.end(), "id should be in rows"); // PADDLE_ENFORCE(it != rows_.end(), "id should be in rows");
return static_cast<int64_t>(std::distance(rows_.begin(), it)); return static_cast<int64_t>(std::distance(rows_.begin(), it));
} }
DDim GetCompleteDims() const { DDim GetCompleteDims() const {
std::vector<int64_t> dims = vectorize(value_->dims()); std::vector<int64_t> dims = vectorize(value_->dims());
dims[0] = height_; dims[0] = height_;
return make_ddim(dims); return make_ddim(dims);
} }
private: private:
// Notice: rows can be duplicate. We can have {0, 4, 7, 0, 5, 7, 9} here. // Notice: rows can be duplicate. We can have {0, 4, 7, 0, 5, 7, 9}
// SelectedRows are simply concated when adding together. Until a // here.
// SelectedRows add a Tensor, will the duplicate rows be handled. // SelectedRows are simply concated when adding together. Until a
std::vector<int64_t> rows_; // SelectedRows add a Tensor, will the duplicate rows be handled.
std::unique_ptr<Tensor> value_{nullptr}; std::vector<int64_t> rows_;
int64_t height_; std::unique_ptr<Tensor> value_{nullptr};
}; int64_t height_;
};
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
此差异已折叠。
此差异已折叠。
...@@ -20,47 +20,47 @@ limitations under the License. */ ...@@ -20,47 +20,47 @@ 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);
dst->resize(src.numel()); dst->resize(src.numel());
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
此差异已折叠。
...@@ -23,16 +23,17 @@ SOFTWARE. ...@@ -23,16 +23,17 @@ 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()) {
return proto::VarType_Type_SELECTED_ROWS; return proto::VarType_Type_SELECTED_ROWS;
} else { } else {
// PADDLE_THROW("ToVarType:Unsupported type %s", type.name()); // PADDLE_THROW("ToVarType:Unsupported type %s",
} // type.name());
} }
}
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
此差异已折叠。
此差异已折叠。
...@@ -27,13 +27,14 @@ SOFTWARE. ...@@ -27,13 +27,14 @@ 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, const std::string &file_path); void LoadVar(framework::LoDTensor *tensor,
}; 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 *>(reinterpret_cast<size_t>(p + offset) & void *r = reinterpret_cast<void *>(
(~(MALLOC_ALIGN - 1))); reinterpret_cast<size_t>(p + offset) & (~(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
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册