作者: Sam (甄峰) sam_code@hotmail.com
对Tengine API的学习记录。
0. Tengine
API一些基本概念和TensorFlow中的对比:
Tengine API 体系中,graph, Node, Tensor等概念与Tensorflow中相同。
Graph 相当于一个计算任务。 通过读取模型文件,创建一个对应的graph.
Node: Graph中的一个节点,可以认为是一个Op. 可以获取0-N个Tensor,
执行计算,产生0-N个Tensor.
Tensor: 为一个N维度数字或者List。作为Op的 Input或者Output.
shape:
Tengine的Shape和TensorFlow的Shape相同。但它更像是设置:NCHW/NHWC.
1. Tengine API :
1.1: 初始化,反初始化,版本控制部分:
rel = init_tengine();
if(rel != 0)
{
printf("Initialize Tengine error.");
return -1;
}
// 2. Tengine Version
pVersion = get_tengine_version();
printf("\nTengine Version is: [%s]\n", pVersion);
if(request_tengine_version("0.9") < 0)
{
printf("\nrequest_tengine_version is 0.9. \n");
return -1;
}
release_tengine();
讲解:
使用Tengine库是,首先要初始化,这个过程需要一点时间。后续是版本相关函数。
1.2:Graph相关:
1.2.1:创建Graph:
PNet_graph =
create_graph(NULL, "tengine", "models/p.tftmfile");
if(PNet_graph ==
NULL)
{
std::cout << "Sam Info:Create Pnet Graph
failed\n";
std::cout << "errno: " <<
get_tengine_errno() << "\n";
return -1;
}
std::cout <<
"SamInfo: Create PNet Graph success." << std::endl;
1.2.2:销毁Graph:
destroy_graph(PNet_graph);
一个Graph,就是一个计算任务,Tengine载入模型(caffe, Tensorflow,Tengine).
以此作为一个计算任务。
1.2.3: 预运行图:
int prerun_graph(graph_t graph)
在真正运行图之前,需要预先准备好资源。 只用调用一次。
1.2.4: 运行图:
int run_graph(graph_t graph, int block)
执行graph计算任务。参数二: 是否阻塞。
1.2.5:释放运行图所用到的资源:
int postrun_graph(graph_t graph)
1.3: Tensor相关 API:
1.3.1: 通过名字获取Graph 中指定Tensor:
tensor_t get_graph_tensor(graph_t graph, const char*
tensor_name)
1.3.2:获取和设置Tensor Shape:
int set_tensor_shape(tensor_t tensor, const int dims[], int
dim_number)
int get_tensor_shape(tensor_t tensor, int dims[], int
dim_number)
获取和设置指定Tensor的shape.
1.3.3:获取Tensor Buffer size:
int get_tensor_buffer_size(tensor_t tensor)
1.3.4:获取和设置Tensor Buffer:
void* get_tensor_buffer(tensor_t tensor)
int set_tensor_buffer(tensor_t tensor, void* buffer, int
buffer_size)
总结一:
以上API,已经能用最简单的方式完成一个推理。
A. 初始化Tengine,载入模型,创建Graph.
B. 通过Tensor 名字,获取Graph的输入Tensor和输出Tensor句柄。
C. 设置shape后,设置输入Tensor的Buffer。
并分配对应空间。
D. 把数据归一化后, 放置到buffer空间。
E. run graph.
F. 通过Tensor名,获取Graph的输出Tensor。
G. 获取Tensor的输出Buffer.
H. 解析Buffer。
.
.
Z. 释放Graph资源。 Release
Graph。反初始化Tengine.
2. 其它相关Tengine API:
2.1 Node相关:
2.1.1:获取Graph Input Node 数量:
int get_graph_input_node_number(graph_t graph)
2.1.2:获取Graph Output Node数量:
int get_graph_output_node_number(graph_t graph)
2.1.3: 获取指定Graph的第index个Input Node的句柄:
node_t get_graph_input_node(graph_t graph, int idx)
2.1.4: 获取指定Graph的第index个Output
Node的句柄:
node_t get_graph_output_node(graph_t graph, int idx)
2.1.5: 获取指定Graph中所有Node数量:
int get_graph_node_number(graph_t graph)
2.1.6: 获取指定Graph的第index个Node句柄:
node_t get_graph_node_by_idx(graph_t graph, int
node_idx)
通过以上几个函数,可以获取Graph的 Input/output
Node数量。再通过get_graph_input_node(), get_graph_output_node()获取每个Node
Handle.
2.1.7:获取Node名:
const char* get_node_name(node_t node)
pNode_Name = get_node_name(node);
std::cout << "\t Node Name is:" << pNode_Name
<< std::endl;
2.1.8:获取Node Op:
const char* get_node_op(node_t node)
pNode_Op = get_node_op(node);
std::cout << "\t Node Op is:" << pNode_Op <<
std::endl;
2.2: Tensor相关 API:
2.2.1: 获取指定Node的Input Tensor数量:
int get_node_input_number(node_t node);
2.2.2:获取指定Node的Output Tensor数量:
int get_node_output_number(node_t node);
2.2.3:获取Node的指定Index Input Tensor句柄:
tensor_t get_node_input_tensor(node_t node, int
input_idx);
2.2.4:获取Node的指定Index Output Tensor句柄:
tensor_t get_node_output_tensor(node_t node, int
output_idx);
通过以上组合,即可得到Graph 所有Input/Output Tensor Handle.