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 /* cnn parameter */
66 static SAMPLE_SVP_NNIE_MODEL_S g_stCnnModel = {0};
67 static SAMPLE_SVP_NNIE_PARAM_S g_stCnnNnieParam = {0};
68 static SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S g_stCnnSoftwareParam = {0};
69
70 /* yolov2 parameter */
71 static SAMPLE_SVP_NNIE_MODEL_S g_stYolov2Model = {0};
72 static SAMPLE_SVP_NNIE_PARAM_S g_stYolov2NnieParam = {0};
73 static SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S g_stYolov2SoftwareParam = {0};
74
75 /* function : Cnn software parameter init */
SampleSvpNnieCnnSoftwareParaInit(SAMPLE_SVP_NNIE_CFG_S * pstNnieCfg,SAMPLE_SVP_NNIE_PARAM_S * pstCnnPara,SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S * pstCnnSoftWarePara)76 static HI_S32 SampleSvpNnieCnnSoftwareParaInit(SAMPLE_SVP_NNIE_CFG_S* pstNnieCfg,
77 SAMPLE_SVP_NNIE_PARAM_S *pstCnnPara, SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S* pstCnnSoftWarePara)
78 {
79 HI_U32 u32GetTopNMemSize;
80 HI_U32 u32GetTopBufSize;
81 HI_U32 u32GetTopFrameSize;
82 HI_U32 u32TotalSize;
83 HI_U32 u32ClassNum = pstCnnPara->pstModel->astSeg[0].astDstNode[0].unShape.stWhc.u32Width;
84 HI_U64 u64PhyAddr = 0;
85 HI_U8* pu8VirAddr = NULL;
86 HI_S32 s32Ret;
87
88 /* get mem size */
89 u32GetTopFrameSize = pstCnnSoftWarePara->u32TopN*sizeof(SAMPLE_SVP_NNIE_CNN_GETTOPN_UNIT_S);
90 u32GetTopNMemSize = SAMPLE_SVP_NNIE_ALIGN16(u32GetTopFrameSize)*pstNnieCfg->u32MaxInputNum;
91 u32GetTopBufSize = u32ClassNum*sizeof(SAMPLE_SVP_NNIE_CNN_GETTOPN_UNIT_S);
92 u32TotalSize = u32GetTopNMemSize + u32GetTopBufSize;
93
94 /* malloc mem */
95 s32Ret = SAMPLE_COMM_SVP_MallocMem("SAMPLE_CNN_INIT", NULL, (HI_U64*)&u64PhyAddr,
96 (void**)&pu8VirAddr, u32TotalSize);
97 SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
98 "Error,Malloc memory failed!\n");
99 memset_s(pu8VirAddr, u32TotalSize, 0, u32TotalSize);
100
101 /* init GetTopn */
102 pstCnnSoftWarePara->stGetTopN.u32Num = pstNnieCfg->u32MaxInputNum;
103 pstCnnSoftWarePara->stGetTopN.unShape.stWhc.u32Chn = 1;
104 pstCnnSoftWarePara->stGetTopN.unShape.stWhc.u32Height = 1;
105 pstCnnSoftWarePara->stGetTopN.unShape.stWhc.u32Width = u32GetTopFrameSize / sizeof(HI_U32);
106 pstCnnSoftWarePara->stGetTopN.u32Stride = SAMPLE_SVP_NNIE_ALIGN16(u32GetTopFrameSize);
107 pstCnnSoftWarePara->stGetTopN.u64PhyAddr = u64PhyAddr;
108 pstCnnSoftWarePara->stGetTopN.u64VirAddr = (HI_U64)(HI_UL)pu8VirAddr;
109
110 /* init AssistBuf */
111 pstCnnSoftWarePara->stAssistBuf.u32Size = u32GetTopBufSize;
112 pstCnnSoftWarePara->stAssistBuf.u64PhyAddr = u64PhyAddr + u32GetTopNMemSize;
113 pstCnnSoftWarePara->stAssistBuf.u64VirAddr = (HI_U64)(HI_UL)pu8VirAddr + u32GetTopNMemSize;
114
115 return s32Ret;
116 }
117
118 /* function : Cnn software deinit */
SampleSvpNnieCnnSoftwareDeinit(SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S * pstCnnSoftWarePara)119 static HI_S32 SampleSvpNnieCnnSoftwareDeinit(SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S* pstCnnSoftWarePara)
120 {
121 HI_S32 s32Ret = HI_SUCCESS;
122 SAMPLE_SVP_CHECK_EXPR_RET(pstCnnSoftWarePara == NULL, HI_INVALID_VALUE, SAMPLE_SVP_ERR_LEVEL_ERROR,
123 "Error, pstCnnSoftWarePara can't be NULL!\n");
124 if (pstCnnSoftWarePara->stGetTopN.u64PhyAddr != 0 && pstCnnSoftWarePara->stGetTopN.u64VirAddr != 0) {
125 SAMPLE_SVP_MMZ_FREE(pstCnnSoftWarePara->stGetTopN.u64PhyAddr,
126 pstCnnSoftWarePara->stGetTopN.u64VirAddr);
127 pstCnnSoftWarePara->stGetTopN.u64PhyAddr = 0;
128 pstCnnSoftWarePara->stGetTopN.u64VirAddr = 0;
129 }
130 return s32Ret;
131 }
132
133 /* function : Cnn Deinit */
SampleSvpNnieCnnDeinit(SAMPLE_SVP_NNIE_PARAM_S * pstNnieParam,SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S * pstSoftWareParam,SAMPLE_SVP_NNIE_MODEL_S * pstNnieModel)134 static HI_S32 SampleSvpNnieCnnDeinit(SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam,
135 SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S* pstSoftWareParam, SAMPLE_SVP_NNIE_MODEL_S* pstNnieModel)
136 {
137 HI_S32 s32Ret = HI_SUCCESS;
138 /* hardware para deinit */
139 if (pstNnieParam != NULL) {
140 s32Ret = SAMPLE_COMM_SVP_NNIE_ParamDeinit(pstNnieParam);
141 SAMPLE_SVP_CHECK_EXPR_TRACE(HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
142 "Error,SAMPLE_COMM_SVP_NNIE_ParamDeinit failed!\n");
143 }
144 /* software para deinit */
145 if (pstSoftWareParam != NULL) {
146 s32Ret = SampleSvpNnieCnnSoftwareDeinit(pstSoftWareParam);
147 SAMPLE_SVP_CHECK_EXPR_TRACE(HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
148 "Error,SampleSvpNnieCnnSoftwareDeinit failed!\n");
149 }
150 /* model deinit */
151 if (pstNnieModel != NULL) {
152 s32Ret = SAMPLE_COMM_SVP_NNIE_UnloadModel(pstNnieModel);
153 SAMPLE_SVP_CHECK_EXPR_TRACE(HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
154 "Error,SAMPLE_COMM_SVP_NNIE_UnloadModel failed!\n");
155 }
156 return s32Ret;
157 }
158
159 /* function : Cnn init */
SampleSvpNnieCnnParamInit(SAMPLE_SVP_NNIE_CFG_S * pstNnieCfg,SAMPLE_SVP_NNIE_PARAM_S * pstCnnPara,SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S * pstCnnSoftWarePara)160 static HI_S32 SampleSvpNnieCnnParamInit(SAMPLE_SVP_NNIE_CFG_S* pstNnieCfg,
161 SAMPLE_SVP_NNIE_PARAM_S *pstCnnPara, SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S* pstCnnSoftWarePara)
162 {
163 HI_S32 s32Ret;
164 /* init hardware para */
165 s32Ret = SAMPLE_COMM_SVP_NNIE_ParamInit(pstNnieCfg, pstCnnPara);
166 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, INIT_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
167 "Error(%#x),SAMPLE_COMM_SVP_NNIE_ParamInit failed!\n", s32Ret);
168
169 /* init software para */
170 if (pstCnnSoftWarePara != NULL) {
171 s32Ret = SampleSvpNnieCnnSoftwareParaInit(pstNnieCfg, pstCnnPara, pstCnnSoftWarePara);
172 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, INIT_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
173 "Error(%#x),SampleSvpNnieCnnSoftwareParaInit failed!\n", s32Ret);
174 }
175
176 return s32Ret;
177 INIT_FAIL_0:
178 s32Ret = SampleSvpNnieCnnDeinit(pstCnnPara, pstCnnSoftWarePara, NULL);
179 SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
180 "Error(%#x),SampleSvpNnieCnnDeinit failed!\n", s32Ret);
181 return HI_FAILURE;
182 }
183
184 /* create CNN model based mode file */
CnnCreate(SAMPLE_SVP_NNIE_CFG_S ** model,const char * modelFile)185 int CnnCreate(SAMPLE_SVP_NNIE_CFG_S **model, const char* modelFile)
186 {
187 SAMPLE_SVP_NNIE_CFG_S *self;
188 HI_U32 u32PicNum = 1;
189 HI_S32 s32Ret;
190
191 self = (SAMPLE_SVP_NNIE_CFG_S*)malloc(sizeof(*self));
192 HI_ASSERT(self);
193 if (memset_s(self, sizeof(*self), 0x00, sizeof(*self)) != EOK) {
194 HI_ASSERT(0);
195 }
196
197 // Set configuration parameter
198 self->pszPic = NULL;
199 self->u32MaxInputNum = u32PicNum; // max input image num in each batch
200 self->u32MaxRoiNum = 0;
201 self->aenNnieCoreId[0] = SVP_NNIE_ID_0; // set NNIE core
202 g_stCnnSoftwareParam.u32TopN = 5; // 5: value of the u32TopN
203
204 // Sys init
205 // CNN Load model
206 SAMPLE_SVP_TRACE_INFO("Cnn Load model!\n");
207 s32Ret = SAMPLE_COMM_SVP_NNIE_LoadModel((char*)modelFile, &g_stCnnModel);
208 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, CNN_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
209 "Error,SAMPLE_COMM_SVP_NNIE_LoadModel failed!\n");
210
211 // CNN parameter initialization
212 // Cnn software parameters are set in SampleSvpNnieCnnSoftwareParaInit,
213 // if user has changed net struct, please make sure the parameter settings in
214 // SampleSvpNnieCnnSoftwareParaInit function are correct
215 SAMPLE_SVP_TRACE_INFO("Cnn parameter initialization!\n");
216 g_stCnnNnieParam.pstModel = &g_stCnnModel.stModel;
217 s32Ret = SampleSvpNnieCnnParamInit(self, &g_stCnnNnieParam, &g_stCnnSoftwareParam);
218 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, CNN_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
219 "Error,SampleSvpNnieCnnParamInit failed!\n");
220
221 // Model key information
222 SAMPLE_PRT("model={ type=%x, frmNum=%u, chnNum=%u, w=%u, h=%u, stride=%u }\n",
223 g_stCnnNnieParam.astSegData[0].astSrc[0].enType,
224 g_stCnnNnieParam.astSegData[0].astSrc[0].u32Num,
225 g_stCnnNnieParam.astSegData[0].astSrc[0].unShape.stWhc.u32Chn,
226 g_stCnnNnieParam.astSegData[0].astSrc[0].unShape.stWhc.u32Width,
227 g_stCnnNnieParam.astSegData[0].astSrc[0].unShape.stWhc.u32Height,
228 g_stCnnNnieParam.astSegData[0].astSrc[0].u32Stride);
229
230 // record tskBuf
231 s32Ret = HI_MPI_SVP_NNIE_AddTskBuf(&(g_stCnnNnieParam.astForwardCtrl[0].stTskBuf));
232 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, CNN_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
233 "Error,HI_MPI_SVP_NNIE_AddTskBuf failed!\n");
234 *model = self;
235 return 0;
236
237 CNN_FAIL_0:
238 SampleSvpNnieCnnDeinit(&g_stCnnNnieParam, &g_stCnnSoftwareParam, &g_stCnnModel);
239 *model = NULL;
240 return -1;
241 }
242
243 /* destroy CNN model */
CnnDestroy(SAMPLE_SVP_NNIE_CFG_S * self)244 void CnnDestroy(SAMPLE_SVP_NNIE_CFG_S *self)
245 {
246 HI_S32 s32Ret;
247
248 /* Remove TskBuf */
249 s32Ret = HI_MPI_SVP_NNIE_RemoveTskBuf(&(g_stCnnNnieParam.astForwardCtrl[0].stTskBuf));
250 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, CNN_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
251 "Error,HI_MPI_SVP_NNIE_RemoveTskBuf failed!\n");
252
253 CNN_FAIL_0:
254 SampleSvpNnieCnnDeinit(&g_stCnnNnieParam, &g_stCnnSoftwareParam, &g_stCnnModel);
255 free(self);
256 }
257
FillNnieByImg(SAMPLE_SVP_NNIE_CFG_S * pstNnieCfg,SAMPLE_SVP_NNIE_PARAM_S * pstNnieParam,int segId,int nodeId,const IVE_IMAGE_S * img)258 static HI_S32 FillNnieByImg(SAMPLE_SVP_NNIE_CFG_S* pstNnieCfg,
259 SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, int segId, int nodeId, const IVE_IMAGE_S *img)
260 {
261 HI_U32 i;
262 HI_U32 j;
263 HI_U32 n;
264 HI_U32 u32Height = 0;
265 HI_U32 u32Width = 0;
266 HI_U32 u32Chn = 0;
267 HI_U32 u32Stride = 0;
268 HI_U32 u32VarSize;
269 HI_U8 *pu8PicAddr = NULL;
270
271 /* get data size */
272 if (SVP_BLOB_TYPE_U8 <= pstNnieParam->astSegData[segId].astSrc[nodeId].enType &&
273 SVP_BLOB_TYPE_YVU422SP >= pstNnieParam->astSegData[segId].astSrc[nodeId].enType) {
274 u32VarSize = sizeof(HI_U8);
275 } else {
276 u32VarSize = sizeof(HI_U32);
277 }
278
279 /* fill src data */
280 if (SVP_BLOB_TYPE_SEQ_S32 == pstNnieParam->astSegData[segId].astSrc[nodeId].enType) {
281 HI_ASSERT(0);
282 } else {
283 u32Height = pstNnieParam->astSegData[segId].astSrc[nodeId].unShape.stWhc.u32Height;
284 u32Width = pstNnieParam->astSegData[segId].astSrc[nodeId].unShape.stWhc.u32Width;
285 u32Chn = pstNnieParam->astSegData[segId].astSrc[nodeId].unShape.stWhc.u32Chn;
286 u32Stride = pstNnieParam->astSegData[segId].astSrc[nodeId].u32Stride;
287 pu8PicAddr = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_U8,
288 pstNnieParam->astSegData[segId].astSrc[nodeId].u64VirAddr);
289
290 if (SVP_BLOB_TYPE_YVU420SP == pstNnieParam->astSegData[segId].astSrc[nodeId].enType) {
291 HI_ASSERT(pstNnieParam->astSegData[segId].astSrc[nodeId].u32Num == 1);
292 for (n = 0; n < pstNnieParam->astSegData[segId].astSrc[nodeId].u32Num; n++) {
293 // Y
294 const uint8_t *srcData = (const uint8_t*)(uintptr_t)img->au64VirAddr[0];
295 HI_ASSERT(srcData);
296 for (j = 0; j < u32Height; j++) {
297 if (memcpy_s(pu8PicAddr, u32Width * u32VarSize, srcData, u32Width * u32VarSize) != EOK) {
298 HI_ASSERT(0);
299 }
300 pu8PicAddr += u32Stride;
301 srcData += img->au32Stride[0];
302 }
303 // UV
304 srcData = (const uint8_t*)(uintptr_t)img->au64VirAddr[1];
305 HI_ASSERT(srcData);
306 for (j = 0; j < u32Height / 2; j++) { // 2: 1/2Height
307 if (memcpy_s(pu8PicAddr, u32Width * u32VarSize, srcData, u32Width * u32VarSize) != EOK) {
308 HI_ASSERT(0);
309 }
310 pu8PicAddr += u32Stride;
311 srcData += img->au32Stride[1];
312 }
313 }
314 } else if (SVP_BLOB_TYPE_YVU422SP == pstNnieParam->astSegData[segId].astSrc[nodeId].enType) {
315 HI_ASSERT(0);
316 } else {
317 for (n = 0; n < pstNnieParam->astSegData[segId].astSrc[nodeId].u32Num; n++) {
318 for (i = 0; i < u32Chn; i++) {
319 const uint8_t *srcData = (const uint8_t*)(uintptr_t)img->au64VirAddr[i];
320 HI_ASSERT(srcData);
321 for (j = 0; j < u32Height; j++) {
322 if (memcpy_s(pu8PicAddr, u32Width * u32VarSize, srcData, u32Width * u32VarSize) != EOK) {
323 HI_ASSERT(0);
324 }
325 pu8PicAddr += u32Stride;
326 srcData += img->au32Stride[i];
327 }
328 }
329 }
330 }
331
332 SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astSegData[segId].astSrc[nodeId].u64PhyAddr,
333 SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_VOID, pstNnieParam->astSegData[segId].astSrc[nodeId].u64VirAddr),
334 pstNnieParam->astSegData[segId].astSrc[nodeId].u32Num*u32Chn*u32Height*u32Stride);
335 }
336
337 return HI_SUCCESS;
338 }
339
CnnFetchRes(SVP_BLOB_S * pstGetTopN,HI_U32 u32TopN,RecogNumInfo resBuf[],int resSize,int * resLen)340 void CnnFetchRes(SVP_BLOB_S *pstGetTopN, HI_U32 u32TopN, RecogNumInfo resBuf[], int resSize, int* resLen)
341 {
342 HI_ASSERT(pstGetTopN);
343 HI_U32 i;
344 HI_U32 j = 0;
345 HI_U32 *pu32Tmp = NULL;
346 HI_U32 u32Stride = pstGetTopN->u32Stride;
347 if (memset_s(resBuf, resSize * sizeof(resBuf[0]), 0x00, resSize * sizeof(resBuf[0])) != EOK) {
348 HI_ASSERT(0);
349 }
350
351 int resId = 0;
352 pu32Tmp = (HI_U32*)((HI_UL)pstGetTopN->u64VirAddr + j * u32Stride);
353 for (i = 0; i < u32TopN * 2 && resId < resSize; i += 2, resId++) { // 2: u32TopN*2
354 resBuf[resId].num = pu32Tmp[i];
355 resBuf[resId].score = pu32Tmp[i + 1];
356 }
357 *resLen = resId;
358 }
359
360 /* function : NNIE Forward */
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)361 static HI_S32 SAMPLE_SVP_NNIE_Forward(SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam,
362 SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S* pstInputDataIdx,
363 SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S* pstProcSegIdx, HI_BOOL bInstant)
364 {
365 HI_S32 s32Ret = HI_SUCCESS;
366 HI_U32 i;
367 HI_U32 j;
368 HI_BOOL bFinish = HI_FALSE;
369 SVP_NNIE_HANDLE hSvpNnieHandle = 0;
370 HI_U32 u32TotalStepNum = 0;
371
372 SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].stTskBuf.u64PhyAddr,
373 SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_VOID,
374 pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].stTskBuf.u64VirAddr),
375 pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].stTskBuf.u32Size);
376
377 for (i = 0; i < pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].u32DstNum; i++) {
378 if (pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].enType == SVP_BLOB_TYPE_SEQ_S32) {
379 for (j = 0; j < pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Num; j++) {
380 u32TotalStepNum += *(SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_U32,
381 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].unShape.stSeq.u64VirAddrStep) + j);
382 }
383 SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64PhyAddr,
384 SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_VOID,
385 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64VirAddr),
386 u32TotalStepNum*pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Stride);
387 } else {
388 SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64PhyAddr,
389 SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_VOID,
390 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64VirAddr),
391 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Num*
392 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].unShape.stWhc.u32Chn*
393 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].unShape.stWhc.u32Height*
394 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Stride);
395 }
396 }
397
398 /* set input blob according to node name */
399 if (pstInputDataIdx->u32SegIdx != pstProcSegIdx->u32SegIdx) {
400 for (i = 0; i < pstNnieParam->pstModel->astSeg[pstProcSegIdx->u32SegIdx].u16SrcNum; i++) {
401 for (j = 0; j < pstNnieParam->pstModel->astSeg[pstInputDataIdx->u32SegIdx].u16DstNum; j++) {
402 if (strncmp(pstNnieParam->pstModel->astSeg[pstInputDataIdx->u32SegIdx].astDstNode[j].szName,
403 pstNnieParam->pstModel->astSeg[pstProcSegIdx->u32SegIdx].astSrcNode[i].szName,
404 SVP_NNIE_NODE_NAME_LEN) == 0) {
405 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astSrc[i] =
406 pstNnieParam->astSegData[pstInputDataIdx->u32SegIdx].astDst[j];
407 break;
408 }
409 }
410 SAMPLE_SVP_CHECK_EXPR_RET((j == pstNnieParam->pstModel->astSeg[pstInputDataIdx->u32SegIdx].u16DstNum),
411 HI_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,can't find %d-th seg's %d-th src blob!\n",
412 pstProcSegIdx->u32SegIdx, i);
413 }
414 }
415
416 /* NNIE_Forward */
417 s32Ret = HI_MPI_SVP_NNIE_Forward(&hSvpNnieHandle,
418 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astSrc,
419 pstNnieParam->pstModel, pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst,
420 &pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx], bInstant);
421 SAMPLE_SVP_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
422 "Error,HI_MPI_SVP_NNIE_Forward failed!\n");
423
424 if (bInstant) {
425 /* Wait NNIE finish */
426 while (HI_ERR_SVP_NNIE_QUERY_TIMEOUT == (s32Ret =
427 HI_MPI_SVP_NNIE_Query(pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].enNnieId,
428 hSvpNnieHandle, &bFinish, HI_TRUE))) {
429 usleep(USLEEP_TIME);
430 SAMPLE_SVP_TRACE(SAMPLE_SVP_ERR_LEVEL_INFO,
431 "HI_MPI_SVP_NNIE_Query Query timeout!\n");
432 }
433 }
434 u32TotalStepNum = 0;
435
436 for (i = 0; i < pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].u32DstNum; i++) {
437 if (SVP_BLOB_TYPE_SEQ_S32 == pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].enType) {
438 for (j = 0; j < pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Num; j++) {
439 u32TotalStepNum += *(SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_U32,
440 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].unShape.stSeq.u64VirAddrStep) + j);
441 }
442 SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64PhyAddr,
443 SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_VOID,
444 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64VirAddr),
445 u32TotalStepNum*pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Stride);
446 } else {
447 SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64PhyAddr,
448 SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_VOID,
449 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u64VirAddr),
450 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Num*
451 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].unShape.stWhc.u32Chn*
452 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].unShape.stWhc.u32Height*
453 pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Stride);
454 }
455 }
456
457 return s32Ret;
458 }
459
460 /* Calculate a U8C1 image */
CnnCalU8c1Img(SAMPLE_SVP_NNIE_CFG_S * self,const IVE_IMAGE_S * img,RecogNumInfo resBuf[],int resSize,int * resLen)461 int CnnCalU8c1Img(SAMPLE_SVP_NNIE_CFG_S* self,
462 const IVE_IMAGE_S *img, RecogNumInfo resBuf[], int resSize, int* resLen)
463 {
464 HI_S32 s32Ret;
465 SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S stInputDataIdx = {0};
466 SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S stProcSegIdx = {0};
467
468 /* Fill src data */
469 self->pszPic = NULL;
470 stInputDataIdx.u32SegIdx = 0;
471 stInputDataIdx.u32NodeIdx = 0;
472 s32Ret = FillNnieByImg(self, &g_stCnnNnieParam, 0, 0, img);
473 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, CNN_FAIL_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
474 "Error,SAMPLE_SVP_NNIE_FillSrcData failed!\n");
475
476 /* NNIE process(process the 0-th segment) */
477 stProcSegIdx.u32SegIdx = 0;
478 s32Ret = SAMPLE_SVP_NNIE_Forward(&g_stCnnNnieParam, &stInputDataIdx, &stProcSegIdx, HI_TRUE);
479 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, CNN_FAIL_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
480 "Error,SAMPLE_SVP_NNIE_Forward failed!\n");
481
482 /* Software process */
483 /* if user has changed net struct, please make sure SAMPLE_SVP_NNIE_Cnn_GetTopN
484 function's input datas are correct */
485 s32Ret = SAMPLE_SVP_NNIE_Cnn_GetTopN(&g_stCnnNnieParam, &g_stCnnSoftwareParam);
486 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, CNN_FAIL_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
487 "Error,SAMPLE_SVP_NNIE_CnnGetTopN failed!\n");
488
489 /* Print result */
490 CnnFetchRes(&g_stCnnSoftwareParam.stGetTopN, g_stCnnSoftwareParam.u32TopN, resBuf, resSize, resLen);
491 return 0;
492
493 CNN_FAIL_1:
494 return -1;
495 }
496
497 /* function : Yolov2 software para init */
SampleSvpNnieYolov2SoftwareInit(SAMPLE_SVP_NNIE_CFG_S * pstCfg,SAMPLE_SVP_NNIE_PARAM_S * pstNnieParam,SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S * pstSoftWareParam)498 static HI_S32 SampleSvpNnieYolov2SoftwareInit(SAMPLE_SVP_NNIE_CFG_S* pstCfg,
499 SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S* pstSoftWareParam)
500 {
501 HI_S32 s32Ret;
502 HI_U32 u32ClassNum = 0;
503 HI_U32 u32BboxNum;
504 HI_U32 u32TotalSize = 0;
505 HI_U32 u32DstRoiSize;
506 HI_U32 u32DstScoreSize;
507 HI_U32 u32ClassRoiNumSize;
508 HI_U32 u32TmpBufTotalSize;
509 HI_U64 u64PhyAddr = 0;
510 HI_U8* pu8VirAddr = NULL;
511
512 pstSoftWareParam->u32OriImHeight = pstNnieParam->astSegData[0].astSrc[0].unShape.stWhc.u32Height;
513 pstSoftWareParam->u32OriImWidth = pstNnieParam->astSegData[0].astSrc[0].unShape.stWhc.u32Width;
514 pstSoftWareParam->u32BboxNumEachGrid = 5; // 5: 2BboxNumEachGrid
515 pstSoftWareParam->u32ClassNum = 1; // 5: class number
516 pstSoftWareParam->u32GridNumHeight = 12; // 12: GridNumHeight
517 pstSoftWareParam->u32GridNumWidth = 20; // 20: GridNumWidth
518 pstSoftWareParam->u32NmsThresh = (HI_U32)(0.3f*SAMPLE_SVP_NNIE_QUANT_BASE);
519 pstSoftWareParam->u32ConfThresh = (HI_U32)(0.25f*SAMPLE_SVP_NNIE_QUANT_BASE);
520 pstSoftWareParam->u32MaxRoiNum = 10; // 10: MaxRoiNum
521 pstSoftWareParam->af32Bias[0] = 0.52; // 0.52: af32Bias[0] value
522 pstSoftWareParam->af32Bias[1] = 0.61; // 0.61: af32Bias[1] value
523 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_2] = 1.05; // 1.05: af32Bias[ARRAY_SUBSCRIPT_2] value
524 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_3] = 1.12; // 1.12: af32Bias[ARRAY_SUBSCRIPT_3] value
525 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_4] = 1.85; // 1.85: af32Bias[ARRAY_SUBSCRIPT_4] value
526 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_5] = 2.05; // 2.05: af32Bias[ARRAY_SUBSCRIPT_5] value
527 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_6] = 4.63; // 4.63: af32Bias[ARRAY_SUBSCRIPT_6] value
528 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_7] = 4.49; // 4.49: af32Bias[ARRAY_SUBSCRIPT_7] value
529 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_8] = 7.15; // 7.15: af32Bias[ARRAY_SUBSCRIPT_8] value
530 pstSoftWareParam->af32Bias[ARRAY_SUBSCRIPT_9] = 7.56; // 7.56: af32Bias[ARRAY_SUBSCRIPT_9] value
531
532 /* Malloc assist buffer memory */
533 u32ClassNum = pstSoftWareParam->u32ClassNum + 1;
534 u32BboxNum = pstSoftWareParam->u32BboxNumEachGrid*pstSoftWareParam->u32GridNumHeight*
535 pstSoftWareParam->u32GridNumWidth;
536 u32TmpBufTotalSize = SAMPLE_SVP_NNIE_Yolov2_GetResultTmpBuf(pstSoftWareParam);
537 u32DstRoiSize = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * u32BboxNum * sizeof(HI_U32) * SAMPLE_SVP_NNIE_COORDI_NUM);
538 u32DstScoreSize = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * u32BboxNum * sizeof(HI_U32));
539 u32ClassRoiNumSize = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * sizeof(HI_U32));
540 u32TotalSize = u32TotalSize + u32DstRoiSize + u32DstScoreSize + u32ClassRoiNumSize + u32TmpBufTotalSize;
541 s32Ret = SAMPLE_COMM_SVP_MallocCached("SAMPLE_YOLOV2_INIT", NULL, (HI_U64*)&u64PhyAddr,
542 (void**)&pu8VirAddr, u32TotalSize);
543 SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
544 "Error,Malloc memory failed!\n");
545 memset_s(pu8VirAddr, u32TotalSize, 0, u32TotalSize);
546 SAMPLE_COMM_SVP_FlushCache(u64PhyAddr, (void*)pu8VirAddr, u32TotalSize);
547
548 /* set each tmp buffer addr */
549 pstSoftWareParam->stGetResultTmpBuf.u64PhyAddr = u64PhyAddr;
550 pstSoftWareParam->stGetResultTmpBuf.u64VirAddr = (HI_U64)((HI_UL)pu8VirAddr);
551
552 /* set result blob */
553 pstSoftWareParam->stDstRoi.enType = SVP_BLOB_TYPE_S32;
554 pstSoftWareParam->stDstRoi.u64PhyAddr = u64PhyAddr + u32TmpBufTotalSize;
555 pstSoftWareParam->stDstRoi.u64VirAddr = (HI_U64)((HI_UL)pu8VirAddr + u32TmpBufTotalSize);
556 pstSoftWareParam->stDstRoi.u32Stride = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum *
557 u32BboxNum * sizeof(HI_U32) * SAMPLE_SVP_NNIE_COORDI_NUM);
558 pstSoftWareParam->stDstRoi.u32Num = 1;
559 pstSoftWareParam->stDstRoi.unShape.stWhc.u32Chn = 1;
560 pstSoftWareParam->stDstRoi.unShape.stWhc.u32Height = 1;
561 pstSoftWareParam->stDstRoi.unShape.stWhc.u32Width = u32ClassNum *
562 u32BboxNum*SAMPLE_SVP_NNIE_COORDI_NUM;
563
564 pstSoftWareParam->stDstScore.enType = SVP_BLOB_TYPE_S32;
565 pstSoftWareParam->stDstScore.u64PhyAddr = u64PhyAddr + u32TmpBufTotalSize + u32DstRoiSize;
566 pstSoftWareParam->stDstScore.u64VirAddr = (HI_U64)((HI_UL)pu8VirAddr + u32TmpBufTotalSize + u32DstRoiSize);
567 pstSoftWareParam->stDstScore.u32Stride = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * u32BboxNum * sizeof(HI_U32));
568 pstSoftWareParam->stDstScore.u32Num = 1;
569 pstSoftWareParam->stDstScore.unShape.stWhc.u32Chn = 1;
570 pstSoftWareParam->stDstScore.unShape.stWhc.u32Height = 1;
571 pstSoftWareParam->stDstScore.unShape.stWhc.u32Width = u32ClassNum*u32BboxNum;
572
573 pstSoftWareParam->stClassRoiNum.enType = SVP_BLOB_TYPE_S32;
574 pstSoftWareParam->stClassRoiNum.u64PhyAddr = u64PhyAddr + u32TmpBufTotalSize +
575 u32DstRoiSize + u32DstScoreSize;
576 pstSoftWareParam->stClassRoiNum.u64VirAddr = (HI_U64)((HI_UL)pu8VirAddr + u32TmpBufTotalSize +
577 u32DstRoiSize + u32DstScoreSize);
578 pstSoftWareParam->stClassRoiNum.u32Stride = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum*sizeof(HI_U32));
579 pstSoftWareParam->stClassRoiNum.u32Num = 1;
580 pstSoftWareParam->stClassRoiNum.unShape.stWhc.u32Chn = 1;
581 pstSoftWareParam->stClassRoiNum.unShape.stWhc.u32Height = 1;
582 pstSoftWareParam->stClassRoiNum.unShape.stWhc.u32Width = u32ClassNum;
583
584 return s32Ret;
585 }
586
587 /* function : Yolov2 software deinit */
SampleSvpNnieYolov2SoftwareDeinit(SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S * pstSoftWareParam)588 static HI_S32 SampleSvpNnieYolov2SoftwareDeinit(SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S* pstSoftWareParam)
589 {
590 HI_S32 s32Ret = HI_SUCCESS;
591 SAMPLE_SVP_CHECK_EXPR_RET(pstSoftWareParam == NULL, HI_INVALID_VALUE, SAMPLE_SVP_ERR_LEVEL_ERROR,
592 "Error, pstSoftWareParam can't be NULL!\n");
593 if (pstSoftWareParam->stGetResultTmpBuf.u64PhyAddr != 0 && pstSoftWareParam->stGetResultTmpBuf.u64VirAddr != 0) {
594 SAMPLE_SVP_MMZ_FREE(pstSoftWareParam->stGetResultTmpBuf.u64PhyAddr,
595 pstSoftWareParam->stGetResultTmpBuf.u64VirAddr);
596 pstSoftWareParam->stGetResultTmpBuf.u64PhyAddr = 0;
597 pstSoftWareParam->stGetResultTmpBuf.u64VirAddr = 0;
598 pstSoftWareParam->stDstRoi.u64PhyAddr = 0;
599 pstSoftWareParam->stDstRoi.u64VirAddr = 0;
600 pstSoftWareParam->stDstScore.u64PhyAddr = 0;
601 pstSoftWareParam->stDstScore.u64VirAddr = 0;
602 pstSoftWareParam->stClassRoiNum.u64PhyAddr = 0;
603 pstSoftWareParam->stClassRoiNum.u64VirAddr = 0;
604 }
605 return s32Ret;
606 }
607
608 /* function : Yolov2 Deinit */
SampleSvpNnieYolov2Deinit(SAMPLE_SVP_NNIE_PARAM_S * pstNnieParam,SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S * pstSoftWareParam,SAMPLE_SVP_NNIE_MODEL_S * pstNnieModel)609 static HI_S32 SampleSvpNnieYolov2Deinit(SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam,
610 SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S* pstSoftWareParam, SAMPLE_SVP_NNIE_MODEL_S *pstNnieModel)
611 {
612 HI_S32 s32Ret = HI_SUCCESS;
613 /* hardware deinit */
614 if (pstNnieParam != NULL) {
615 s32Ret = SAMPLE_COMM_SVP_NNIE_ParamDeinit(pstNnieParam);
616 SAMPLE_SVP_CHECK_EXPR_TRACE(HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
617 "Error,SAMPLE_COMM_SVP_NNIE_ParamDeinit failed!\n");
618 }
619 /* software deinit */
620 if (pstSoftWareParam != NULL) {
621 s32Ret = SampleSvpNnieYolov2SoftwareDeinit(pstSoftWareParam);
622 SAMPLE_SVP_CHECK_EXPR_TRACE(HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
623 "Error,SampleSvpNnieYolov2SoftwareDeinit failed!\n");
624 }
625 /* model deinit */
626 if (pstNnieModel != NULL) {
627 s32Ret = SAMPLE_COMM_SVP_NNIE_UnloadModel(pstNnieModel);
628 SAMPLE_SVP_CHECK_EXPR_TRACE(HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
629 "Error,SAMPLE_COMM_SVP_NNIE_UnloadModel failed!\n");
630 }
631 return s32Ret;
632 }
633
634 /* function : Yolov2 init */
SampleSvpNnieYolov2ParamInit(SAMPLE_SVP_NNIE_CFG_S * pstCfg,SAMPLE_SVP_NNIE_PARAM_S * pstNnieParam,SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S * pstSoftWareParam)635 static HI_S32 SampleSvpNnieYolov2ParamInit(SAMPLE_SVP_NNIE_CFG_S* pstCfg,
636 SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, SAMPLE_SVP_NNIE_YOLOV2_SOFTWARE_PARAM_S* pstSoftWareParam)
637 {
638 HI_S32 s32Ret;
639 /* init hardware para */
640 s32Ret = SAMPLE_COMM_SVP_NNIE_ParamInit(pstCfg, pstNnieParam);
641 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, INIT_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
642 "Error(%#x),SAMPLE_COMM_SVP_NNIE_ParamInit failed!\n", s32Ret);
643
644 /* init software para */
645 s32Ret = SampleSvpNnieYolov2SoftwareInit(pstCfg, pstNnieParam,
646 pstSoftWareParam);
647 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, INIT_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
648 "Error(%#x),SAMPLE_SVP_NNIE_Yolov1_SoftwareInit failed!\n", s32Ret);
649 return s32Ret;
650 INIT_FAIL_0:
651 s32Ret = SampleSvpNnieYolov2Deinit(pstNnieParam, pstSoftWareParam, NULL);
652 SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
653 "Error(%#x),SAMPLE_SVP_NNIE_Yolov1_Deinit failed!\n", s32Ret);
654 return HI_FAILURE;
655 }
656
657 /* function : creat yolo2 model basad mode file */
Yolo2Create(SAMPLE_SVP_NNIE_CFG_S ** model,const char * modelFile)658 int Yolo2Create(SAMPLE_SVP_NNIE_CFG_S **model, const char* modelFile)
659 {
660 SAMPLE_SVP_NNIE_CFG_S *self;
661 HI_U32 u32PicNum = 1;
662 HI_S32 s32Ret;
663
664 self = (SAMPLE_SVP_NNIE_CFG_S*)malloc(sizeof(*self));
665 HI_ASSERT(self);
666 memset_s(self, sizeof(*self), 0x00, sizeof(*self));
667
668 // Set configuration parameter
669 self->pszPic = NULL;
670 self->u32MaxInputNum = u32PicNum; // max input image num in each batch
671 self->u32MaxRoiNum = 0;
672 self->aenNnieCoreId[0] = SVP_NNIE_ID_0; // set NNIE core
673
674 // Yolov2 Load model
675 SAMPLE_SVP_TRACE_INFO("Yolov2 Load model!\n");
676 s32Ret = SAMPLE_COMM_SVP_NNIE_LoadModel((char*)modelFile, &g_stYolov2Model);
677 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, YOLOV2_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
678 "Error, SAMPLE_COMM_SVP_NNIE_LoadModel failed!\n");
679
680 /* Yolov2 parameter initialization */
681 /* Yolov2 software parameters are set in SampleSvpNnieYolov2SoftwareInit,
682 if user has changed net struct, please make sure the parameter settings in
683 SampleSvpNnieYolov2SoftwareInit function are correct */
684 SAMPLE_SVP_TRACE_INFO("Yolov2 parameter initialization!\n");
685 g_stYolov2NnieParam.pstModel = &g_stYolov2Model.stModel;
686 s32Ret = SampleSvpNnieYolov2ParamInit(self, &g_stYolov2NnieParam, &g_stYolov2SoftwareParam);
687 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, YOLOV2_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
688 "Error,SampleSvpNnieYolov2ParamInit failed!\n");
689
690 // model important info
691 SAMPLE_PRT("model.base={ type=%x, frmNum=%u, chnNum=%u, w=%u, h=%u, stride=%u }\n",
692 g_stYolov2NnieParam.astSegData[0].astSrc[0].enType,
693 g_stYolov2NnieParam.astSegData[0].astSrc[0].u32Num,
694 g_stYolov2NnieParam.astSegData[0].astSrc[0].unShape.stWhc.u32Chn,
695 g_stYolov2NnieParam.astSegData[0].astSrc[0].unShape.stWhc.u32Width,
696 g_stYolov2NnieParam.astSegData[0].astSrc[0].unShape.stWhc.u32Height,
697 g_stYolov2NnieParam.astSegData[0].astSrc[0].u32Stride);
698 SAMPLE_PRT("model.soft={ class=%u, ori.w=%u, ori.h=%u, bnum=%u, \
699 grid.w=%u, grid.h=%u, nmsThresh=%u, confThresh=%u, u32MaxRoiNum=%u }\n",
700 g_stYolov2SoftwareParam.u32ClassNum,
701 g_stYolov2SoftwareParam.u32OriImWidth,
702 g_stYolov2SoftwareParam.u32OriImHeight,
703 g_stYolov2SoftwareParam.u32BboxNumEachGrid,
704 g_stYolov2SoftwareParam.u32GridNumWidth,
705 g_stYolov2SoftwareParam.u32GridNumHeight,
706 g_stYolov2SoftwareParam.u32NmsThresh,
707 g_stYolov2SoftwareParam.u32ConfThresh,
708 g_stYolov2SoftwareParam.u32MaxRoiNum);
709
710 *model = self;
711 return 0;
712
713 YOLOV2_FAIL_0:
714 SAMPLE_PRT("Yolo2Create SampleSvpNnieYolov2Deinit\n");
715 SampleSvpNnieYolov2Deinit(&g_stYolov2NnieParam, &g_stYolov2SoftwareParam, &g_stYolov2Model);
716 *model = NULL;
717 return -1;
718 }
719
720 /* function : destory yolo2 model */
Yolo2Destory(SAMPLE_SVP_NNIE_CFG_S * self)721 void Yolo2Destory(SAMPLE_SVP_NNIE_CFG_S *self)
722 {
723 SampleSvpNnieYolov2Deinit(&g_stYolov2NnieParam, &g_stYolov2SoftwareParam, &g_stYolov2Model);
724 SAMPLE_COMM_SVP_CheckSysExit();
725 free(self);
726 }
727
728 /* function : fetch result */
Yolo2FetchRes(SVP_BLOB_S * pstDstScore,SVP_BLOB_S * pstDstRoi,SVP_BLOB_S * pstClassRoiNum,DetectObjInfo resBuf[],int resSize,int * resLen)729 static void Yolo2FetchRes(SVP_BLOB_S *pstDstScore, SVP_BLOB_S *pstDstRoi, SVP_BLOB_S *pstClassRoiNum,
730 DetectObjInfo resBuf[], int resSize, int* resLen)
731 {
732 HI_U32 i;
733 HI_U32 j;
734 HI_U32 u32RoiNumBias = 0;
735 HI_U32 u32ScoreBias;
736 HI_U32 u32BboxBias;
737 HI_FLOAT f32Score;
738 HI_S32* ps32Score = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32, pstDstScore->u64VirAddr);
739 HI_S32* ps32Roi = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32, pstDstRoi->u64VirAddr);
740 HI_S32* ps32ClassRoiNum = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32, pstClassRoiNum->u64VirAddr);
741 HI_U32 u32ClassNum = pstClassRoiNum->unShape.stWhc.u32Width;
742
743 HI_ASSERT(u32ClassNum == 2); // 2: the number of class
744 HI_ASSERT(resSize > 0);
745 int resId = 0;
746 *resLen = 0;
747 memset_s(resBuf, resSize * sizeof(resBuf[0]), 0x00, resSize * sizeof(resBuf[0]));
748
749 u32RoiNumBias += ps32ClassRoiNum[0];
750 for (i = 1; i < u32ClassNum; i++) {
751 u32ScoreBias = u32RoiNumBias;
752 u32BboxBias = u32RoiNumBias * SAMPLE_SVP_NNIE_COORDI_NUM;
753 /* if the confidence score greater than result threshold, the result will be printed */
754 if ((HI_FLOAT)ps32Score[u32ScoreBias] / SAMPLE_SVP_NNIE_QUANT_BASE >=
755 THRESH_MIN && ps32ClassRoiNum[i] != 0) {
756 }
757 for (j = 0; j < (HI_U32)ps32ClassRoiNum[i]; j++) {
758 f32Score = (HI_FLOAT)ps32Score[u32ScoreBias + j] / SAMPLE_SVP_NNIE_QUANT_BASE;
759 if (f32Score < THRESH_MIN) {
760 SAMPLE_PRT("f32Score:%.2f\n", f32Score);
761 break;
762 }
763 if (resId >= resSize) {
764 SAMPLE_PRT("yolo2 resBuf full\n");
765 break;
766 }
767 resBuf[resId].cls = 1; // class 1
768 resBuf[resId].score = f32Score;
769
770 RectBox *box = &resBuf[resId].box;
771 box->xmin = ps32Roi[u32BboxBias + j * SAMPLE_SVP_NNIE_COORDI_NUM];
772 box->ymin = ps32Roi[u32BboxBias + j * SAMPLE_SVP_NNIE_COORDI_NUM + ARRAY_SUBSCRIPT_OFFSET_1];
773 box->xmax = ps32Roi[u32BboxBias + j * SAMPLE_SVP_NNIE_COORDI_NUM + ARRAY_SUBSCRIPT_OFFSET_2];
774 box->ymax = ps32Roi[u32BboxBias + j * SAMPLE_SVP_NNIE_COORDI_NUM + ARRAY_SUBSCRIPT_OFFSET_3];
775 if (box->xmin >= box->xmax || box->ymin >= box->ymax) {
776 SAMPLE_PRT("yolo1_orig: {%d, %d, %d, %d}, %f, discard for coord ERR\n",
777 box->xmin, box->ymin, box->xmax, box->ymax, f32Score);
778 } else {
779 resId++;
780 }
781 }
782 u32RoiNumBias += ps32ClassRoiNum[i];
783 }
784
785 *resLen = resId;
786 }
787
788 /* function : calculation yuv image */
Yolo2CalImg(SAMPLE_SVP_NNIE_CFG_S * self,const IVE_IMAGE_S * img,DetectObjInfo resBuf[],int resSize,int * resLen)789 int Yolo2CalImg(SAMPLE_SVP_NNIE_CFG_S* self,
790 const IVE_IMAGE_S *img, DetectObjInfo resBuf[], int resSize, int* resLen)
791 {
792 SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S stInputDataIdx = {0};
793 SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S stProcSegIdx = {0};
794 HI_S32 s32Ret;
795
796 // Fill src data
797 self->pszPic = NULL;
798 stInputDataIdx.u32SegIdx = 0;
799 stInputDataIdx.u32NodeIdx = 0;
800
801 s32Ret = FillNnieByImg(self, &g_stYolov2NnieParam, 0, 0, img);
802 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, YOLOV2_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
803 "Error,SAMPLE_SVP_NNIE_FillSrcData failed!\n");
804
805 // NNIE process(process the 0-th segment)
806 stProcSegIdx.u32SegIdx = 0;
807 s32Ret = SAMPLE_SVP_NNIE_Forward(&g_stYolov2NnieParam, &stInputDataIdx, &stProcSegIdx, HI_TRUE);
808 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, YOLOV2_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
809 "Error,SAMPLE_SVP_NNIE_Forward failed!\n");
810
811 /* Software process */
812 /* if user has changed net struct, please make sure SAMPLE_SVP_NNIE_Yolov2_GetResult
813 function input datas are correct */
814 s32Ret = SAMPLE_SVP_NNIE_Yolov2_GetResult(&g_stYolov2NnieParam, &g_stYolov2SoftwareParam);
815 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, YOLOV2_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
816 "Error,SAMPLE_SVP_NNIE_Yolov2_GetResult failed!\n");
817
818 Yolo2FetchRes(&g_stYolov2SoftwareParam.stDstScore,
819 &g_stYolov2SoftwareParam.stDstRoi, &g_stYolov2SoftwareParam.stClassRoiNum, resBuf, resSize, resLen);
820 return 0;
821
822 YOLOV2_FAIL_0:
823 return -1;
824 }
825
826 #ifdef __cplusplus
827 #if __cplusplus
828 }
829 #endif
830 #endif /* End of #ifdef __cplusplus */
831