本文主要是介绍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过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!