之后随笔将更多笔墨着重于NNIE开发系列,下文是关于Hi3559AV100 NNIE开发(2)-RFCN(.wk)LoadModel及NNIE Init函数运行过程分析,通过对LoadModel函数及NNIE Init函数实现分析,结合上一篇随笔对LoadModel函数参数挖掘,很大程度上能够理解NNIE初始化实现过程,并给其他算法模型在NNIE移植提供参考,下面将给出RFCN Load_Model函数执行过程与NNIE_RFCN参数初始化过程。

1、RFCN Load_Model函数执行过程

  pszModelFile是导入目标检测方法RFCN .wk模型的位置与文件名,pstNnieModel结构的详细解析已经通过上一篇随笔(Hi3359AV100 NNIE开发(1)-RFCN(.wk)LoadModel函数参数解析 :https://www.cnblogs.com/iFrank/p/14500648.html)给出。

  而在RFCN demo中把RFCN的.wk模型文件通过函数导出模型参数,具体调用如下所示:

1 static SAMPLE_SVP_NNIE_MODEL_S s_stRfcnModel = {0};
2
3 HI_CHAR *pcModelName = "./data/nnie_model/detection/inst_rfcn_resnet50_cycle_352x288.wk";
4
5 //函数输入参数
6 SAMPLE_COMM_SVP_NNIE_LoadModel(pcModelName,&s_stRfcnModel);

  下面给出LoadModel函数的具体分析,深入函数内部,把各个细节弄清楚,先给SAMPLE_COMM_SVP_NNIE_LoadModel函数:

 1 /*SAMPLE_COMM_SVP_NNIE_LoadModel(pcModelName,
2 &s_stRfcnModel);*/
3 HI_S32 SAMPLE_COMM_SVP_NNIE_LoadModel(
4 HI_CHAR * pszModelFile,
5 SAMPLE_SVP_NNIE_MODEL_S *pstNnieModel)
6 {
7 HI_S32 s32Ret = HI_INVALID_VALUE;
8 HI_U64 u64PhyAddr = 0;
9 HI_U8 *pu8VirAddr = NULL;
10 HI_SL slFileSize = 0;
11 /*Get model file size*/
12 FILE *fp=fopen(pszModelFile,"rb");
13 SAMPLE_SVP_CHECK_EXPR_RET(NULL == fp,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error, open model file failed!\n");
14 s32Ret = fseek(fp,0L,SEEK_END); // 文件指针指向文件尾
15 SAMPLE_SVP_CHECK_EXPR_GOTO(-1 == s32Ret,FAIL_0,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error, fseek failed!\n");
16 slFileSize = ftell(fp); // 获取文件字节大小
17 SAMPLE_SVP_CHECK_EXPR_GOTO(slFileSize <= 0,FAIL_0,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error, ftell failed!\n");
18 s32Ret = fseek(fp,0L,SEEK_SET); // 再将文件指针指向文件头
19 SAMPLE_SVP_CHECK_EXPR_GOTO(-1 == s32Ret,FAIL_0,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error, fseek failed!\n");
20
21 /*malloc model file mem 根据文件大小计算需分配的物理地址及虚拟地址大小*/
22 s32Ret = SAMPLE_COMM_SVP_MallocMem("SAMPLE_NNIE_MODEL",
23 NULL,
24 (HI_U64*)&u64PhyAddr, //0
25 (void**)&pu8VirAddr, //NULL
26 slFileSize); //ftell(fp)
27 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret,FAIL_0,SAMPLE_SVP_ERR_LEVEL_ERROR,
28 "Error(%#x),Malloc memory failed!\n",s32Ret);
29
30 pstNnieModel->stModelBuf.u32Size = (HI_U32)slFileSize; //文件大小
31 pstNnieModel->stModelBuf.u64PhyAddr = u64PhyAddr; //物理地址
32 pstNnieModel->stModelBuf.u64VirAddr = (HI_U64)pu8VirAddr; //虚拟指针
33
34 /*读取整个wk文件到虚拟地址*/
35 s32Ret = fread(pu8VirAddr,slFileSize,1,fp);
36 SAMPLE_SVP_CHECK_EXPR_GOTO(1 != s32Ret,FAIL_1,SAMPLE_SVP_ERR_LEVEL_ERROR,
37 "Error,read model file failed!\n");
38
39 /*load model ,从wk文件数据buf 中的模型中解析出网络模型*/
40 s32Ret = HI_MPI_SVP_NNIE_LoadModel(&pstNnieModel->stModelBuf, /*输入:模型数据buf*/
41 &pstNnieModel->stModel); /*输出:网络模型结构体*/
42
43 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret,FAIL_1,SAMPLE_SVP_ERR_LEVEL_ERROR,
44 "Error,HI_MPI_SVP_NNIE_LoadModel failed!\n");
45
46 fclose(fp);
47 return HI_SUCCESS;
48 FAIL_1:
49 SAMPLE_SVP_MMZ_FREE(pstNnieModel->stModelBuf.u64PhyAddr,pstNnieModel->stModelBuf.u64VirAddr);
50 pstNnieModel->stModelBuf.u32Size = 0;
51 FAIL_0:
52 if (NULL != fp)
53 {
54 fclose(fp);
55 }
56
57 return HI_FAILURE;
58 }

  通过分析,LoadModel函数执行以下步骤:

  (1)获取wk文件文件大小;
  (2)根据文件大小分配存储wk文件的物理地址与虚拟地址;
  (3)读取wk文件到虚拟地址
  (4)从wk文件数据的buf中解析出网络模型信息
  执行完后上述步骤后,模型存储在s_stRfcnModel.stModel结构体里,这个结构体里存储的是什么信息,可参考我上一篇随笔Hi3359AV100 NNIE开发(1)-RFCN(.wk)LoadModel函数参数解析 :https://www.cnblogs.com/iFrank/p/14500648.html,这里简单罗列各个段、输入输出节点(以Fast RCNN为例,因为HiSVP开发是以Fast RCNN为例进行细节说明的,此处与文档匹配)的信息如下:

2、NNIE_RFCN参数初始化过程

  在完成SAMPLE_COMM_SVP_NNIE_LoadModel提取.wk模型参数值之后,结构体指针给到 s_stRfcnNnieParam.pstModel = &s_stRfcnModel.stModel;这个结构体中,随后进行的就是RFCN算法的NNIE参数初始化,具体如下所示:

 1 /*
2 stNnieCfg.pszPic= NULL;
3 stNnieCfg.u32MaxInputNum = 1; //max input image num in each batch
4 stNnieCfg.u32MaxRoiNum = 300;
5 stNnieCfg.aenNnieCoreId[0] = SVP_NNIE_ID_0; //set NNIE core for 0-th Seg
6 //表示下标为 0 的 NNIE 引擎
7 stNnieCfg.aenNnieCoreId[1] = SVP_NNIE_ID_0; //set NNIE core for 1-th Seg
8 stNnieCfg.aenNnieCoreId[2] = SVP_NNIE_ID_0; //set NNIE core for 2-th Seg
9
10 s_stRfcnNnieParam.pstModel = &s_stRfcnModel.stModel;
11 s_stRfcnSoftwareParam.apcRpnDataLayerName[0] = "rpn_cls_score";
12 s_stRfcnSoftwareParam.apcRpnDataLayerName[1] = "rpn_bbox_pred";
13
14 s32Ret = SAMPLE_SVP_NNIE_Rfcn_ParamInit(&stNnieCfg,
15 &s_stRfcnNnieParam,
16 &s_stRfcnSoftwareParam);
17 */
18
19 //函数初始化
20 static HI_S32 SAMPLE_SVP_NNIE_Rfcn_ParamInit(
21 SAMPLE_SVP_NNIE_CFG_S* pstCfg,
22 SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, //pstModel
23 SAMPLE_SVP_NNIE_RFCN_SOFTWARE_PARAM_S* pstSoftWareParam)
24 {
25 HI_S32 s32Ret = HI_SUCCESS;
26 /*init hardware para*/
27 s32Ret = SAMPLE_COMM_SVP_NNIE_ParamInit(pstCfg,pstNnieParam);
28 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret,INIT_FAIL_0,SAMPLE_SVP_ERR_LEVEL_ERROR,
29 "Error(%#x),SAMPLE_COMM_SVP_NNIE_ParamInit failed!\n",s32Ret);
30
31 /*init software para*/
32 s32Ret = SAMPLE_SVP_NNIE_Rfcn_SoftwareInit(pstCfg,pstNnieParam,pstSoftWareParam);
33 SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret,INIT_FAIL_0,SAMPLE_SVP_ERR_LEVEL_ERROR,
34 "Error(%#x),SAMPLE_SVP_NNIE_Rfcn_SoftwareInit failed!\n",s32Ret);
35
36 return s32Ret;
37 INIT_FAIL_0:
38 s32Ret = SAMPLE_SVP_NNIE_Rfcn_Deinit(pstNnieParam,pstSoftWareParam,NULL);
39 SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,
40 "Error(%#x),SAMPLE_SVP_NNIE_Rfcn_Deinit failed!\n",s32Ret);
41 return HI_FAILURE;
42
43 }

  这个函数里面执行稍复杂,简单来说就是使用stNnieCfg等信息来初始化s_stRfcnNnieParam,在使用s_stRfcnNnieParam等来初始化s_stRfcnSoftwareParam。

  RFCN NNIE初始化函数分为SAMPLE_COMM_SVP_NNIE_ParamInit(初始化硬件参数)与SAMPLE_SVP_NNIE_Rfcn_SoftwareInit(初始化软件参数)两个函数。

