算子开发工具链快速入门
1. 概述
MindStudio 算子开发工具链包含多种工具。本文档以开发一个简单加法算子为例,带您贯穿算子开发全流程,直观体验工具链带来的高效与便捷。
1.1 前言
体验地图 (核心操作仅需 10 分钟)
执行顺序建议:步骤 1 为基础;完成 1 后可体验 2 或 3;步骤 4、5、6 均依赖步骤 3 生成的工程,但这三者之间相互独立,可按需选学。
| 步骤 | 环节 | 核心工具 | 实测操作耗时 | 建议原理学习 |
|---|---|---|---|---|
| 1 | 环境准备 | CANN容器镜像 |
3分钟 | 5分钟 |
| 2 | 算子设计 | msKPP |
30 秒 | 5分钟 |
| 3 | 工程开发 | msOpGen |
1 分钟 | 20分钟 |
| 4 | 异常检测 | msSanitizer |
1 分钟 | 10分钟 |
| 5 | 原生调试 | msDebug |
1 分钟 | 10分钟 |
| 6 | 性能调优 | msOpProf |
1 分钟 | 10分钟 |
1.2 环境准备
👉 【重要】请严格按 《昇腾 AI 算子开发工具链学习环境安装指南》完成环境安装和配置。
注意
本教程专为标准化容器环境设计。请务必依据上述安装指南完成容器部署;若当前环境不符(如裸机或虚拟机等非容器环境),请暂缓体验,以免因依赖缺失或配置差异引发难以诊断的问题,待环境满足要求后再操作。
2. 操作步骤
说明
后续体验环节全程支持 Copy/Paste 快速执行,请按照每节中的步骤顺序操作,勿跳过或打乱操作步骤。
2.1【环境】运行环境预检
2.1.1 验证环境变量配置
执行如下指令,确认系统输出正确的芯片 SoC 型号信息(如 910B4、910_9392):
echo $MY_STUDY_VAR_CHIP_SOC_TYPE
若该变量为空,参照 1.2 环境准备 正确设置。务必确保此环境变量已正确配置,否则后续步骤将频繁报错。
2.1.2 确认代码仓正常
执行以下命令,若能正常列出目录内容,则说明代码仓已正确就位:
ls -al ~/ot_demo/msot/example/quick_start
若命令报错,请参照 1.2 环境准备 完成准备。
2.2【设计】算子建模设计(msKPP)
首先,进行算子算法设计。借助 msKPP 工具,可在秒级时间内获得算子性能建模结果,在无硬件条件下预估性能,快速验证实现方案的可行性。先跟着操作体验效果,原理部分可稍后阅读:
说明
知识点:msKPP 工具原理
msKPP 并非传统可执行程序,而是一套专用于昇腾的 Python 类库。用户需通过 import 相关模块、编写并执行 Python 脚本,生成性能分析结果文件以完成建模。内部原理是预先采集真实环境中各类指令操作的性能数据,基于用户定义的算子执行流程,对各种性能开销进行建模与估算。
2.2.1 编写 Python 建模脚本
-
创建子工作区目录
mkdir -p ~/ot_demo/workspace/mskpp && cd ~/ot_demo/workspace/mskpp -
开发 Python 脚本
说明
知识点(可选阅读):msKPP 的 DSL 语言方案(Domain-Specific Language,领域特定语言)
这套类库及接口是专为昇腾性能建模而设计的“方言”,需经过专门学习方可掌握,无法仅凭通用 Python 语法直接编写,但用法较简单,稍加学习即可应用。 常规开发流程:需先导入 Tensor、Chip 以及算子实现所必需的指令(例如 vadd),通过 with 语句进入算子实现代码的上下文,再创建 Tensor 以执行具体操作,样例脚本中已做了详细的注释,其他指令接口说明请参考《msKPP 工具接口说明》。因是快速入门,将准备好的 msKPP 的 DSL 脚本复制到此即视为开发完成(本教程聚焦工具链使用,实际开发需自行实现):
\cp -f ~/ot_demo/msot/example/quick_start/mskpp/mskpp_demo.py ./
2.2.2 执行性能建模
执行 Python 脚本开始性能建模,如果成功,将自动在当前目录下生成 "MSKPP{timestamp}" 结果目录:
python3 mskpp_demo.py
如果脚本报错,提示 Chip is unsupported,请确认环境变量 MY_STUDY_VAR_CHIP_SOC_TYPE 是否正确设置,如变量为空,请参考1.2 环境准备正确设置。
2.2.3 查看建模结果
以下为部分生成结果文件的示例:
MSKPP{timestamp}/
├── Instruction_statistic.csv
├── Pipe_statistic.csv
└── trace.json
以 Instruction_statistic.csv 为例,其内容如下:
| Instruction | Duration(us) | Cycle | Size(B) | Ops |
|---|---|---|---|---|
| MOV-GM_TO_UB | 0.3081 | 570 | 6144 | - |
| VADD | 0.0135 | 25 | - | 1536 |
| MOV-UB_TO_GM | 0.4254 | 787 | 3072 | - |
由上述内容可见,MOV-UB_TO_GM(从 UB 搬移到 GM)的耗时(Duration)最长,指令周期数(Cycle)也最多,是性能优化中需重点关注的关键路径。在实际开发中,如果发现此类内存搬运耗时占比过高,应优先考虑优化数据复用(Tiling)或使用更高效的搬运指令。
2.3【开发】构建算子工程(msOpGen)
算法设计完成后,即可进入算子代码编写阶段。算子工程较为复杂且包含大量框架代码,msOpGen 工具可自动生成完整的算子工程框架,使开发者聚焦于核心算法实现,避免在项目搭建、编译配置等重复性工作上耗费时间。先跟着操作体验效果,原理部分可稍后阅读:
2.3.1 生成工程框架
-
创建子工作区目录
创建名为
src的子目录,作为算子源码根目录,后续所有源码操作均基于此路径开展:mkdir -p ~/ot_demo/workspace/src && cd ~/ot_demo/workspace/src/ -
开发算子定义配置文件
说明
知识点(可选阅读):msOpGen 输入配置文件
自定义格式的 json 配置文件,可以简单类比理解为定义了一个 C 语言函数的声明,包括:函数名、入参及返回值的类型信息。 比如 msopgen_demo.json 中就是定义了算子的名字、输入输出变量的名字、类型、数据排布格式。 算子函数的声明代码统一由工具生成,即生成一个空函数(只有函数名、入参和返回值),函数体需要用户自己实现。因是快速入门,将准备好的配置文件拷贝到此即视为开发完成(本教程聚焦工具链使用,实际开发需自行实现):
\cp -f ~/ot_demo/msot/example/quick_start/msopgen/msopgen_demo.json ./ -
基于配置生成代码框架
执行以下命令生成 Ascend C 算子工程,参数说明:-lan cpp 表明要生成 Ascend C 代码;-c 为芯片 SoC 型号(不同芯片处理上可能有区别):
msopgen gen -i msopgen_demo.json -c ai_core-ascend${MY_STUDY_VAR_CHIP_SOC_TYPE} -lan cpp -out AddCustom注意
上述命令生成的代码框架中,具体算子的实现为空,无法正常执行加法运算,需按照 2.3.2节 内容进行修改后方可正常运行。
-
查看生成的结果
说明
知识点(可选阅读):关键概念
Host 侧:运行于 CPU 的代码,负责数据预处理、任务调度及算子调用。
Kernel 侧:运行于 NPU 的代码,负责执行实际的大规模并行计算逻辑。
Tiling:将大规模数据分块处理,以提高 Local Memory 利用率并优化内存访问效率。以下为部分生成结果文件的示例,生成的工程结构看起来庞大而复杂,但我们仅需关注标记为【用户扩展点】的三个C++文件,其余均为框架代码,无特殊需求无需查看修改:
AddCustom ├── build.sh // 编译入口脚本 ├── CMakeLists.txt // 算子工程的CMakeLists.txt ├── framework // 算子插件实现文件目录,单算子模型文件的生成不依赖算子适配插件,无需关注 │ ├── CMakeLists.txt │ └── tf_plugin ├── op_host // Host侧实现文件 │ ├── add_custom.cpp // 【用户扩展点】算子原型注册、shape推导、信息库、tiling实现等内容文件 │ └── CMakeLists.txt ├── op_kernel // Kernel侧实现文件 │ ├── add_custom.cpp // 【用户扩展点】算子代码实现文件 │ ├── add_custom_tiling.h // 【用户扩展点】算子tiling定义文件 │ └── CMakeLists.txt └── CMakePresets.json // 编译配置项
2.3.2 实现核心逻辑
说明
知识点(可选阅读):算子核心代码文件实现原理
op_host/add_custom.cpp:实现 Host 侧的 Tiling 计算逻辑与算子原型注册。
op_kernel/add_custom_tiling.h:定义 Tiling 分块策略的数据结构。
op_kernel/add_custom.cpp:实现 Kernel 侧加法算子的具体计算逻辑(GM→UB 搬运→向量加法→UB→GM 写回)。
若需深入理解上述三个文件的功能与协作机制,除参考代码注释外,建议详细阅读《昇腾Ascend C编程入门教程(纯干货)》。
如下 keep_soc_info.py 原理说明:此脚本会自动获取当前环境的SoC信息,并自动刷新到cpp文件中。
在上述三个【用户扩展点】文件中实现具体算法逻辑。因是快速入门,将准备好的 3 个 C++ 文件拷贝到此即视为开发完成(本教程聚焦工具链使用,实际开发需自行实现核心逻辑):
cd ~/ot_demo/workspace/src/AddCustom/
python3 ~/ot_demo/msot/example/quick_start/msopgen/keep_soc_info.py get ./op_host/add_custom.cpp
\cp -f ~/ot_demo/msot/example/quick_start/msopgen/code/op_host/add_custom.cpp ./op_host/
\cp -f ~/ot_demo/msot/example/quick_start/msopgen/code/op_kernel/add_custom_tiling.h ./op_kernel/
\cp -f ~/ot_demo/msot/example/quick_start/msopgen/code/op_kernel/add_custom.cpp ./op_kernel/
python3 ~/ot_demo/msot/example/quick_start/msopgen/keep_soc_info.py set ./op_host/add_custom.cpp
2.3.3 编译与部署算子
-
编译算子
执行构建脚本,成功后将在 build_out 目录下生成 .run 格式的算子部署包(sed 命令用于规避某些环境下的并发 pipe 问题,将打包改为串行):
sed -i 's/--target $target -j$(nproc)/--target $target -j1/g' build.sh bash ./build.sh -
部署算子
说明
知识点:什么是部署算子
部署算子是指将算子注册到 CANN 框架中,本质上是将算子的二进制文件拷贝至系统公共目录,使其他程序能够通过标准接口(如 CANN API 或 PyTorch 等)自动发现并调用该算子。*.run 的部署包格式可以简单理解为一种自解压的压缩包。因各平台生成的算子部署包名称略有差异,执行以下脚本以自动定位并运行部署包(在固定环境中,实际等效于执行类似 ./build_out/custom_opp_ubuntu_aarch64.run 的命令):
MY_OP_PKG=$(find ./build_out -maxdepth 1 -name "custom_opp_*.run" | head -1) && bash $MY_OP_PKG -
加入动态库路径
部署成功后,按终端提示追加算子依赖的动态库路径:
export LD_LIBRARY_PATH=${ASCEND_OPP_PATH}/vendors/customize/op_api/lib:$LD_LIBRARY_PATH echo "export LD_LIBRARY_PATH=${ASCEND_OPP_PATH}/vendors/customize/op_api/lib:$LD_LIBRARY_PATH" >> ~/.bashrc
2.3.4 验证算子功能
注意
关于 NPU 设备选择的说明
执行以下 run.sh 脚本将实际运行算子,会随机选择一张空闲卡执行任务。
若因随机选定的卡存在故障等原因需指定 NPU 卡,请根据 npu-smi info 命令返回的 NPU 信息,使用其顺序号(取值范围为 [0, NPU 数量 - 1])按如下方式调用:bash ./run.sh 2
执行算子调用工程,验证算子功能(本例执行 1.0 + 2.0,预期结果为 3.0):
\cp -rf ~/ot_demo/msot/example/quick_start/msopgen/caller ~/ot_demo/workspace/src/
cd ~/ot_demo/workspace/src/caller
bash ./run.sh
若输出如下内容,结果为 3.0,则表明算子已成功加载并计算正确:
result is:
3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0
test pass
若超过 30 秒未返回结果,可能是 NPU 卡繁忙,可按 Ctrl+C 终止后切换至其他空闲卡重试;若出现类似如下错误,可能原因包括:NPU卡异常(硬件故障、驱动问题等),/dev/hisi_hdc 设备异常(如容器内未成功挂载、缺乏访问权限、因线程数过多导致设备无法打开等),以及内存等系统资源不足等。
错误码说明请参见:《ACL错误码表》,请先解决 NPU 卡故障或更换为其他正常卡后再继续体验(指定 NPU 卡运行的方法详见上文“关于 NPU 设备选择的说明”):
aclrtSetDevice failed. ERROR: xxxxxx
Init acl failed. ERROR: 1
2.3.5 备份 Kernel 侧 CMakeLists.txt
后续 3 个工具的执行都需要修改此 CMakeLists.txt,保留此备份,用于恢复环境:
\cp ~/ot_demo/workspace/src/AddCustom/op_kernel/CMakeLists.txt ~/ot_demo/workspace/src/AddCustom/op_kernel/CMakeLists.txt.bak
2.4【检测】算子异常检测(msSanitizer)
算子开发完成后,可借助 msSanitizer 工具检测是否存在内存越界、竞争条件、未初始化变量或同步异常等严重运行时缺陷,从而高效定位潜在的隐蔽性错误。先跟着操作体验效果,原理部分可稍后阅读:
2.4.1 修改编译选项
为启用检测能力,需在 Kernel 侧的 CMakeLists.txt 首行插入 sanitizer 编译选项,注入检测桩代码:
cd ~/ot_demo/workspace/src/AddCustom
printf '%s\n' "if(COMMAND add_ops_compile_options)" " add_ops_compile_options(ALL OPTIONS -sanitizer)" "elseif(COMMAND npu_op_kernel_options)" " npu_op_kernel_options(ascendc_kernels ALL OPTIONS -sanitizer)" "endif()" | cat - op_kernel/CMakeLists.txt > tmp && mv -f tmp op_kernel/CMakeLists.txt;
2.4.2 构造内存越界错误
将准备好的含缺陷代码的源文件覆盖原始实现,人为引入越界访问:
\cp -f ~/ot_demo/msot/example/quick_start/mssanitizer/bug_code/add_custom.cpp op_kernel/add_custom.cpp
说明
关键修改如下(2 * this->tileLength 试图读取 2 倍长度,超出 GM 内存中 xGm 的分配范围,触发 “非法读取”):
- AscendC::DataCopy(xLocal, xGm[progress * this->tileLength], this->tileLength);
+ AscendC::DataCopy(xLocal, xGm[progress * this->tileLength], 2 * this->tileLength);
2.4.3 重新编译部署
bash ./build.sh
MY_OP_PKG=$(find ./build_out -maxdepth 1 -name "custom_opp_*.run" | head -1) && bash $MY_OP_PKG
2.4.4 执行内存检测
cd ~/ot_demo/workspace/src/caller
mssanitizer --tool=memcheck -- bash run.sh
工具输出如下错误报告,则表明已成功执行(如下示例显示各版本可能会稍有不同,不影响学习工具使用):
- illegal read of size 224:表示非法读取了 224 字节。
- op_kernel/add_custom.cpp:44:9:表明越界访问发生在 add_custom.cpp 第 44 行。
====== ERROR: illegal read of size 224
====== at 0x12c0c001af00 on GM in AddCustom_ab1b6750d7f510985325b603cb06dc8b_0
====== in block aiv(7) on device 0
====== code in pc current 0x2928 (serialNo:555)
====== #0 /usr/local/Ascend/ascend-toolkit/8.3.RC2/aarch64-linux/tikcpp/tikcfw/impl/dav_c220/kernel_operator_data_copy_impl.h:77:9
====== #1 /usr/local/Ascend/ascend-toolkit/8.3.RC2/aarch64-linux/tikcpp/tikcfw/impl/kernel_operator_data_copy_intf_impl.h:53:9
====== #2 /usr/local/Ascend/ascend-toolkit/8.3.RC2/aarch64-linux/tikcpp/tikcfw/impl/kernel_operator_data_copy_intf_impl.h:502:5
====== #3 /home/mgx/ot_demo/workspace/src/caller/AddCustom/op_kernel/add_custom.cpp:44:9
====== #4 /home/mgx/ot_demo/workspace/src/caller/AddCustom/op_kernel/add_custom.cpp:33:13
====== #5 /home/mgx/ot_demo/workspace/src/caller/AddCustom/op_kernel/add_custom.cpp:83:8
====== #6 /home/mgx/ot_demo/workspace/src/caller/AddCustom/build_out/op_kernel/AddCustom_ascend910b/kernel_0/kernel_meta_AddCustom_ab1b6750d7f510985325b603cb06dc8b/kernel_meta/AddCustom_ab1b6750d7f510985325b603cb06dc8b_2130445_kernel.cpp:37:5
说明
算子执行后仍能成功输出正确结果,这正体现了该工具的价值:内存问题通常具有偶发性,在多数情况下即使存在内存异常,程序仍可正常运行;仅当问题累积至临界点时才会突发崩溃,难以通过表象直接定位。
2.4.5 恢复手工修改
为后续工具使用做准备,回退手工修改:
\cp -f ~/ot_demo/msot/example/quick_start/msopgen/code/op_kernel/add_custom.cpp ~/ot_demo/workspace/src/AddCustom/op_kernel/
\cp -f ~/ot_demo/workspace/src/AddCustom/op_kernel/CMakeLists.txt.bak ~/ot_demo/workspace/src/AddCustom/op_kernel/CMakeLists.txt
2.5【调试】断点调试算子代码(msDebug)
若算子功能异常,可借助 msDebug 工具进行断点调试,高效定位问题。先跟着操作体验效果,原理部分可稍后阅读:
2.5.1 开启内核调试开关
注意
msDebug 需以 root 权限启用内核调试开关 /proc/debug_switch
该开关默认关闭,仅 root 用户可修改。msDebug 必须在该开关开启后才能正常工作。
容器中操作通常无效:
即使在容器内以 root 身份成功写入 /proc/debug_switch,由于宿主机普遍对 /proc 使用写时复制(CoW)、影子文件或 overlay 挂载等机制进行虚拟化,该设置仅作用于容器视图,并未真正生效于内核。因此,即便 cat /proc/debug_switch 显示为 1,msDebug 仍可能无法使用,并在调试时返回错误(如 'A' packet returned an error: 8)。
推荐做法:
若您处于共享开发机、普通容器或无宿主机访问权限的环境中,请联系系统管理员协助开启,或切换至具备 root 权限的宿主机环境体验本功能。
确认内核调试开关 debug_switch 是否打开:
cat /proc/debug_switch
若输出值不为 1,请使用 root 权限在宿主机执行以下命令:
echo 1 > /proc/debug_switch
如果不能成功设置为 1,msDebug 功能不可用,只能跳过此节 msDebug 的体验。
2.5.2 修改编译选项并重新部署
-
修改编译选项
在 Kernel 侧 CMakeLists.txt 首行插入配置,用于启用调试信息、禁用编译优化:
cd ~/ot_demo/workspace/src/AddCustom printf '%s\n' "if(COMMAND add_ops_compile_options)" " add_ops_compile_options(ALL OPTIONS -g -O0)" "elseif(COMMAND npu_op_kernel_options)" " npu_op_kernel_options(ascendc_kernels ALL OPTIONS -g -O0)" "endif()" | cat - op_kernel/CMakeLists.txt > tmp && mv -f tmp op_kernel/CMakeLists.txt; -
重新编译部署算子
bash ./build.sh MY_OP_PKG=$(find ./build_out -maxdepth 1 -name "custom_opp_*.run" | head -1) && bash $MY_OP_PKG
2.5.3 设置调试环境变量
通过脚本设置 LAUNCH_KERNEL_PATH,指定算子obj加载路径并导入调试符号信息:
source ~/ot_demo/msot/example/quick_start/msdebug/set_kernel_obj_env.sh
2.5.4 断点调试与变量查看
-
启动调试器
cd ~/ot_demo/workspace/src/caller/build msdebug execute_add_op -
设置断点
待 (msdebug) 提示符出现后,设置断点于 add_custom.cpp 第 34 行:
b add_custom.cpp:34注意
若此前未在宿主机正确启用 /proc/debug_switch,执行上一节所述的断点设置将触发警告,而按照后续章节运行
run命令时将触发调试器错误(例如 'A' packet returned an error: 8),表明 msDebug 无法正常工作。 -
运行算子
输入 run 启动程序,等待命中断点:
run显示如下信息,则成功命中断点(如下示例显示各版本可能会稍有不同,不影响学习工具使用):
Process 163027 launched: '/root/ot_demo/workspace/src/caller/build/execute_add_op' (aarch64) [Launch of Kernel AddCustom_ab1b6750d7f510985325b603cb06dc8b_0 on Device 0] Process 163027 stopped [Switching to focus on Kernel AddCustom_ab1b6750d7f510985325b603cb06dc8b_0, CoreId 1, Type aiv] * thread #1, name = 'execute_add_op', stop reason = breakpoint 1.1 frame #0: 0x00000000000007e0 AddCustom_ab1b6750d7f510985325b603cb06dc8b.o`KernelAdd::Init(this=0x00000000001d78a8, x=0x12c0c0013000, y=0x12c0c001c000, z=0x12c0c0025000, totalLength=16384, tileNum=8) (.vector) at add_custom.cpp:34:9 31 this->tileLength = this->blockLength / tileNum / BUFFER_NUM; 32 33 // 设置全局内存缓冲区,为当前AI Core分配其负责的全局共享内存区域 -> 34 xGm.SetGlobalBuffer((__gm__ DTYPE_X *)x + this->blockLength * AscendC::GetBlockIdx(), this->blockLength); 35 yGm.SetGlobalBuffer((__gm__ DTYPE_Y *)y + this->blockLength * AscendC::GetBlockIdx(), this->blockLength); 36 zGm.SetGlobalBuffer((__gm__ DTYPE_Z *)z + this->blockLength * AscendC::GetBlockIdx(), this->blockLength); -
查看变量的值
在断点处执行以下命令,显示当前作用域内的所有局部变量:
var -
退出调试器
q
2.5.5 恢复手工修改
为后续工具使用做准备,回退手工修改:
\cp -f ~/ot_demo/workspace/src/AddCustom/op_kernel/CMakeLists.txt.bak ~/ot_demo/workspace/src/AddCustom/op_kernel/CMakeLists.txt
2.6【调优】分析算子性能(msOpProf)
若算子性能未达预期,可借助 msOpProf 工具采集运行时性能数据,进行深入分析与优化,确保算子在不同昇腾硬件平台上高效执行。先跟着操作体验效果,原理部分可稍后阅读:
2.6.1 修改编译选项并重新编译部署
-
修改编译选项
在 Kernel 侧 CMakeLists.txt 首行插入一行配置,开启调试信息:
cd ~/ot_demo/workspace/src/AddCustom printf '%s\n' "if(COMMAND add_ops_compile_options)" " add_ops_compile_options(ALL OPTIONS -g)" "elseif(COMMAND npu_op_kernel_options)" " npu_op_kernel_options(ascendc_kernels ALL OPTIONS -g)" "endif()" | cat - op_kernel/CMakeLists.txt > tmp && mv -f tmp op_kernel/CMakeLists.txt;说明
知识点(可选阅读):为何 -O 优化等级在各工具间切来切去
调试阶段为支持断点与变量查看,必须使用 -O0 关闭优化,以保留准确的符号映射;但 -O0 与 -O2 的性能差距可达数倍,因此性能分析必须基于 -O2(或默认优化级别)编译的代码,否则采集的数据将严重偏离真实场景,失去参考价值。 -
重新编译部署算子
bash ./build.sh MY_OP_PKG=$(find ./build_out -maxdepth 1 -name "custom_opp_*.run" | head -1) && bash $MY_OP_PKG
2.6.2 启动真机与仿真采集
说明
知识点:上板和仿真采集信息的区别
上板:可精确捕获算子运行耗时、各 Pipe 使用情况、内存带宽、Cache 行为等真实硬件特性,而这些往往是仿真器难以高保真复现的关键指标。
仿真:在指令流追踪、代码热点定位等方面提供更完整、稳定的分析能力,但对内存访问延迟、带宽瓶颈等硬件相关行为的模拟精度有限。
因此,建议结合两种方式,互补优势,实现全面性能诊断。若某些场景下您没有真实硬件(NPU 卡),可以使用仿真模式进行初步的性能估算和热点分析。
-
上板性能采集
cd ~/ot_demo/workspace/src/caller/build msopprof --output=./msopprof_output_npu ./execute_add_op -
仿真器性能采集
msopprof simulator --soc-version=Ascend${MY_STUDY_VAR_CHIP_SOC_TYPE} --output=./msopprof_output_sim ./execute_add_op
2.6.3 查看性能数据结果
工具在指定 --output 目录下生成 .csv 和 .bin 格式的结果文件,若输出未报错,则表明执行成功:
-
csv 文件
例如 MemoryUB.csv,打开可以看到如下信息:
数据显示任务被均分为 8 个 block,全部调度至 Vector Core 执行。例如 Block 0 的带宽(1.02 GB/s)明显高于 Block 1(0.77 GB/s),如果差异过大,可能提示存在优化空间:block_id sub_block_id aiv_time(us) aiv_total_cycles aiv_ub_read_bw_vector(GB/s) aiv_ub_write_bw_vector(GB/s) 0 vector0 7.456666 13422 1.023164 0.511582 1 vector0 9.914444 17846 0.769523 0.384762 2 vector0 10.001111 18002 0.762855 0.381427 3 vector0 9.684444 17432 0.787799 0.393899 4 vector0 9.747222 17545 0.782725 0.391363 5 vector0 9.062222 16312 0.84189 0.420945 6 vector0 9.293889 16729 0.820904 0.410452 7 vector0 8.658889 15586 0.881105 0.440553 -
bin 文件
可使用MindStudio Insight工具打开,以图形化方式直观展示各类性能视图,例如:计算内存热力图、Cache 热力图以及算子代码热点图等。说明
若想体验可视化的图表查看,请参考《MindStudio Insight工具文档》安装 Insight 工具。
2.6.4 恢复手工修改
为后续工具使用做准备,回退手工修改:
\cp -f ~/ot_demo/workspace/src/AddCustom/op_kernel/CMakeLists.txt.bak ~/ot_demo/workspace/src/AddCustom/op_kernel/CMakeLists.txt
2.7【结业】后续进阶路径
恭喜您完成算子开发工具链入门体验。
至此,您已完整走通“设计 → 开发 → 检测 → 调试 → 调优”的算子开发全流程,并实际体验了以下五个核心工具的基本用法:
| 工具 | 您已掌握的核心能力 |
|---|---|
| msKPP | 编写 DSL 脚本进行算子性能建模,在无硬件条件下预估性能瓶颈 |
| msOpGen | 基于配置文件自动生成算子工程框架,完成编译、部署与功能验证 |
| msSanitizer | 注入检测桩代码,定位内存越界等运行时缺陷的源码位置 |
| msDebug | 启动断点调试,在 NPU 算子代码中设置断点并查看变量 |
| msOpProf | 通过上板与仿真两种模式采集性能数据,分析各 Block 的执行效率 |
如果您想继续进阶体验,可参考以下步骤:
第一步:巩固基础 —— 独立开发一个新算子
参考本教程中的 AddCustom,尝试独立实现一个减法算子(SubCustom)或乘法算子(MulCustom),重点关注:Tiling 策略的设计差异、不同计算指令(如 vsub、vmul)的使用,以及端到端的编译部署流程。
第二步:深入工具 —— 掌握各工具的高级功能
本教程仅覆盖了各工具的入门用法,每个工具都提供了更丰富的高级能力,建议按需访问对应仓的《使用指南》等深入学习:
| 工具 | 高级能力说明 |
|---|---|
| msKPP | 使用Cache命中率、随路转换等建模、多种 Tiling 方案的性能对比分析等。 |
| msOpGen | 复杂算子模板定制、多输入多输出算子的工程生成等。 |
| msSanitizer | 竞争条件检测、同步异常诊断、未初始化变量检查等更多检测模式。 |
| msDebug | 内存查看、核切换、解析Core dump文件等高级调试技巧。 |
| msOpProf | 结合 MindStudio Insight 进行可视化性能分析,包括计算内存热力图、Cache 热力图及代码热点图。 |
第三步:落地真实业务 —— 从教学走向生产
深入研读《Ascend C 编程指南(官方教程)》,系统掌握多级流水、数据排布、内存管理等核心概念,在此基础上尝试将工具链应用于实际业务算子的开发与调优,逐步构建从原型验证到生产级交付的完整能力。
3. FAQ
3.1 执行 mskpp_demo.py 报错:Exception: Parameter chip_name in Chip is unsupported
问题现象
root@localhost:~/ot_demo/workspace/mskpp# python3 mskpp_demo.py
Traceback (most recent call last):
File "/root/ot_demo/workspace/mskpp/mskpp_demo.py", line 28, in <module>
with Chip("Ascend" + chip_name) as chip: # 格式为Ascendxxxyy,其中xxxyy为用户实际使用的具体芯片SoC型号,可通过npu-smi info查询
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/Ascend/ascend-toolkit/latest/python/site-packages/mskpp/core/chip.py", line 30, in __init__
self.param_transfer()
File "/usr/local/Ascend/ascend-toolkit/latest/python/site-packages/mskpp/core/chip.py", line 110, in param_transfer
raise Exception("Parameter chip_name in Chip is unsupported")
Exception: Parameter chip_name in Chip is unsupported
问题原因
MY_STUDY_VAR_CHIP_SOC_TYPE 环境变量丢失。
解决方法
参考《算子开发工具链学习环境安装指南》的第1.3节重新设置。
3.2 编译调用算子程序时报错:fatal error: aclnn_add_custom.h: No such file or directory
问题现象
-- Build files have been written to: /root/ot_demo/workspace/src/caller/build
[ 50%] Building CXX object CMakeFiles/execute_add_op.dir/main.cpp.o
/root/ot_demo/workspace/src/caller/main.cpp:16:10: fatal error: aclnn_add_custom.h: No such file or directory
16 | #include "aclnn_add_custom.h"
| ^~~~~~~~~~~~~~~~~~~~
compilation terminated.
gmake[2]: *** [CMakeFiles/execute_add_op.dir/build.make:76: CMakeFiles/execute_add_op.dir/main.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/execute_add_op.dir/all] Error 2
问题原因
算子部署时没有将 op_api/include/aclnn_add_custom.h 部署到正确位置,导致找不到头文件。一种可能的原因是环境中存在环境变量 ASCEND_CUSTOM_OPP_PATH,且其值不正确或包含多个以冒号间隔的路径,但部署头文件时只会成功拷贝到第一个路径,后续目录均未部署。
解决方法
删除该环境变量(执行 unset ASCEND_CUSTOM_OPP_PATH),然后重新部署算子。
3.3 执行 execute_add_op 时异常报错:undefined symbol: aclnnAddCustomGetWorkspaceSize
问题现象
execute_add_op: symbol lookup error: ./build/execute_add_op: undefined symbol: aclnnAddCustomGetWorkspaceSize
问题原因
部署完算子后,没有按输出提示将 so 加入环境变量 LD_LIBRARY_PATH 中。
解决方法
按2.3.3 编译与部署算子第 3 步,重新设置 LD_LIBRARY_PATH 环境变量。
3.4 执行 msDebug 设置断点时报错:WARNING: Unable to resolve breakpoint to any actual locations
问题现象
(msdebug) b add_custom.cpp:23
Breakpoint 1: no locations (pending on future shared library load).
WARNING: Unable to resolve breakpoint to any actual locations.
问题原因
指定的断点行可能是空行或注释等无法设置断点的行,或者 /proc/debug_switch 没有成功设置,原因参考下节说明。
解决方法
查看代码源文件,确认代码的真实行号;按 2.5.1 开启内核调试开关 以 root 权限在宿主机上(注意不是容器内)设置 /proc/debug_switch = 1。
3.5 执行 msDebug 的 run 时报错:error: 'A' packet returned an error: 8
问题现象
error: 'A' packet returned an error: 8
问题原因
没有成功设置/proc/debug_switch = 1。确认宿主机上是否被修改回0了,或者若您在云服务商提供的容器环境中操作的,这种场景即使在容器内成功将 /proc/debug_switch 设置并查询为 1,
该状态也可能是虚假的。因出于安全考虑,底层宿主机通常会通过写时复制(CoW)、影子文件或覆盖挂载(overlay mount)等机制对 /proc 目录进行隔离,导致设置未实际生效。
解决方法
以 root 权限登录到宿主机上(注意不是容器内),按 2.5.1 开启内核调试开关 设置 /proc/debug_switch = 1,如果不能设置成功只能跳过此工具体验。