单算子API调用方式,是指直接调用单算子API接口,基于C语言的API执行算子。算子工程创建完成后,基于工程代码框架完成算子原型定义、kernel侧算子实现、host侧tiling实现,通过工程编译脚本完成算子的编译部署,之后再进行单算子API的调用。
完成自定义算子编译后,会自动生成单算子API,可以直接在应用程序中调用。
单算子API的形式一般定义为“两段式接口”,形如:
其中aclnn_Xxx_GetWorkspaceSize/aclnn_Xxx_TensorGetWorkspaceSize为第一段接口,主要用于计算本次API调用过程中需要多少workspace内存,获取到本次计算所需的workspaceSize后,按照workspaceSize申请NPU内存,然后调用第二段接口aclnn_Xxx_执行计算_。Xxx代表时传入的算子类型。
aclnn_Xxx_GetWorkspaceSize接口的输入输出参数生成规则如下:
可选输入的命名增加Optional后缀。如下样例中,x是可选输入。
[object Object]输入输出同名、使用同一个Tensor承载的情况下,生成的aclnn接口中只保留input参数同时去掉input的const修饰,并以Ref作为后缀。如下样例中,原型定义input、output都定义为x,xRef既作为输入,又作为输出。
[object Object]如果仅有一个输出,输出参数命名为out;如果存在多个输出,每个输出后面都以Out作为后缀。
[object Object]如果算子包含属性,则属性参数的位置介于输入输出之间。如下示例中,x是算子输入,negativeSlope是算子属性,out是算子输出。
[object Object]
当算子原型注册时使用ValueDepend接口标识输入为数据依赖输入时,会额外生成一个API,该API支持值依赖场景输入数据为空的一阶段计算。
在aclnn_Xxx_TensorGetWorkspaceSize中,aclnn_Xxx_GetWorkspaceSize参数的数据类型(aclIntArray、aclFloatArray和aclBoolArray)将被转换为aclTensor数据类型,其他输入输出参数生成规则与aclnn_Xxx_GetWorkspaceSize一致。如下示例中,x0、x1、x2是算子声明为数据依赖的输入,数据类型分别为DT_INT64、DT_BOOL、DT_FLOAT,out是算子输出。
对于算子包编译场景,参考、完成算子的编译部署,编译部署时需要开启算子的二进制编译功能:修改算子工程中的编译配置项文件CMakePresets.json,将ENABLE_BINARY_PACKAGE设置为True。编译部署时可将算子的二进制部署到当前环境,便于后续算子的调用。
[object Object]算子编译部署后,会在算子包安装目录下的op_api目录生成单算子调用的头文件aclnn_xx.h和动态库libcust_opapi.so。
以默认安装场景为例,单算子调用的头文件.h和动态库libcust_opapi.so所在的目录结构,如下所示:
[object Object]对于算子动态库编译场景,参考完成算子的编译。编译完成后会在如下路径生成单算子调用的头文件aclnn_xx.h和动态库libcust_opapi.so。其中CMAKE_INSTALL_PREFIX为开发者在cmake文件中配置的编译产物存放路径。
- 动态库路径:${CMAKE_INSTALL_PREFIX}/op_api/lib/libcust_opapi.so
- 头文件路径:${CMAKE_INSTALL_PREFIX}/op_api/include
单算子API执行流程如下:
图 1 单算子API执行接口调用流程[object Object][object Object]
本节以AddCustom自定义算子调用为例,介绍如何编写单算子调用的代码逻辑。其他算子的调用逻辑与Add算子大致一样,请根据实际情况自行修改代码。
以下是关键步骤的代码示例,不可以直接拷贝编译运行,仅供参考,调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。
[object Object]
算子编译后,会生成单算子调用的头文件aclnn_xx.h和动态库libcust_opapi.so。具体路径请参考。
编译算子调用程序时,需要在头文件的搜索路径include_directories中增加单算子调用的头文件目录,便于找到该头文件;同时需要链接cust_opapi动态库并在库文件的搜索路径link_directories中增加libcust_opapi.so所在目录。
在头文件的搜索路径include_directories中增加单算子调用的头文件目录。以下样例仅为参考,请根据头文件的实际目录位置进行设置。
[object Object]链接cust_opapi链接库。
[object Object]在库文件的搜索路径link_directories中增加libcust_opapi.so所在目录。以下样例仅为参考,请根据库文件的实际目录位置进行设置。
[object Object]
开发环境上,设置环境变量,配置单算子验证程序编译依赖的头文件与库文件路径,如下为设置环境变量的示例。${INSTALL_DIR}请替换为CANN软件安装后文件存储路径。以root用户安装为例,安装后文件默认存储路径为:/usr/local/Ascend/cann。_{arch-os}_为运行环境的架构和操作系统,_arch_表示操作系统架构,_os_表示操作系统,例如x86_64-linux或aarch64-linux。
[object Object]编译样例工程,生成单算子验证可执行文件。
切换到样例工程根目录,然后在样例工程根目录下执行如下命令创建目录用于存放编译文件,例如,创建的目录为“build“。
[object Object]进入build目录,执行cmake编译命令,生成编译文件
命令示例如下所示:
[object Object]执行如下命令,生成可执行文件。
[object Object]会在工程目录的output目录下生成可执行文件execute_add_op。
执行单算子
以运行用户(例如HwHiAiUser)拷贝开发环境中样例工程output目录下的execute_add_op到运行环境任一目录。
说明: 若您的开发环境即为运行环境,此拷贝操作可跳过。
在运行环境中,执行execute_add_op文件:
[object Object]如果有test pass,表明执行成功。