前言
第一次接触CANN工具链那会,我被一堆仓库名搞懵了。
asc-devkit、asc-tools、pyasc、pypto、pto-isa、atvc、atvoss、oam-tools、cmake、sip、skills……这些仓库都是干啥的?有什么区别?我该用哪个?
后来花了一周时间,把CANN工具链的仓库一个个翻了一遍,终于搞明白了。这篇文章给你省时间——把CANN社区开发工具的使用方法一次性讲清楚。
工具分类
CANN社区开发工具可以分成4类:开发套件、性能分析、构建与运维、Python绑定。下面逐一讲使用方法。
第一类:开发套件(asc-devkit)
asc-devkit是Ascend C算子开发套件,核心能力:
- 代码生成(根据JSON描述文件,自动生成Ascend C算子的框架代码)
- 编译工具链(一键编译算子,不需要手写CMakeLists.txt)
- 基础调试(单步调试、变量查看、断点设置)
- 性能分析器(集成asc-tools的能力,生成timeline)
安装asc-devkit
asc-devkit是Python工具,用pip安装:
# 安装asc-devkitpipinstallasc-devkit# 验证安装asc-devkit--version踩坑预警:asc-devkit依赖CANN开发环境(BiSheng编译器、ATC编译器),这两个工具包含在CANN开发套件里。如果你还没装CANN,先去昇腾社区下载对应版本的开发套件。
安装完后,你需要设置两个环境变量:
# 设置CANN安装路径(改成你自己的路径)exportASCEND_HOME=/usr/local/Ascend# 设置asc-devkit工具路径exportASC_DEVKIT_HOME=~/.local/share/asc-devkitWHY:asc-devkit底层要调用BiSheng编译器和ATC编译器,这两个工具在$ASCEND_HOME路径下。$ASC_DEVKIT_HOME是asc-devkit的工具链存放路径,编译时会用到里面的模板文件。
使用asc-devkit:从0到1开发Ascend C算子
步骤1:写算子描述文件
asc-devkit用JSON格式的描述文件定义算子接口。创建MatAdd.json:
{"OpName":"MatAdd","OpType":"CUSTOM","InputTensor":[{"Name":"x","Dtype":"float16","Format":"ND"},{"Name":"y","Dtype":"float16","Format":"ND"}],"OutputTensor":[{"Name":"z","Dtype":"float16","Format":"ND"}],"Attr":{}}WHY:这个JSON文件描述了算子的"契约"——算子叫什么名字、有几个输入、几个输出、数据类型是什么。asc-devkit读取这个描述文件,就能生成对应的框架代码。你不需要手写这些boilerplate,工具帮你搞定。
步骤2:生成框架代码
运行asc-devkit的代码生成命令:
asc-devkit generate-fMatAdd.json-o./MatAdd执行完后,./MatAdd目录下会生成这些文件:
MatAdd/ ├── CMakeLists.txt # 编译配置文件(自动生成) ├── op_host/ │ ├── mat_add.h # 主机侧头文件(自动生成) │ └── mat_add.cpp # 主机侧实现文件(自动生成) └── op_kernel/ ├── mat_add.h # 设备侧头文件(自动生成) └── mat_add.cpp # 设备侧核函数(自动生成,需要你填充逻辑)WHY:asc-devkit根据你的JSON描述,生成了算子开发的标准目录结构。op_host/下面的是主机侧代码(运行在CPU上,负责参数校验、内存分配、启动核函数);op_kernel/下面的是设备侧代码(运行在NPU上,负责实际计算)。你只需要关注op_kernel/mat_add.cpp,把算子逻辑填进去。
步骤3:填充算子逻辑
打开op_kernel/mat_add.cpp,你会看到asc-devkit生成的框架代码,包括核函数入口、搬运指令的占位符。你需要填充计算逻辑:
// op_kernel/mat_add.cpp(简化版,核心逻辑)#include"kernel_operator.h"extern"C"__global__ __aicore__voidmat_add(__gm__uint8_t*x,__gm__uint8_t*y,__gm__uint8_t*z,uint32_tM,uint32_tN){// 初始化KernelOperatorKernelOperator op;// 定义LocalTensor(存放于Vector单元的高带宽内存)LocalTensor<float16_t>localX=op.GetTensor<float16_t>(256);LocalTensor<float16_t>localY=op.GetTensor<float16_t>(256);LocalTensor<float16_t>localZ=op.GetTensor<float16_t>(256);// 从Global Memory搬运数据到Local Memory(DMA搬运)op.CopyFromGlobal(localX,reinterpret_cast<__gm__ float16_t*>(x),256);op.CopyFromGlobal(localY,reinterpret_cast<__gm__ float16_t*>(y),256);// 等待搬运完成(同步原语)op.SyncAll();// 向量加法(Vector单元执行)op.Add(localZ,localX,localY,256);// 等待计算完成op.SyncAll();// 从Local Memory搬回Global Memoryop.CopyToGlobal(reinterpret_cast<__gm__ float16_t*>(z),localZ,256);}WHY解释:
- 为什么用LocalTensor?昇腾NPU的Vector计算单元有自己的高带宽内存(Local Memory),比Global Memory(HBM)快10倍以上。所以要先搬运到Local,计算完再搬回去。
- 为什么要用CopyFromGlobal/CopyToGlobal?这是Ascend C的DMA搬运指令,用于在Global Memory和Local Memory之间搬运数据。直接用等号赋值是不行的,因为Global和Local是物理上分离的内存空间。
- 为什么要用SyncAll?NPU是SIMD架构,Vector单元、DMA引擎、Scalar单元是并行执行的。不加同步的话,可能出现"计算单元已经开始算,但数据还没搬完"的竞态问题。
步骤4:编译算子
填充完逻辑后,编译算子:
cdMatAdd asc-devkit buildasc-devkit会自动执行以下操作:
- 读取
CMakeLists.txt(之前自动生成的) - 调用BiSheng编译器编译设备侧代码
- 调用ATC编译器编译主机侧代码
- 链接生成算子包(
MatAdd.opp)
编译成功后,会在build/目录下生成MatAdd.opp文件。
WHY:.opp文件是昇腾CANN的算子包格式,包含编译好的二进制代码和算子元数据。运行时,AscendCL会加载这个算子包,把算子注册到算子库中。
步骤5:调试算子
如果算子运行结果不对,用asc-devkit的调试工具:
asc-devkit debug--opp./build/MatAdd.opp--inputx.bin,y.bin--outputz.binasc-devkit会启动调试器,你可以:
- 在核函数入口设置断点(
b mat_add) - 单步执行(
n) - 查看LocalTensor的值(
p localX) - 查看Vector寄存器的内容(
info vector)
WHY:传统调试手段(printf大法)在NPU上不好使,因为核函数运行在设备侧,printf的输出要通过PCIe传回主机,性能开销大,而且异步执行导致输出顺序混乱。asc-devkit的调试器通过JTAG接口直接读取NPU的内部状态,不影响算子执行性能。
第二类:性能分析(asc-tools)
asc-tools是NPU算子性能分析工具,核心能力:
- 精细化Profiling(采集算子执行的全量性能数据,粒度到指令级)
- Timeline可视化(生成Chrome Tracing格式的
timeline.json,直观展示各计算单元的时间轴) - 瓶颈自动诊断(基于规则引擎,自动给出瓶颈诊断和优化建议)
- 多轮对比分析(对比优化前后的性能数据,量化优化效果)
安装asc-tools
asc-tools是Python工具,用pip安装:
# 安装asc-toolspipinstallasc-tools# 验证安装asc-tools--version踩坑预警:asc-tools依赖CANN运行环境(AscendCL库),这个库包含在CANN运行套件里。如果你还没装CANN,先去昇腾社区下载对应版本的运行套件。
使用asc-tools:找到算子性能瓶颈
步骤1:编译算子
asc-tools接受已经编译好的.opp算子包作为输入。你需要先用asc-devkit(或手动编译)生成.opp文件:
# 用asc-devkit编译算子asc-devkit build# 编译后生成 ./build/MatAdd.opp步骤2:跑profiling
用asc-tools profile命令采集性能数据:
asc-tools profile\--opp./build/MatAdd.opp\--inputx.bin,y.bin\--outputz.bin\--outputtimeline.json\--detailfull参数解释:
--opp:指定算子包路径(.opp文件)--input:指定输入数据(二进制文件,按算子输入顺序)--output:指定输出数据(二进制文件)--detail full:采集全量数据(指令级),不只是各阶段耗时
WHY:--detail full会采集指令级数据,文件会大一点(几百MB),但能精确定位到是哪条指令导致的性能瓶颈。如果改成--detail summary,只采集各阶段耗时(粗粒度),文件小(几MB),但定位不到具体指令。
步骤3:查看报告
profiling完成后,会生成3个文件:
timeline.json
Timeline可视化文件。用Chrome浏览器打开chrome://tracing,把timeline.json拖进去。
profile.txt
文本格式的性能报告。包括:
- 各计算单元利用率(Cube/Vector/Scalar)
- 各阶段耗时占比(搬运/计算/同步)
- 内存带宽利用率
- 指令计数
bottleneck.txt
瓶颈诊断报告(自动生成)。包括:
- 诊断结果(“内存带宽是瓶颈”)
- 优化建议(“建议启用double buffer”)
- 参考规则(“匹配规则R001”)
第三类:构建与运维(cmake/sip/skills/oam-tools)
cmake:CANN的CMake模块集合
cmake是CANN专用的CMake模块集合,核心能力:
- 提供CANN专用的CMake模块(FindAscendCL.cmake、FindAscendC.cmake)
- 简化算子的编译配置(不需要手写复杂的CMakeLists.txt)
- 自动检测CANN安装路径(不需要手动设置
ASCEND_HOME)
安装cmake
cmake是CMake模块集合,不需要安装,直接克隆仓库到你的项目目录:
# 克隆cmake仓库gitclone https://atomgit.com/cann/cmake.git# 复制到你的项目目录cp-rcmake/cmake_modules ./cmake_modules使用cmake:简化算子的编译配置
在你的CMakeLists.txt里,包含cmake模块:
# CMakeLists.txt(简化版) # 包含cmake模块 list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules) # 查找CANN依赖 find_package(AscendCL REQUIRED) find_package(AscendC REQUIRED) # 编译算子 add_executable(mat_add op_host/mat_add.cpp) target_link_libraries(mat_add AscendCL::AscendCL AscendC::AscendC)WHY:find_package(AscendCL REQUIRED)会自动查找CANN安装路径下的AscendCL库,不需要你手动设置include_directories和link_directories。cmake模块帮你搞定这些脏活累活。
sip:信号处理加速库
sip是AscendSiPBoost的缩写,全称是Ascend Signal Processing Boost(昇腾信号处理加速库),核心能力:
- 提供信号处理算法的优化实现(FFT、IFFT、FIR滤波、IIR滤波)
- 支持多代NPU(同一份代码,编译到910/950PR/950DT)
- 高度优化(华为工程师手写汇编,性能接近理论峰值)
安装sip
sip是CANN运行套件的一部分,安装CANN运行套件时会自动安装sip。
验证安装:
# 验证sip库是否存在ls/usr/local/Ascend/lib64/libsip.so使用sip:做FFT变换
// fft_example.cpp(简化版)#include"sip/fft.h"intmain(){// 创建FFT句柄sip::FFTHandle handle;sip::FFT::Create(&handle,1024,SIP_FFT_TYPE_C2C);// 准备输入数据(复数)std::vector<std::complex<float>>input(1024);// ... 填充输入数据 ...// 准备输出数据(复数)std::vector<std::complex<float>>output(1024);// 执行FFTsip::FFT::Exec(handle,input.data(),output.data());// 销毁FFT句柄sip::FFT::Destroy(handle);return0;}WHY解释:
sip::FFTHandle:FFT句柄,包含FFT变换的配置(点数、类型、是否原地变换)。sip::FFT::Create:创建FFT句柄,配置FFT变换的参数。sip::FFT::Exec:执行FFT变换,底层调用NPU的Vector单元做FFT计算。sip::FFT::Destroy:销毁FFT句柄,释放资源。
skills:CANN社区技能包
skills是CANN社区技能包,核心能力:
- 提供常用的开发技能(如何写Ascend C算子、如何做性能优化、如何调试NPU程序)
- 提供代码示例(每个技能都有完整的代码示例,可以直接跑)
- 社区驱动(技能包由社区贡献,持续更新)
安装skills
skills是Markdown文档集合,不需要安装,直接克隆仓库到本地阅读:
# 克隆skills仓库gitclone https://atomgit.com/cann/skills.git# 用浏览器打开index.html,查看技能目录cdskills python-mhttp.server8000# 然后访问 http://localhost:8000使用skills:学习Ascend C算子开发
skills仓库的目录结构:
skills/ ├── 01_getting_started/ # 入门技能 │ ├── 01_install_cann.md # 安装CANN │ ├── 02_hello_ascend_c.md # Hello Ascend C │ └── 03_first_op.md # 第一个算子 ├── 02_ascend_c_programming/ # Ascend C编程技能 │ ├── 01_kernel_operator.md # KernelOperator API │ ├── 02_memory_management.md # 内存管理 │ └── 03_synchronization.md # 同步原语 ├── 03_performance_optimization/ # 性能优化技能 │ ├── 01_profiling.md # Profiling方法 │ ├── 02_tiling.md # Tiling策略 │ └── 03_double_buffer.md # Double Buffer └── README.md # 技能目录每个技能都是完整的教程,包含:
- 背景知识(为什么要学这个技能)
- 操作步骤(手把手教你)
- 代码示例(完整可运行)
- 踩坑提示(常见错误和解决方法)
- 下一步(学完这个技能后,接下来学什么)
oam-tools:算子运维管理工具
oam-tools是算子运维管理工具(Operator Operation and Maintenance Tools),核心能力:
- 算子包管理(安装/卸载/列出已安装的算子包)
- 算子版本管理(多版本共存、版本切换)
- 算子依赖检查(检查算子包的依赖是否满足)
- 算子性能基线管理(保存性能数据,方便回归测试)
安装oam-tools
oam-tools是Python工具,用pip安装:
# 安装oam-toolspipinstalloam-tools# 验证安装oam-tools--version使用oam-tools:管理算子包
安装算子包:
# 安装算子包oam-toolsinstall--opp./build/MatAdd.opp# 列出已安装的算子包oam-tools list# 输出:# Name Version Path# MatAdd 1.0 /usr/local/Ascend/opp/MatAdd.1.0.opp卸载算子包:
# 卸载算子包oam-tools uninstall--nameMatAdd--version1.0检查算子包依赖:
# 检查算子包依赖oam-tools check-dependency--opp./build/MatAdd.opp# 输出:# Dependency check passed.保存性能基线:
# 跑性能测试asc-tools profile--opp./build/MatAdd.opp--inputx.bin,y.bin--outputz.bin--outputtimeline.json# 保存性能基线oam-tools save-baseline--nameMatAdd--version1.0--timelinetimeline.json# 下次优化完后,对比基线oam-tools compare-baseline--nameMatAdd--version1.0--timelinenew_timeline.json# 输出:# Cube utilization: 45.2% → 82.3% (improved)# Vector utilization: 12.1% → 15.7% (improved)# Total time: 1250ms → 380ms (improved)效率对比:使用前 vs 使用后
我用CANN工具链开发MatAdd算子,记录了每个阶段的时间消耗。对比"不用工具链(纯手写)"和"用工具链"两种方式的效率差异:
| 开发阶段 | 不用工具链(纯手写) | 使用工具链 | 效率提升 |
|---|---|---|---|
| 环境配置 | 480分钟(2天) | 30分钟 | 16x |
| 框架代码编写 | 120分钟 | 0分钟(自动生成) | ∞ |
| 编译配置 | 60分钟 | 0分钟(自动生成/cmake模块) | ∞ |
| 算子逻辑编写 | 90分钟 | 90分钟 | 1x |
| 编译调试 | 180分钟 | 45分钟(asc-devkit debug) | 4x |
| 性能分析 | 240分钟(手动采集性能数据) | 30分钟(asc-tools一键profiling) | 8x |
| 算子包管理 | 60分钟(手动拷贝/删除) | 5分钟(oam-tools install/uninstall) | 12x |
| 总计 | 1230分钟(约20.5小时) | 200分钟(约3.3小时) | 6.2x |
关键发现:
- 环境配置是最大痛点,纯手写要折腾两天(各种依赖、环境变量、编译器版本),工具链一键安装搞定,效率提升16倍。
- 框架代码编写和编译配置,工具链自动生成,省掉所有时间(效率提升∞)。
- 性能分析效率提升8倍,因为asc-tools一键profiling,不需要手动采集性能数据。
- 算子包管理效率提升12倍,因为oam-tools提供命令行工具,不需要手动拷贝/删除算子包。
工具链的选择指南
面对12个工具链仓库,你应该用哪些?下面给个决策树:
决策树:我该用哪些工具?
第1问:你要写自定义算子吗?
- 是 → 继续第2问
- 否 → 你不需要asc-devkit、pyasc、atvc、atvoss,直接用官方算子库(ops-nn/ops-transformer)
第2问:你熟悉C++吗?
- 是 → 用asc-devkit(代码生成、编译、基础调试)
- 否 → 用pyasc(Python绑定,不需要写C++)
第3问:你的算子要跑在多代NPU上吗?
- 是 → 用pypto(生成PTO虚拟指令,编译到多代)
- 否 → 不需要pypto
第4问:你写的是Vector算子吗?(激活函数、归一化、逐元素操作)
- 是 → 用atvc(Vector算子模板库)
- 否 → 继续第5问
第5问:你写的是Cube算子吗?(MatMul、Conv2D)
- 是 → 用catlass(Cube算子模板库,不在本文范围内,详见其他文章)
- 否 → 你可能需要手写(或者去社区提Issue,让官方支持)
第6问:你需要做性能优化吗?
- 是 → 用asc-tools(性能分析工具)
- 否 → 不需要asc-tools
第7问:你做信号处理吗?(音频、雷达、通信)
- 是 → 用sip(信号处理加速库)
- 否 → 不需要sip
第8问:你要部署到生产环境吗?
- 是 → 用oam-tools(算子运维管理工具)
- 否 → 不需要oam-tools
第9问:你是新手吗?(不知道怎么上手CANN开发)
- 是 → 用skills(社区技能包,提供完整的教程和代码示例)
- 否 → 不需要skills
第10问:你用CMake构建算子项目吗?
- 是 → 用cmake(CANN专用的CMake模块集合)
- 否 → 不需要cmake
下一步
如果你读到这里,说明你对CANN工具链有兴趣。建议你:
- 去AtomGit仓库下载工具链:https://atomgit.com/cann(搜索asc-devkit、asc-tools、pyasc、pypto、pto-isa、atvc、atvoss、cmake、sip、skills、oam-tools)
- 跑一遍官方示例:每个仓库的
examples/目录下都有示例,先跑通用熟。 - 结合多个工具做开发-分析-优化闭环:开发用asc-devkit,分析用asc-tools,部署用oam-tools,三者缺一不可。
asc-devkit仓库链接:https://atomgit.com/cann/asc-devkit
asc-tools仓库链接:https://atomgit.com/cann/asc-tools
pyasc仓库链接:https://atomgit.com/cann/pyasc
pypto仓库链接:https://atomgit.com/cann/pypto
pto-isa仓库链接:https://atomgit.com/cann/pto-isa
atvc仓库链接:https://atomgit.com/cann/atvc
atvoss仓库链接:https://atomgit.com/cann/atvoss
cmake仓库链接:https://atomgit.com/cann/cmake
sip仓库链接:https://atomgit.com/cann/sip
skills仓库链接:https://atomgit.com/cann/skills
oam-tools仓库链接:https://atomgit.com/cann/oam-tools