在参与2025年CANN训练营第二季的算子开发过程中,笔者对环境配置阶段所遇到的若干问题进行了梳理与总结,现将关键点整理如下:
1. 如何调用已有的aclnn接口源码而非自动生成aclnn代码?
当目标算子在开源仓库中已存在对应的aclnn接口实现时,应避免使用系统自动生成的版本。可参考链接:
https://gitcode.com/org/cann/discussions/37
但需注意,不能直接复制原仓库中的op_host/CMakeLists.txt文件,必须进行适配性修改。
在CMakeLists.txt中,应设置选项为aclnn_exclude,以阻止自动生成aclnn相关函数。由于训练营要求所有代码存放于experimental目录下,因此还需手动补充正确的代码路径信息,确保后续编译流程能够顺利执行。
#optiling and opapi
include_directories(
${CMAKE_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/experimental
${CMAKE_SOURCE_DIR}/experimental/math/xxx
${CMAKE_SOURCE_DIR}/experimental/math/xxx/op_kernel
)
add_modules_sources(OPTYPE xxx ACLNNTYPE aclnn_exclude)
2. 编译自定义算子时报错:无法找到库路径
此问题通常出现在用户自行编写或修改了example目录下的CMakeLists脚本后。此时编译器会尝试自动识别并处理该部分代码,然而自定义算子尚未完成构建,导致链接失败。
CMake Error at CMakeLists.txt:32 (message):
未在LD_LIBRARY_PATH中找到包含/vendors/的路径
解决方法包括以下几种:
- 提前设置必要的环境变量,使编译器能定位到所需依赖;
- 临时移除example文件夹或其中的CMakeLists.txt文件;
- 先跳过example编译,完成自定义算子的安装后再恢复原结构,继续进行aclnn功能测试。
export LD_LIBRARY_PATH=/home/ma-user/Ascend/ascend-toolkit/latest/opp/vendors/custom_math/op_api/lib/:${LD_LIBRARY_PATH}
3. 利用ascendoptest工具测试自定义算子时的常见错误及修复
该环节曾耗费较长时间排查问题,详细讨论可见:
https://gitee.com/sutonghua/ascendoptest/issues/ID7JGN?from=project-issue
主要表现为:使用已有aclnn源码编译的算子,在运行ascendoptest时提示找不到util头文件,以及ViewCopy、Cast、Contiguous和l0op等API符号缺失。
根本原因在于ascendoptest默认未包含这些必要的头文件路径和库依赖。解决方案是手动修改ascendoptest项目中的cmake_generator.py脚本,显式添加缺失的头文件搜索路径和库文件链接项。
# --- Conditional Blocks ---
include_paths = [
"${INC_PATH}/runtime/include",
"${INC_PATH}/atc/include",
"${INC_PATH}/aarch64-linux/include/aclnnop", # 新增:aclnn_util.h 所在目录
"${INC_PATH}/aarch64-linux/include/aclnnop/level2", # 新增:level2 中的aclnn_util.h
link_paths.extend([
"${LIB_PATH}",
"${LIB_PATH1}",
"${CUST_PKG_PATH}/lib",
"${INC_PATH}/aarch64-linux/lib64" # 新增:l0op库所在目录
])
link_libraries.extend([
"cust_opapi",
"opapi" # 新增:提供 ViewCopy/Cast/Contiguous 符号
])
4. 算子代码引发内存越界后,即使修正代码仍无法重新编译?如何恢复?
此类现象常发生在因代码错误(如内存访问越界)导致编译中断之后。即便问题代码已被修复,再次尝试编译时仍可能被跳过,无法继续。
通过分析plog日志可发现,这实际上是TBE编译器的目录锁机制遗留所致——即“脏锁文件”未被清除。该锁并非操作系统级别的进程占用,而是上次异常退出(例如出现Segmentation fault)时未能清理kernel_meta.lock文件。
TBE编译器在每次编译某个内核(如Atan)前,会在对应的kernel_meta_目录中创建一个lock文件,并写入当前PID用于独占判断。若此前异常终止而未删除该文件,则下次编译将误判为“有其他进程正在使用”,从而直接跳过编译流程。
应对策略为:手动查找并删除残留的kernel_meta.lock文件,解除锁定状态,即可恢复正常编译。
rm -rf /home/ma-user/work/ops-math/scripts/kernel/binary_script/kernel_meta_*