mace micro: init过程

include/public/micro.h 没有对应的class MaceMicroEngine.h

struct MaceMicroEngineConfig {
  model::NetDef *net_def_;
  const uint8_t *model_data_;
  framework::Graph *graph_; //has a graph
  framework::Operator **op_array_;
  uint8_t *tensor_mem_;
  const void **input_buffers_;
  const int32_t **input_shapes_;
  uint8_t *scratch_buffer_;
  uint32_t scratch_buffer_size_;
};

class MaceMicroEngine {
 public:
  MaceMicroEngine() {} //defalt construct/disconstruct
  ~MaceMicroEngine() {}

  MaceStatus Init(MaceMicroEngineConfig *engine_config);

  MaceStatus RegisterInputData(uint32_t idx, const void *input_buffer,
                               const int32_t *input_dims);
  MaceStatus Run();

  MaceStatus GetOutputData(const uint32_t idx, void **output_data,
                           const int32_t **output_dims,
                           uint32_t *output_dim_size);
  MaceStatus GetOpOutputData(const uint32_t op_def_idx,
                             const uint32_t output_idx,
                             void **output_data,
                             const int32_t **output_dims,
                             uint32_t *output_dim_size);

 private:
  MaceMicroEngineConfig *engine_config_; //唯一数据成员不是在构造函数里赋值而是在 function member: Init

  MaceMicroEngine(const MaceMicroEngine &);
  MaceMicroEngine &operator=(const MaceMicroEngine &);
}; 

  namespace {
    uint8_t kTensorMem[113664] = {0};
    uint8_t kScratchBuffer[1024] = {0};
    const void *kInputBuffers[1] = {NULL};   //指针数组:(有多个input)保存inputBuffers的开始地址和shape
    const int32_t *kInputShapes[1] = {NULL};
  
    MaceMicroEngineConfig kMicroEngineConfig = { 
      reinterpret_cast<model::NetDef *>(kNetDef),
      kModelData,
      reinterpret_cast<framework::Graph *>(kGraphData),
      kOpsArray,
      kTensorMem,
      kInputBuffers,
      kInputShapes,
      kScratchBuffer,
      1024
    };  
  }
  
  MaceMicroEngineConfig *GetMicroEngineConfig() {
    return &kMicroEngineConfig;
  }

 

   24 namespace micro {
   25 MaceStatus MaceMicroEngine::Init(MaceMicroEngineConfig *engine_config) {
   26   MACE_ASSERT(engine_config != NULL && engine_config->net_def_ != NULL
   27                   && engine_config->model_data_ != NULL
   28                   && engine_config->graph_ != NULL
   29                   && engine_config->op_array_ != NULL
   30                   && engine_config->tensor_mem_ != NULL);
   31   engine_config_ = engine_config;
   32 
   33   MACE_RETURN_IF_ERROR(engine_config_->graph_->Init(engine_config_));
   34 
   35   return MACE_SUCCESS;
   36 }

Graph: MaceMicroEngineConfig并不是Graph的data member, 此时Graph的 object已经赋值
MaceStatus Init(MaceMicroEngineConfig *engine_config);

 54  protected:
 55   SerialArray<OpContext> op_contexts_;
 56   SerialArray<SerialUint32> input_op_idxs_;
 57   SerialArray<OpIOInfo> output_infos_;
 58 };

 