2.1、NNIE初始化下SAMPLE_COMM_SVP_NNIE_ParamInit实现分析

  首先看SAMPLE_COMM_SVP_NNIE_ParamInit:

1 HI_S32 SAMPLE_COMM_SVP_NNIE_ParamInit(SAMPLE_SVP_NNIE_CFG_S *pstNnieCfg,
2 SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam)
3 {
4 .......
5
6 /*NNIE parameter initialization */
7 s32Ret = SAMPLE_SVP_NNIE_ParamInit(pstNnieCfg,pstNnieParam);
8 .......
9 }

  这个函数的实现里做了一些输入参数的有效判断后,就直接调用SAMPLE_SVP_NNIE_ParamInit,因此我们就直接看SAMPLE_SVP_NNIE_ParamInit(NNIE参数初始化)的实现,在这个函数里首先调用:

1 /*fill forward info*/
2 s32Ret = SAMPLE_SVP_NNIE_FillForwardInfo(pstNnieCfg,pstNnieParam);

  这个函数的实质就是使用pstNnieParam->pstModel->astSeg的信息来初始化pstNnieParam->astForwardWithBboxCtrl与pstNnieParam->astSegData这两个结构体。

  SAMPLE_SVP_NNIE_ParamInit下第2个关键SAMPLE_SVP_NNIE_GetTaskAndBlobBufSize函数,输入参数如下:

