使用正确的内存申请接口,但内存大小传值错误
内存被提前释放,导致解码数据花屏
现象描述
原始H264/H265每一帧视频流正常,解码过程无异常(无异常日志),仅仅输出图片有异常。
可能原因
解码过程无异常,说明送入的码流非异常码流,仅仅输出被破坏,可能由于:
-
输出内存被别人复用,被踩或者被提前释放;
-
解码需要的输出内存比实际申请的内存大。
处理步骤
- 对于DVPP内存申请接口,增加日志打印内存大小及地址,检查VDEC输出内存,检查申请的内存大小是否与实际使用的一致,比如典型的错误场景,VDEC解码输出格式预期是RGB,实际仍按照YUV420sp申请内存。
- 在DVPP内存释放接口处、以及hi_mpi_vdec_get_frame/aclvdecCallback/acldvppJpegDecodeAsync接口处,增加内存大小及地址的打印日志,确认内存释放时序,是否存在内存地址解码完成前被提前释放的情况。
父主题: JPEGD图片解码/VDEC视频解码
调用错误的内存申请接口,导致内存地址校验出错
现象描述
日志报错如下:
-
日志1
device:0 chan 0, venc or jpege input buffer is invalid, make sure it has been allocated with hi_mpi_dvpp_malloc or aclDvppMalloc. -
日志2
device:0 chan 0, venc or jpege output buffer is invalid, make sure it has been allocated with hi_mpi_dvpp_malloc or aclDvppMalloc. -
日志3
device:0 chan 0, jpege input buffer is invalid, make sure it has been allocated with hi_mpi_dvpp_malloc or aclDvppMalloc. -
日志4
device:0 chan 0, jpege output buffer is invalid, make sure it has been allocated with hi_mpi_dvpp_malloc or aclDvppMalloc.
可能原因
根据日志提示,是由于没有使用指定的接口申请内存。
处理步骤
使用媒体数据处理V1版本中的acldvppMalloc接口/媒体数据处理V2版本中的hi_mpi_dvpp_malloc接口申请DVPP内存,存放JPEGE图片编码/VENC视频编码输入或输出数据。
父主题: JPEGE图片编码/VENC视频编码
内存被提前释放,导致编码数据花屏
现象描述
编码出来的数据花屏,其他无异常日志信息。
可能原因
VENC输入内存是YUV图片数据,输入内存被踩或者被提前释放。
处理步骤
在DVPP内存释放接口处、以及hi_mpi_venc_get_stream/aclvencCallback/acldvppJpegEncodeAsync接口处,增加内存大小及地址的打印日志,确认内存释放时序,是否存在输入内存在编码完成前被提前释放的情况。
父主题: JPEGE图片编码/VENC视频编码
使用正确的内存申请接口,但内存大小传值错误
现象描述
日志报错如下:
device:0 chan 0, output terminal address is invalid, maybe outBufSize:3110400 is invalid.
可能原因
传入的buffer size太大,超出了实际申请的buffer范围,导致内部结束地址校验出错。
处理步骤
如果内存申请接口使用正常,业务流程中dvpp内存申请接口增加地址及长度日志,检查接口hi_mpi_venc_send_frame/hi_mpi_venc_send_jpege_frame/aclvencSendFrame/acldvppJpegEncodeAsync传入buffer长度是否一致。
父主题: JPEGE图片编码/VENC视频编码
单算子调用视频课程
通过在线视频课程学习该功能,请参见AscendCL加载与执行算子。
父主题: 单算子调用
单算子调用基础知识
单算子调用的使用场景
如果AI应用中不仅仅包括模型推理,还有数学运算(例如BLAS基础线性代数运算)、数据类型转换等功能,也想使用昇腾的算力,昇腾CANN还能支持吗?
答案是肯定的,昇腾CANN提供了单算子调用的方式,直接通过AscendCL接口加载并执行单个算子,省去模型构建、训练的过程,相对轻量级,又可以使用昇腾的算力。
另外,自定义的算子,也可以通过单算子调用的方式来验证算子的功能。
单算子调用与模型推理的差别
在解释单算子调用与模型推理的差别前,我们先观察下面这个开发流程图,先找出基本的共同点、不同点。
- 共同点:
- 不管是模型推理,还是单算子调用,都需要AscendCL初始化和去初始化、运行管理资源申请和释放。
- 不管是模型推理,还是单算子调用,都涉及加载、执行的步骤,但是要注意,两者的加载、执行是调用不同的AscendCL接口。
- 不同点:
- 模型推理涉及模型卸载的步骤,单算子调用不涉及。
图1 单算子调用与模型推理的流程对比

单算子调用功能开发流程
图2 开发流程

