mace micro: init过程

2024-06-03 14:48
文章标签 init 过程 micro mace

本文主要是介绍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
 

这篇关于mace micro: init过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1027292

相关文章

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

SpringBoot整合liteflow的详细过程

《SpringBoot整合liteflow的详细过程》:本文主要介绍SpringBoot整合liteflow的详细过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋...  liteflow 是什么? 能做什么?总之一句话:能帮你规范写代码逻辑 ,编排并解耦业务逻辑,代码

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

MySQL中的InnoDB单表访问过程

《MySQL中的InnoDB单表访问过程》:本文主要介绍MySQL中的InnoDB单表访问过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、访问类型【1】const【2】ref【3】ref_or_null【4】range【5】index【6】

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机

Navicat数据表的数据添加,删除及使用sql完成数据的添加过程

《Navicat数据表的数据添加,删除及使用sql完成数据的添加过程》:本文主要介绍Navicat数据表的数据添加,删除及使用sql完成数据的添加过程,具有很好的参考价值,希望对大家有所帮助,如有... 目录Navicat数据表数据添加,删除及使用sql完成数据添加选中操作的表则出现如下界面,查看左下角从左

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte