之後隨筆將更多筆墨著重於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初始化函式分析已經完成。