前面随笔给出了NNIE开发的基本知识,下面几篇随笔将着重于Mobilefacenet NNIE开发,实现mobilefacenet.wk的chip版本,并在Hi3559AV100上实现mobilefacenet网络功能,外接USB摄像头通过MPP平台输出至VO HDMI显示结果。下文是Hi3559AV100 NNIE开发(4)mobilefacenet.cfg参数配置挖坑解决与SVP_NNIE_Cnn实现分析,目前项目需要对mobilefacenet网络进行.wk的开发,下面给出在.wk生成过程中遇到的坑与解决方式,并给出SVP_NNIE_Cnn整体实现的各个step分析,为后面在板载上实现mobilefacenet网络打下基础。

1、mobilefacenet.cfg参数配置挖坑解决

  CNN_convert_bin_and_print_featuremap.py和Get Caffe Output这里的预处理方式都是先乘以【data_scale】,再减均值【mean_file】,而在量化生成 .mk 文件时却是先减均值再乘以scale的。

  给出预处理这一个环节对输入数据data的处理方式:

1     data = inputs
2 if norm_type == '4' or norm_type == '5':
3 data = data * float(data_scale)

  data是uint8类型的array,是先乘以了【data_scale】的,也就是说和NNIE 生成wk中的操作顺序是不一致的,对于mobilefacenet.cfg网络输入数据预处理方法时,当norm_type = 5时,输入数据减通道均值后再乘以 data_scale,如下所示:

  所在在实际操作中,需要对均值文件进行处理,转换方式如下:

 (data - 128.0) * 0.0078125 <==> data * 0.0078125 - 1

  因此这里需要做的修改就是需要将【mean_file】pixel_mean_compare.txt修设置为1.0:

  最终生成mobilefacenet.wk,结果如下所示,具体的测试需要下一步进行。

 1 begin parameter compressing....
2
3 end parameter compressing
4
5 begin compress index generating....
6
7 end compress index generating
8
9 begin binary code generating....
10
11 .........................................................................................................................
12 ....................................................................end binary code generating
13
14 begin quant files writing....
15
16 end quant files writing
17
18 .
19 ===============D:\Hi3559_NNIE\3559\mobileface\mobileface.cfg Successfully!===============
20
21 End [RuyiStudio Wk NNIE Mapper] [D:\Hi3559_NNIE\3559\mobileface\mobileface.cfg] mobileface

2、SVP_NNIE_Cnn实现分析

  下面给出SAMPLE_SVP_NNIE_Cnn函数的执行过程,主要分为下面八个步骤:

 1     HI_CHAR *pcSrcFile = "./data/nnie_image/y/0_28x28.y";
