• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 Unionman Technology Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 /*-------------------------------------------
18                    Includes
19  -------------------------------------------*/
20 #include <stdio.h>
21 #include <stdlib.h>
22 
23 #include "vsi_nn_pub.h"
24 
25 #include "vnn_global.h"
26 #include "vnn_yolov5s.h"
27 
28 /*-------------------------------------------
29                    Macros
30  -------------------------------------------*/
31 
32 #define NEW_VXNODE(_node, _type, _in, _out, _uid)                                                                      \
33     do {                                                                                                               \
34         _node = vsi_nn_AddNode(graph, _type, _in, _out, NULL);                                                         \
35         if (NULL == (_node)) {                                                                                         \
36             goto error;                                                                                                \
37         }                                                                                                              \
38         (_node)->uid = (uint32_t)(_uid);                                                                               \
39     } while (0)
40 
41 #define NEW_VIRTUAL_TENSOR(_id, _attr, _dtype)                                                                         \
42     do {                                                                                                               \
43         memset((_attr).size, 0, VSI_NN_MAX_DIM_NUM * sizeof(vsi_size_t));                                              \
44         (_attr).dim_num = VSI_NN_DIM_AUTO;                                                                             \
45         (_attr).vtl = !VNN_APP_DEBUG;                                                                                  \
46         (_attr).is_const = FALSE;                                                                                      \
47         (_attr).dtype.vx_type = (_dtype);                                                                              \
48         (_id) = vsi_nn_AddTensor(graph, VSI_NN_TENSOR_ID_AUTO, &(_attr), NULL);                                        \
49         if (VSI_NN_TENSOR_ID_NA == (_id)) {                                                                            \
50             goto error;                                                                                                \
51         }                                                                                                              \
52     } while (0)
53 
54 // Set const tensor dims out of this macro.
55 #define NEW_CONST_TENSOR(_id, _attr, _dtype, _ofst, _size)                                                             \
56     do {                                                                                                               \
57         data = load_data(fp, (_ofst), (_size));                                                                        \
58         (_attr).vtl = FALSE;                                                                                           \
59         (_attr).is_const = TRUE;                                                                                       \
60         (_attr).dtype.vx_type = (_dtype);                                                                              \
61         (_id) = vsi_nn_AddTensor(graph, VSI_NN_TENSOR_ID_AUTO, &(_attr), data);                                        \
62         free(data);                                                                                                    \
63         if (VSI_NN_TENSOR_ID_NA == (_id)) {                                                                            \
64             goto error;                                                                                                \
65         }                                                                                                              \
66     } while (0)
67 
68 // Set generic tensor dims out of this macro.
69 #define NEW_NORM_TENSOR(_id, _attr, _dtype)                                                                            \
70     do {                                                                                                               \
71         (_attr).vtl = FALSE;                                                                                           \
72         (_attr).is_const = FALSE;                                                                                      \
73         (_attr).dtype.vx_type = (_dtype);                                                                              \
74         (_id) = vsi_nn_AddTensor(graph, VSI_NN_TENSOR_ID_AUTO, &(_attr), NULL);                                        \
75         if (VSI_NN_TENSOR_ID_NA == (_id)) {                                                                            \
76             goto error;                                                                                                \
77         }                                                                                                              \
78     } while (0)
79 
80 // Set generic tensor dims out of this macro.
81 #define NEW_NORM_TENSOR_FROM_HANDLE(_id, _attr, _dtype)                                                                \
82     do {                                                                                                               \
83         (_attr).vtl = FALSE;                                                                                           \
84         (_attr).is_const = FALSE;                                                                                      \
85         (_attr).dtype.vx_type = (_dtype);                                                                              \
86         (_id) = vsi_nn_AddTensorFromHandle(graph, VSI_NN_TENSOR_ID_AUTO, &(_attr), NULL);                              \
87         if (VSI_NN_TENSOR_ID_NA == (_id)) {                                                                            \
88             goto error;                                                                                                \
89         }                                                                                                              \
90     } while (0)
91 
92 #define NET_NODE_NUM (1)
93 #define NET_NORM_TENSOR_NUM (4)
94 #define NET_CONST_TENSOR_NUM (0)
95 #define NET_VIRTUAL_TENSOR_NUM (3)
96 #define NET_TOTAL_TENSOR_NUM (NET_NORM_TENSOR_NUM + NET_CONST_TENSOR_NUM + NET_VIRTUAL_TENSOR_NUM)
97 
98 /*-------------------------------------------
99                Local Variables
100  -------------------------------------------*/
101 
102 /*-------------------------------------------
103                   Functions
104  -------------------------------------------*/
load_data(FILE * fp,size_t ofst,size_t sz)105 static uint8_t *load_data(FILE *fp, size_t ofst, size_t sz)
106 {
107     uint8_t *data;
108     int32_t ret;
109     data = NULL;
110     if (NULL == fp) {
111         return NULL;
112     }
113 
114     ret = fseek(fp, ofst, SEEK_SET);
115     if (ret != 0) {
116         VSILOGE("blob seek failure.");
117         return NULL;
118     }
119 
120     if (sz <= 0) {
121         // error
122         return NULL;
123     }
124     data = (uint8_t *)malloc(sz);
125     if (data == NULL) {
126         VSILOGE("buffer malloc failure.");
127         return NULL;
128     }
129     ret = fread(data, 1, sz, fp);
130     return data;
131 } /* load_data() */
132 
vnn_CreateYolov5s(const char * data_file_name,vsi_nn_context_t in_ctx,const vsi_nn_preprocess_map_element_t * pre_process_map,uint32_t pre_process_map_count,const vsi_nn_postprocess_map_element_t * post_process_map,uint32_t post_process_map_count)133 vsi_nn_graph_t *vnn_CreateYolov5s(const char *data_file_name, vsi_nn_context_t in_ctx,
134                                   const vsi_nn_preprocess_map_element_t *pre_process_map,
135                                   uint32_t pre_process_map_count,
136                                   const vsi_nn_postprocess_map_element_t *post_process_map,
137                                   uint32_t post_process_map_count)
138 {
139     uint32_t _infinity = VSI_NN_FLOAT32_INF;
140     vsi_status status;
141     vsi_bool release_ctx;
142     vsi_nn_context_t ctx;
143     vsi_nn_graph_t *graph;
144     vsi_nn_node_t *node[NET_NODE_NUM];
145     vsi_nn_tensor_id_t norm_tensor[NET_NORM_TENSOR_NUM];
146 
147     vsi_nn_tensor_attr_t attr;
148     FILE *fp;
149     uint8_t *data;
150     uint32_t i = 0L;
151     char *use_img_process_s;
152     int32_t enable_pre_post_process = 0L;
153     vsi_bool sort = FALSE;
154     vsi_bool inference_with_nbg = FALSE;
155     char *pos = NULL;
156 
157     (void)(_infinity);
158     ctx = NULL;
159     graph = NULL;
160     status = VSI_FAILURE;
161     memset(&attr, 0, sizeof(attr));
162     memset(&node, 0, sizeof(vsi_nn_node_t *) * NET_NODE_NUM);
163 
164     fp = fopen(data_file_name, "rb");
165     if (NULL == fp) {
166         VSILOGE("Open file %s failed.", data_file_name);
167         goto error;
168     }
169 
170     pos = strstr((char *)data_file_name, ".nb");
171     if (pos && strcmp(pos, ".nb") == 0) {
172         inference_with_nbg = TRUE;
173     }
174 
175     if (NULL == in_ctx) {
176         ctx = vsi_nn_CreateContext();
177     } else {
178         ctx = in_ctx;
179     }
180 
181     use_img_process_s = getenv("VSI_USE_IMAGE_PROCESS");
182     if (use_img_process_s) {
183         enable_pre_post_process = atoi(use_img_process_s);
184     }
185 
186     graph = vsi_nn_CreateGraph(ctx, NET_TOTAL_TENSOR_NUM, NET_NODE_NUM);
187     if (NULL == graph) {
188         VSILOGE("Create graph fail.");
189         goto error;
190     }
191     vsi_nn_SetGraphVersion(graph, VNN_VERSION_MAJOR, VNN_VERSION_MINOR, VNN_VERSION_PATCH);
192     vsi_nn_SetGraphInputs(graph, NULL, 1L);
193     vsi_nn_SetGraphOutputs(graph, NULL, 3L);
194 
195     /*-----------------------------------------
196       Register client ops
197      -----------------------------------------*/
198 
199     /*-----------------------------------------
200       Node definitions
201      -----------------------------------------*/
202     if (!inference_with_nbg) {
203 
204         /*-----------------------------------------
205           lid       - nbg_0
206           var       - node[0]
207           name      - nbg
208           operation - nbg
209           input     - [640, 640, 3, 1]
210           output    - [80, 80, 255, 1]
211                       [40, 40, 255, 1]
212                       [20, 20, 255, 1]
213         -----------------------------------------*/
214         NEW_VXNODE(node[0], VSI_NN_OP_NBG, 1, 3, 0);
215         node[0]->nn_param.nbg.type = VSI_NN_NBG_FILE;
216         node[0]->nn_param.nbg.url = data_file_name;
217 
218     } else {
219         NEW_VXNODE(node[0], VSI_NN_OP_NBG, 1, 3, 0);
220         node[0]->nn_param.nbg.type = VSI_NN_NBG_FILE;
221         node[0]->nn_param.nbg.url = data_file_name;
222     }
223 
224     /*-----------------------------------------
225       Tensor initialize
226      -----------------------------------------*/
227     attr.dtype.fmt = VSI_NN_DIM_FMT_NCHW;
228     /* @attach_Sigmoid_Sigmoid_146/out0_0:out0 */
229     attr.size[0L] = 80L;
230     attr.size[1L] = 80L;
231     attr.size[2L] = 255L;
232     attr.size[3L] = 1L;
233     attr.dim_num = 4L;
234     attr.dtype.scale = 0.0039130267687141895f;
235     attr.dtype.zero_point = 0L;
236     attr.dtype.qnt_type = VSI_NN_QNT_TYPE_AFFINE_ASYMMETRIC;
237     NEW_NORM_TENSOR(norm_tensor[0], attr, VSI_NN_TYPE_UINT8);
238 
239     /* @attach_Sigmoid_Sigmoid_148/out0_1:out0 */
240     attr.size[0L] = 40L;
241     attr.size[1L] = 40L;
242     attr.size[2L] = 255L;
243     attr.size[3L] = 1L;
244     attr.dim_num = 4L;
245     attr.dtype.scale = 0.003908432554453611f;
246     attr.dtype.zero_point = 0L;
247     attr.dtype.qnt_type = VSI_NN_QNT_TYPE_AFFINE_ASYMMETRIC;
248     NEW_NORM_TENSOR(norm_tensor[1], attr, VSI_NN_TYPE_UINT8);
249 
250     /* @attach_Sigmoid_Sigmoid_150/out0_2:out0 */
251     attr.size[0L] = 20L;
252     attr.size[1L] = 20L;
253     attr.size[2L] = 255L;
254     attr.size[3L] = 1L;
255     attr.dim_num = 4L;
256     attr.dtype.scale = 0.003916851710528135f;
257     attr.dtype.zero_point = 0L;
258     attr.dtype.qnt_type = VSI_NN_QNT_TYPE_AFFINE_ASYMMETRIC;
259     NEW_NORM_TENSOR(norm_tensor[2], attr, VSI_NN_TYPE_UINT8);
260 
261     /* @images_152:out0 */
262     attr.size[0L] = 640L;
263     attr.size[1L] = 640L;
264     attr.size[2L] = 3L;
265     attr.size[3L] = 1L;
266     attr.dim_num = 4L;
267     attr.dtype.scale = 0.00390625f;
268     attr.dtype.zero_point = 0L;
269     attr.dtype.qnt_type = VSI_NN_QNT_TYPE_AFFINE_ASYMMETRIC;
270     NEW_NORM_TENSOR(norm_tensor[3], attr, VSI_NN_TYPE_UINT8);
271 
272     if (!inference_with_nbg) {
273         /*-----------------------------------------
274           Connection initialize
275          -----------------------------------------*/
276         node[0L]->input.tensors[0L] = norm_tensor[3L];
277         node[0L]->output.tensors[0L] = norm_tensor[0L];
278         node[0L]->output.tensors[1L] = norm_tensor[1L];
279         node[0L]->output.tensors[2L] = norm_tensor[2L];
280         /* nbg_0L */
281     } else {
282         node[0L]->output.tensors[0L] = norm_tensor[0L];
283         node[0L]->output.tensors[1L] = norm_tensor[1L];
284         node[0L]->output.tensors[2L] = norm_tensor[2L];
285         node[0L]->input.tensors[0L] = norm_tensor[3L];
286     }
287     graph->output.tensors[0L] = norm_tensor[0L];
288     graph->output.tensors[1L] = norm_tensor[1L];
289     graph->output.tensors[2L] = norm_tensor[2L];
290     graph->input.tensors[0L] = norm_tensor[3L];
291 
292     if (enable_pre_post_process) {
293         sort = TRUE;
294         if (pre_process_map_count > 0) {
295             for (i = 0; i < pre_process_map_count; i++) {
296                 status =
297                     vsi_nn_AddGraphPreProcess(graph, pre_process_map[i].graph_input_idx,
298                                               pre_process_map[i].preprocesses, pre_process_map[i].preprocess_count);
299                 TEST_CHECK_STATUS(status, error);
300             }
301         }
302 
303         if (post_process_map_count > 0) {
304             for (i = 0; i < post_process_map_count; i++) {
305                 status = vsi_nn_AddGraphPostProcess(graph, post_process_map[i].graph_output_idx,
306                                                     post_process_map[i].postprocesses,
307                                                     post_process_map[i].postprocess_count);
308                 TEST_CHECK_STATUS(status, error);
309             }
310         }
311     }
312 
313     status = vsi_nn_SetupGraph(graph, sort);
314     TEST_CHECK_STATUS(status, error);
315 
316     if (VSI_FAILURE == status) {
317         goto error;
318     }
319 
320     fclose(fp);
321 
322     return graph;
323 
324 error:
325     if (NULL != fp) {
326         fclose(fp);
327     }
328 
329     release_ctx = (NULL == in_ctx);
330     vsi_nn_DumpGraphToJson(graph);
331     vnn_ReleaseYolov5s(graph, release_ctx);
332 
333     return NULL;
334 } /* vsi_nn_CreateYolov5s() */
335 
vnn_ReleaseYolov5s(vsi_nn_graph_t * graph,vsi_bool release_ctx)336 void vnn_ReleaseYolov5s(vsi_nn_graph_t *graph, vsi_bool release_ctx)
337 {
338     vsi_nn_context_t ctx;
339     if (NULL != graph) {
340         ctx = graph->ctx;
341         vsi_nn_ReleaseGraph(&graph);
342 
343         /*-----------------------------------------
344         Unregister client ops
345         -----------------------------------------*/
346 
347         if (release_ctx) {
348             vsi_nn_ReleaseContext(&ctx);
349         }
350     }
351 } /* vsi_nn_ReleaseYolov5s() */
352