1     /*Get taskInfo and Blob mem size*/
2 s32Ret = SAMPLE_SVP_NNIE_GetTaskAndBlobBufSize(pstNnieCfg,
3 pstNnieParam,
4 &u32TotalTaskBufSize,/*输入&输出:输入值为0; 输出:网络各段辅助内存的总和*/
5 &u32TmpBufSize,/*输入&输出,输入值为0; 输出:模型辅助内存大小*/
6 astBlobSize,/*输入&输出:输入为空; 输出:各段第1个输入、输出节点辅助内存*/
7 &u32TotalSize);

  这个函数是计算各个段、各个段中的各个节点的的辅助内存大小。我们知道,在之前的load模型的步骤中,是已经获取到模型的辅助内存(pstNnieParam->pstModel->u32TmpBufSize),但各段、段中各个节点的辅助内存是不知道的,因此该函数就是获取这些辅助内存。在这个函数中,首先调用底层API  HI_MPI_SVP_NNIE_GetTskBufSize获取到网络任务的各段的辅助内存pstNnieParam->au32TaskBufSize,然后再调用SAMPLE_SVP_NNIE_GetBlobMemSize计算第1段的第1个输入节点Blob的辅助内存,以及每段的第1个输出节点的Blob辅助内存。

  回到SAMPLE_SVP_NNIE_ParamInit函数中,SAMPLE_SVP_NNIE_GetTaskAndBlobBufSize执行完后,u32TotalSize为总的辅助内存大小(含模型、段、节点),此时调用第三个函数MallocCached实现内存空间分配:

1 /*Malloc mem*/
2 s32Ret = SAMPLE_COMM_SVP_MallocCached("SAMPLE_NNIE_TASK",NULL,(HI_U64*)&u64PhyAddr,(void**)&pu8VirAddr,u32TotalSize);

  接着后面,执行SAMLE_COMM_SVP_FlushCacheha函数,实现cache数据转移到内存中,具体实现如下:

