飞桨PaddleLite架构研读
一、架构全景图
二、源码详细解读
1. Lite体系下似乎有多种 op_desc/program_desc
的定义,之间的关系是什么?这样设计的背景和好处是什么?
- model_parser目录下,包含
- flatbuffers——结构描述定义在
framework.fbs
文件中,命名空间为paddle.lite.fbs.proto
- 它除了定义OpDesc,还定义了
OpDescView
(这个用来做什么的?)
- 它除了定义OpDesc,还定义了
- naive_buffer——结构描述定义在
proto/framework.nb.h
中,其中Attr
为继承StructBuilder,内含一个map结构- BinaryTable、FieldBuider、PrimaryBuilder、PrimaryListBuilder、EnumBuilder、StringBuilder、ListBuilder
- pb——结构描述定义在
core/framework.pb.h
中,对应于主框架Paddle中的proto描述,二者为同一个(似乎会延迟更新) - ssa——结构描述定义在
ssa/op_proto.h
,有别于前三个,这里仅仅定义了BlockOpProto
- 从头文件包含来看,是复用的
core/model/general/op_desc.h
的定义 - 个人觉得ssa是为了转graph,因此直接依赖genernal模块的IR表示即可,无需额外定义新的结构描述
- 从头文件包含来看,是复用的
- 注意:除了ssa以外,其他三个目录下的IR表示都是继承自core/model/base下的xxDescAPI
- cpp_desc定义:
- 通过一个宏来切换,LITE_ON_FLATBUFFERS_DESC_VIEW
- 若开启了此宏,则cpp命名空间里的Desc表示使用类似
fbs::ProgramDescView
- 若关闭了此宏,则cpp命名空间里的Desc表示使用类似
general::ProgrMode
- 若开启了此宏,则cpp命名空间里的Desc表示使用类似
- 通过一个宏来切换,LITE_ON_FLATBUFFERS_DESC_VIEW
- flatbuffers——结构描述定义在
- core/model 目录下,包含:
- base公共API:
- VarDesc相关:VarDescAPI多继承自
VarDescReadAPI
和VarDescWriteAPI
,分别约定了可读、可写的接口虚函数 - OpDesc相关:OpDescAPI多继承自
OpDescReadAPI
和OpDescWriteAPI
,分别约定了可读、可写的接口虚函数 - BlockDesc相关:BlockDescAPI多继承自
BlockDescReadAPI
和BlockDescWriteAPI
,分别约定了可读、可写的接口虚函数 - ProgramDesc相关:ProgramDescAPI多继承自
ProgramDescReadAPI
和ProgramDescWriteAPI
,分别约定了可读、可写的接口虚函数 - ParamDesc相关:ParamDescAPI多继承自
ParamDescReadAPI
和ParamDescWriteAPI
,分别约定了可读、可写的接口虚函数- 这里还有一个
CombinedParamDescAPI
,和上面类似,父类不一样,多了ParamDesc的更新操作
- 这里还有一个
- VarDesc相关:VarDescAPI多继承自
- general目录下,包含
- VarDesc类:继承自VarDescAPI,不持有任何proto相关的成员,很简洁地描述VarDesc信息
- OpDesc类:继承自OpDescAPI,不持有任何proto相关的成员,很简洁地描述OpDesc信息
- attrs_ 是
std::map<string, Any>
- attrs_ 是
- BlockDesc类:继承自BlockDescAPI,不持有任何proto相关的成员,很简洁地描述BlockDesc信息
- ProgramDesc类:继承自ProgramDescAPI,不持有任何proto相关的成员,很简洁地描述ProgramDesc信息
- base公共API:
core/mode/base/traits.h目录下的OpDataTypeTrait似乎是与OpAttrType一一对应关系,不允许重复?
如下是OpAttrType的定义:
// The AttrType is used to make the proto::AttrType portable.
enum class OpAttrType {
INT = 0,
FLOAT = 1,
STRING = 2,
INTS = 3,
FLOATS = 4,
STRINGS = 5,
BOOLEAN = 6,
BOOLEANS = 7,
BLOCK = 8,
LONG = 9,
BLOCKS = 10,
LONGS = 11,
UNK,
};
如下是OpDataTypeTrait机制实现:
#define ATTR_TYPE_TRAIT_IMPL(T, type__) \
template <typename U> \
struct OpDataTypeTrait<type__, U> { \
typedef type__ ET; \
typedef type__ RT; \
static constexpr OpAttrType AT{OpAttrType::T}; \
static constexpr const char* ATN{#T}; \
}; \
template <typename U> \
constexpr OpAttrType OpDataTypeTrait<type__, U>::AT; \
template <typename U> \
constexpr const char* OpDataTypeTrait<type__, U>::ATN;
ATTR_TYPE_TRAIT_IMPL(BLOCK, int16_t);
ATTR_TYPE_TRAIT_IMPL(INT, int32_t);
ATTR_TYPE_TRAIT_IMPL(FLOAT, float);
ATTR_TYPE_TRAIT_IMPL(STRING, std::string);
ATTR_TYPE_TRAIT_IMPL(BOOLEAN, bool);
ATTR_TYPE_TRAIT_IMPL(LONG, int64_t);
// general/op_desc.h 中的接口调用:
template <typename T>
void SetAttr(const std::string& name, const T& v) {
attr_types_[name] = OpDataTypeTrait<T>::AT; // <----- 如T为int16_t,则attr_type记录为BLOCK
attrs_[name].set(v);
}