-
准备环境。
请参见。
-
创建代码目录。
在开发应用前,您需要先创建目录,存放代码文件、编译脚本、测试图片数据、模型文件等。
如下仅是示例,供参考:
├App名称├── op_model // 该目录下存放编译算子的算子描述文件│ ├── xxx.json├── data│ ├── xxxxxx // 测试数据├── inc // 该目录下存放声明函数的头文件│ ├── xxx.h├── out // 该目录下存放输出结果├── src│ ├── xxx.json // 系统初始化的配置文件│ ├── CMakeLists.txt // 编译脚本│ ├── xxx.cpp // 实现文件 -
编译算子。
若基于“单算子模型执行”方式调用算子,则需编译算子,编译算子有以下两种方式:
-
使用ATC工具编译算子生成om模型文件
该种方式,需要先构造*.json格式单算子描述文件(描述算子的输入、输出及属性等信息),借助ATC工具,将单算子描述文件编译成om模型文件;再分别调用AscendCL接口加载om模型文件、执行算子。
关于ATC工具的使用说明,请参见《ATC工具使用指南》。
-
也可以调用AscendCL提供的编译算子接口
该种方式,直接调用AscendCL接口编译、执行算子。
:::note 说明 关于单算子模型执行详细的接口调用流程请参见单算子调用流程。 :::
-
-
开发应用。
依赖的头文件和库文件的说明请参见调用接口依赖的头文件和库文件说明。
单算子调用的流程请参见单算子调用流程及相关的示例代码。
-
编译运行应用,请参见应用调试。
父主题: 单算子调用
单算子调用流程
开发应用时,如果涉及执行单个算子,请先参见AscendCL接口调用流程了解整体流程,再查看本节中的流程说明。
系统支持的算子请参见《算子清单》。
对于系统不支持的算子,用户需先参见《TBE&AI CPU算子开发指南》完成自定义算子开发。
单算子模型执行接口调用流程
图1 单算子模型执行接口调用流程

关键接口的说明如下:
-
编译算子。
根据算子编译的方式,可分为以下两种:
-
编译算子后,算子相关数据保存在*.om模型文件中
该种方式下编译算子,需使用ATC工具,详细描述请参见《ATC工具使用指南》,将单算子定义文件(*.json)编译成适配昇腾AI处理器的离线模型(*.om文件)。
-
编译算子后,算子相关数据保存在内存中
该种方式下编译算子,需调用AscendCL提供的接口,根据不同场景调用不同的接口:
- 对于同一个算子,编译一次,多次执行的场景,建议调用aclopCompile接口编译算子。编译算子后,依次进行3、4、5、6、7。
- 对于编译算子、执行算子次数相同的场景,建议先执行3,再调用aclopCompileAndExecute接口编译算子。编译算子后,再依次进行6、7。
-
-
加载算子模型文件。
支持以下2种方式中的一种加载单算子模型文件:
- 调用aclopSetModelDir接口,设置加载模型文件的目录,目录下存放单算子模型文件(*.om文件)。
- 调用aclopLoad接口,从内存中加载单算子模型数据,由用户管理内存。单算子模型数据是指“单算子编译成*.om文件后,再将om文件读取到内存中”的数据。
-
调用aclrtMalloc接口申请Device上的内存,存放执行算子的输入、输出数据。
-
动态Shape场景,如果无法明确算子的输出Shape时,在执行算子前,还需推导或预估算子的输出Shape。
需用户调用aclopInferShape接口、aclGetTensorDescNumDims接口、aclGetTensorDescDimV2接口、aclGetTensorDescDimRange等接口,推导或预估算子的输出Shape,作为算子执行接口aclopExecuteV2的输入。
-
执行算子。
- 对于被封装成AscendCL接口的算子(参见CBLAS接口),包括GEMM算子、Cast算子,目前支持以下两种执行方式:
- 不以handle方式执行算子,接口名称中不包含“Handle”关键字,例如,调用aclblasGemmEx接口(封装GEMM算子)、aclopCast接口(封装Cast算子)等执行算子。
- 以handle方式执行算子,接口名称中包含“Handle”关键字,例如,调用aclblasCreateHandleForGemmEx接口、aclopCreateHandleForCast接口等创建handle后,还需要调用aclopExecWithHandle接口执行算子。
- 对于未被封装成AscendCL接口的算子,目前支持以下两种执行方式:
- 不以handle方式执行算子,调用aclopExecuteV2接口执行算子。
- 以handle方式执行算子,调用aclopCreateHandle接口创建handle,再调用aclopExecWithHandle接口执行算子。
:::note 说明 不以handle方式执行算子时,每次执行算子时,系统内部都会根据算子描述信息匹配内存中的模型。
以handle方式执行算子时,系统内部将算子描述信息匹配到内存中的模型,并缓存在Handle中,每次执行算子时,无需重复匹配算子与模型,因此在涉及多次执行同一个算子时,效率更高,但该方式不支持动态Shape算子,且Handle使用结束后,需调用aclopDestroyHandle接口释放。 :::
- 对于被封装成AscendCL接口的算子(参见CBLAS接口),包括GEMM算子、Cast算子,目前支持以下两种执行方式:
-
调用aclrtSynchronizeStream接口阻塞应用运行,直到指定Stream中的所有任务都完成。
-
调用aclrtFree接口释放内存。
父主题: 单算子调用
在线提单