2 HI_CHAR *pcModelName = "./data/nnie_model/classification/inst_mnist_cycle.wk";
3
4
5 /*Set configuration parameter */
6 stNnieCfg.pszPic= pcSrcFile;
7 stNnieCfg.u32MaxInputNum = u32PicNum; //max input image num in each batch
8 stNnieCfg.u32MaxRoiNum = 0;
9 stNnieCfg.aenNnieCoreId[0] = SVP_NNIE_ID_0;//set NNIE core
10 s_stCnnSoftwareParam.u32TopN = 5;
11
12
13
14 /*Sys init ---step1*/
15 SAMPLE_COMM_SVP_CheckSysInit();
16
17 /*CNN Load model ------step2*/
18 s32Ret = SAMPLE_COMM_SVP_NNIE_LoadModel(pcModelName,&s_stCnnModel);
19
20
21 /*CNN parameter initialization -------step3*/
22 /*Cnn software parameters are set in SAMPLE_SVP_NNIE_Cnn_SoftwareParaInit,
23 if user has changed net struct, please make sure the parameter settings in
24 SAMPLE_SVP_NNIE_Cnn_SoftwareParaInit function are correct*/
25 s_stCnnNnieParam.pstModel = &s_stCnnModel.stModel;
26 s32Ret = SAMPLE_SVP_NNIE_Cnn_ParamInit(&stNnieCfg,&s_stCnnNnieParam,&s_stCnnSoftwareParam);
27
28
29 /*record tskBuf -------step4*/
30 s32Ret = HI_MPI_SVP_NNIE_AddTskBuf(&(s_stCnnNnieParam.astForwardCtrl[0].stTskBuf));
31
32
33 /*Fill src data -------step5*/
34 SAMPLE_SVP_TRACE_INFO("Cnn start!\n");
35 stInputDataIdx.u32SegIdx = 0;
36 stInputDataIdx.u32NodeIdx = 0;
37 s32Ret = SAMPLE_SVP_NNIE_FillSrcData(&stNnieCfg,&s_stCnnNnieParam,&stInputDataIdx);
38
39
40 /*NNIE process(process the 0-th segment) -------step6*/
41 stProcSegIdx.u32SegIdx = 0;
42 s32Ret = SAMPLE_SVP_NNIE_Forward(&s_stCnnNnieParam,&stInputDataIdx,&stProcSegIdx,HI_TRUE);
43
44
45
46 /*Software process --------step7*/
47 /*if user has changed net struct, please make sure SAMPLE_SVP_NNIE_Cnn_GetTopN
48 function's input datas are correct*/
49 s32Ret = SAMPLE_SVP_NNIE_Cnn_GetTopN(&s_stCnnNnieParam,&s_stCnnSoftwareParam);
50
51
52
53 /*Print result --------step8*/
54 SAMPLE_SVP_TRACE_INFO("Cnn result:\n");
55 s32Ret = SAMPLE_SVP_NNIE_Cnn_PrintResult(&(s_stCnnSoftwareParam.stGetTopN),
56 s_stCnnSoftwareParam.u32TopN);

  (1)step1为SAMPLE_COMM_SVP_CheckSysInit(),完成的是MPP系统的初始化,主要实现的是Sys_Init和VB_Init,实现MPP内存池的配置,具体实现如下:

 1 HI_VOID SAMPLE_COMM_SVP_CheckSysInit(HI_VOID)