1 HI_S32 SAMPLE_COMM_SVP_FlushCache(HI_U64 u64PhyAddr, HI_VOID *pvVirAddr, HI_U32 u32Size)
2 {
3 HI_S32 s32Ret = HI_SUCCESS;
4 s32Ret = HI_MPI_SYS_MmzFlushCache(u64PhyAddr, pvVirAddr,u32Size);
5
6 /*刷新 cache 里的内容到内存并且使 cache 里的内容无效
7 此接口应与 HI_MPI_SYS_MmzAlloc_Cached 接口配套使用。*/
8 return s32Ret;
9 }

  再根据得到的虚拟内存地址、物理内存地址来初始化pstNnieParam->stTaskBuf、pstNnieParam->stTmpBuf、pstNnieParam->astForwardWithBboxCtrl[i].stTmpBuf、pstNnieParam->astForwardWithBboxCtrl[i].stTskBuf、stNnieParam->astForwardCtrl[i].stTskBuf、stNnieParam->astSegData[i].astSrc[j]这些结构体中的内存地址值,这个才是真正的初始化,之前在SAMPLE_SVP_NNIE_FillForwardInfo函数中也有对这些结构体做初始化,但那是“false init”,到此SAMPLE_COMM_SVP_NNIE_paramInit函数下SAMPLE_SVP_NNIE_ParamInit函数执行完毕。

2.2、NNIE初始化下SAMPLE_SVP_NNIE_Rfcn_SoftwareInit实现分析

  首先给出SAMPLE_SVP_NNIE_Rfcn_SoftwareInit函数调用,输入三个参数,相比于SAMPLE_COMM_SVP_NNIE_ParamInit,多了s_stRfcnSoftwareParam参数,其参数用来设置RPN data layer name

和查找RPN input data,这个需根据项目实际的算法模型来进行调整改变,参数设置与调用具体如下所示:

 1     stNnieCfg.pszPic= NULL;
2 stNnieCfg.u32MaxInputNum = 1; //max input image num in each batch
3 stNnieCfg.u32MaxRoiNum = 300;
4 stNnieCfg.aenNnieCoreId[0] = SVP_NNIE_ID_0; //set NNIE core for 0-th Seg
5 //表示下标为 0 的 NNIE 引擎
6 stNnieCfg.aenNnieCoreId[1] = SVP_NNIE_ID_0; //set NNIE core for 1-th Seg
7 stNnieCfg.aenNnieCoreId[2] = SVP_NNIE_ID_0; //set NNIE core for 2-th Seg
8
9 s_stRfcnNnieParam.pstModel = &s_stRfcnModel.stModel;
10 s_stRfcnSoftwareParam.apcRpnDataLayerName[0] = "rpn_cls_score";
11 s_stRfcnSoftwareParam.apcRpnDataLayerName[1] = "rpn_bbox_pred";
12
13 s32Ret = SAMPLE_SVP_NNIE_Rfcn_ParamInit(&stNnieCfg,
14 &s_stRfcnNnieParam,
15 &s_stRfcnSoftwareParam);

  随后我们进入到SAMPLE_SVP_NNIE_Rfcn_SoftwareInit函数体,定义如下:

1 /******************************************************************************
2 * function : Rfcn software para init
3 ******************************************************************************/
4 static HI_S32 SAMPLE_SVP_NNIE_Rfcn_SoftwareInit(
5 SAMPLE_SVP_NNIE_CFG_S* pstCfg,
6 SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam,
7 SAMPLE_SVP_NNIE_RFCN_SOFTWARE_PARAM_S* pstSoftWareParam)

  函数体内最主要功能是实现s_stRfcnSoftwareParam参数的赋值,大量赋值语句,来实现Rpn参数的软件初始化,具体过程分为如下:

  (1)Init Rpn para;

 1     pstSoftWareParam->u32MaxRoiNum = pstCfg->u32MaxRoiNum;
