算子动态库和静态库编译是将算子实现代码及相关文件编译为动态库和静态库的过程。相比自定义算子包编译,动态库和静态库编译能够显著简化集成与部署流程。该过程包括将算子Kernel实现、Host侧Tiling实现、入图适配文件以及自动生成的单算子调用实现代码编译链接成动态库和静态库。
同时会自动生成以下头文件:
算子动态库和静态库编译支持如下型号:
算子动态库和静态库编译的具体步骤如下:
"ASCEND_PACK_SHARED_LIBRARY": {
"type": "BOOL",
"value": "True"
}
./build.sh
编译成功后,会在${CMAKE_INSTALL_PREFIX}/op_api目录生成以下文件:
具体目录结构如下:
├── op_api
│ ├── include
│ ├── aclnn_optype1.h // 单算子调用aclnn头文件
│ └── aclnn_optype2.h
│ └── aclnn_optypexxx.h
│ └── op_proto.h // 算子原型定义头文件
│ ├── lib
│ ├── cmake
│ └── ${vendor_name}
│ ├──${vendor_name}-config.cmake // 安装文件,定义了项目中的配置选项和变量
│ └──${vendor_name}-targets.cmake // 安装文件,定义静态库和动态库的构建目标${vendor_name}::static和${vendor_name}::shared,便于开发者使用静态库和动态库,自动处理库的依赖关系
│ ├── libcust_opapi.so // 算子动态库
│ └── lib${vendor_name}.a // 算子静态库
单算子调用场景可以通过如下方式对算子库编译中生成的动态库和静态库进行集成和使用。
find_package(${vendor_name} REQUIRED # ${vendor_name}为编译生成的算子package名称
PATHS ${CUST_PKG_PATH} # ${CUST_PKG_PATH}为编译生成的算子package的存放路径
NO_DEFAULT_PATH
)
target_link_libraries(op_runner PRIVATE
...
${vendor_name}::shared # 已自动包含相关的target依赖
...
)
find_package(${vendor_name} REQUIRED # ${vendor_name}为编译生成的算子package名称
PATHS ${CUST_PKG_PATH} # ${CUST_PKG_PATH}为编译生成的算子package的存放路径
NO_DEFAULT_PATH
)
target_link_libraries(op_runner PRIVATE
...
${vendor_name}::static # 已自动包含相关的target依赖
...
)
find_package(${vendor_name1} REQUIRED # ${vendor_name1}为编译生成的算子package名称
PATHS ${CUST_PKG_PATH_1} # ${CUST_PKG_PATH_1}为编译生成的算子package的存放路径
NO_DEFAULT_PATH
)
find_package(${vendor_name2} REQUIRED # ${vendor_name2}为编译生成的算子package名称
PATHS ${CUST_PKG_PATH_2} # ${CUST_PKG_PATH_2}为编译生成的算子package的存放路径
NO_DEFAULT_PATH
)
target_link_libraries(op_runner PRIVATE
...
${vendor_name1}::static # 已自动包含相关的静态库target依赖
${vendor_name2}::shared # 已自动包含相关的动态库target依赖
...
)
set_target_properties(cust_opapi PROPERTIES
OUTPUT_NAME ${vendor_name}
)
编译后,修改生成的op_api目录中的${vendor_name}-targets.cmake文件,将其中的libcust_opapi.so修改为lib${vendor_name}.so。保证动态库名称的一致性。
export ASCEND_CUSTOM_OPP_PATH=${CMAKE_INSTALL_PREFIX}/op_api/lib/:${ASCEND_CUSTOM_OPP_PATH}
动态库编译和算子包编译功能同时使用时,前者生成的动态库优先级更高。
如下示例中,path1和path3是算子包编译生成的目录,path2和path4是动态库编译产物的存放目录,则编译产物的优先级为2>4>1>3。
ASCEND_CUSTOM_OPP_PATH=<path1>/vendor_name1:<path2>/op_api/lib/:<path3>/vendor_name3:<path4>/op_api/lib/