2 {
3 ..............
4 SAMPLE_COMM_SVP_SysInit()
5 {
6 //省略了部分过程,列出实现关键函数
7 HI_MPI_SYS_Exit();
8 HI_MPI_VB_Exit();
9
10 memset(&struVbConf,0,sizeof(VB_CONFIG_S));
11
12 struVbConf.u32MaxPoolCnt = 2;
13 struVbConf.astCommPool[1].u64BlkSize = 768*576*2;
14 struVbConf.astCommPool[1].u32BlkCnt = 1;
15
16 s32Ret = HI_MPI_VB_SetConfig((const VB_CONFIG_S *)&struVbConf); //设置MPP视频缓存池属性
17
18
19 s32Ret = HI_MPI_VB_Init(); //初始化MPP缓存池
20
21
22 s32Ret = HI_MPI_SYS_Init(); //初始化MPP系统
23
24 }
25
26 .............
27 }

  (2)step2为SAMPLE_COMM_SVP_NNIE_LoadModel(pcModelName,&s_stCnnModel)从用户事先加载到 buf 中的模型中解析出网络模型,其函数实现较为复杂,具体的函数参数解析和函数运行过程已经在前面随笔给出了,需要的话,可以参考随笔:

  Hi3559AV100 NNIE开发(1)-RFCN(.wk)LoadModel函数参数解析 (https://www.cnblogs.com/iFrank/p/14500648.html)

  Hi3559AV100 NNIE开发(2)-RFCN(.wk)LoadModel及NNIE Init函数运行过程分析   (https://www.cnblogs.com/iFrank/p/14503482.html)

  (3)step3为SAMPLE_SVP_NNIE_Cnn_ParamInit,首先给出调用与定义,便于分析:

 1 /*Set configuration parameter*/
2 stNnieCfg.pszPic= pcSrcFile;
3 stNnieCfg.u32MaxInputNum = u32PicNum; //max input image num in each batch
4 stNnieCfg.u32MaxRoiNum = 0;
5 stNnieCfg.aenNnieCoreId[0] = SVP_NNIE_ID_0;//set NNIE core
6
7 s_stCnnSoftwareParam.u32TopN = 5;
8
9 s_stCnnNnieParam.pstModel = &s_stCnnModel.stModel;
10 s32Ret = SAMPLE_SVP_NNIE_Cnn_ParamInit(&stNnieCfg,
11 &s_stCnnNnieParam,
12 &s_stCnnSoftwareParam);
13
14
15
16 static HI_S32 SAMPLE_SVP_NNIE_Cnn_ParamInit(SAMPLE_SVP_NNIE_CFG_S* pstNnieCfg,
17 SAMPLE_SVP_NNIE_PARAM_S *pstCnnPara,
18 SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S* pstCnnSoftWarePara)
19 {
20 ........
21
22 /*init hardware para*/
23 s32Ret = SAMPLE_COMM_SVP_NNIE_ParamInit(pstNnieCfg,
24 pstCnnPara);
25
26
27 /*init software para*/
28 if(pstCnnSoftWarePara!=NULL)
29 {
30 s32Ret = SAMPLE_SVP_NNIE_Cnn_SoftwareParaInit(pstNnieCfg,
31 pstCnnPara,
32 pstCnnSoftWarePara);
33 "Error(%#x),SAMPLE_SVP_NNIE_Cnn_SoftwareParaInit failed!\n",s32Ret);
34 }
35
36 ........
37 }

  其中SAMPLE_COMM_SVP_NNIE_ParamInit函数及参数分析可见之前随笔:

  Hi3559AV100 NNIE开发(2)-RFCN(.wk)LoadModel及NNIE Init函数运行过程分析   (https://www.cnblogs.com/iFrank/p/14503482.html),之前的随笔介绍的很详细,这里就不在赘述了。

  对SAMPLE_SVP_NNIE_Cnn_SoftwareParaInit函数,首先给出定义:

 1 static HI_S32 SAMPLE_SVP_NNIE_Cnn_SoftwareParaInit(
2 SAMPLE_SVP_NNIE_CFG_S* pstNnieCfg,
3 SAMPLE_SVP_NNIE_PARAM_S *pstCnnPara,
SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S* pstCnnSoftWarePara)
4 {
5 HI_U32 u32GetTopNMemSize = 0;
6 HI_U32 u32GetTopNAssistBufSize = 0;
7 HI_U32 u32GetTopNPerFrameSize = 0;
8 HI_U32 u32TotalSize = 0;
9 HI_U32 u32ClassNum = pstCnnPara->pstModel->astSeg[0].astDstNode[0].unShape.stWhc.u32Width;
10 HI_U64 u64PhyAddr = 0;
11 HI_U8* pu8VirAddr = NULL;
12 HI_S32 s32Ret = HI_SUCCESS;
13
14 /*get mem size*/
15 u32GetTopNPerFrameSize = pstCnnSoftWarePara->u32TopN*sizeof(SAMPLE_SVP_NNIE_CNN_GETTOPN_UNIT_S);
16 u32GetTopNMemSize = SAMPLE_SVP_NNIE_ALIGN16(u32GetTopNPerFrameSize)*pstNnieCfg->u32MaxInputNum;
17 u32GetTopNAssistBufSize = u32ClassNum*sizeof(SAMPLE_SVP_NNIE_CNN_GETTOPN_UNIT_S);
18 u32TotalSize = u32GetTopNMemSize+u32GetTopNAssistBufSize;
19
20 /*malloc mem*/
21 s32Ret = SAMPLE_COMM_SVP_MallocMem("SAMPLE_CNN_INIT",NULL,(HI_U64*)&u64PhyAddr,
22 (void**)&pu8VirAddr,u32TotalSize);
23 SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,
24 "Error,Malloc memory failed!\n");
25 memset(pu8VirAddr, 0, u32TotalSize);
26
27 /*init GetTopn */
28 pstCnnSoftWarePara->stGetTopN.u32Num= pstNnieCfg->u32MaxInputNum;
29 pstCnnSoftWarePara->stGetTopN.unShape.stWhc.u32Chn = 1;
30 pstCnnSoftWarePara->stGetTopN.unShape.stWhc.u32Height = 1;
31 pstCnnSoftWarePara->stGetTopN.unShape.stWhc.u32Width = u32GetTopNPerFrameSize/sizeof(HI_U32);
32 pstCnnSoftWarePara->stGetTopN.u32Stride = SAMPLE_SVP_NNIE_ALIGN16(u32GetTopNPerFrameSize);
33 pstCnnSoftWarePara->stGetTopN.u64PhyAddr = u64PhyAddr;
34 pstCnnSoftWarePara->stGetTopN.u64VirAddr = (HI_U64)pu8VirAddr;
35
36 /*init AssistBuf */
37 pstCnnSoftWarePara->stAssistBuf.u32Size = u32GetTopNAssistBufSize;
38 pstCnnSoftWarePara->stAssistBuf.u64PhyAddr = u64PhyAddr+u32GetTopNMemSize;
39 pstCnnSoftWarePara->stAssistBuf.u64VirAddr = (HI_U64)pu8VirAddr+u32GetTopNMemSize;
40
41 return s32Ret;
42 }

  函数体内最主要功能是实现s_stCnnSoftwareParam参数的赋值,包含大量赋值语句,其中s_stCnnSoftwareParam结构体各个元素赋值的意义等需要的时候再进行研讨,此外函数还实现在用户态分配 MMZ 内存。通过对两个函数的分析,step3 SAMPLE_SVP_NNIE_Cnn_ParamInit()完成。

(4)step4为HI_MPI_SVP_NNIE_AddTskBuf,为了记录 TskBuf 地址信息,其作用和注意事项:

  ①记录 TskBuf 地址信息,用于减少内核态内存映射次数,提升效率;

  ②TskBuf 地址信息的记录是通过链表进行管理,链表长度默认值为 32,链表长度可通过模块参数 nnie_max_tskbuf_num 进行配;

  ③若没调用 HI_MPI_SVP_NNIE_AddTskBuf 预先把 TskBuf 地址信息记录到系统,那么之后调用 Forward/ForwardWithBbox 每次都会 Map/Unmap 操作 TskBuf 内核态虚拟地址,效率会比较低。  

  给出函数调用和定义:

1 /*SAMPLE_COMM_SVP_NNIE_LoadModel(pcModelName,&s_stCnnModel);*/
2 s_stCnnNnieParam.pstModel = &s_stCnnModel.stModel;
3
4 s32Ret = HI_MPI_SVP_NNIE_AddTskBuf(&(s_stCnnNnieParam.astForwardCtrl[0].stTskBuf));
5
6
7 //定义
8 HI_S32 HI_MPI_SVP_NNIE_AddTskBuf(const SVP_MEM_INFO_S* pstTskBuf);

(5)step5为SAMPLE_SVP_NNIE_FillSrcData,实现src数据的填充,此函数十分关键,对所给图像数据:./data/nnie_image/y/0_28x28.y进行处理,为了更好的分析数据处理函数,首先给出函数调用信息:

 1     stNnieCfg.pszPic= pcSrcFile;
2 stNnieCfg.u32MaxInputNum = u32PicNum; //max input image num in each batch
3 stNnieCfg.u32MaxRoiNum = 0;
4 stNnieCfg.aenNnieCoreId[0] = SVP_NNIE_ID_0;//set NNIE core
5
6 /*SAMPLE_COMM_SVP_NNIE_LoadModel(pcModelName,&s_stCnnModel);*/
7 s_stCnnNnieParam.pstModel = &s_stCnnModel.stModel;
8
9 stInputDataIdx.u32SegIdx = 0;
10 stInputDataIdx.u32NodeIdx = 0;
11 s32Ret = SAMPLE_SVP_NNIE_FillSrcData(&stNnieCfg,
                          &s_stCnnNnieParam,
                          &stInputDataIdx);

  为了更加清楚函数功能,先给出函数定义,方便后面分析(忽略一些次要信息):

  1 static HI_S32 SAMPLE_SVP_NNIE_FillSrcData(SAMPLE_SVP_NNIE_CFG_S* pstNnieCfg,
2 SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam,
3 SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S* pstInputDataIdx)

  总的来说,函数实现以下功能:

  ①open file fopen(pstNnieCfg->pszPic,"rb");

 1 //定义文件名
2 HI_CHAR *pcSrcFile = "./data/nnie_image/y/0_28x28.y";
3
4 stNnieCfg.pszPic= pcSrcFile;
5
6 //函数定义
7 HI_S32 SAMPLE_SVP_NNIE_FillSrcData(SAMPLE_SVP_NNIE_CFG_S* pstNnieCfg,
8 SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam,
9 SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S* pstInputDataIdx)
10 //函数调用
11 SAMPLE_SVP_NNIE_FillSrcData(&stNnieCfg,
12 &s_stCnnNnieParam,
13 &stInputDataIdx);
14
15 fp = fopen(pstNnieCfg->pszPic,"rb");

  ②为后面fread读取数据量确定u32VarSize大小:

 1     /*get data size   s32Ret = fread(pu8PicAddr,u32Dim*u32VarSize,1,fp);*/
2 if(SVP_BLOB_TYPE_U8 <= pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].enType &&
3 SVP_BLOB_TYPE_YVU422SP >= pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].enType)
4 {
5 u32VarSize = sizeof(HI_U8);
6 }
7 else
8 {
9 u32VarSize = sizeof(HI_U32);
10 }

  ③随即通过pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].enType参数(参数找定义,应该是与输入模型.wk的模型参数有关,后面可以直接通过printf进行打印输出,看结果是啥)进行if-lese分支选择,之后通过fread对fp文件指针读取数据,确定数据内存地址,并刷新 cache 里的内容到内存并且使 cache 里的内容无效,最后fclose(fp)。

  先给出enType参数类型:

  代码实现:

 1     /*fill src data*/
