graph-autofusion 编译构建全攻略:build.sh 参数详解、增量编译与常见报错排查实战
【免费下载链接】graph-autofusionGraph-autofusion 是一个面向昇腾(Ascend)芯片的轻量级、解耦式组件集合,旨在通过自动融合技术加速模型执行。 目前已开源 SuperKernel 组件和 Autofuse 组件,未来将持续开放更多自动融合相关模块。项目地址: https://gitcode.com/cann/graph-autofusion
本指南以 graph-autofusion 仓库中的构建辅助技能文档为核心骨架,围绕项目根目录的build.sh统一构建入口,系统讲解编译、打包、测试运行、环境配置与第三方依赖管理的完整实操流程,并结合 build.sh 源码与 docs/zh/build.md 官方文档做纵深解读。读完本文,你将掌握:如何避免编译 OOM 与超时、如何用增量编译实现秒级迭代、如何按模块运行 UT/ST、如何完成离线编译与.run包安装卸载,以及常见编译错误的精准定位与修复。
一、构建入口与核心参数总览
graph-autofusion 使用项目根目录的 build.sh 作为统一构建入口,支持编译、打包、测试、覆盖率采集等全部构建动作。其完整用法为:
sh build.sh [-h|--help] [--pkg] [-u|--ut] [-s|--st] [--impl=<py|cpp|all>] [--module=<name>] [-c|--coverage] [-j <N>] [--build-type=<TYPE>] [--no-autofuse] [--output_path=<PATH>] [--cann_3rd_lib_path=<PATH>] [--run_example] [--test_case=<FILTER>]各参数含义(与源码 build.sh 的usage()逐一对应):
| 参数 | 说明 | 取值/默认值 |
|---|---|---|
-h, --help | 打印用法说明 | — |
--pkg | 构建并打包生成.run运行包 | 开/关 |
--no-autofuse | 跳过 autofuse 后端编译,仅编译 SuperKernel | 开/关 |
-j <N> | 编译线程数 | 默认取 CPU 核数;文档与源码均强调必须显式限制 |
-u, --ut | 运行单元测试 | 开/关 |
-s, --st | 运行系统测试 | 开/关 |
--impl=<py\|cpp\|all> | 选择测试实现类型 | 默认 all |
--module=<name> | 选择测试模块 | superkernel / autofuse_framework / autofuse_ascendc_api / autofuse_e2e / all |
-c, --coverage | 带覆盖率报告运行测试 | 开/关 |
--output_path=<PATH> | 运行包输出目录 | 默认./build_out |
--cann_3rd_lib_path=<PATH> | 第三方依赖包路径 | 默认./output/third_party |
--build-type=<TYPE> | 编译类型 | Debug / Release(默认 Release) |
--pkg-type=<TYPE> | 打包类型 | run / rpm / deb(默认 run) |
-f <FILE> | 变更文件清单文件,用于智能模块选择(详见后文) | 文件路径 |
几个从源码确认的关键行为:
- 必须带参数运行:源码 checkopts() 中,
build.sh无参数时直接报错退出("has no options available, please select at least one option!"),因此sh build.sh裸跑是无效的。 - -j 校验严格:
check_param_j()只接受正整数,超过 CPU 核数时会被钳制为核数(build.sh#L88-L105)。 --module只影响测试范围,不影响编译范围:编译始终全量执行;要限制编译范围,应改用cmake --build build --target <target>(后文详解)。- 新增参数(源码中已实现,SKILL 文档未列全):
--pkg-type(run/rpm/deb)、-f <FILE>智能模块选择、--autofuse(与--no-autofuse对应显式开启 autofuse)。
二、两条铁律:编译必须加 -j、警惕编译超时
2.1 为什么必须指定-j 8
编译默认并行度无限制。在 build.sh 中:
CPU_NUM=$(($(cat /proc/cpuinfo | grep "^processor" | wc -l))) THREAD_NUM=${CPU_NUM}即默认线程数等于机器全部 CPU 核数,多核服务器上并行编译会瞬间吃满内存,导致OOM(Killed)。因此:
所有编译命令必须指定
-j 8(或合理线程数),否则默认无限制会导致 OOM。
2.2 编译超时与三套解决方案
全量编译 autofuse 组件耗时较长(通常 15–30 分钟),可能超过工具的执行超时限制。解决方案按优先级排列:
方案一:优先增量编译(推荐)。已有build/目录时只重编变更的源文件:
cmake --build build --target <target> -j 8方案二:后台运行全量编译。用nohup避免超时中断:
# 后台运行,日志写入 build.log nohup sh build.sh --pkg -j 8 > build.log 2>&1 & # 查看编译进度 tail -f build.log # 检查编译是否完成 ps aux | grep "build.sh" | grep -v grep方案三:分阶段编译。拆成多个可短时完成的子任务:
# 先编译核心库 cmake --build build --target aihac_codegen -j 8 # 再编译测试目标 cmake --build build --target test_common -j 8检查编译产物:
ls -la build/cann-graph-autofusion_*.run ls -la build/autofuse/tests/ut/common/test_common三、增量编译:日常开发首选
CMake 天然支持增量编译:build/目录已存在时,只重编译变更的源文件,日常开发应优先增量编译,避免全量重建。
3.1 判断是否需要全量重建
| 场景 | 是否需要全量 | 说明 |
|---|---|---|
修改了.cpp/.h/.py源码 | 否 | 增量编译即可 |
修改了CMakeLists.txt | 否 | CMake 自动检测并重新 configure |
| 切换 Debug/Release | 是 | 编译选项变化,需清理build/ |
| 首次编译 | 是 | 无build/目录 |
| 切换了 CANN Toolkit 版本 | 是 | 头文件和库路径变化 |
| 添加了新的源文件 | 否 | CMake 的CONFIGURE_DEPENDS/GLOB_RECURSE会自动发现 |
3.2 三种增量编译方式
# 方式一:通过 build.sh(自动 configure + build,未变更文件不重编) sh build.sh --pkg -j 8 # 方式二:直接 cmake --build(跳过 configure,最快,适用于源码修改) cmake --build build --target ascendsk -j 8 # 只重编 SuperKernel cmake --build build --target aihac_codegen -j 8 # 只重编 autofuse 核心库 cmake --build build --target pyautofuse -j 8 # 只重编 Python 绑定 cmake --build build -j 8 # 增量编译所有目标 # 方式三:只编译指定目标后直接打包 cmake --build build --target ascendsk -j 8 && cmake --build build --target package -j 83.3 单目标增量编译参考表
根据修改的源码区域,选择对应的编译目标(.so产物路径已在仓库 CMake 配置中确认,如 autofuse/CMakeLists.txt 定义aihac_codegen、super_kernel/CMakeLists.txt 定义ascendsk):
| 修改的源码目录 | 编译目标 | .so 产物 |
|---|---|---|
super_kernel/src/ | ascendsk | build/super_kernel/libascendsk.so |
super_kernel/kernel/ | ascendsk(含 sk_scope 子目标) | build/super_kernel/libascendsk.so |
super_kernel/*.py | superkernel_whl | build/super_kernel/superkernel-*.whl |
autofuse/codegen/ | aihac_codegen | build/autofuse/libaihac_codegen.so |
autofuse/optimize/ | aihac_codegen | build/autofuse/libaihac_codegen.so |
autofuse/ascir/ | aihac_codegen(含ascir、ascir_builtin_ops) | build/autofuse/libaihac_codegen.so |
autofuse/graph_metadef/graph/ | graph_af、graph_base_af、aihac_ir等 | 各自.so |
autofuse/compiler/py_module/ | pyautofuse | build/autofuse/compiler/py_module/pyautofuse.so |
autofuse/att/ | aihac_codegen | build/autofuse/libaihac_codegen.so |
autofuse/common/ | aihac_codegen | build/autofuse/libaihac_codegen.so |
说明:
ascir、ascir_builtin_ops等子目标会通过target_sources汇聚进aihac_codegen(见 autofuse/ascir/generator/CMakeLists.txt),因此修改 ascir 区域统一重编aihac_codegen即可。
3.4 快速迭代工作流
修改代码后快速验证、不打包:
# 1. 增量编译目标库 cmake --build build --target ascendsk -j 8 # 2. 直接运行测试验证 sh build.sh -u --module=superkernel --impl=py # 或 sh build.sh -u --module=superkernel --impl=cpp --test_case="*SkEntry*"3.5 换 .so:替换动态库快速验证
需要把编译产物部署到 CANN 安装目录或其他环境时:
# 增量编译目标 cmake --build build --target ascendsk -j 8 cmake --build build --target aihac_codegen -j 8 # 替换到部署目录 cp build/super_kernel/libascendsk.so <部署路径>/lib64/ cp build/autofuse/libaihac_codegen.so <部署路径>/lib64/ # 或通过 LD_LIBRARY_PATH 优先加载 export LD_LIBRARY_PATH=$(pwd)/build/super_kernel:$(pwd)/build/autofuse:$LD_LIBRARY_PATH注意:换.so需确保 ABI 兼容(相同编译选项、相同编译器版本、相同 Build Type)。否则会出现链接期/运行期符号错误。
四、全量编译
仅在必要时使用(首次编译、切换 Build Type、切换 Toolkit 版本):
# 清理后全量重建 rm -rf build && sh build.sh --pkg -j 8 # 切换 Debug 模式(需全量) rm -rf build && sh build.sh --pkg --build-type=Debug -j 8从源码看,cmake_config()会将-DCMAKE_BUILD_TYPE=${BUILD_TYPE}传给 CMake(build.sh),Build Type 变化后旧缓存会冲突,因此必须先清理build/。
五、常用构建命令实战
5.1 编译
# 编译并打包(Release 模式,最常用;已有 build/ 时自动增量) sh build.sh --pkg -j 8 # Debug 模式编译(切换 Build Type 需全量) rm -rf build && sh build.sh --pkg --build-type=Debug -j 8 # 跳过 autofuse 后端编译(只编 SuperKernel) sh build.sh --pkg --no-autofuse -j 8再次强调:--no-autofuse会向 CMake 传递-DBUILD_AUTOFUSE=OFF(见 build.sh),仅影响编译范围。
5.2 打包
# 构建运行包(已有 build/ 时增量编译后打包) sh build.sh --pkg -j 8 # 只重新打包(不重编,适用于已编译完成只需生成 .run 包) cmake --build build --target package -j 8 # 指定输出路径 sh build.sh --pkg --output_path=/path/to/output -j 8打包流程在源码build_package()(build.sh)中实现:先cmake --build . --target "all package",再将_CPack_Packages/makeself_staging/下的cann-graph-autofusion*.run拷贝到输出目录(默认build_out/)。
5.3 运行测试
# SuperKernel Python UT sh build.sh -u --module=superkernel --impl=py # SuperKernel C++ UT sh build.sh -u --module=superkernel --impl=cpp # SuperKernel Python ST sh build.sh -s --module=superkernel --impl=py # Autofuse Framework UT sh build.sh -u --module=autofuse_framework # Autofuse AscendC API UT sh build.sh -u --module=autofuse_ascendc_api # Autofuse E2E ST sh build.sh -s --module=autofuse_e2e # 带覆盖率报告 sh build.sh -u --module=superkernel -c # 运行指定的 C++ UT 用例(gtest filter) sh build.sh -u --module=superkernel --impl=cpp --test_case="*SkEntry*"注意:autofuse_e2e模块只支持 ST(-s),不支持 UT(-u)。这一约束在源码 build.sh 的MODULE_ACTION_HANDLERS中写死:autofuse_e2e只注册了all_st动作。
从源码看测试的底层调用链:
- SuperKernel 测试:py 测试实际执行
pip install -e .[dev]后运行pytest tests/ut -m ut -n auto或pytest tests/st -m st -n auto(build.sh);cpp 测试则重新 configure CMake 并构建run_super_kernel_aot_utest/run_super_kernel_aot_stest目标(build.sh)。 - Autofuse 测试:统一转调 scripts/test/run_autofuse_test.sh,按模块映射为
framework/ascendc_api/e2e(build.sh)。
5.4 运行示例
sh build.sh --run_example --module=superkernel5.5 智能模块选择(-f <FILE>)
源码新增了-f <FILE>参数:传入包含变更文件列表的文件,analyze_changed_modules()会分析变更范围(build.sh):
- 仅修改
super_kernel/:跳过 autofuse 编译与 autofuse 测试; - 仅修改
autofuse/:跳过 superkernel 测试; - 两者都改:全量构建;
- 仅修改
docs/、examples/、.claude/、.opencode/、README 等:跳过全部构建(退出码 200)。
该机制适合 CI 场景按变更范围做差异化构建,可显著缩短流水线时间。
六、支持的测试模块一览
| 模块名 | 说明 | 支持的测试类型 |
|---|---|---|
superkernel | SuperKernel 组件 | UT(py/cpp)、ST(py) |
autofuse_framework | Autofuse 框架 | UT、ST |
autofuse_ascendc_api | Autofuse AscendC API | UT、ST |
autofuse_e2e | Autofuse 端到端测试 | 仅 ST |
七、环境依赖与环境变量
7.1 依赖版本要求
| 依赖 | 版本要求 |
|---|---|
| CANN Toolkit | >= 9.1.0(使用/cann-toolkit-installer安装) |
| Python3 | >= 3.8.0(建议 3.9+,使用虚拟环境) |
| CMake | >= 3.16.0 |
| bash | >= 5.0 |
补充说明(来自 docs/zh/build.md):GCC >= 7.3.0,默认使用环境已装 gcc/g++;如需切换到 gcc15/gcc16,可显式设置export CC=gcc-15 CXX=g++-15或GCC_VERSION=15。
7.2 必须 source CANN 环境变量
编译前必须 source CANN 环境变量。set_env.sh位于ASCEND_HOME_PATH目录下:
# 如果 ASCEND_HOME_PATH 已设置 source ${ASCEND_HOME_PATH}/set_env.sh # 常见安装路径(按优先级尝试) source /home/developer/Ascend/master/cann-9.1.0/set_env.sh # master 构建版本 source /home/developer/Ascend/cann-9.0.0/set_env.sh # 发布版本 source /usr/local/Ascend/cann/set_env.sh # 系统级安装注意:项目源码依赖 CANN 9.1.0+ 的 API(如sk::SkSystemArgs),使用低版本 Toolkit 会编译报错no type named 'SkSystemArgs',优先使用 master 路径下的 Toolkit。ASCEND_HOME_PATH会通过build.sh的CUSTOM_OPTION以-DASCEND_INSTALL_PATH=传入 CMake(build.sh)。
7.3 验证环境
# 检查 ASCEND_HOME_PATH 是否设置 echo $ASCEND_HOME_PATH # 检查 atc 工具是否存在 ls ${ASCEND_HOME_PATH}/bin/atc # 检查 set_env.sh 是否存在 ls ${ASCEND_HOME_PATH}/set_env.sh也可运行仓库自带的 scripts/check_env.sh 一键体检,输出[PASS]/[WARNING]/[ERROR]三档结果(详见 docs/zh/build.md 4.2.2 节)。
八、第三方依赖管理
首次编译会自动下载第三方依赖到output/third_party/,后续编译跳过此步骤。
离线环境需手动下载并放到open_source/目录(针对 makeself、cann-cmake),详见 docs/zh/build.md。
指定第三方库路径:
sh build.sh --cann_3rd_lib_path=/path/to/third_party -j 88.1 网络与代理问题
编译过程中 CMake 通过ExternalProject_Add从外网自动下载 autofuse 和 superkernel AOT UT 所需第三方源码包(abseil-cpp、boost、json、protobuf、symengine、googletest、mockcpp 等)。内网/Docker 环境无法直连外网时:
方案一:配置代理(推荐)。build.sh会自动检测并继承 shell 中的http_proxy/https_proxy环境变量(源码 build.sh 会打印代理检测信息):
export http_proxy=http://user:password@proxy-server:port export https_proxy=http://user:password@proxy-server:port bash build.sh --pkg方案二:手动预下载离线编译。在联网机器上预先下载第三方包(abseil-cpp 20230802.1、json 3.11.3、boost 1.87.0、protobuf 25.1、symengine 0.12.0、googletest 1.14.0、mockcpp 2.7 + mockcpp-2.7-h5.patch、makeself 2.5.0 等,下载地址清单见 docs/zh/build.md),拷贝到output/third_party/对应子目录后编译:
# 创建目录结构 mkdir -p output/third_party/{abseil-cpp,json,boost,protobuf,symengine,gtest,mockcpp,makeself} # 将包放入对应目录,再指定路径编译 bash build.sh --pkg --cann_3rd_lib_path=$(pwd)/output/third_party关键细节:
mockcpp-2.7-h5.patch是 mockcpp 编译必需的补丁,CMake 会在解压后自动执行git init && git apply应用(优先查找output/third_party/mockcpp-2.7-h5.patch,备用路径output/third_party/pkg/);若缺失,离线环境会构建失败。同时必须保证 CANN 安装路径(安装.run包与 cann-toolkit 的路径一致)与构建环境匹配。
九、编译产物说明
9.1 目录结构
build/ # 编译中间文件(CMAKE_INSTALL_PREFIX) ├── super_kernel/ │ ├── libascendsk.so # SuperKernel 动态库 │ └── superkernel-*.whl # Python wheel 包 ├── autofuse/ │ ├── libaihac_codegen.so # autofuse 编译器核心库 │ ├── compiler/py_module/pyautofuse.so # Python 绑定 │ ├── ascir/meta/libascir.so │ ├── ascir/generator/libascir_builtin_ops.so │ ├── graph_metadef/graph/ │ │ ├── libgraph_af.so │ │ ├── libgraph_base_af.so │ │ ├── expression/libaihac_symbolizer_af.so │ │ └── ascendc_ir/ │ │ ├── libaihac_ir.so │ │ └── generator/ │ │ ├── libascir_generate.so │ │ └── libaihac_ir_register.so │ └── tests/ # 测试专用 .so(仅测试时生成) └── _CPack_Packages/ # 打包中间文件 build_out/ # 最终输出 └── cann-graph-autofusion_*.run # 运行包(可部署)9.2 正式产物 .so 清单(11 个)
| .so | 编译目标 | 说明 |
|---|---|---|
libascendsk.so | ascendsk | SuperKernel 动态库 |
libaihac_codegen.so | aihac_codegen | Autofuse 编译器核心 |
libgraph_af.so | graph_af | 图定义库 |
libgraph_base_af.so | graph_base_af | 图基础设施 |
libaihac_ir.so | aihac_ir | AIHAC IR |
libaihac_ir_register.so | aihac_ir_register | AIHAC IR 注册 |
libaihac_symbolizer_af.so | aihac_symbolizer_af | 符号化库 |
libascir.so | ascir | ASCIR 中间表示 |
libascir_builtin_ops.so | ascir_builtin_ops | ASCIR 内置算子 |
libascir_generate.so | ascir_generate | ASCIR 代码生成 |
pyautofuse.so | pyautofuse | Python 绑定模块 |
十、run 包安装与卸载(测试前置条件)
重要:执行 UT/ST 测试前,必须先安装编译生成的
.run包。否则测试运行时LD_LIBRARY_PATH会加载到 CANN 安装路径下的旧版本动态库,导致undefined symbol等运行时错误。
安装
# 如需指定安装路径,则加上 --install-path=${install_path} ./build_out/cann-graph-autofusion_${cann_version}_linux-${arch}.run --full --quiet --pylocal--full:全量模式安装;--install-path:指定安装路径,默认/usr/local/Ascend(root 用户)或${HOME}/Ascend(非 root 用户),且需与 cann-toolkit 安装路径保持一致;--quiet:静默安装,跳过人机交互;--pylocal:将包内.whl跟随 run 包路径安装(否则装入本地 python 的 site-packages)。
卸载
# 指定路径安装时同样加上 --install-path ./build_out/cann-graph-autofusion_${cann_version}_linux-${arch}.run --uninstall安装完成后可参考 super_kernel/examples/README.md 与 autofuse/examples/pytorch/README.md 尝试运行样例。
十一、常见编译错误排查
| 问题 | 根因 | 解决方案 |
|---|---|---|
no type named 'SkSystemArgs' | CANN Toolkit 版本过低 | 使用 >= 9.1.0,执行source /home/developer/Ascend/master/cann-9.1.0/set_env.sh切换 master 版本 |
| CANN Toolkit 未找到 | ASCEND_HOME_PATH未设置或未安装 | 执行source ${ASCEND_HOME_PATH}/set_env.sh;未安装则使用/cann-toolkit-installer安装 |
| 编译 OOM(Killed) | 编译默认并行度无限制 | 必须使用-j 8限制并行线程数 |
| 第三方依赖下载失败 | 网络不通 / 缺离线包 | 配置代理,或手动下载到output/third_party/(mockcpp 需同时准备 patch 文件) |
| CMake 版本过低 | 环境 CMake 过旧 | 升级到 >= 3.16.0 |
| Python 版本不兼容 | 环境 Python 过旧 | 使用 Python 3.9+ 虚拟环境 |
| 增量编译后链接错误 | 切换了 Build Type 或 Toolkit 版本但未清理build/ | 执行rm -rf build后全量重建 |
十二、结语:一条可落地的构建工作流
综合 SKILL 文档与仓库源码,推荐一条经过验证的日常构建路径:
- 环境准备:安装 CANN Toolkit >= 9.1.0,
source ${ASCEND_HOME_PATH}/set_env.sh,创建 Python 3.9+ 虚拟环境并pip3 install -r super_kernel/requirements-dev.txt,运行 scripts/check_env.sh 体检; - 首次全量编译:
rm -rf build && sh build.sh --pkg -j 8(确保第三方依赖自动下载或离线就绪); - 日常迭代:修改源码后
cmake --build build --target <目标> -j 8增量编译,配合sh build.sh -u --module=<模块> --impl=<py|cpp>快速验证; - 发版打包:
sh build.sh --pkg -j 8生成build_out/cann-graph-autofusion_*.run,安装后执行 UT/ST 全量回归(sh build.sh -u/-s -c可同时采集覆盖率)。
把「加-j 8」「优先增量」「切 Build Type/Toolkit 必清 build」「UT/ST 前先装 run 包」四条铁律内化成习惯,就能在 graph-autofusion 的编译构建上少踩绝大多数坑。
【免费下载链接】graph-autofusionGraph-autofusion 是一个面向昇腾(Ascend)芯片的轻量级、解耦式组件集合,旨在通过自动融合技术加速模型执行。 目前已开源 SuperKernel 组件和 Autofuse 组件,未来将持续开放更多自动融合相关模块。项目地址: https://gitcode.com/cann/graph-autofusion
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考