2 pstSoftWareParam->u32ClassNum = 21;
3 pstSoftWareParam->u32NumRatioAnchors = 3;
4 pstSoftWareParam->u32NumScaleAnchors = 3;
5 pstSoftWareParam->au32Scales[0] = 8 * SAMPLE_SVP_NNIE_QUANT_BASE;
6 pstSoftWareParam->au32Scales[1] = 16 * SAMPLE_SVP_NNIE_QUANT_BASE;
7 pstSoftWareParam->au32Scales[2] = 32 * SAMPLE_SVP_NNIE_QUANT_BASE;
8 pstSoftWareParam->au32Ratios[0] = 0.5 * SAMPLE_SVP_NNIE_QUANT_BASE;
9 pstSoftWareParam->au32Ratios[1] = 1 * SAMPLE_SVP_NNIE_QUANT_BASE;
10 pstSoftWareParam->au32Ratios[2] = 2 * SAMPLE_SVP_NNIE_QUANT_BASE;
11 pstSoftWareParam->u32OriImHeight = pstNnieParam->astSegData[0].astSrc[0].unShape.stWhc.u32Height;
12 pstSoftWareParam->u32OriImWidth = pstNnieParam->astSegData[0].astSrc[0].unShape.stWhc.u32Width;
13 pstSoftWareParam->u32MinSize = 16;
14 pstSoftWareParam->u32FilterThresh = 0;
15 pstSoftWareParam->u32SpatialScale = (HI_U32)(0.0625 * SAMPLE_SVP_NNIE_QUANT_BASE);
16 pstSoftWareParam->u32NmsThresh = (HI_U32)(0.7 * SAMPLE_SVP_NNIE_QUANT_BASE);
17 pstSoftWareParam->u32FilterThresh = 0;
18 pstSoftWareParam->u32NumBeforeNms = 6000;
19 for(i = 0; i < pstSoftWareParam->u32ClassNum; i++)
20 {
21 pstSoftWareParam->au32ConfThresh[i] = 1;
22 pstSoftWareParam->af32ScoreThr[i] = 0.8f;
23 }
24 pstSoftWareParam->u32ValidNmsThresh = (HI_U32)(0.3 * 4096);

  (2)设置Rpn输入数据信息,输入信息是由RPN data layer‘s name作为设置的依据;

 1     for(i = 0; i < 2; i++)
