概念及使用说明
相关概念
本章中的接口涉及对算子的算子二进制、核函数、核函数参数列表以及参数的操作,为便于理解,您可以先通过下图了解它们之间的关系。
Kernel加载与执行接口调用流程
关键流程说明如下:
- 调用aclInit接口初始化AscendCL。
- 申请运行管理资源,包括调用aclrtSetDevice接口指定用于运算的Device、调用aclrtCreateStream接口创建Stream。
- 调用aclrtBinaryLoadFromFile接口加载算子二进制文件。
- 调用aclrtBinaryGetFunctionByEntry或aclrtBinaryGetFunction接口获取核函数句柄。
- 根据核函数句柄操作其参数列表,操作包括:
- 初始化参数列表
当前支持由系统管理内存(调用aclrtKernelArgsInit接口)、由用户管理内存(调用aclrtKernelArgsInitByUserMem接口)两种方式。
- 追加参数、更新参数值
核函数参数列表中包含不同类型的参数,例如指针类型参数、placeHolder、uint8_t类型参数等,其中:
- 指针类型参数:其值为Device内存地址。一般来说,算子的输入、输出是该种类型的参数,用户需提前调用Device内存申请接口(例如aclrtMalloc接口)申请内存,并自行拷贝数据至Device侧。
- placeHolder:也是指针类型参数,但区别在于,用户无需手动将参数数据复制到Device,这项操作由Runtime完成。在追加参数时Runtime并不会填写真实的Device地址,而是在Launch Kernel时才会刷新为真实的Device地址,所以称之为placeHolder。对算子的非输入、输出参数,可以使用placeHolder方式,将小块数据(建议小于2KB)的Host->Device拷贝合并到Launch Kernel时的一次拷贝操作中去,减少拷贝次数,提升性能。
不同类型参数,可调用不同的参数追加接口:
- 对于placeHolder参数,由于关联的内存必须放在所有参数之后,所以在追加参数时,先调用aclrtKernelArgsAppendPlaceHolder接口占位,等所有参数都追加之后,可调用aclrtKernelArgsGetPlaceHolderBuffer接口获取对应占位符指向的内存地址。用户可根据获取的内存地址,管理该内存中的数据。
- 对于非placeHolder参数(例如指针类型参数、uint8_t类型参数等),调用aclrtKernelArgsAppend接口将用户设置的参数值追加拷贝到argsHandle指向的参数数据区域。如果要更新参数值,可调用aclrtKernelArgsParaUpdate接口进行更新。
注意,核函数参数列表中,实际可能存在多个参数,并且不同类型的参数可能交错出现,因此需要按照参数列表中的参数顺序从左到右进行追加,追加的参数最多支持128个。
- 结束参数列表的追加、参数值的更新
在所有参数追加之后,调用aclrtKernelArgsFinalize接口以标识参数组装完毕。但aclrtKernelArgsFinalize接口之后,也支持继续更新参数值,更新之后,还要再调用一次aclrtKernelArgsFinalize接口。
- 初始化参数列表
- 调用aclrtLaunchKernelWithConfig接口Launch Kernel,启动对应算子的计算任务。
- 调用接口aclrtBinaryUnLoad卸载算子二进制文件。
- 释放运行管理资源,包括调用aclrtDestroyStream接口释放Stream、调用aclrtResetDevice接口释放Device上的资源。
- 调用aclFinalize接口去初始化AscendCL。
父主题: Kernel加载与执行