1 /*
2 * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <sys/mman.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 #include <signal.h>
26 #include <pthread.h>
27 #include <sys/prctl.h>
28 #include <math.h>
29 #include <assert.h>
30
31 #include "hi_common.h"
32 #include "hi_comm_sys.h"
33 #include "hi_comm_svp.h"
34 #include "sample_comm_svp.h"
35 #include "hi_comm_ive.h"
36 #include "sample_svp_nnie_software.h"
37 #include "sample_media_ai.h"
38 #include "ai_infer_process.h"
39
40 #ifdef __cplusplus
41 #if __cplusplus
42 extern "C" {
43 #endif
44 #endif /* End of #ifdef __cplusplus */
45
46 #define USLEEP_TIME 100 // 100: usleep time, in microseconds
47
48 #define ARRAY_SUBSCRIPT_0 0
49 #define ARRAY_SUBSCRIPT_1 1
50 #define ARRAY_SUBSCRIPT_2 2
51 #define ARRAY_SUBSCRIPT_3 3
52 #define ARRAY_SUBSCRIPT_4 4
53 #define ARRAY_SUBSCRIPT_5 5
54 #define ARRAY_SUBSCRIPT_6 6
55 #define ARRAY_SUBSCRIPT_7 7
56 #define ARRAY_SUBSCRIPT_8 8
57 #define ARRAY_SUBSCRIPT_9 9
58
59 #define ARRAY_SUBSCRIPT_OFFSET_1 1
60 #define ARRAY_SUBSCRIPT_OFFSET_2 2
61 #define ARRAY_SUBSCRIPT_OFFSET_3 3
62
63 #define THRESH_MIN 0.25
64
65 /*
66 * CNN 参数
67 * CNN parameter
68 */
69 static SAMPLE_SVP_NNIE_MODEL_S g_stCnnModel = {0};
70 static SAMPLE_SVP_NNIE_PARAM_S g_stCnnNnieParam = {0};
71 static SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S g_stCnnSoftwareParam = {0};
72
73 /*
74 * Yolov2 参数
75 * Yolov2 parameter
76 */
77 static SAMPLE_SVP_NNIE_MODEL_S g_stYolov2Model = {0};
78 static SAMPLE_SVP_NNIE_PARAM_S g_stYolov2NnieParam = {0};
79 static SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S g_stYolov2SoftwareParam = {0};
80
81 /*
82 * 函数:Cnn software参数初始化
83 * function : Cnn software parameter init
84 */
SampleSvpNnieCnnSoftwareParaInit(SAMPLE_SVP_NNIE_CFG_S * pstNnieCfg,SAMPLE_SVP_NNIE_PARAM_S * pstCnnPara,SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S * pstCnnSoftWarePara)85 static HI_S32 SampleSvpNnieCnnSoftwareParaInit(SAMPLE_SVP_NNIE_CFG_S* pstNnieCfg,
86 SAMPLE_SVP_NNIE_PARAM_S *pstCnnPara, SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S* pstCnnSoftWarePara)
87 {
88 HI_U32 u32GetTopNMemSize;
89 HI_U32 u32GetTopBufSize;
90 HI_U32 u32GetTopFrameSize;
91 HI_U32 u32TotalSize;
92 HI_U32 u32ClassNum = pstCnnPara->pstModel->astSeg[0].astDstNode[0].unShape.stWhc.u32Width;
93 HI_U64 u64PhyAddr = 0;
94 HI_U8* pu8VirAddr = NULL;
95 HI_S32 s32Ret;
96
97 /*
98 * 获取内存大小
99 * Get mem size
100 */
101 u32GetTopFrameSize = pstCnnSoftWarePara->u32TopN*sizeof(SAMPLE_SVP_NNIE_CNN_GETTOPN_UNIT_S);
102 u32GetTopNMemSize = SAMPLE_SVP_NNIE_ALIGN16(u32GetTopFrameSize)*pstNnieCfg->u32MaxInputNum;
103 u32GetTopBufSize = u32ClassNum*sizeof(SAMPLE_SVP_NNIE_CNN_GETTOPN_UNIT_S);
104 u32TotalSize = u32GetTopNMemSize + u32GetTopBufSize;
105
106 /*
107 * 在用户态分配MMZ内存
108 * Malloc memory in user mode
109 */
110 s32Ret = SAMPLE_COMM_SVP_MallocMem("SAMPLE_CNN_INIT", NULL, (HI_U64*)&u64PhyAddr,
111 (void**)&pu8VirAddr, u32TotalSize);
112 SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
113 "Error,Malloc memory failed!\n");
114 memset_s(pu8VirAddr, u32TotalSize, 0, u32TotalSize);
115
116 /*
117 * 初始化GetTopN参数
118 * Init GetTopN param
119 */
120 pstCnnSoftWarePara->stGetTopN.u32Num = pstNnieCfg->u32MaxInputNum;
121 pstCnnSoftWarePara->stGetTopN.unShape.stWhc.u32Chn = 1;
122 pstCnnSoftWarePara->stGetTopN.unShape.stWhc.u32Height = 1;
123 pstCnnSoftWarePara->stGetTopN.unShape.stWhc.u32Width = u32GetTopFrameSize / sizeof(HI_U32);
124 pstCnnSoftWarePara->stGetTopN.u32Stride = SAMPLE_SVP_NNIE_ALIGN16(u32GetTopFrameSize);
125 pstCnnSoftWarePara->stGetTopN.u64PhyAddr = u64PhyAddr;
126 pstCnnSoftWarePara->stGetTopN.u64VirAddr = (HI_U64)(HI_UL)pu8VirAddr;
127
128 /*
129 * 初始化AssistBuf参数
130 * Init AssistBuf
131 */
132 pstCnnSoftWarePara->stAssistBuf.u32Size = u32GetTopBufSize;
133 pstCnnSoftWarePara->stAssistBuf.u64PhyAddr = u64PhyAddr + u32GetTopNMemSize;
134 pstCnnSoftWarePara->stAssistBuf.u64VirAddr = (HI_U64)(HI_UL)pu8VirAddr + u32GetTopNMemSize;
135
136 return s32Ret;
137 }
138
139 /*
140 * 函数:Cnn software参数去初始化
141 * function : Cnn software deinit
142 */
SampleSvpNnieCnnSoftwareDeinit(SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S * pstCnnSoftWarePara)143 static HI_S32 SampleSvpNnieCnnSoftwareDeinit(SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S* pstCnnSoftWarePara)
144 {
145 HI_S32 s32Ret = HI_SUCCESS;
146 SAMPLE_SVP_CHECK_EXPR_RET(pstCnnSoftWarePara == NULL, HI_INVALID_VALUE, SAMPLE_SVP_ERR_LEVEL_ERROR,
147 "Error, pstCnnSoftWarePara can't be NULL!\n");
148 if (pstCnnSoftWarePara->stGetTopN.u64PhyAddr != 0 && pstCnnSoftWarePara->stGetTopN.u64VirAddr != 0) {
149 SAMPLE_SVP_MMZ_FREE(pstCnnSoftWarePara->stGetTopN.u64PhyAddr,
150 pstCnnSoftWarePara->stGetTopN.u64VirAddr);
151 pstCnnSoftWarePara->stGetTopN.u64PhyAddr = 0;
152 pstCnnSoftWarePara->stGetTopN.u64VirAddr = 0;
153 }
154 return s32Ret;
155 }
156
157 /*
158 * 函数:Cnn去初始化
159 * function : Cnn Deinit
160 */
SampleSvpNnieCnnDeinit(SAMPLE_SVP_NNIE_PARAM_S * pstNnieParam,SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S * pstSoftWareParam,SAMPLE_SVP_NNIE_MODEL_S * pstNnieModel)161 static HI_S32 SampleSvpNnieCnnDeinit(SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam,
162 SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S* pstSoftWareParam, SAMPLE_SVP_NNIE_MODEL_S* pstNnieModel)
163 {
164 HI_S32 s32Ret = HI_SUCCESS;
165 /*
166 * SAMPLE_SVP_NNIE_PARAM_S参数去初始化
167 * Hardware param deinit
168 */
169 if (pstNnieParam != NULL) {
170 s32Ret = SAMPLE_COMM_SVP_NNIE_ParamDeinit(pstNnieParam);
171 SAMPLE_SVP_CHECK_EXPR_TRACE(HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
172 "Error,SAMPLE_COMM_SVP_NNIE_ParamDeinit failed!\n");
173 }
174 /*
175 * SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S参数去初始化
176 * Software param deinit
177 */
178 if (pstSoftWareParam != NULL) {
179 s32Ret = SampleSvpNnieCnnSoftwareDeinit(pstSoftWareParam);
180 SAMPLE_SVP_CHECK_EXPR_TRACE(HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
181 "Error,SampleSvpNnieCnnSoftwareDeinit failed!\n");
182 }
183 /*
184 * SAMPLE_SVP_NNIE_MODEL_S参数去初始化
185 * Model deinit
186 */
187 if (pstNnieModel != NULL) {
188 s32Ret = SAMPLE_COMM_SVP_NNIE_UnloadModel(pstNnieModel);
189 SAMPLE_SVP_CHECK_EXPR_TRACE(HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
190 "Error,SAMPLE_COMM_SVP_NNIE_UnloadModel failed!\n");
191 }
192 return s32Ret;
193 }
194
195 /*
196 * 函数:Cnn参数初始化
197 * function : Cnn Param init
198 */
SampleSvpNnieCnnParamInit(SAMPLE_SVP_NNIE_CFG_S * pstNnieCfg,SAMPLE_SVP_NNIE_PARAM_S * pstCnnPara,SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S * pstCnnSoftWarePara)199 static HI_S32 SampleSvpNnieCnnParamInit(SAMPLE_SVP_NNIE_CFG_S* pstNnieCfg,
200 SAMPLE_SVP_NNIE_PARAM_S *pstCnnPara, SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S* pstCnnSoftWarePara)
201 {
202 HI_S32 s32Ret;
203 /*
204 * 初始化hardware参数
205 * Init hardware param
206 */
207 s32Ret = SAMPLE_COMM_SVP_NNIE_ParamInit(pstNnieCfg, pstCnnPara);
208 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, INIT_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
209 "Error(%#x),SAMPLE_COMM_SVP_NNIE_ParamInit failed!\n", s32Ret);
210
211 /*
212 * 初始化software参数
213 * Init software param
214 */
215 if (pstCnnSoftWarePara != NULL) {
216 s32Ret = SampleSvpNnieCnnSoftwareParaInit(pstNnieCfg, pstCnnPara, pstCnnSoftWarePara);
217 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, INIT_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
218 "Error(%#x),SampleSvpNnieCnnSoftwareParaInit failed!\n", s32Ret);
219 }
220
221 return s32Ret;
222 INIT_FAIL_0:
223 s32Ret = SampleSvpNnieCnnDeinit(pstCnnPara, pstCnnSoftWarePara, NULL);
224 SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
225 "Error(%#x),SampleSvpNnieCnnDeinit failed!\n", s32Ret);
226 return HI_FAILURE;
227 }
228
229 /*
230 * 基于模型文件创建CNN模型
231 * Create CNN model based mode file
232 */
CnnCreate(SAMPLE_SVP_NNIE_CFG_S ** model,const char * modelFile)233 int CnnCreate(SAMPLE_SVP_NNIE_CFG_S **model, const char* modelFile)
234 {
235 SAMPLE_SVP_NNIE_CFG_S *self;
236 HI_U32 u32PicNum = 1;
237 HI_S32 s32Ret;
238
239 self = (SAMPLE_SVP_NNIE_CFG_S*)malloc(sizeof(*self));
240 HI_ASSERT(self);
241 if (memset_s(self, sizeof(*self), 0x00, sizeof(*self)) != EOK) {
242 HI_ASSERT(0);
243 }
244 /*
245 * 设置配置参数
246 * Set configuration parameter
247 */
248 self->pszPic = NULL;
249 self->u32MaxInputNum = u32PicNum; // max input image num in each batch
250 self->u32MaxRoiNum = 0;
251 self->aenNnieCoreId[0] = SVP_NNIE_ID_0; // set NNIE core
252 g_stCnnSoftwareParam.u32TopN = 5; // 5: value of the u32TopN
253
254 /*
255 * 加载CNN模型
256 * Load cnn model
257 */
258 SAMPLE_SVP_TRACE_INFO("Cnn Load model!\n");
259 s32Ret = SAMPLE_COMM_SVP_NNIE_LoadModel((char*)modelFile, &g_stCnnModel);
260 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, CNN_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
261 "Error,SAMPLE_COMM_SVP_NNIE_LoadModel failed!\n");
262
263 /*
264 * CNN参数初始化
265 * Cnn软件参数设置在SampleSvpNnieCnnSoftwareParaInit,
266 * 如果用户更改了网络结构,请确保
267 * SampleSvpNnieCnnSoftwareParaInit函数中的参数设置是正确的
268 *
269 * CNN parameter initialization
270 * Cnn software parameters are set in SampleSvpNnieCnnSoftwareParaInit,
271 * if user has changed net struct, please make sure the parameter settings in
272 * SampleSvpNnieCnnSoftwareParaInit function are correct
273 */
274 SAMPLE_SVP_TRACE_INFO("Cnn parameter initialization!\n");
275 g_stCnnNnieParam.pstModel = &g_stCnnModel.stModel;
276 s32Ret = SampleSvpNnieCnnParamInit(self, &g_stCnnNnieParam, &g_stCnnSoftwareParam);
277 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, CNN_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
278 "Error,SampleSvpNnieCnnParamInit failed!\n");
279
280 /*
281 * 模型关键数据
282 * Model important information
283 */
284 SAMPLE_PRT("model={ type=%x, frmNum=%u, chnNum=%u, w=%u, h=%u, stride=%u }\n",
285 g_stCnnNnieParam.astSegData[0].astSrc[0].enType,
286 g_stCnnNnieParam.astSegData[0].astSrc[0].u32Num,
287 g_stCnnNnieParam.astSegData[0].astSrc[0].unShape.stWhc.u32Chn,
288 g_stCnnNnieParam.astSegData[0].astSrc[0].unShape.stWhc.u32Width,
289 g_stCnnNnieParam.astSegData[0].astSrc[0].unShape.stWhc.u32Height,
290 g_stCnnNnieParam.astSegData[0].astSrc[0].u32Stride);
291
292 /*
293 * 记录TskBuf地址信息
294 * Record TskBuf address information
295 */
296 s32Ret = HI_MPI_SVP_NNIE_AddTskBuf(&(g_stCnnNnieParam.astForwardCtrl[0].stTskBuf));
297 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, CNN_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
298 "Error,HI_MPI_SVP_NNIE_AddTskBuf failed!\n");
299 *model = self;
300 return 0;
301
302 CNN_FAIL_0:
303 SampleSvpNnieCnnDeinit(&g_stCnnNnieParam, &g_stCnnSoftwareParam, &g_stCnnModel);
304 *model = NULL;
305 return -1;
306 }
307
308 /*
309 * 销毁CNN模型
310 * Destroy CNN model
311 */
CnnDestroy(SAMPLE_SVP_NNIE_CFG_S * self)312 void CnnDestroy(SAMPLE_SVP_NNIE_CFG_S *self)
313 {
314 HI_S32 s32Ret;
315
316 /*
317 * 移除TskBuf地址信息
318 * Remove TskBuf address information
319 */
320 s32Ret = HI_MPI_SVP_NNIE_RemoveTskBuf(&(g_stCnnNnieParam.astForwardCtrl[0].stTskBuf));
321 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, CNN_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
322 "Error,HI_MPI_SVP_NNIE_RemoveTskBuf failed!\n");
323
324 CNN_FAIL_0:
325 SampleSvpNnieCnnDeinit(&g_stCnnNnieParam, &g_stCnnSoftwareParam, &g_stCnnModel);
326 free(self);
327 }
328
FillNnieByImg(SAMPLE_SVP_NNIE_CFG_S * pstNnieCfg,SAMPLE_SVP_NNIE_PARAM_S * pstNnieParam,int segId,int nodeId,const IVE_IMAGE_S * img)329 static HI_S32 FillNnieByImg(SAMPLE_SVP_NNIE_CFG_S* pstNnieCfg,
330 SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, int segId, int nodeId, const IVE_IMAGE_S *img)
331 {
332 HI_U32 i;
333 HI_U32 j;
334 HI_U32 n;
335 HI_U32 u32Height = 0;
336 HI_U32 u32Width = 0;
337 HI_U32 u32Chn = 0;
338 HI_U32 u32Stride = 0;
339 HI_U32 u32VarSize;
340 HI_U8 *pu8PicAddr = NULL;
341
342 /*
343 * 获取数据大小
344 * Get data size
345 */
346 if (SVP_BLOB_TYPE_U8 <= pstNnieParam->astSegData[segId].astSrc[nodeId].enType &&
347 SVP_BLOB_TYPE_YVU422SP >= pstNnieParam->astSegData[segId].astSrc[nodeId].enType) {
348 u32VarSize = sizeof(HI_U8);
349 } else {
350 u32VarSize = sizeof(HI_U32);
351 }
352
353 /*
354 * 填充源数据
355 * Fill src data
356 */
357 if (SVP_BLOB_TYPE_SEQ_S32 == pstNnieParam->astSegData[segId].astSrc[nodeId].enType) {
358 HI_ASSERT(0);
359 } else {
360 u32Height = pstNnieParam->astSegData[segId].astSrc[nodeId].unShape.stWhc.u32Height;
361 u32Width = pstNnieParam->astSegData[segId].astSrc[nodeId].unShape.stWhc.u32Width;
362 u32Chn = pstNnieParam->astSegData[segId].astSrc[nodeId].unShape.stWhc.u32Chn;
363 u32Stride = pstNnieParam->astSegData[segId].astSrc[nodeId].u32Stride;
364 pu8PicAddr = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_U8,
365 pstNnieParam->astSegData[segId].astSrc[nodeId].u64VirAddr);
366
367 if (SVP_BLOB_TYPE_YVU420SP == pstNnieParam->astSegData[segId].astSrc[nodeId].enType) {
368 HI_ASSERT(pstNnieParam->astSegData[segId].astSrc[nodeId].u32Num == 1);
369 for (n = 0; n < pstNnieParam->astSegData[segId].astSrc[nodeId].u32Num; n++) {
370 // Y
371 const uint8_t *srcData = (const uint8_t*)(uintptr_t)img->au64VirAddr[0];
372 HI_ASSERT(srcData);
373 for (j = 0; j < u32Height; j++) {
374 if (memcpy_s(pu8PicAddr, u32Width * u32VarSize, srcData, u32Width * u32VarSize) != EOK) {
375 HI_ASSERT(0);
376 }
377 pu8PicAddr += u32Stride;
378 srcData += img->au32Stride[0];
379 }
380 // UV
381 srcData = (const uint8_t*)(uintptr_t)img->au64VirAddr[1];
382 HI_ASSERT(srcData);
383 for (j = 0; j < u32Height / 2; j++) { // 2: 1/2Height
384 if (memcpy_s(pu8PicAddr, u32Width * u32VarSize, srcData, u32Width * u32VarSize) != EOK) {
385 HI_ASSERT(0);
386 }
387 pu8PicAddr += u32Stride;
388 srcData += img->au32Stride[1];
389 }
390 }
391 } else if (SVP_BLOB_TYPE_YVU422SP == pstNnieParam->astSegData[segId].astSrc[nodeId].enType) {
392 HI_ASSERT(0);
393 } else {
394 for (n = 0; n < pstNnieParam->astSegData[segId].astSrc[nodeId].u32Num; n++) {
395 for (i = 0; i < u32Chn; i++) {
396 const uint8_t *srcData = (const uint8_t*)(uintptr_t)img->au64VirAddr[i];
397 HI_ASSERT(srcData);
398 for (j = 0; j < u32Height; j++) {
399 if (memcpy_s(pu8PicAddr, u32Width * u32VarSize, srcData, u32Width * u32VarSize) != EOK) {
400 HI_ASSERT(0);
401 }
402 pu8PicAddr += u32Stride;
403 srcData += img->au32Stride[i];
404 }
405 }
406 }
407 }
408
409 SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astSegData[segId].astSrc[nodeId].u64PhyAddr,
410 SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_VOID, pstNnieParam->astSegData[segId].astSrc[nodeId].u64VirAddr),
411 pstNnieParam->astSegData[segId].astSrc[nodeId].u32Num*u32Chn*u32Height*u32Stride);
412 }
413
414 return HI_SUCCESS;
415 }
416
CnnFetchRes(SVP_BLOB_S * pstGetTopN,HI_U32 u32TopN,RecogNumInfo resBuf[],int resSize,int * resLen)417 void CnnFetchRes(SVP_BLOB_S *pstGetTopN, HI_U32 u32TopN, RecogNumInfo resBuf[], int resSize, int* resLen)
418 {
419 HI_ASSERT(pstGetTopN);
420 HI_U32 i;
421 HI_U32 j = 0;
422 HI_U32 *pu32Tmp = NULL;
423 HI_U32 u32Stride = pstGetTopN->u32Stride;
424 if (memset_s(resBuf, resSize * sizeof(resBuf[0]), 0x00, resSize * sizeof(resBuf[0])) != EOK) {
425 HI_ASSERT(0);
426 }
427
428 int resId = 0;
429 pu32Tmp = (HI_U32*)((HI_UL)pstGetTopN->u64VirAddr + j * u32Stride);
430 for (i = 0; i < u32TopN * 2 && resId < resSize; i += 2, resId++) { // 2: u32TopN*2
431 resBuf[resId].num = pu32Tmp[i];
432 resBuf[resId].score = pu32Tmp[i + 1];
433 }
434 *resLen = resId;
435 }
436
437 /*
438 * 函数:NNIE网络预测
439 * function : NNIE Forward
440 */
SAMPLE_SVP_NNIE_Forward(SAMPLE_SVP_NNIE_PARAM_S * pstNnieParam,SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S * pstInputDataIdx,SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S * pstProcSegIdx,HI_BOOL bInstant)441 static HI_S32 SAMPLE_SVP_NNIE_Forward(SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam,
442 SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S* pstInputDataIdx,
443 SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S* pstProcSegIdx, HI_BOOL bInstant)
444 {
445 HI_S32 s32Ret = HI_SUCCESS;
446 HI_U32 i;
447 HI_U32 j;
448 HI_BOOL bFinish = HI_FALSE;
449 SVP_NNIE_HANDLE hSvpNnieHandle = 0;
450 HI_U32 u32TotalStepNum = 0;
451
452 SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].stTskBuf.u64PhyAddr,
453 SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_VOID,
454 pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].stTskBuf.u64VirAddr),
455 pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].stTskBuf.u32Size);
456
457 for (i = 0; i < pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].u32DstNum; i++) {
458 if (pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].enType == SVP_BLOB_TYPE_SEQ_S32) {
459 for (j = 0; j < pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Num; j++) {
460 u32TotalStepNum += *(SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_U32,
461 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].unShape.stSeq.u64VirAddrStep) + j);
462 }
463 SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64PhyAddr,
464 SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_VOID,
465 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64VirAddr),
466 u32TotalStepNum*pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Stride);
467 } else {
468 SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64PhyAddr,
469 SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_VOID,
470 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64VirAddr),
471 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Num*
472 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].unShape.stWhc.u32Chn*
473 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].unShape.stWhc.u32Height*
474 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Stride);
475 }
476 }
477
478 /*
479 * 根据节点名称设置输入blob
480 * Set input blob according to node name
481 */
482 if (pstInputDataIdx->u32SegIdx != pstProcSegIdx->u32SegIdx) {
483 for (i = 0; i < pstNnieParam->pstModel->astSeg[pstProcSegIdx->u32SegIdx].u16SrcNum; i++) {
484 for (j = 0; j < pstNnieParam->pstModel->astSeg[pstInputDataIdx->u32SegIdx].u16DstNum; j++) {
485 if (strncmp(pstNnieParam->pstModel->astSeg[pstInputDataIdx->u32SegIdx].astDstNode[j].szName,
486 pstNnieParam->pstModel->astSeg[pstProcSegIdx->u32SegIdx].astSrcNode[i].szName,
487 SVP_NNIE_NODE_NAME_LEN) == 0) {
488 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astSrc[i] =
489 pstNnieParam->astSegData[pstInputDataIdx->u32SegIdx].astDst[j];
490 break;
491 }
492 }
493 SAMPLE_SVP_CHECK_EXPR_RET((j == pstNnieParam->pstModel->astSeg[pstInputDataIdx->u32SegIdx].u16DstNum),
494 HI_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,can't find %d-th seg's %d-th src blob!\n",
495 pstProcSegIdx->u32SegIdx, i);
496 }
497 }
498
499 /*
500 * 多节点输入输出的CNN类型网络预测
501 * CNN-type network prediction with multi-node input and output
502 */
503 s32Ret = HI_MPI_SVP_NNIE_Forward(&hSvpNnieHandle,
504 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astSrc,
505 pstNnieParam->pstModel, pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst,
506 &pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx], bInstant);
507 SAMPLE_SVP_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
508 "Error,HI_MPI_SVP_NNIE_Forward failed!\n");
509
510 if (bInstant) {
511 /*
512 * 查询任务是否完成
513 * Query whether the task is completed
514 */
515 while (HI_ERR_SVP_NNIE_QUERY_TIMEOUT == (s32Ret =
516 HI_MPI_SVP_NNIE_Query(pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].enNnieId,
517 hSvpNnieHandle, &bFinish, HI_TRUE))) {
518 usleep(USLEEP_TIME);
519 SAMPLE_SVP_TRACE(SAMPLE_SVP_ERR_LEVEL_INFO,
520 "HI_MPI_SVP_NNIE_Query Query timeout!\n");
521 }
522 }
523 u32TotalStepNum = 0;
524
525 for (i = 0; i < pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].u32DstNum; i++) {
526 if (SVP_BLOB_TYPE_SEQ_S32 == pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].enType) {
527 for (j = 0; j < pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Num; j++) {
528 u32TotalStepNum += *(SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_U32,
529 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].unShape.stSeq.u64VirAddrStep) + j);
530 }
531 SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64PhyAddr,
532 SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_VOID,
533 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64VirAddr),
534 u32TotalStepNum*pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Stride);
535 } else {
536 SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64PhyAddr,
537 SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_VOID,
538 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64VirAddr),
539 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Num*
540 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].unShape.stWhc.u32Chn*
541 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].unShape.stWhc.u32Height*
542 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Stride);
543 }
544 }
545
546 return s32Ret;
547 }
548
549 /*
550 * 对一帧图像进行推理
551 * Calculate a frame of image
552 */
CnnCalImg(SAMPLE_SVP_NNIE_CFG_S * self,const IVE_IMAGE_S * img,RecogNumInfo resBuf[],int resSize,int * resLen)553 int CnnCalImg(SAMPLE_SVP_NNIE_CFG_S* self,
554 const IVE_IMAGE_S *img, RecogNumInfo resBuf[], int resSize, int* resLen)
555 {
556 HI_S32 s32Ret;
557 SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S stInputDataIdx = {0};
558 SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S stProcSegIdx = {0};
559
560 /*
561 * 填充源数据
562 * Fill src data
563 */
564 self->pszPic = NULL;
565 stInputDataIdx.u32SegIdx = 0;
566 stInputDataIdx.u32NodeIdx = 0;
567 s32Ret = FillNnieByImg(self, &g_stCnnNnieParam, 0, 0, img);
568 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, CNN_FAIL_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
569 "Error,SAMPLE_SVP_NNIE_FillSrcData failed!\n");
570
571 /*
572 * NNIE推理(process the 0-th segment)
573 * NNIE process(process the 0-th segment)
574 */
575 stProcSegIdx.u32SegIdx = 0;
576 s32Ret = SAMPLE_SVP_NNIE_Forward(&g_stCnnNnieParam, &stInputDataIdx, &stProcSegIdx, HI_TRUE);
577 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, CNN_FAIL_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
578 "Error,SAMPLE_SVP_NNIE_Forward failed!\n");
579
580 /*
581 * CPU处理
582 * 如果用户更改了网络结构,请确保SAMPLE_SVP_NNIE_Cnn_GetTopN函数的输入数据是正确的
583 *
584 * Software process
585 * if user has changed net struct, please make sure SAMPLE_SVP_NNIE_Cnn_GetTopN
586 * function's input datas are correct
587 */
588 s32Ret = SAMPLE_SVP_NNIE_Cnn_GetTopN(&g_stCnnNnieParam, &g_stCnnSoftwareParam);
589 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, CNN_FAIL_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
590 "Error,SAMPLE_SVP_NNIE_CnnGetTopN failed!\n");
591
592 /*
593 * 打印结果
594 * Print result
595 */
596 CnnFetchRes(&g_stCnnSoftwareParam.stGetTopN, g_stCnnSoftwareParam.u32TopN, resBuf, resSize, resLen);
597 return 0;
598
599 CNN_FAIL_1:
600 return -1;
601 }
602
603 /*
604 * 函数:Yolov2 software参数初始化
605 * function : Yolov2 software param init
606 */
SampleSvpNnieYolov2SoftwareInit(SAMPLE_SVP_NNIE_CFG_S * pstCfg,SAMPLE_SVP_NNIE_PARAM_S * pstNnieParam,SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S * pstSoftWareParam)607 static HI_S32 SampleSvpNnieYolov2SoftwareInit(SAMPLE_SVP_NNIE_CFG_S* pstCfg,
608 SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S* pstSoftWareParam)
609 {
610 HI_S32 s32Ret;
611 HI_U32 u32ClassNum = 0;
612 HI_U32 u32BboxNum;
613 HI_U32 u32TotalSize = 0;
614 HI_U32 u32DstRoiSize;
615 HI_U32 u32DstScoreSize;
616 HI_U32 u32ClassRoiNumSize;
617 HI_U32 u32TmpBufTotalSize;
618 HI_U64 u64PhyAddr = 0;
619 HI_U8* pu8VirAddr = NULL;
620
621 pstSoftWareParam->u32OriImHeight = pstNnieParam->astSegData[0].astSrc[0].unShape.stWhc.u32Height;
622 pstSoftWareParam->u32OriImWidth = pstNnieParam->astSegData[0].astSrc[0].unShape.stWhc.u32Width;
623 pstSoftWareParam->u32BboxNumEachGrid = 5; // 5: 2BboxNumEachGrid
624 pstSoftWareParam->u32ClassNum = 1; // 5: class number
625 pstSoftWareParam->u32GridNumHeight = 12; // 12: GridNumHeight
626 pstSoftWareParam->u32GridNumWidth = 20; // 20: GridNumWidth
627 pstSoftWareParam->u32NmsThresh = (HI_U32)(0.3f*SAMPLE_SVP_NNIE_QUANT_BASE);
628 pstSoftWareParam->u32ConfThresh = (HI_U32)(0.25f*SAMPLE_SVP_NNIE_QUANT_BASE);
629 pstSoftWareParam->u32MaxRoiNum = 10; // 10: MaxRoiNum
630 pstSoftWareParam->af32Bias[0] = 0.52; // 0.52: af32Bias[0] value
631 pstSoftWareParam->af32Bias[1] = 0.61; // 0.61: af32Bias[1] value
632 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_2] = 1.05; // 1.05: af32Bias[ARRAY_SUBSCRIPT_2] value
633 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_3] = 1.12; // 1.12: af32Bias[ARRAY_SUBSCRIPT_3] value
634 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_4] = 1.85; // 1.85: af32Bias[ARRAY_SUBSCRIPT_4] value
635 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_5] = 2.05; // 2.05: af32Bias[ARRAY_SUBSCRIPT_5] value
636 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_6] = 4.63; // 4.63: af32Bias[ARRAY_SUBSCRIPT_6] value
637 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_7] = 4.49; // 4.49: af32Bias[ARRAY_SUBSCRIPT_7] value
638 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_8] = 7.15; // 7.15: af32Bias[ARRAY_SUBSCRIPT_8] value
639 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_9] = 7.56; // 7.56: af32Bias[ARRAY_SUBSCRIPT_9] value
640
641 /*
642 * 申请辅助内存空间
643 * Malloc assist buffer memory
644 */
645 u32ClassNum = pstSoftWareParam->u32ClassNum + 1;
646 u32BboxNum = pstSoftWareParam->u32BboxNumEachGrid*pstSoftWareParam->u32GridNumHeight*
647 pstSoftWareParam->u32GridNumWidth;
648 u32TmpBufTotalSize = SAMPLE_SVP_NNIE_Yolov2_GetResultTmpBuf(pstSoftWareParam);
649 u32DstRoiSize = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * u32BboxNum * sizeof(HI_U32) * SAMPLE_SVP_NNIE_COORDI_NUM);
650 u32DstScoreSize = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * u32BboxNum * sizeof(HI_U32));
651 u32ClassRoiNumSize = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * sizeof(HI_U32));
652 u32TotalSize = u32TotalSize + u32DstRoiSize + u32DstScoreSize + u32ClassRoiNumSize + u32TmpBufTotalSize;
653 s32Ret = SAMPLE_COMM_SVP_MallocCached("SAMPLE_YOLOV2_INIT", NULL, (HI_U64*)&u64PhyAddr,
654 (void**)&pu8VirAddr, u32TotalSize);
655 SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
656 "Error,Malloc memory failed!\n");
657 memset_s(pu8VirAddr, u32TotalSize, 0, u32TotalSize);
658 SAMPLE_COMM_SVP_FlushCache(u64PhyAddr, (void*)pu8VirAddr, u32TotalSize);
659
660 /*
661 * 设置每个tmp buffer地址
662 * Set each tmp buffer addr
663 */
664 pstSoftWareParam->stGetResultTmpBuf.u64PhyAddr = u64PhyAddr;
665 pstSoftWareParam->stGetResultTmpBuf.u64VirAddr = (HI_U64)((HI_UL)pu8VirAddr);
666
667 /*
668 * 设置结果blob
669 * Set result blob
670 */
671 pstSoftWareParam->stDstRoi.enType = SVP_BLOB_TYPE_S32;
672 pstSoftWareParam->stDstRoi.u64PhyAddr = u64PhyAddr + u32TmpBufTotalSize;
673 pstSoftWareParam->stDstRoi.u64VirAddr = (HI_U64)((HI_UL)pu8VirAddr + u32TmpBufTotalSize);
674 pstSoftWareParam->stDstRoi.u32Stride = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum *
675 u32BboxNum * sizeof(HI_U32) * SAMPLE_SVP_NNIE_COORDI_NUM);
676 pstSoftWareParam->stDstRoi.u32Num = 1;
677 pstSoftWareParam->stDstRoi.unShape.stWhc.u32Chn = 1;
678 pstSoftWareParam->stDstRoi.unShape.stWhc.u32Height = 1;
679 pstSoftWareParam->stDstRoi.unShape.stWhc.u32Width = u32ClassNum *
680 u32BboxNum*SAMPLE_SVP_NNIE_COORDI_NUM;
681
682 pstSoftWareParam->stDstScore.enType = SVP_BLOB_TYPE_S32;
683 pstSoftWareParam->stDstScore.u64PhyAddr = u64PhyAddr + u32TmpBufTotalSize + u32DstRoiSize;
684 pstSoftWareParam->stDstScore.u64VirAddr = (HI_U64)((HI_UL)pu8VirAddr + u32TmpBufTotalSize + u32DstRoiSize);
685 pstSoftWareParam->stDstScore.u32Stride = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * u32BboxNum * sizeof(HI_U32));
686 pstSoftWareParam->stDstScore.u32Num = 1;
687 pstSoftWareParam->stDstScore.unShape.stWhc.u32Chn = 1;
688 pstSoftWareParam->stDstScore.unShape.stWhc.u32Height = 1;
689 pstSoftWareParam->stDstScore.unShape.stWhc.u32Width = u32ClassNum*u32BboxNum;
690
691 pstSoftWareParam->stClassRoiNum.enType = SVP_BLOB_TYPE_S32;
692 pstSoftWareParam->stClassRoiNum.u64PhyAddr = u64PhyAddr + u32TmpBufTotalSize +
693 u32DstRoiSize + u32DstScoreSize;
694 pstSoftWareParam->stClassRoiNum.u64VirAddr = (HI_U64)((HI_UL)pu8VirAddr + u32TmpBufTotalSize +
695 u32DstRoiSize + u32DstScoreSize);
696 pstSoftWareParam->stClassRoiNum.u32Stride = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum*sizeof(HI_U32));
697 pstSoftWareParam->stClassRoiNum.u32Num = 1;
698 pstSoftWareParam->stClassRoiNum.unShape.stWhc.u32Chn = 1;
699 pstSoftWareParam->stClassRoiNum.unShape.stWhc.u32Height = 1;
700 pstSoftWareParam->stClassRoiNum.unShape.stWhc.u32Width = u32ClassNum;
701
702 return s32Ret;
703 }
704
705 /*
706 * 函数:Yolov2 software参数去初始化
707 * function : Yolov2 software param Deinit
708 */
SampleSvpNnieYolov2SoftwareDeinit(SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S * pstSoftWareParam)709 static HI_S32 SampleSvpNnieYolov2SoftwareDeinit(SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S* pstSoftWareParam)
710 {
711 HI_S32 s32Ret = HI_SUCCESS;
712 SAMPLE_SVP_CHECK_EXPR_RET(pstSoftWareParam == NULL, HI_INVALID_VALUE, SAMPLE_SVP_ERR_LEVEL_ERROR,
713 "Error, pstSoftWareParam can't be NULL!\n");
714 if (pstSoftWareParam->stGetResultTmpBuf.u64PhyAddr != 0 && pstSoftWareParam->stGetResultTmpBuf.u64VirAddr != 0) {
715 SAMPLE_SVP_MMZ_FREE(pstSoftWareParam->stGetResultTmpBuf.u64PhyAddr,
716 pstSoftWareParam->stGetResultTmpBuf.u64VirAddr);
717 pstSoftWareParam->stGetResultTmpBuf.u64PhyAddr = 0;
718 pstSoftWareParam->stGetResultTmpBuf.u64VirAddr = 0;
719 pstSoftWareParam->stDstRoi.u64PhyAddr = 0;
720 pstSoftWareParam->stDstRoi.u64VirAddr = 0;
721 pstSoftWareParam->stDstScore.u64PhyAddr = 0;
722 pstSoftWareParam->stDstScore.u64VirAddr = 0;
723 pstSoftWareParam->stClassRoiNum.u64PhyAddr = 0;
724 pstSoftWareParam->stClassRoiNum.u64VirAddr = 0;
725 }
726 return s32Ret;
727 }
728
729 /*
730 * 函数:Yolov2去初始化
731 * function : Yolov2 Deinit
732 */
SampleSvpNnieYolov2Deinit(SAMPLE_SVP_NNIE_PARAM_S * pstNnieParam,SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S * pstSoftWareParam,SAMPLE_SVP_NNIE_MODEL_S * pstNnieModel)733 static HI_S32 SampleSvpNnieYolov2Deinit(SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam,
734 SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S* pstSoftWareParam, SAMPLE_SVP_NNIE_MODEL_S *pstNnieModel)
735 {
736 HI_S32 s32Ret = HI_SUCCESS;
737 /*
738 * SAMPLE_SVP_NNIE_PARAM_S参数去初始化
739 * Hardware param deinit
740 */
741 if (pstNnieParam != NULL) {
742 s32Ret = SAMPLE_COMM_SVP_NNIE_ParamDeinit(pstNnieParam);
743 SAMPLE_SVP_CHECK_EXPR_TRACE(HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
744 "Error,SAMPLE_COMM_SVP_NNIE_ParamDeinit failed!\n");
745 }
746 /*
747 * SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S参数去初始化
748 * Software deinit
749 */
750 if (pstSoftWareParam != NULL) {
751 s32Ret = SampleSvpNnieYolov2SoftwareDeinit(pstSoftWareParam);
752 SAMPLE_SVP_CHECK_EXPR_TRACE(HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
753 "Error,SampleSvpNnieYolov2SoftwareDeinit failed!\n");
754 }
755
756 /*
757 * SAMPLE_SVP_NNIE_MODEL_S参数去初始化
758 * Model deinit
759 */
760 if (pstNnieModel != NULL) {
761 s32Ret = SAMPLE_COMM_SVP_NNIE_UnloadModel(pstNnieModel);
762 SAMPLE_SVP_CHECK_EXPR_TRACE(HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
763 "Error,SAMPLE_COMM_SVP_NNIE_UnloadModel failed!\n");
764 }
765 return s32Ret;
766 }
767
768 /*
769 * 函数:Yolov2参数初始化
770 * function : Yolov2 Param init
771 */
SampleSvpNnieYolov2ParamInit(SAMPLE_SVP_NNIE_CFG_S * pstCfg,SAMPLE_SVP_NNIE_PARAM_S * pstNnieParam,SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S * pstSoftWareParam)772 static HI_S32 SampleSvpNnieYolov2ParamInit(SAMPLE_SVP_NNIE_CFG_S* pstCfg,
773 SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S* pstSoftWareParam)
774 {
775 HI_S32 s32Ret;
776 /*
777 * 初始化hardware参数
778 * Init hardware param
779 */
780 s32Ret = SAMPLE_COMM_SVP_NNIE_ParamInit(pstCfg, pstNnieParam);
781 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, INIT_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
782 "Error(%#x),SAMPLE_COMM_SVP_NNIE_ParamInit failed!\n", s32Ret);
783
784 /*
785 * 初始化software参数
786 * Init software param
787 */
788 s32Ret = SampleSvpNnieYolov2SoftwareInit(pstCfg, pstNnieParam,
789 pstSoftWareParam);
790 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, INIT_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
791 "Error(%#x),SAMPLE_SVP_NNIE_Yolov1_SoftwareInit failed!\n", s32Ret);
792 return s32Ret;
793 INIT_FAIL_0:
794 s32Ret = SampleSvpNnieYolov2Deinit(pstNnieParam, pstSoftWareParam, NULL);
795 SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
796 "Error(%#x),SAMPLE_SVP_NNIE_Yolov1_Deinit failed!\n", s32Ret);
797 return HI_FAILURE;
798 }
799
800 /*
801 * 函数:基于模型文件创建Yolov2模型
802 * function : Creat Yolov2 model basad mode file
803 */
Yolo2Create(SAMPLE_SVP_NNIE_CFG_S ** model,const char * modelFile)804 int Yolo2Create(SAMPLE_SVP_NNIE_CFG_S **model, const char* modelFile)
805 {
806 SAMPLE_SVP_NNIE_CFG_S *self;
807 HI_U32 u32PicNum = 1;
808 HI_S32 s32Ret;
809
810 self = (SAMPLE_SVP_NNIE_CFG_S*)malloc(sizeof(*self));
811 HI_ASSERT(self);
812 memset_s(self, sizeof(*self), 0x00, sizeof(*self));
813
814 /*
815 * 设置配置参数
816 * Set configuration parameter
817 */
818 self->pszPic = NULL;
819 self->u32MaxInputNum = u32PicNum; // max input image num in each batch
820 self->u32MaxRoiNum = 0;
821 self->aenNnieCoreId[0] = SVP_NNIE_ID_0; // set NNIE core
822
823 /*
824 * 加载Yolov2模型
825 * Load Yolov2 model
826 */
827 SAMPLE_SVP_TRACE_INFO("Yolov2 Load model!\n");
828 s32Ret = SAMPLE_COMM_SVP_NNIE_LoadModel((char*)modelFile, &g_stYolov2Model);
829 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, YOLOV2_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
830 "Error, SAMPLE_COMM_SVP_NNIE_LoadModel failed!\n");
831
832 /*
833 * Yolov2参数初始化
834 * Yolov2软件参数设置在SampleSvpNnieYolov2SoftwareInit,
835 * 如果用户更改了网络结构,请确保
836 * SampleSvpNnieYolov2SoftwareInit函数中的参数设置是正确的
837 *
838 * Yolov2 parameter initialization
839 * Yolov2 software parameters are set in SampleSvpNnieYolov2SoftwareInit,
840 * if user has changed net struct, please make sure the parameter settings in
841 * SampleSvpNnieYolov2SoftwareInit function are correct
842 */
843 SAMPLE_SVP_TRACE_INFO("Yolov2 parameter initialization!\n");
844 g_stYolov2NnieParam.pstModel = &g_stYolov2Model.stModel;
845 s32Ret = SampleSvpNnieYolov2ParamInit(self, &g_stYolov2NnieParam, &g_stYolov2SoftwareParam);
846 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, YOLOV2_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
847 "Error,SampleSvpNnieYolov2ParamInit failed!\n");
848
849 /*
850 * 模型关键数据
851 * Model important information
852 */
853 SAMPLE_PRT("model.base={ type=%x, frmNum=%u, chnNum=%u, w=%u, h=%u, stride=%u }\n",
854 g_stYolov2NnieParam.astSegData[0].astSrc[0].enType,
855 g_stYolov2NnieParam.astSegData[0].astSrc[0].u32Num,
856 g_stYolov2NnieParam.astSegData[0].astSrc[0].unShape.stWhc.u32Chn,
857 g_stYolov2NnieParam.astSegData[0].astSrc[0].unShape.stWhc.u32Width,
858 g_stYolov2NnieParam.astSegData[0].astSrc[0].unShape.stWhc.u32Height,
859 g_stYolov2NnieParam.astSegData[0].astSrc[0].u32Stride);
860 SAMPLE_PRT("model.soft={ class=%u, ori.w=%u, ori.h=%u, bnum=%u, \
861 grid.w=%u, grid.h=%u, nmsThresh=%u, confThresh=%u, u32MaxRoiNum=%u }\n",
862 g_stYolov2SoftwareParam.u32ClassNum,
863 g_stYolov2SoftwareParam.u32OriImWidth,
864 g_stYolov2SoftwareParam.u32OriImHeight,
865 g_stYolov2SoftwareParam.u32BboxNumEachGrid,
866 g_stYolov2SoftwareParam.u32GridNumWidth,
867 g_stYolov2SoftwareParam.u32GridNumHeight,
868 g_stYolov2SoftwareParam.u32NmsThresh,
869 g_stYolov2SoftwareParam.u32ConfThresh,
870 g_stYolov2SoftwareParam.u32MaxRoiNum);
871
872 *model = self;
873 return 0;
874
875 YOLOV2_FAIL_0:
876 SAMPLE_PRT("Yolo2Create SampleSvpNnieYolov2Deinit\n");
877 SampleSvpNnieYolov2Deinit(&g_stYolov2NnieParam, &g_stYolov2SoftwareParam, &g_stYolov2Model);
878 *model = NULL;
879 return -1;
880 }
881
882 /*
883 * 销毁Yolov2模型
884 * Destroy Yolov2 model
885 */
Yolo2Destory(SAMPLE_SVP_NNIE_CFG_S * self)886 void Yolo2Destory(SAMPLE_SVP_NNIE_CFG_S *self)
887 {
888 SampleSvpNnieYolov2Deinit(&g_stYolov2NnieParam, &g_stYolov2SoftwareParam, &g_stYolov2Model);
889 SAMPLE_COMM_SVP_CheckSysExit();
890 free(self);
891 }
892
893 /*
894 * 获取结果
895 * Fetch result
896 */
Yolo2FetchRes(SVP_BLOB_S * pstDstScore,SVP_BLOB_S * pstDstRoi,SVP_BLOB_S * pstClassRoiNum,DetectObjInfo resBuf[],int resSize,int * resLen)897 static void Yolo2FetchRes(SVP_BLOB_S *pstDstScore, SVP_BLOB_S *pstDstRoi, SVP_BLOB_S *pstClassRoiNum,
898 DetectObjInfo resBuf[], int resSize, int* resLen)
899 {
900 HI_U32 i;
901 HI_U32 j;
902 HI_U32 u32RoiNumBias = 0;
903 HI_U32 u32ScoreBias;
904 HI_U32 u32BboxBias;
905 HI_FLOAT f32Score;
906 HI_S32* ps32Score = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32, pstDstScore->u64VirAddr);
907 HI_S32* ps32Roi = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32, pstDstRoi->u64VirAddr);
908 HI_S32* ps32ClassRoiNum = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32, pstClassRoiNum->u64VirAddr);
909 HI_U32 u32ClassNum = pstClassRoiNum->unShape.stWhc.u32Width;
910
911 HI_ASSERT(u32ClassNum == 2); // 2: the number of class
912 HI_ASSERT(resSize > 0);
913 int resId = 0;
914 *resLen = 0;
915 memset_s(resBuf, resSize * sizeof(resBuf[0]), 0x00, resSize * sizeof(resBuf[0]));
916
917 u32RoiNumBias += ps32ClassRoiNum[0];
918 for (i = 1; i < u32ClassNum; i++) {
919 u32ScoreBias = u32RoiNumBias;
920 u32BboxBias = u32RoiNumBias * SAMPLE_SVP_NNIE_COORDI_NUM;
921 /*
922 * 如果置信度分数大于结果阈值,则打印结果
923 * If the confidence score greater than result threshold, the result will be printed
924 */
925 if ((HI_FLOAT)ps32Score[u32ScoreBias] / SAMPLE_SVP_NNIE_QUANT_BASE >=
926 THRESH_MIN && ps32ClassRoiNum[i] != 0) {
927 }
928 for (j = 0; j < (HI_U32)ps32ClassRoiNum[i]; j++) {
929 f32Score = (HI_FLOAT)ps32Score[u32ScoreBias + j] / SAMPLE_SVP_NNIE_QUANT_BASE;
930 if (f32Score < THRESH_MIN) {
931 SAMPLE_PRT("f32Score:%.2f\n", f32Score);
932 break;
933 }
934 if (resId >= resSize) {
935 SAMPLE_PRT("yolo2 resBuf full\n");
936 break;
937 }
938 resBuf[resId].cls = 1; // class 1
939 resBuf[resId].score = f32Score;
940
941 RectBox *box = &resBuf[resId].box;
942 box->xmin = ps32Roi[u32BboxBias + j * SAMPLE_SVP_NNIE_COORDI_NUM];
943 box->ymin = ps32Roi[u32BboxBias + j * SAMPLE_SVP_NNIE_COORDI_NUM + ARRAY_SUBSCRIPT_OFFSET_1];
944 box->xmax = ps32Roi[u32BboxBias + j * SAMPLE_SVP_NNIE_COORDI_NUM + ARRAY_SUBSCRIPT_OFFSET_2];
945 box->ymax = ps32Roi[u32BboxBias + j * SAMPLE_SVP_NNIE_COORDI_NUM + ARRAY_SUBSCRIPT_OFFSET_3];
946 if (box->xmin >= box->xmax || box->ymin >= box->ymax) {
947 SAMPLE_PRT("yolo1_orig: {%d, %d, %d, %d}, %f, discard for coord ERR\n",
948 box->xmin, box->ymin, box->xmax, box->ymax, f32Score);
949 } else {
950 resId++;
951 }
952 }
953 u32RoiNumBias += ps32ClassRoiNum[i];
954 }
955
956 *resLen = resId;
957 }
958
959 /*
960 * 对一帧yuv图片进行推理
961 * Calculation yuv image
962 */
Yolo2CalImg(SAMPLE_SVP_NNIE_CFG_S * self,const IVE_IMAGE_S * img,DetectObjInfo resBuf[],int resSize,int * resLen)963 int Yolo2CalImg(SAMPLE_SVP_NNIE_CFG_S* self,
964 const IVE_IMAGE_S *img, DetectObjInfo resBuf[], int resSize, int* resLen)
965 {
966 SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S stInputDataIdx = {0};
967 SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S stProcSegIdx = {0};
968 HI_S32 s32Ret;
969
970 /*
971 * 填充源数据
972 * Fill src data
973 */
974 self->pszPic = NULL;
975 stInputDataIdx.u32SegIdx = 0;
976 stInputDataIdx.u32NodeIdx = 0;
977
978 s32Ret = FillNnieByImg(self, &g_stYolov2NnieParam, 0, 0, img);
979 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, YOLOV2_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
980 "Error,SAMPLE_SVP_NNIE_FillSrcData failed!\n");
981
982 /*
983 * NNIE推理(process the 0-th segment)
984 * NNIE process(process the 0-th segment)
985 */
986 stProcSegIdx.u32SegIdx = 0;
987 s32Ret = SAMPLE_SVP_NNIE_Forward(&g_stYolov2NnieParam, &stInputDataIdx, &stProcSegIdx, HI_TRUE);
988 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, YOLOV2_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
989 "Error,SAMPLE_SVP_NNIE_Forward failed!\n");
990
991 /*
992 * CPU处理
993 * 如果用户更改了网络结构,请确保SAMPLE_SVP_NNIE_Yolov2_GetResult函数的输入数据是正确的
994 *
995 * Software process
996 * if user has changed net struct, please make sure SAMPLE_SVP_NNIE_Yolov2_GetResult
997 * function's input datas are correct
998 */
999 s32Ret = SAMPLE_SVP_NNIE_Yolov2_GetResult(&g_stYolov2NnieParam, &g_stYolov2SoftwareParam);
1000 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, YOLOV2_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
1001 "Error,SAMPLE_SVP_NNIE_Yolov2_GetResult failed!\n");
1002
1003 Yolo2FetchRes(&g_stYolov2SoftwareParam.stDstScore,
1004 &g_stYolov2SoftwareParam.stDstRoi, &g_stYolov2SoftwareParam.stClassRoiNum, resBuf, resSize, resLen);
1005 return 0;
1006
1007 YOLOV2_FAIL_0:
1008 return -1;
1009 }
1010
1011 #ifdef __cplusplus
1012 #if __cplusplus
1013 }
1014 #endif
1015 #endif /* End of #ifdef __cplusplus */
1016