2 {
3 for(j = 0; j < pstNnieParam->pstModel->astSeg[0].u16DstNum; j++)
4 {
5 if(0 == strncmp(pstNnieParam->pstModel->astSeg[0].astDstNode[j].szName,
6 pstSoftWareParam->apcRpnDataLayerName[i],
7 SVP_NNIE_NODE_NAME_LEN))
8 {
9 pstSoftWareParam->aps32Conv[i] =(HI_S32*)pstNnieParam->astSegData[0].astDst[j].u64VirAddr;
10 pstSoftWareParam->au32ConvHeight[i] = pstNnieParam->pstModel->astSeg[0].astDstNode[j].unShape.stWhc.u32Height;
11 pstSoftWareParam->au32ConvWidth[i] = pstNnieParam->pstModel->astSeg[0].astDstNode[j].unShape.stWhc.u32Width;
12 pstSoftWareParam->au32ConvChannel[i] = pstNnieParam->pstModel->astSeg[0].astDstNode[j].unShape.stWhc.u32Chn;
13 break;
14 }
15 }
16 SAMPLE_SVP_CHECK_EXPR_RET((j == pstNnieParam->pstModel->astSeg[0].u16DstNum),
17 HI_FAILURE,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error,failed to find report node %s!\n",
18 pstSoftWareParam->apcRpnDataLayerName[i]);
19 if(0 == i)
20 {
21 pstSoftWareParam->u32ConvStride = pstNnieParam->astSegData[0].astDst[j].u32Stride;
22 }
23 }
24
25 pstSoftWareParam->stRpnBbox.enType = SVP_BLOB_TYPE_S32;
26 pstSoftWareParam->stRpnBbox.unShape.stWhc.u32Chn = 1;
27 pstSoftWareParam->stRpnBbox.unShape.stWhc.u32Height = pstCfg->u32MaxRoiNum;
28 pstSoftWareParam->stRpnBbox.unShape.stWhc.u32Width = SAMPLE_SVP_COORDI_NUM;
29 pstSoftWareParam->stRpnBbox.u32Stride = SAMPLE_SVP_NNIE_ALIGN16(SAMPLE_SVP_COORDI_NUM*sizeof(HI_U32));
30 pstSoftWareParam->stRpnBbox.u32Num = 1;

  (3)最后一步是配置Rfcn软件内存空间大小;

 1     u32RpnTmpBufSize = SAMPLE_SVP_NNIE_RpnTmpBufSize(pstSoftWareParam->u32NumRatioAnchors,
2 pstSoftWareParam->u32NumScaleAnchors,pstSoftWareParam->au32ConvHeight[0],
3 pstSoftWareParam->au32ConvWidth[0]);
4 u32RpnTmpBufSize = SAMPLE_SVP_NNIE_ALIGN16(u32RpnTmpBufSize);
5 u32RpnBboxBufSize = pstSoftWareParam->stRpnBbox.u32Num*
6 pstSoftWareParam->stRpnBbox.unShape.stWhc.u32Height*pstSoftWareParam->stRpnBbox.u32Stride;
7 u32GetResultTmpBufSize = SAMPLE_SVP_NNIE_Rfcn_GetResultTmpBuf(pstCfg->u32MaxRoiNum,pstSoftWareParam->u32ClassNum);
8 u32GetResultTmpBufSize = SAMPLE_SVP_NNIE_ALIGN16(u32GetResultTmpBufSize);
9 u32ClassNum = pstSoftWareParam->u32ClassNum;
10 u32DstRoiSize = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum*pstCfg->u32MaxRoiNum*sizeof(HI_U32)*SAMPLE_SVP_NNIE_COORDI_NUM);
11 u32DstScoreSize = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum*pstCfg->u32MaxRoiNum*sizeof(HI_U32));
12 u32ClassRoiNumSize = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum*sizeof(HI_U32));
13 u32TotalSize = u32RpnTmpBufSize + u32RpnBboxBufSize + u32GetResultTmpBufSize + u32DstRoiSize +
14 u32DstScoreSize + u32ClassRoiNumSize;
15
16 s32Ret = SAMPLE_COMM_SVP_MallocCached("SAMPLE_RFCN_INIT",NULL,(HI_U64*)&u64PhyAddr,
17 (void**)&pu8VirAddr,u32TotalSize);
18 SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,
19 "Error,Malloc memory failed!\n");
20 memset(pu8VirAddr,0, u32TotalSize);
21 SAMPLE_COMM_SVP_FlushCache(u64PhyAddr,(void*)pu8VirAddr,u32TotalSize);
22
23 pstSoftWareParam->stRpnTmpBuf.u64PhyAddr = u64PhyAddr;
24 pstSoftWareParam->stRpnTmpBuf.u64VirAddr = (HI_U64)(pu8VirAddr);
25 pstSoftWareParam->stRpnTmpBuf.u32Size = u32RpnTmpBufSize;
26
27 pstSoftWareParam->stRpnBbox.u64PhyAddr = u64PhyAddr+u32RpnTmpBufSize;
28 pstSoftWareParam->stRpnBbox.u64VirAddr = (HI_U64)(pu8VirAddr)+u32RpnTmpBufSize;
29
30 pstSoftWareParam->stGetResultTmpBuf.u64PhyAddr = u64PhyAddr+u32RpnTmpBufSize+u32RpnBboxBufSize;
31 pstSoftWareParam->stGetResultTmpBuf.u64VirAddr = (HI_U64)(pu8VirAddr+u32RpnTmpBufSize+u32RpnBboxBufSize);
32 pstSoftWareParam->stGetResultTmpBuf.u32Size = u32GetResultTmpBufSize;
33
34 pstSoftWareParam->stDstRoi.enType = SVP_BLOB_TYPE_S32;
35 pstSoftWareParam->stDstRoi.u64PhyAddr = u64PhyAddr+u32RpnTmpBufSize+u32RpnBboxBufSize+u32GetResultTmpBufSize;
36 pstSoftWareParam->stDstRoi.u64VirAddr = (HI_U64)(pu8VirAddr+u32RpnTmpBufSize+u32RpnBboxBufSize+u32GetResultTmpBufSize);
37 pstSoftWareParam->stDstRoi.u32Stride = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum*pstSoftWareParam->u32MaxRoiNum*sizeof(HI_U32)*SAMPLE_SVP_NNIE_COORDI_NUM);
38 pstSoftWareParam->stDstRoi.u32Num = 1;
39 pstSoftWareParam->stDstRoi.unShape.stWhc.u32Chn = 1;
40 pstSoftWareParam->stDstRoi.unShape.stWhc.u32Height = 1;
41 pstSoftWareParam->stDstRoi.unShape.stWhc.u32Width = u32ClassNum*pstSoftWareParam->u32MaxRoiNum*SAMPLE_SVP_NNIE_COORDI_NUM;
42
43 pstSoftWareParam->stDstScore.enType = SVP_BLOB_TYPE_S32;
44 pstSoftWareParam->stDstScore.u64PhyAddr = u64PhyAddr+u32RpnTmpBufSize+u32RpnBboxBufSize+u32GetResultTmpBufSize+u32DstRoiSize;
45 pstSoftWareParam->stDstScore.u64VirAddr = (HI_U64)(pu8VirAddr+u32RpnTmpBufSize+u32RpnBboxBufSize+u32GetResultTmpBufSize+u32DstRoiSize);
46 pstSoftWareParam->stDstScore.u32Stride = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum*pstSoftWareParam->u32MaxRoiNum*sizeof(HI_U32));
47 pstSoftWareParam->stDstScore.u32Num = 1;
48 pstSoftWareParam->stDstScore.unShape.stWhc.u32Chn = 1;
49 pstSoftWareParam->stDstScore.unShape.stWhc.u32Height = 1;
50 pstSoftWareParam->stDstScore.unShape.stWhc.u32Width = u32ClassNum*pstSoftWareParam->u32MaxRoiNum;
51
52 pstSoftWareParam->stClassRoiNum.enType = SVP_BLOB_TYPE_S32;
53 pstSoftWareParam->stClassRoiNum.u64PhyAddr = u64PhyAddr+u32RpnTmpBufSize+u32RpnBboxBufSize+u32GetResultTmpBufSize+u32DstRoiSize+u32DstScoreSize;
54 pstSoftWareParam->stClassRoiNum.u64VirAddr = (HI_U64)(pu8VirAddr+u32RpnTmpBufSize+u32RpnBboxBufSize+u32GetResultTmpBufSize+u32DstRoiSize+u32DstScoreSize);
55 pstSoftWareParam->stClassRoiNum.u32Stride = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum*sizeof(HI_U32));
56 pstSoftWareParam->stClassRoiNum.u32Num = 1;
57 pstSoftWareParam->stClassRoiNum.unShape.stWhc.u32Chn = 1;
58 pstSoftWareParam->stClassRoiNum.unShape.stWhc.u32Height = 1;
59 pstSoftWareParam->stClassRoiNum.unShape.stWhc.u32Width = u32ClassNum;

  pstSoftWareParam(s_stRfcnSoftwareParam)参数的大量赋值完成上述操作后,为后续NNIE thread work函数SAMPLE_SVP_NNIE_Rfcn_ViToVo提供参数,如下所示:

