前面随笔给出了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. HTTP笔记1--Web及网络基础

    web页面如何呈现? 客户端:通过发送请求获取服务器资源的 Web 浏览器 web是建立在 HTTP 协议上通信的   WWW(万维网/web)的构建技术 把 SGML(StandardGeneral ...

  2. EF Core数据访问入门

    重要概念 Entity Framework (EF) Core 是轻量化.可扩展.开源和跨平台的数据访问技术,它还是一 种对象关系映射器 (ORM),它使 .NET 开发人员能够使用面向对象的思想处理 ...

  3. pip&conda 换源

    PIP 各种可用源 清华源:https://pypi.tuna.tsinghua.edu.cn/simple 临时指定源 pip install -i https://pypi.tuna.tsingh ...

  4. windows 命令行 cmd 控制exe程序输入输出并比较

    参考 https://www.cnblogs.com/zccz14/p/4588634.html 例子: 对exe输入输出 使用fc比较不同

  5. 014.NET5_MVC_Razor扩展Html控件02

    第二种方法: 通过一个后台方法,返回一个不存在的html标签字符串,在读取的时候,通过后台方法去渲染成需要的标签和内容: 1. 定义一个普通类,类名称建议以TagHelper结尾,并且给类添加特性[H ...

  6. PWA All In One

    PWA All In One chrome://apps/ PWA Progressive Web App 可安装,添加到主屏 离线使用 轻量,快速 基于 Web 技术一套代码多端复用(移动端,桌面端 ...

  7. Awesome Gatsby blog websites

    Awesome Gatsby blog websites very simple very clean i18n dark mode (css var) demos https://overreact ...

  8. uname -a

    uname -a Linux shell command https://en.wikipedia.org/wiki/Uname#:~:text=uname $ uname # Darwin $ un ...

  9. Rust learning notes

    Rust learning notes Rust Version 1.42.0 $ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs ...

  10. fetch & form-data & upload & image file

    fetch & form-data & upload & image file no need multipart/form-data https://blog.xinshan ...