本文共 2410 字,大约阅读时间需要 8 分钟。
code:
图片,代码都来自以上项目。
Tengine 由 OPEN AI LAB 主导开发,该项目实现了深度学习神经网络模型在嵌入式设备上的快速、高效部署需求。为实现在众多 AIoT 应用中的跨平台部署,本项目使用 C 语言进行核心模块开发,针对嵌入式设备资源有限的特点进行了深度框架裁剪。同时采用了完全分离的前后端设计,有利于 CPU、GPU、NPU 等异构计算单元的快速移植和部署,降低评估、迁移成本。
因为Tengine是由C语言开发的,和ncnn,mnn等用C++开发的框架有一定的区别。因为只能用函数,所以op,serializer(模型解析器)等的注册都是要在程序的时候进行的。而且对op,serializer等组织需要使用函数指针来模拟C++的多态性。
这里对op的注册机制进行解读。
首先给出数据结构之间的关系图:
这里只是对op_method
和op_name
的注册梳理,以absval
的注册为例
absval
的op_method
和op_name
struct method m;m.version = 1;m.init = init_op; // 函数指针m.release = release_op; // 函数指针return register_op(OP_ABSVAL, OP_ABSVAL_NAME, &m);
static vector_t* internal_op_method_registry
和static vector_t* internal_op_name_registry
这里可以就着上面的关系图进行梳理这里最外面的容器是vector_t
, 然后vector_t
中mem
才是指向注册数据的位置。mem
指向8个vector_entry_t
空间(初始为8个,如果不够了按8个递增申请),valid
指示数据是否写入,这里的unsigned char data[]
指明method
,op_name
在内存的初始位置。后面在使用的时候,就在internal_op_method_registry
和internal_op_name_registry
去找。
vector_t* v = (vector_t*)sys_malloc(sizeof(vector_t)); if (v == NULL) { return NULL; } v->elem_num = 0; v->elem_size = elem_size; v->free_func = free_data; v->entry_size = align(elem_size + (int)sizeof(vector_entry_t), TE_VECTOR_ALIGN_SIZE); // 32, 要写入的数据 字节数 v->ahead_num = 8; // 为什么有8个空间, 以8的倍数进行拓展 v->space_num = v->ahead_num; v->real_mem = sys_malloc(v->entry_size * v->space_num + TE_VECTOR_ALIGN_SIZE); // 32*8+8 v->mem = align_address(v->real_mem, TE_VECTOR_ALIGN_SIZE); // align = 8, 对申请的内存进行 8 字节对齐 for (int i = 0; i < v->space_num; i++) { vector_entry_t* e = get_vector_entry(v, i); // 前面放 vector_entry_t e->valid = 0; // 是否写入的标志位 } return v;
op_name
下面的 push_vector_data , 会用 memcpy 把栈上的数据内容 copy 到已申请的堆内存上memcpy(e->data, data, v->elem_size);
ir_op_name_entry_t op_map; op_map.type = type; op_map.name = name; return push_vector_data(internal_op_name_registry, &op_map); // 写入数据,如果
method
这里在注册前会internal_op_method_registry
遍历,看是否已经注册static int register_op_registry(ir_method_t* method){ if (find_op_method(method->type, method->version)) // 遍历检查是否已经注册 { return -1; } return push_vector_data(internal_op_method_registry, method);}
op
的ir_method_t
数据保存到internal_op_method_registry
, ir_op_name_entry_t
数据保存到internal_op_name_registry
转载地址:http://yuhws.baihongyu.com/