Quantcast
Channel: Sam的技术Blog
Viewing all articles
Browse latest Browse all 158

OAL_Tengine学习Tengine_API

$
0
0
作者: 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.






 

Viewing all articles
Browse latest Browse all 158

Trending Articles