1     pstParam = &s_stRfcnNnieParam;  //SAMPLE_SVP_NNIE_Rfcn_ViToVo函数内进行再赋值操作
2 pstSwParam = &s_stRfcnSoftwareParam;

  到此为止,RFCN LoadModel与RFCN NNIE初始化函数分析已经完成。

 

Hi3559AV100 NNIE开发(2)-RFCN(.wk)LoadModel及NNIE Init函数运行过程分析的更多相关文章

  1. Hi3559AV100 NNIE开发(4)mobilefacenet.cfg参数配置挖坑解决与SVP_NNIE_Cnn实现分析

    前面随笔给出了NNIE开发的基本知识,下面几篇随笔将着重于Mobilefacenet NNIE开发,实现mobilefacenet.wk的chip版本,并在Hi3559AV100上实现mobilefa ...

  2. Hi3359AV100 NNIE开发(1)-RFCN demo LoadModel函数与参数解析

    之后随笔将更多笔墨着重于NNIE开发系列,下文是关于Hi3359AV100 NNIE开发(1)-RFCN demo LoadModel函数与参数解析,通过对LoadModel函数的解析,能够很好理解. ...

  3. Hi3559AV100 NNIE开发(6)RFCN中NNIE实现关键线程函数->SAMPLE_SVP_NNIE_Rfcn_ViToVo()进行数据流分析

    前面随笔给出了NNIE开发的基本知识,下面几篇随笔将着重于Mobilefacenet NNIE开发,实现mobilefacenet.wk的chip版本,并在Hi3559AV100上实现mobilefa ...

  4. Hi3559AV100 NNIE开发(3)RuyiStudio软件 .wk文件生成过程-mobilefacenet.cfg的参数配置

    之后随笔将更多笔墨着重于NNIE开发系列,下文是关于Hi3559AV100 NNIE开发(3)RuyiStudio软件 .wk文件生成过程-mobilefacenet.cfg的参数配置,目前项目需要对 ...

  5. Hi3559AV100 NNIE开发(5)mobilefacenet.wk仿真成功量化及与CNN_convert_bin_and_print_featuremap.py输出中间层数据对比过程

    前面随笔给出了NNIE开发的基本知识,下面几篇随笔将着重于Mobilefacenet NNIE开发,实现mobilefacenet.wk的chip版本,并在Hi3559AV100上实现mobilefa ...

  6. Hi3559AV100 NNIE开发(7) Ruyistudio 输出mobileface_func.wk与板载运行mobileface_chip.wk输出中间层数据对比

    前面随笔讲了关于NNIE的整个开发流程,并给出了Hi3559AV100 NNIE开发(5)mobilefacenet.wk仿真成功量化及与CNN_convert_bin_and_print_featu ...

  7. 基于Hi3559AV100的SVP(NNIE)开发整体流程

    在之后的hi3559AV100板载开发中,除了走通V4L2->VDEC->VPSS->VO(HDMI)输出,还有需要进行神经网络的开发学习,进行如face detection的开发等 ...

  8. C#开发Windows服务 附简单实例实现禁止QQ运行

    本实例主要实现下面三个基本功能 1.C#开发windows服务 2.禁止QQ等程序运行 3.为windows服务创建自动安装程序 下面针对这三个基本功能进行实现 一.C#开发windows服务 Win ...

  9. Android开发 ---从互联网上下载文件,回调函数,图片压缩、倒转

     Android开发 ---从互联网上下载文件,回调函数,图片压缩.倒转 效果图: 描述: 当点击“下载网络图像”按钮时,系统会将图二中的照片在互联网上找到,并显示在图像框中 注意:这个例子并没有将图 ...