2 if(SVP_BLOB_TYPE_SEQ_S32 == pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].enType)
3 {
4 u32Dim = pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].unShape.stSeq.u32Dim;
5 u32Stride = pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u32Stride;
6 pu32StepAddr = (HI_U32*)(pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].unShape.stSeq.u64VirAddrStep);
7 pu8PicAddr = (HI_U8*)(pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u64VirAddr);
8 for(n = 0; n < pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u32Num; n++)
9 {
10 for(i = 0;i < *(pu32StepAddr+n); i++)
11 {
12 s32Ret = fread(pu8PicAddr,u32Dim*u32VarSize,1,fp);
13 SAMPLE_SVP_CHECK_EXPR_GOTO(1 != s32Ret,FAIL,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error,Read image file failed!\n");
14 pu8PicAddr += u32Stride;
15 }
16 u32TotalStepNum += *(pu32StepAddr+n);
17 }
18 SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u64PhyAddr,
19 (HI_VOID *) pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u64VirAddr,
20 u32TotalStepNum*u32Stride);
21 }
22 else
23 {
24 u32Height = pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].unShape.stWhc.u32Height;
25 u32Width = pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].unShape.stWhc.u32Width;
26 u32Chn = pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].unShape.stWhc.u32Chn;
27 u32Stride = pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u32Stride;
28 pu8PicAddr = (HI_U8*)(pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u64VirAddr);
29 if(SVP_BLOB_TYPE_YVU420SP== pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].enType)
30 {
31 for(n = 0; n < pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u32Num; n++)
32 {
33 for(i = 0; i < u32Chn*u32Height/2; i++)
34 {
35 s32Ret = fread(pu8PicAddr,u32Width*u32VarSize,1,fp);
36 SAMPLE_SVP_CHECK_EXPR_GOTO(1 != s32Ret,FAIL,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error,Read image file failed!\n");
37 pu8PicAddr += u32Stride;
38 }
39 }
40 }
41 else if(SVP_BLOB_TYPE_YVU422SP== pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].enType)
42 {
43 for(n = 0; n < pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u32Num; n++)
44 {
45 for(i = 0; i < u32Height*2; i++)
46 {
47 s32Ret = fread(pu8PicAddr,u32Width*u32VarSize,1,fp);
48 SAMPLE_SVP_CHECK_EXPR_GOTO(1 != s32Ret,FAIL,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error,Read image file failed!\n");
49 pu8PicAddr += u32Stride;
50 }
51 }
52 }
53 else
54 {
55 for(n = 0; n < pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u32Num; n++)
56 {
57 for(i = 0;i < u32Chn; i++)
58 {
59 for(j = 0; j < u32Height; j++)
60 {
61 s32Ret = fread(pu8PicAddr,u32Width*u32VarSize,1,fp);
62 SAMPLE_SVP_CHECK_EXPR_GOTO(1 != s32Ret,FAIL,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error,Read image file failed!\n");
63 pu8PicAddr += u32Stride;
64 }
65 }
66 }
67 }
68 SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u64PhyAddr,
69 (HI_VOID *) pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u64VirAddr,
70 pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u32Num*u32Chn*u32Height*u32Stride);
71 }
72
73 fclose(fp);

