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

相关文章

最新版IDEA配置 Tomcat的详细过程

《最新版IDEA配置Tomcat的详细过程》本文介绍如何在IDEA中配置Tomcat服务器,并创建Web项目,首先检查Tomcat是否安装完成,然后在IDEA中创建Web项目并添加Web结构,接着,... 目录配置tomcat第一步,先给项目添加Web结构查看端口号配置tomcat    先检查自己的to

SpringBoot集成SOL链的详细过程

《SpringBoot集成SOL链的详细过程》Solanaj是一个用于与Solana区块链交互的Java库,它为Java开发者提供了一套功能丰富的API,使得在Java环境中可以轻松构建与Solana... 目录一、什么是solanaj?二、Pom依赖三、主要类3.1 RpcClient3.2 Public

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

SpringBoot整合kaptcha验证码过程(复制粘贴即可用)

《SpringBoot整合kaptcha验证码过程(复制粘贴即可用)》本文介绍了如何在SpringBoot项目中整合Kaptcha验证码实现,通过配置和编写相应的Controller、工具类以及前端页... 目录SpringBoot整合kaptcha验证码程序目录参考有两种方式在springboot中使用k

SpringBoot整合InfluxDB的详细过程

《SpringBoot整合InfluxDB的详细过程》InfluxDB是一个开源的时间序列数据库,由Go语言编写,适用于存储和查询按时间顺序产生的数据,它具有高效的数据存储和查询机制,支持高并发写入和... 目录一、简单介绍InfluxDB是什么?1、主要特点2、应用场景二、使用步骤1、集成原生的Influ

SpringBoot实现websocket服务端及客户端的详细过程

《SpringBoot实现websocket服务端及客户端的详细过程》文章介绍了WebSocket通信过程、服务端和客户端的实现,以及可能遇到的问题及解决方案,感兴趣的朋友一起看看吧... 目录一、WebSocket通信过程二、服务端实现1.pom文件添加依赖2.启用Springboot对WebSocket

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

Solr 使用Facet分组过程中与分词的矛盾解决办法

对于一般查询而言  ,  分词和存储都是必要的  .  比如  CPU  类型  ”Intel  酷睿  2  双核  P7570”,  拆分成  ”Intel”,”  酷睿  ”,”P7570”  这样一些关键字并分别索引  ,  可能提供更好的搜索体验  .  但是如果将  CPU  作为 Facet  字段  ,  最好不进行分词  .  这样就造成了矛盾  ,  解决方法