随机推荐

  1. Codeforces Round #649 (Div. 2) A. XXXXX (贪心)

    题意:有一个长度为\(n\)的数组,找一段最长子数组,使得其元素和为\(x\),如果存在,输出子数组的长度,否则输出\(-1\). 题解:这题我们要从元素和\(sum\)来考虑,首先,如果原数组的所有 ...

  2. Windows Terminal 更换主题

    1. 打开设置,是个json文件 2. 在此处获取主题配置:https://atomcorp.github.io/themes/ 3.将主题配置粘贴到schemes节点(可以增加N个) 4.配置每个命 ...

  3. httprunner(8)用例调用-RunTestCase

    前言 一般我们写接口自动化的时候,遇到复杂的逻辑,都会调用API方法来满足前置条件,Pytest的特性是无法用例之间相互调动的,我们一般只调用自己封装的API方法. 而httprunner支持用例之间 ...

  4. MySQL数据库系列(四)- InnoDB下的共享表空间和独立表空间详解

    一.概念 共享表空间: Innodb的所有数据保存在一个单独的表空间里面,而这个表空间可以由很多个文件组成,一个表可以跨多个文件存在,所以其大小限制不再是文件大小的限制,而是其自身的限制.从Innod ...

  5. Jenkins管理员密码忘记修改操作

    一.Jenkins管理员密码忘记 当jenkins忘记了管理用户的密码时,只能通过修改配置文件并重启的方式初始化设置用户名及密码,操作如下: [root@localhost jenkins]# vim ...

  6. C++中的explicit

    首先, C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数 ...

  7. filter_var 函数()绕过执行命令

    escape 过滤器来过滤link,而实际上这里的 escape 过滤器,是用PHP内置函数 htmlspecialchars 来实现的 htmlspecialchars 函数定义如下: htmlsp ...

  8. 使用 js 实现十大排序算法: 插入排序

    使用 js 实现十大排序算法: 插入排序 插入排序 // 双重循环 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  9. Xcode show whitespace

    Xcode show whitespace Xcode 11.5 how to config Xcode show whitespace 如何配置 Xcode 显示空白字符 Editor -> ...

  10. CSS 设置多行文本省略号 ...

    CSS 设置多行文本省略号 ... .box{ display: -webkit-box; overflow: hidden; text-overflow: ellipsis; word-wrap: ...