(6)step6为SAMPLE_SVP_NNIE_Forward实现NNIE process,便于分析先给出函数的调用及参数的定义:

 1     s_stCnnNnieParam.pstModel = &s_stCnnModel.stModel;
2 /* SAMPLE_COMM_SVP_NNIE_LoadModel(pcModelName,&s_stCnnModel); */
3
4 stInputDataIdx.u32SegIdx = 0;
5 stInputDataIdx.u32NodeIdx = 0;
6
7 stProcSegIdx.u32SegIdx = 0;
8
9 s32Ret = SAMPLE_SVP_NNIE_Forward(&s_stCnnNnieParam,
10 &stInputDataIdx,
11 &stProcSegIdx,
12 HI_TRUE);
13
14 static HI_S32 SAMPLE_SVP_NNIE_Forward(
15 SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam,
16 SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S* pstInputDataIdx,
17 SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S* pstProcSegIdx,
18 HI_BOOL bInstant)

  SAMPLE_SVP_NNIE_Forward中①SAMPLE_COMM_SVP_FlushCache函数主要实现将内存数据刷新到内存中;②HI_MPI_SVP_NNIE_Forward函数同时对输入样本(s)进行CNN预测,对对应样本(s)进行输出响应;③HI_MPI_SVP_NNIE_Query函数用于查询nnie上运行函数的状态,在阻塞模式下,系统等待,直到被查询的函数被调用;在非阻塞模式下,查询当前状态,不做任何操作。

