• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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