MC3302_SDK_V1.1.9_202507281.../media/sample/modules/npu/common.c
2025-11-11 12:08:31 +08:00

276 lines
8.8 KiB
C
Executable File

/**
* @file utils.cpp
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include "base.h"
#include "common.h"
#ifdef USEMOLCHIP
#include "mpi_sys.h"
#endif
#ifdef USEFULLHAN
#include "types/vmm_api.h"
#endif
// Fullhan vmm free interface will free all vmm memory, only really free at the last call
#ifdef DP2000
static uint32_t gVmmRefCnt = 0;
#endif
void printMemSegments(T_TY_MemSegmentInfo *ptrMemInfo){
char *allocTypeStr[] ={"NO_CACHED", "CACHED", "MALLOC"};
char *shareTypeStr[] ={"SHARED", "EXCLUSIVED"};
INFO_LOG("memory segment number:%d", ptrMemInfo->segNum);
int32_t idx=0;
for(;idx<ptrMemInfo->segNum; idx++){
INFO_LOG("seg:%d, size:%d align:%d allocType:%s shareType:%s v:%p phy:%p", idx,
ptrMemInfo->memInfo[idx].allocInfo.size,
ptrMemInfo->memInfo[idx].allocInfo.alignByteSize,
allocTypeStr[ptrMemInfo->memInfo[idx].allocInfo.allocType],
shareTypeStr[ptrMemInfo->memInfo[idx].allocInfo.shareType],
(void*)ptrMemInfo->memInfo[idx].mem.virAddr,
(void*)ptrMemInfo->memInfo[idx].mem.phyAddr
);
}
}
int32_t freeMem(uint64_t virAddr, uint64_t phyAddr, uint32_t size){
#ifndef DP2000
free((void*)virAddr);
#else
gVmmRefCnt--;
#ifdef USEFULLHAN
FH_SYS_VmmFreeOne64(phyAddr);
#endif
#ifdef USEMOLCHIP
FY_MPI_SYS_MmzFree(phyAddr, (void*)virAddr);
#endif
#endif
return 0;
}
int32_t flushVmmMem(uint64_t virAddr, uint64_t phyAddr, uint32_t size){
#ifndef DP2000
return 0;
#else
#ifdef USEFULLHAN
int32_t ret = FH_SYS_VmmFlushCache64(phyAddr, (void*)virAddr, size);
#endif
#ifdef USEMOLCHIP
int32_t ret = FY_MPI_SYS_MmzFlushCache(phyAddr, (void*)virAddr, size);
#endif
return ret;
#endif
}
int32_t mallocMem(void **ppVirAddr, uint64_t *ptrPhyAddr, uint32_t size, uint32_t align, E_TY_MemAllocType type){
// int ret;
#ifndef DP2000
*ppVirAddr = aligned_alloc(align, size);
*ptrPhyAddr= (uint64_t)*ppVirAddr;
#else
switch(type){
case E_TY_MEM_VMM_NO_CACHED:
#ifdef USEFULLHAN
FH_SYS_VmmAllocEx64(ptrPhyAddr, ppVirAddr, "IVE", "anonymous", size, align);
#endif
#ifdef USEMOLCHIP
FY_MPI_SYS_MmzAlloc(ptrPhyAddr, ppVirAddr, "IVE", "anonymous", size);
#endif
gVmmRefCnt++;
break;
case E_TY_MEM_VMM_CACHED:
#ifdef USEFULLHAN
FH_SYS_VmmAllocEx_Cached64(ptrPhyAddr, ppVirAddr, "IVE", "anonymous", size, align);
FH_SYS_VmmFlushCache64(*ptrPhyAddr, *ppVirAddr, size);
#endif
#ifdef USEMOLCHIP
ret = FY_MPI_SYS_MmzAlloc_Cached(ptrPhyAddr, ppVirAddr, "TY", "anonymous", size);
ret = FY_MPI_SYS_MmzFlushCache(*ptrPhyAddr, *ppVirAddr, size);
#endif
gVmmRefCnt++;
break;
case E_TY_MEM_MALLOC:
posix_memalign(ppVirAddr, align, size);
*ptrPhyAddr= (uint64_t)((*ppVirAddr));
break;
default:
ERROR_LOG("allocType error, %d", type);
*ppVirAddr = NULL;
*ptrPhyAddr= 0;
break;
}
#endif
return 0;
}
int32_t freeMemSegments(T_TY_MemSegmentInfo *ptrMemInfo){
INFO_LOG("memory segment number:%d", ptrMemInfo->segNum);
int32_t idx=0;
for(; idx<ptrMemInfo->segNum; idx++){
freeMem(ptrMemInfo->memInfo[idx].mem.virAddr, ptrMemInfo->memInfo[idx].mem.phyAddr, ptrMemInfo->memInfo[idx].mem.size);
}
return 0;
}
int32_t allocMemSegments(T_TY_MemSegmentInfo *ptrMemInfo){
INFO_LOG("memory segment number:%d", ptrMemInfo->segNum);
int32_t idx=0;
for(; idx<ptrMemInfo->segNum; idx++){
void **ppVirAddr = (void**)&ptrMemInfo->memInfo[idx].mem.virAddr;
uint64_t *ptrPhyAddr = &ptrMemInfo->memInfo[idx].mem.phyAddr;
uint32_t size = ptrMemInfo->memInfo[idx].allocInfo.size;
uint32_t align= ptrMemInfo->memInfo[idx].allocInfo.alignByteSize;
mallocMem(ppVirAddr, ptrPhyAddr, size, align, ptrMemInfo->memInfo[idx].allocInfo.allocType);
ptrMemInfo->memInfo[idx].mem.size = size;
}
return 0;
}
int32_t getImageSize(uint32_t width, uint32_t height, E_TY_PixelFormat fmt){
int32_t size =0;
switch(fmt){
case E_TY_PIXEL_FORMAT_U8C1:
size = width * height * 1;
break;
case E_TY_PIXEL_FORMAT_U16C1:
size = width * height * 2;
break;
case E_TY_PIXEL_FORMAT_YUV_SEMIPLANAR_420:
size = width * height * 3 /2;
break;
default:
size =0;
ERROR_LOG("not supported format %d", fmt);
break;
}
return size;
}
int32_t readFile(T_TY_Mem *ptrMem, char *path){
int32_t fileLen = GetFileSize(path);
if(fileLen != ptrMem->size){
ERROR_LOG("image size error, file size:%d, required:%d", fileLen, ptrMem->size);
return -1;
}
FILE *fp =fopen(path, "rb");
if(fp == NULL)
{
INFO_LOG("open input file %s, failed", path);
return -1;
}
#ifndef DP2000
fread((void*)ptrMem->virAddr, ptrMem->size, 1, fp);
INFO_LOG("load file to addr:%p, size %d, path:%s", (void*)ptrMem->virAddr, ptrMem->size, path);
#else
fread((void*)ptrMem->virAddr, ptrMem->size, 1, fp);
INFO_LOG("load file to addr:%p, size %d, path:%s", (void*)ptrMem->virAddr, ptrMem->size, path);
#endif
return 0;
}
int32_t writeFile(T_TY_Mem *ptrMem, char *path){
FILE *fp =fopen(path, "wb");
if(fp == NULL)
{
INFO_LOG("open output file %s, failed", path);
return -1;
}
#ifndef DP2000
fwrite((void*)ptrMem->virAddr, 1, ptrMem->size, fp);
INFO_LOG("write addr:%p, size %d, to path:%s", (void*)ptrMem->virAddr, ptrMem->size, path);
#else
fwrite((void*)(uint32_t)ptrMem->virAddr, 1, ptrMem->size, fp);
INFO_LOG("write addr:%p, size %d, to path:%s", (void*)(size_t)ptrMem->virAddr, ptrMem->size, path);
#endif
return 0;
}
int32_t readImage(T_TY_Image *img, char *imgPath){
uint32_t imgSize = getImageSize(img->desc.picFormat, img->desc.picWidthStride, img->desc.picHeightStride);
img->mem.size = imgSize;
readFile(&img->mem, imgPath);
return 0;
}
void printBlob(T_TY_BlobDesc *blob){
switch(blob->type){
case E_TY_BLOB_DATA:
INFO_LOG("BLOB Tensor");
INFO_LOG("tensor name:%s", blob->tensor.name);
INFO_LOG("tensor dataType:%d", blob->tensor.dataType);
INFO_LOG("tensor numDims:%d", blob->tensor.numDims);
#ifndef DP2000
INFO_LOG("tensor dims:[%ld, %ld, %ld, %ld, %ld]", blob->tensor.dims[0],
blob->tensor.dims[1],
blob->tensor.dims[2],
blob->tensor.dims[3],
blob->tensor.dims[4]);
#else
INFO_LOG("tensor dims:[%lld, %lld, %lld, %lld, %lld]",blob->tensor.dims[0],
blob->tensor.dims[1],
blob->tensor.dims[2],
blob->tensor.dims[3],
blob->tensor.dims[4]);
#endif
break;
case E_TY_BLOB_IMAGE:
INFO_LOG("BLOB Image");
break;
case E_TY_BLOB_IMAGE_WITH_PRE_PROC:
INFO_LOG("BLOB Image with pre proc");
default:
break;
}
}
uint32_t getBlobSize(T_TY_BlobDesc *blob){
int32_t byteUnitVec[] ={4, 2, 1, 4, 1, 2, 4, 8, 8, 1}; //对应E_TY_DataType
uint32_t blobByteSize = 0;
int32_t unitSize = byteUnitVec[blob->tensor.dataType];
int64_t unitNum = 1;
int32_t idx=0;
switch(blob->type){
case E_TY_BLOB_DATA:
idx=0;
for(; idx<blob->tensor.numDims; idx++){
unitNum *= blob->tensor.dims[idx];
}
blobByteSize = unitSize * unitNum;
break;
case E_TY_BLOB_IMAGE:
blobByteSize = 0;
break;
default:
blobByteSize = 0;
break;
}
return blobByteSize;
}
int32_t GetFileSize(char *path){
struct stat statbuf;
int ret = stat(path, &statbuf);
if(0 != ret){
ERROR_LOG("read file error, path:%s", path);
return 0;
}else{
return statbuf.st_size;
}
}