(7)step7为SAMPLE_SVP_NNIE_Cnn_GetTopN实现软件过程,给出函数调用与参数细节:

 1     s_stCnnNnieParam.pstModel = &s_stCnnModel.stModel;
2 /* SAMPLE_COMM_SVP_NNIE_LoadModel(pcModelName,&s_stCnnModel); */
3
4 s_stCnnSoftwareParam.u32TopN = 5;
5 SAMPLE_SVP_NNIE_Cnn_ParamInit(&stNnieCfg, //通过此函数对s_stCnnSoftwareParam进行了赋值操作
6 &s_stCnnNnieParam,
7 &s_stCnnSoftwareParam);
8
9 s32Ret = SAMPLE_SVP_NNIE_Cnn_GetTopN(&s_stCnnNnieParam,
10 &s_stCnnSoftwareParam);
11
12 HI_S32 SAMPLE_SVP_NNIE_Cnn_GetTopN(SAMPLE_SVP_NNIE_PARAM_S*pstNnieParam,
13 SAMPLE_SVP_NNIE_CNN_SOFTWARE_PARAM_S* pstSoftwareParam)

  此函数目前基本不修改,函数内部具体实现目前暂不说明,只需注意一点如果改变了网络结构,请确保SAMPLE_SVP_NNIE_Cnn_GetTopN

函数的输入数据正确。

(8)step8为SAMPLE_SVP_NNIE_Cnn_PrintResult打印blob参数值,给出函数调用与参数细节:

 1     s_stCnnNnieParam.pstModel = &s_stCnnModel.stModel;
2 /* SAMPLE_COMM_SVP_NNIE_LoadModel(pcModelName,&s_stCnnModel); */
3
4 s_stCnnSoftwareParam.u32TopN = 5;
5 SAMPLE_SVP_NNIE_Cnn_ParamInit(&stNnieCfg, //通过此函数对s_stCnnSoftwareParam进行了赋值操作
6 &s_stCnnNnieParam,
7 &s_stCnnSoftwareParam);
8
9 s32Ret = SAMPLE_SVP_NNIE_Cnn_PrintResult(&(s_stCnnSoftwareParam.stGetTopN),
10 s_stCnnSoftwareParam.u32TopN);
11
12 HI_S32 SAMPLE_SVP_NNIE_Cnn_PrintResult(SVP_BLOB_S *pstGetTopN,
13 HI_U32 u32TopN)

