×
分享到微信

打开微信,使用扫一扫进入页面后,点击右上角菜单,

点击“发送给朋友”或“分享到朋友圈”完成分享

关于视频流RTSP抓取图像进行在MLU220芯片盒子上进行推理的问题 官方回复 yinyin1234562022-04-20 09:53:25 回复 17 查看 技术答疑
关于视频流RTSP抓取图像进行在MLU220芯片盒子上进行推理的问题
分享到:

根据代码,如果读取视频流,每一帧传入设别的话都要进行离线模型加载,1、这样实时性是否存在问题? 2、能够只加载一次模型,后续无需加载,是否推理时间会更快?
离线模型推理代码如下:

int main(int argc,char *argv[])

{

    if(argc!=8)

    {

    printf("Usage:%s model_path function_name dev_id dev_channel image_path is_rgb label_filename\n",argv[0]);

    printf("\nex.  ./build/yolov5_offline_simple_demo model/yolov5.cambricon subnet0 0 0 data/000000000872.jpg 2 data/label_map_coco.txt\n\n");

    return -1;

    }


    unsigned int dev_num=0;


    CNRT_CHECK(cnrtInit(0));

    CNRT_CHECK(cnrtGetDeviceCount(&dev_num));

    if (dev_num == 0)

        return -1;


    const char*model_path=argv[1]; //模型路径

    const char *function_name=argv[2];//离线模型中的Function Name

    unsigned    dev_id=atoi(argv[3]);//使用的MLU 设备ID

    int dev_channel=atoi(argv[4]);//使用MLU设备的通道号 -1 为自动分配

    const char *image_path=argv[5];//测试图片的路径

    int                                 is_rgb=atoi(argv[6]);       //数据预处理选项

    string                              label_filename(argv[7]);    //label文件

    int     input_width;  //网络输入的宽度

    int     input_height; //网络输入的高度

    int             batch_size;  //网络的batch


    int64_t     *inputSizeS;  //网络输入数据大小,用于分配内存

    int64_t*outputSizeS; //网络输出数据量大小,用于分配内存


    cnrtDataType_t     *inputTypeS;//网络输入的数据类型

    cnrtDataType_t*outputTypeS;//网络输出的数据类型

    vector

    cnrtQueue_t     queue;//cnrt queue


    cnrtModel_t     model;//离线模型

    cnrtFunction_t     function;//离线模型中的Function

    cnrtDev_t dev;//MLU设备句柄

cnrtRuntimeContext_t ctx;//推理上下文


    int*dimValues;//保存维度shape

    int dimNum;//保存维度大小


    int inputNum;//输入节点个数

    int outputNum;//输出节点个数


    void **param;//保存推理时,mlu上内存地址的指针

    void **inputCpuPtrS;//输入数据的CPU指针

    void **outputCpuPtrS;//输出数据的CPU指针

void **outputCpuNchwPtrS;//用来保存transpose后的NCHW数据


    void **inputMluPtrS;//输入数据的MLU指针

    void **outputMluPtrS;//输出数据的MLU指针



//获取指定设备的句柄

    CNRT_CHECK(cnrtGetDeviceHandle(&dev, dev_id));


//设置当前使用的设备,作用于线程上下文

    CNRT_CHECK(cnrtSetCurrentDevice(dev));


//加载离线模型

    CNRT_CHECK(cnrtLoadModel(&model, model_path));


//创建function

    CNRT_CHECK(cnrtCreateFunction(&function));


//从离线模型中提取指定的function,离线模型可以存储多个function

    CNRT_CHECK(cnrtExtractFunction(&function, model, function_name));


//调用cnrtSetCurrentChannel之后 CNRT 仅在指定的通道上分配MLU内存,否则采用交织的方式分配

if(dev_channel>=0)

CNRT_CHECK(cnrtSetCurrentChannel((cnrtChannelType_t)dev_channel));


//创建运行时

CNRT_CHECK(cnrtCreateRuntimeContext(&ctx,function,NULL));


//设置运行时使用的设备ID

    CNRT_CHECK(cnrtSetRuntimeContextDeviceId(ctx,dev_id));


//初始化运行时

    CNRT_CHECK(cnrtInitRuntimeContext(ctx,NULL));


//创建队列

CNRT_CHECK(cnrtRuntimeContextCreateQueue(ctx,&queue));


//获取模型输入/输出 的数据大小及节点个数

CNRT_CHECK(cnrtGetInputDataSize(&inputSizeS,&inputNum,function));

CNRT_CHECK(cnrtGetOutputDataSize(&outputSizeS,&outputNum,function));


//获取模型输入/输出 的数据类型

CNRT_CHECK(cnrtGetInputDataType(&inputTypeS,&inputNum,function));

CNRT_CHECK(cnrtGetOutputDataType(&outputTypeS,&outputNum,function));


//分配 存放CPU端输入/输出地址的 指针数组

    inputCpuPtrS = (void **)malloc(sizeof(void *) * inputNum);

    outputCpuPtrS = (void **)malloc(sizeof(void *) * outputNum);

outputCpuNchwPtrS = (void **)malloc(sizeof(void *) * outputNum);


//分配 存放MLU端输入/输出地址的 指针数组

    outputMluPtrS = (void **)malloc(sizeof(void *) * outputNum);

    inputMluPtrS = (void **)malloc(sizeof(void *) * inputNum);


//为输入节点 分配CPU/MLU内存

for (int i = 0; i < inputNum; i++)

{

CNRT_CHECK(cnrtMalloc(&inputMluPtrS[i],inputSizeS[i]));//分配MLU上内存

        inputCpuPtrS[i] = (void *)malloc(inputSizeS[i]); //分配CPU上的内存

//printf("%d\n", inputSizeS[i]);

//获取输入的维度信息 NHWC

CNRT_CHECK(cnrtGetInputDataShape(&dimValues,&dimNum,i,function));

printf("input shape:\n");

    for(int y=0;y<dimNum;y++)

{

printf("%d ",dimValues[y]);

}

printf("\n");


input_width=dimValues[2];

input_height=dimValues[1];

batch_size=dimValues[0];

        free(dimValues);

    }


//为输出节点 分配CPU/MLU内存

    for (int i = 0; i < outputNum; i++) {

CNRT_CHECK(cnrtMalloc(&outputMluPtrS[i],outputSizeS[i])); //分配MLU上内存

        outputCpuPtrS[i] = (void *)malloc(outputSizeS[i]); //分配CPU上的内存

//printf("%d\n", outputSizeS[i]);

//获取输出的维度信息 NHWC

CNRT_CHECK(cnrtGetOutputDataShape(&dimValues,&dimNum,i,function));

int count=1;

printf("output shape:\n");

for(int y=0;y<dimNum;y++)

{

printf("%d ",dimValues[y]);

count=count*dimValues[y];

}

printf("\n");

outputCpuNchwPtrS[i] = (void *)malloc(count*sizeof(float)); //将输出转为float32类型,方便用户后处理

output_count.push_back(count);

        free(dimValues);

    }


//配置MLU输入/输出 地址的指针

    param = (void **)malloc(sizeof(void *) * (inputNum + outputNum));

    for (int i = 0; i < inputNum; i++) {

        param[i] = inputMluPtrS[i];

    }

    for (int i = 0; i < outputNum; i++) {

        param[i + inputNum] = outputMluPtrS[i];

    }

版权所有 © 2022 寒武纪 Cambricon.com 备案/许可证号:京ICP备17003415号-1
关闭