Hi3559AV100 NNIE開發(2)-RFCN(.wk)LoadModel及NNIE Init函數運行過程分析

  以後隨筆將更多筆墨着重於NNIE開發系列,下文是關於Hi3559AV100 NNIE開發(2)-RFCN(.wk)LoadModel及NNIE Init函數運行過程分析,經過對LoadModel函數及NNIE Init函數實現分析,結合上一篇隨筆對LoadModel函數參數挖掘,很大程度上可以理解NNIE初始化實現過程,並給其餘算法模型在NNIE移植提供參考,下面將給出RFCN Load_Model函數執行過程與NNIE_RFCN參數初始化過程。html

一、RFCN Load_Model函數執行過程

  pszModelFile是導入目標檢測方法RFCN .wk模型的位置與文件名,pstNnieModel結構的詳細解析已經經過上一篇隨筆(Hi3359AV100 NNIE開發(1)-RFCN(.wk)LoadModel函數參數解析 :https://www.cnblogs.com/iFrank/p/14500648.html)給出。node

  而在RFCN demo中把RFCN的.wk模型文件經過函數導出模型參數,具體調用以下所示:ios

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爲例進行細節說明的,此處與文檔匹配)的信息以下:
ide

 二、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。spa

  RFCN NNIE初始化函數分爲SAMPLE_COMM_SVP_NNIE_ParamInit(初始化硬件參數)與SAMPLE_SVP_NNIE_Rfcn_SoftwareInit(初始化軟件參數)兩個函數。指針

2.一、NNIE初始化下SAMPLE_COMM_SVP_NNIE_ParamInit實現分析

  首先看SAMPLE_COMM_SVP_NNIE_ParamInit:code

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.二、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初始化函數分析已經完成。

相關文章
相關標籤/搜索