>> 32 MaceStatus Graph::Init(MaceMicroEngineConfig *engine_config) {

   //这里为什么不用this 和下面的不一致
   33   MACE_ASSERT(engine_config->net_def_->op_size() == op_context_size());
   34 
   35   uint32_t output_info_size = this->output_info_size();
   36   for (uint32_t i = 0; i < output_info_size; ++i) {
   37     Uint2OpIOInfo(this->output_info(i)); //不是对象的原始数据
   38   }
   39 
   40   uint32_t op_size = engine_config->net_def_->op_size(); //用op_context_size不是更直观
   41   for (uint32_t i = 0; i < op_size; ++i) {
   42     OpContext *op_ctx = const_cast<OpContext *>(op_context(i));//遍历SerialArray<OpContext>对象, 调用OpContext: Init
   43     MACE_RETURN_IF_ERROR(op_ctx->Init(
   44         engine_config, engine_config->net_def_->op(i)));//通过net_def 找到operator信息
   45   }
   46 
   47   return MACE_SUCCESS;
   48 }

 

 30 class OpContext : public Serialize {
 31  public:
 32   MACE_DEFINE_HARD_CODE_MAGIC(OpContext)
 33 
 34   MACE_DECLARE_OBJECT_FUNC(uint32_t, op_idx);
 35   MACE_DECLARE_PTR_ARRAY_FUNC(OpIOInfo, input_info);
 36   MACE_DECLARE_PTR_ARRAY_FUNC(model::OutputShape, output_resize_shape);
 37 
 38   MaceStatus Init(MaceMicroEngineConfig *engine_config,
 39                   const model::OperatorDef *op_def);
 40   MaceStatus Run(MaceMicroEngineConfig *engine_config);
 41 
 42  protected:
 43   SerialUint32 op_idx_;
 44   SerialArray<OpIOInfo> input_infos_;
 45   SerialArray<model::OutputShape> output_resize_shapes_;
 46 };

   32 MaceStatus OpContext::Init(MaceMicroEngineConfig *engine_config,
   33                            const model::OperatorDef *op_def) {
   34   // init OpContext
   35   uint32_t input_info_size = this->input_info_size();
   36   for (uint32_t i = 0; i < input_info_size; ++i) {
   37     Uint2OpIOInfo(this->input_info(i));
   38   }
   39 
   40   // init Op
   41   uint32_t op_i = op_idx();
   42   MACE_RETURN_IF_ERROR(
   43       engine_config->op_array_[op_i]->Init(engine_config, this, op_def));
   44 
   45   return MACE_SUCCESS;
   46 }

 51 class Operator {
 52  public:
 53   Operator() {}
 54   // Note: This func should be virtual, but if we make it virtual,
 55   // the operator delete will be needed, which is in c++ runtime library.
 56   // For we don't use the Operator pointer to point sub-classes, the
 57   // virtual ~Operator() is not needed.
 58   ~Operator();
 59 
 60   MaceStatus Init(MaceMicroEngineConfig *engine_config,
 61                   OpContext *op_context,
 62                   const model::OperatorDef *op_def);

 63   virtual MaceStatus OnInit();
 64   virtual MaceStatus Run();  

103  protected: //operator的成员变量: OperatorDef/ MaceMicroEngineConfig/ OpContext
104   const model::OperatorDef *op_def_;
105   MaceMicroEngineConfig *engine_config_;
108   OpContext *op_context_;
109 };

>> 36 MaceStatus Operator::Init(MaceMicroEngineConfig *engine_config,                                                          
>> 37                           framework::OpContext *op_context,
>> 38                           const model::OperatorDef *op_def) {
   39   engine_config_ = engine_config;
   40   op_context_ = op_context;
   41   op_def_ = op_def;
   42 
   48 
   49   return OnInit();
   50 }

>> 23 MaceStatus SoftmaxOp::OnInit() {
   24   data_format_ = static_cast<DataFormat>(GetArgByName(
   25       "data_format", static_cast<int32_t>(NHWC)));
   26   input_ = GetInputData<mifloat>(INPUT);
   27   input_dims_ = GetInputShapeDims(INPUT);
   28   input_dim_size_ = GetInputShapeDimSize(INPUT);
   29   MACE_ASSERT1(input_dim_size_ >= 2, "The input->dim_size() >= 2 failed.");
   30 
   31   output_ = GetOutputData<mifloat>(OUTPUT);
   32   use_log_ = GetArgByName("use_log", false);
   33 
   34   return MACE_SUCCESS;
   35 } 

Operator的input虽然都用 data struct: OpIOInfo表示,但意义还是差别挺大的
tensor分为三类:
1. OpIOInfo表示model的input时: op_def_idx:是固定值kIdxModelInput: 0xfffe, 
   output_idx_表示的是input的Index(model可以有多个input)