ps32GetTopN

Hi3559AV100 NNIE开发(4)mobilefacenet.cfg参数配置挖坑解决与SVP_NNIE_Cnn实现分析的更多相关文章

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

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

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

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

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

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

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

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

  5. Hi3559AV100 NNIE开发(2)-RFCN(.wk)LoadModel及NNIE Init函数运行过程分析

    之后随笔将更多笔墨着重于NNIE开发系列,下文是关于Hi3559AV100 NNIE开发(2)-RFCN(.wk)LoadModel及NNIE Init函数运行过程分析,通过对LoadModel函数及 ...

  6. 循序渐进VUE+Element 前端应用开发(33)--- 邮件参数配置和模板邮件发送处理

    在系统处理中,有时候需要发送邮件通知用户,如新增用户的邮件确认,密码找回,以及常规订阅消息.通知等内容处理,都可以通过邮件的方式进行处理.本篇随笔介绍结合VUE+Element 前端,实现系统的邮件参 ...

  7. windows下搭建eclipse关于python的开发环境及初始化参数配置

    1.安装jdk 因为eclipse是java开发的,运行eclipse程序需要安装jdk 安装jdk以后需要配置java_home环境变量 2.安装python2.7(比较简单,此处略) 3.下载ec ...

  8. Hi3559AV100 NNIE RFCN开发:V4L2->VDEC->VPSS->NNIE->VGS->VO系统整体动态调试实现

    下面随笔将给出Hi3559AV100 NNIE RFCN开发:V4L2->VDEC->VPSS->NNIE->VGS->VO系统整体动态调试实现,最终的效果是:USB摄像 ...

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

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

随机推荐

  1. Navicat 快捷键 for Mysql

     常用快捷键: 1. ctrl + q: 打开新查询窗口 2. ctrl + r: 运行当前窗口内的所有语句 3. ctrl + w: 关闭当前窗口 4. F6: 打开一个MySQL命令行窗口 5. ...

  2. Redis性能指标监控

    监控指标 •性能指标:Performance•内存指标: Memory•基本活动指标:Basic activity•持久性指标: Persistence•错误指标:Error 性能指标:Perform ...

  3. 初学算法之最基础的stl队列

    简记为先进先出(first in first out) 它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作. 实用: #include <queue>//头 ...

  4. zzuli-2259 matrix

    题目描述 在麦克雷的面前有N个数,以及一个R*C的矩阵.现在他的任务是从N个数中取出 R*C 个,并填入这个矩阵中.矩阵每一行的法值为本行最大值与最小值的差,而整个矩阵的法值为每一行的法值的最大值.现 ...

  5. 7816协议时序和采用UART模拟7816时序与智能卡APDU指令协议

    7816时序 7816时一个比较早的老通讯时序了,最近项目上需要用UART模拟所以,简单学习时序. 时序比较简单,熟悉UART的一眼看着就像是串口的时序,只是他没有停止位,取而代之的就是保护时间gur ...

  6. 011.NET5_MVC解读Razor混编

    MVC开发 1. 什么是MVC? V-视图,呈现给用户看到的内容---表现层 C-控制器,控制业务逻辑计算,可定义多种返回类型.可以是视图模型.JSON.字符串等等 M-视图模型,用于视图和控制之间传 ...

  7. Sentry 高级使用教程

    Sentry 高级使用教程 Sentry versions https://github.com/getsentry/sentry-docs https://github.com/getsentry/ ...

  8. Android Activity All In One

    Android Activity All In One Android Activity Lifecycle https://developer.android.com/reference/andro ...

  9. 来必力 & Disqus

    来必力 & Disqus 正在载入来必力 https://livere.com 个人博客-双评论系统(来必力与Disqus) https://tianbozhang.coding.me/com ...

  10. 抓手 & 技术管理

    抓手 & 技术管理 https://zhuanlan.zhihu.com/p/28891618 技术管理的目的 管理就是通过别人拿到结果.而管理的两个着眼点就是:成事.育人. 把事情搞定,把人 ...