飞桨PaddleLite架构研读

一、架构全景图

二、源码详细解读

1. Lite体系下似乎有多种 op_desc/program_desc 的定义,之间的关系是什么?这样设计的背景和好处是什么?

  • model_parser目录下,包含
    • flatbuffers——结构描述定义在 framework.fbs 文件中,命名空间为paddle.lite.fbs.proto
      • 它除了定义OpDesc,还定义了OpDescView(这个用来做什么的?)
    • 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
  • core/model 目录下,包含:
    • base公共API:
      • VarDesc相关:VarDescAPI多继承自VarDescReadAPIVarDescWriteAPI,分别约定了可读、可写的接口虚函数
      • OpDesc相关:OpDescAPI多继承自OpDescReadAPIOpDescWriteAPI,分别约定了可读、可写的接口虚函数
      • BlockDesc相关:BlockDescAPI多继承自BlockDescReadAPIBlockDescWriteAPI,分别约定了可读、可写的接口虚函数
      • ProgramDesc相关:ProgramDescAPI多继承自ProgramDescReadAPIProgramDescWriteAPI,分别约定了可读、可写的接口虚函数
      • ParamDesc相关:ParamDescAPI多继承自ParamDescReadAPIParamDescWriteAPI,分别约定了可读、可写的接口虚函数
        • 这里还有一个 CombinedParamDescAPI,和上面类似,父类不一样,多了ParamDesc的更新操作
    • general目录下,包含
      • VarDesc类:继承自VarDescAPI,不持有任何proto相关的成员,很简洁地描述VarDesc信息
      • OpDesc类:继承自OpDescAPI,不持有任何proto相关的成员,很简洁地描述OpDesc信息
        • attrs_ 是 std::map<string, Any>
      • BlockDesc类:继承自BlockDescAPI,不持有任何proto相关的成员,很简洁地描述BlockDesc信息
      • ProgramDesc类:继承自ProgramDescAPI,不持有任何proto相关的成员,很简洁地描述ProgramDesc信息

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);
  }
posted @ 2022-09-27 17:35  Aurelius84  阅读(254)  评论(0编辑  收藏  举报