2. OpIOInfo表示model的训练参数时: op_def_idx:是固定值kIdxConstTensor: 0xffff, 
   output_idx_表示的是net_def_->tensor(input_info->output_idx_)
3. OpIOInfo表示是某个Operator的输出时:op_def_idx是operator的Index: engine_config_->net_def_->op(op_def_idx)
   output_idx_表示的是operator的输出index(一个operator可以有多个输出)
    
 972 const void *Operator::DoGetInputData(uint32_t idx) { 
 975   const void *data = 0;
 976   const OpIOInfo *input_info = op_context_->input_info(idx);
 977   const uint32_t op_def_idx = input_info->op_def_idx_;
 978   if (kIdxConstTensor == op_def_idx) {
 979     const model::ConstTensor *const_tensor =
 980         engine_config_->net_def_->tensor(input_info->output_idx_);//在net_def_->tensor中的index
 981     data = engine_config_->model_data_ + const_tensor->offset();
 982   } else if (kIdxModelInput == op_def_idx)      {                                                                                                                                                           
 983     data = engine_config_->input_buffers_[input_info->output_idx_];//在input中index
 984   } else {//来自上个opDef的输出,保存在tensor_mem_里
 985     const model::OperatorDef *pre_op_def = engine_config_->net_def_->op(op_def_idx);//net_def_->op中的index
 987     data = engine_config_->tensor_mem_ + pre_op_def->mem_offset(input_info->output_idx_);//model::OperatorDef的mem_offset(Index)
 989   }
 990 
 991   return data;
 992 }

可以通过下面的Log清晰的看出

OpContext Init的部分工作是Initialized Uint2OpIOInfo, 为后面的operator init和Run 做准备

op_ctx: 0 init
Uint2OpIOInfo: fffe0000
Uint2OpIOInfo: op_def_idx_: fffe, output_idx_: 0
Uint2OpIOInfo: ffff0000
Uint2OpIOInfo: op_def_idx_: ffff, output_idx_: 0
Uint2OpIOInfo: ffff0001
Uint2OpIOInfo: op_def_idx_: ffff, output_idx_: 1
op_ctx: 1 init
Uint2OpIOInfo: 0
Uint2OpIOInfo: op_def_idx_: 0, output_idx_: 0
op_ctx: 2 init
Uint2OpIOInfo: 10000
Uint2OpIOInfo: op_def_idx_: 1, output_idx_: 0
Uint2OpIOInfo: ffff0008
Uint2OpIOInfo: op_def_idx_: ffff, output_idx_: 8
op_ctx: 3 init
Uint2OpIOInfo: 20000
Uint2OpIOInfo: op_def_idx_: 2, output_idx_: 0
Uint2OpIOInfo: ffff0002
Uint2OpIOInfo: op_def_idx_: ffff, output_idx_: 2
Uint2OpIOInfo: ffff0003
Uint2OpIOInfo: op_def_idx_: ffff, output_idx_: 3
op_ctx: 4 init
Uint2OpIOInfo: 30000
Uint2OpIOInfo: op_def_idx_: 3, output_idx_: 0
op_ctx: 5 init
Uint2OpIOInfo: 40000
Uint2OpIOInfo: op_def_idx_: 4, output_idx_: 0
Uint2OpIOInfo: ffff0004
Uint2OpIOInfo: op_def_idx_: ffff, output_idx_: 4
Uint2OpIOInfo: ffff0005
Uint2OpIOInfo: op_def_idx_: ffff, output_idx_: 5
op_ctx: 6 init
Uint2OpIOInfo: 50000
Uint2OpIOInfo: op_def_idx_: 5, output_idx_: 0
op_ctx: 7 init
Uint2OpIOInfo: 60000
Uint2OpIOInfo: op_def_idx_: 6, output_idx_: 0
Uint2OpIOInfo: ffff0006
Uint2OpIOInfo: op_def_idx_: ffff, output_idx_: 6
Uint2OpIOInfo: ffff0007
Uint2OpIOInfo: op_def_idx_: ffff, output_idx_: 7
op_ctx: 8 init
Uint2OpIOInfo: 70000
Uint2OpIOInfo: op_def_idx_: 7, output_idx_: 0
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值