已合并
[feature] add design docs for 26.2.0 #119
gong-siwei创建于 8月6日
[feature] add design docs for 26.2.0 #119
已合并
共 6 个文件变更+866-0
| @@ -0,0 +1,220 @@ | |||
| 1 | +# MindStudio Sanitizer 功能设计文档 | ||
| 2 | + | ||
| 3 | +状态 (Status): Reviewing | ||
| 4 | +作者 (Authors): @gong-siwei | ||
| 5 | +创建日期 (Created): 2026-08-06 | ||
| 6 | +更新日期 (Updated): 2026-08-06 | ||
| 7 | +相关 Issue/PR: [177](https://gitcode.com/Ascend/mssanitizer/issues/177) | ||
| 8 | + | ||
| 9 | +--- | ||
| 10 | + | ||
| 11 | +# 1. 概述 | ||
| 12 | + | ||
| 13 | +## 1.1 简介 | ||
| 14 | + | ||
| 15 | +昇腾芯片本身内部有多个核心,基于昇腾芯片的开发需要小心地处理各个核心负责的内存块,同时,片上内存有对齐的要求,容易产生内存踩踏、内存对齐、内存初始化、流水竞争等问题。本工具提供内存检测、竞争检测等检测功能,帮助用户快速识别并定位此类问题。 | ||
| 16 | + | ||
| 17 | +本次需新支持的功能如下: | ||
| 18 | + | ||
| 19 | +- 支持纯SIMT算子异常检测 | ||
| 20 | +- 支持CATLASS DSL算子异常检测 | ||
| 21 | +- ops-transformer算子仓检测准确率提升 | ||
| 22 | +- 寄存器检测支持展示使用非默认值mask寄存器的vector指令 | ||
| 23 | +- 支持DCCI检测 | ||
| 24 | + | ||
| 25 | +## 1.2 动机 | ||
| 26 | + | ||
| 27 | +### 1.2.1 支持纯SIMT算子异常检测 | ||
| 28 | + | ||
| 29 | +AscendC为了支持竞品代码的算子迁移,提供了pure simt算子编写能力,pure simt算子通过特殊runtime接口下发kernel,与既有算子的编程模型差异较大,开发者较难发现越界、踩踏、竞争等异常,需要mssanitizer工具与算子协同实现runtime接口劫持与动态插桩,复用既有检测算法,补齐纯SIMT算子的调试调优能力。 | ||
| 30 | + | ||
| 31 | +### 1.2.2 支持CATLASS DSL算子异常检测 | ||
| 32 | + | ||
| 33 | +CATLASS DSL编程语言即将发布,开发者使用该语言编写算子时同样面临越界、竞争、未初始化内存等问题,需mssanitizer工具支持该编程语言的异常检测,提升编程易用性。 | ||
| 34 | + | ||
| 35 | +### 1.2.3 ops-transformer算子仓检测准确率提升 | ||
| 36 | + | ||
| 37 | +mssanitizer在部分开源算子仓使用时误报率较高,影响用户对检测结果的信任,需要对ops-transformer算子仓进行全量扫描,识别并修复误报问题,降低误报率。 | ||
| 38 | + | ||
| 39 | +### 1.2.4 寄存器检测支持展示使用非默认值mask寄存器的vector指令 | ||
| 40 | + | ||
| 41 | +AscendC API中可能存在隐式的修改特殊寄存器的行为,比如vector mask寄存器,当开发者不知道寄存器被修改,以此为前提进行编程,容易出现精度、功能问题,因此期望mssanitizer工具可以辅助开发者识别寄存器不处于默认值的指令,提高定位效率。 | ||
| 42 | + | ||
| 43 | +### 1.2.5 支持DCCI检测 | ||
| 44 | + | ||
| 45 | +kernel函数在多核处理数据时,经常需要核A写入GM后通知核B从GM读出数据,由于每个核具有独立的Data Cache,为使该过程正常运行,需要利用DCCI指令使核A写入后让cache写回GM,核B读出数据前利用DCCI指令刷新cache把最新数据从GM取回,保证两个核的cache一致性,当一致性未被保证时,数据无法在核间被正确读取,此类问题一般隐藏较深、定位麻烦,需mssanitizer支持识别此类场景中DCCI指令漏插的问题。 | ||
| 46 | + | ||
| 47 | +## 1.3 目标 | ||
| 48 | + | ||
| 49 | +- 纯SIMT算子异常检测目标:复用既有检测算法,通过runtime接口劫持与动态插桩,支持越界、非对齐、线程间踩踏、线程间竞争、读未初始化内存、SIMT内sync_thread同步检测。 | ||
| 50 | +- CATLASS DSL算子异常检测目标:支持越界、非对齐、线程间踩踏、线程间竞争、读未初始化内存、同步检测。 | ||
| 51 | +- ops-transformer算子仓检测准确率提升目标:全量扫描ops-transformer算子仓,最终误报率<5%。 | ||
| 52 | +- mask寄存器检测目标:支持展示使用非默认值mask寄存器的vector指令,包括normal/counter模式、vector mask值。 | ||
| 53 | +- DCCI检测目标:识别核间一读一写时是否存在DCCI指令漏加的问题。 | ||
| 54 | + | ||
| 55 | +# 2. 用例分析 | ||
| 56 | + | ||
| 57 | +## 2.1 支持纯SIMT算子异常检测 | ||
| 58 | + | ||
| 59 | +参考asc样例算子仓纯SIMT算子样例,使用mssanitizer对pure simt算子进行异常检测,可正常完成检测: | ||
| 60 | + | ||
| 61 | +1. 越界、非对齐、线程间踩踏检测。 | ||
| 62 | +2. 线程间竞争。 | ||
| 63 | +3. 读未初始化内存。 | ||
| 64 | +4. SIMT内sync_thread同步检测。 | ||
| 65 | + | ||
| 66 | +## 2.2 支持CATLASS DSL算子异常检测 | ||
| 67 | + | ||
| 68 | +修改一个CATLASS DSL算子,构造越界、非对齐、线程间踩踏、线程间竞争、读未初始化内存、同步异常,使用mssanitizer拉起算子,可正常完成检测。 | ||
| 69 | + | ||
| 70 | +## 2.3 ops-transformer算子仓检测准确率提升 | ||
| 71 | + | ||
| 72 | +覆盖ops-transformer仓所有算子,通过算子仓提供的用例作为单算子用例,完成全量扫描,识别误报问题并修复,最终误报率<5%。 | ||
| 73 | + | ||
| 74 | +## 2.4 寄存器检测支持展示使用非默认值mask寄存器的vector指令 | ||
| 75 | + | ||
| 76 | +构造AscendC算子,vector指令调用前配置mask,使用工具可展示vector指令使用的mask寄存器值,包括normal/counter模式及mask值。 | ||
| 77 | + | ||
| 78 | +## 2.5 支持DCCI检测 | ||
| 79 | + | ||
| 80 | +构造核间一读一写场景,覆盖以下三类场景,缺失DCCI时,工具可检测到: | ||
| 81 | + | ||
| 82 | +1. 核A SetValue + DCCI;核B DCCI + GetValue | ||
| 83 | +2. 核A MTE3;核B DCCI + GetValue | ||
| 84 | +3. 核A SetValue + DCCI;核B MTE2 | ||
| 85 | + | ||
| 86 | +# 3.方案设计 | ||
| 87 | + | ||
| 88 | +## 3.1 总体方案 | ||
| 89 | + | ||
| 90 | +### 3.1.1 支持纯SIMT算子异常检测 | ||
| 91 | + | ||
| 92 | +pure simt算子通过特殊runtime接口下发kernel,与既有算子的下发方式不同,编译器对SIMT指令的插桩方式与SIMD指令也不同,需mssanitizer工具与算子协同:一方面劫持特殊runtime接口,识别pure simt算子的kernel下发;另一方面通过动态插桩方式记录SIMT线程的内存访问、同步等行为,将各线程的内存访问记录纳入既有检测框架,复用既有检测算法完成越界、非对齐、线程间踩踏、线程间竞争、读未初始化内存、sync_thread同步检测。 | ||
| 93 | + | ||
| 94 | +### 3.1.2 支持CATLASS DSL算子异常检测 | ||
| 95 | + | ||
| 96 | +CATLASS DSL作为新编程语言,其kernel编译流程与AscendC不同,需工具在CATLASS DSL的编译链路中接入插桩,将指令记录接入既有检测框架,复用既有检测算法完成越界、非对齐、线程间踩踏、线程间竞争、读未初始化内存、同步检测。 | ||
| 97 | + | ||
| 98 | +### 3.1.3 ops-transformer算子仓检测准确率提升 | ||
| 99 | + | ||
| 100 | +以ops-transformer算子仓RP2 release版本为基线,使用算子仓提供的用例作为单算子用例进行全量扫描,对识别出的误报进行根因分析,区分是检测算法逻辑缺陷、插桩方式导致的误报,还是对合法编程模式覆盖不全,针对性地优化检测算法并回归验证,最终达成误报率<5%的目标。 | ||
| 101 | + | ||
| 102 | +### 3.1.4 寄存器检测支持展示使用非默认值mask寄存器的vector指令 | ||
| 103 | + | ||
| 104 | +在指令分析阶段跟踪vector mask寄存器(normal/counter模式)的写入与使用,记录每条vector指令执行时所使用的mask寄存器状态,当mask寄存器不处于默认值时,展示该vector指令及对应mask寄存器的模式与值。 | ||
| 105 | + | ||
| 106 | +### 3.1.5 支持DCCI检测 | ||
| 107 | + | ||
| 108 | +DCCI检测采用指令序列模式匹配的方式,按照"SetValue(addr)的下一条指令是否紧跟DCCI(addr)"以及"GetValue(addr)的上一条指令是否紧跟DCCI(addr)"的模式进行检测,识别核间一读一写场景中DCCI指令漏插的问题,针对scalar上的DCCI进行检测,A5场景与A2/A3场景检测模式保持一致。 | ||
| 109 | + | ||
| 110 | +## 3.2 技术选型(可选) | ||
| 111 | + | ||
| 112 | +方案设计简单,不涉及多重选型。 | ||
| 113 | + | ||
| 114 | +## 3.3 安全隐私与DFX设计 | ||
| 115 | + | ||
| 116 | +*结合场景用例,对本提案所涉及的安全隐私及DFX(兼容性、可维护性、可测试性、可靠性...)等属性影响进行设计。* | ||
| 117 | + | ||
| 118 | +### 3.3.1 支持纯SIMT算子异常检测 | ||
| 119 | + | ||
| 120 | +兼容性:作为额外选项启用,与原检测能力不冲突。 | ||
| 121 | + | ||
| 122 | +可靠性:复用既有检测算法,通过runtime接口劫持与动态插桩实现,覆盖pure simt算子编程模型下的越界、竞争、初始化、同步等异常。 | ||
| 123 | + | ||
| 124 | +### 3.3.2 支持CATLASS DSL算子异常检测 | ||
| 125 | + | ||
| 126 | +兼容性:作为额外选项启用,与原检测能力不冲突。 | ||
| 127 | + | ||
| 128 | +可靠性:检测算法复用,仅在CATLASS DSL编译链路接入插桩,功能覆盖与AscendC保持一致。 | ||
| 129 | + | ||
| 130 | +### 3.3.3 ops-transformer算子仓检测准确率提升 | ||
| 131 | + | ||
| 132 | +可靠性:以RP2 release版本作为基线,扫描结果可回归对比,保证误报率持续收敛至<5%。 | ||
| 133 | + | ||
| 134 | +### 3.3.4 寄存器检测支持展示使用非默认值mask寄存器的vector指令 | ||
| 135 | + | ||
| 136 | +兼容性:通过子命令按需开启,不影响默认检测流程。 | ||
| 137 | + | ||
| 138 | +可靠性:mask寄存器状态跟踪覆盖normal/counter两种模式。 | ||
| 139 | + | ||
| 140 | +### 3.3.5 支持DCCI检测 | ||
| 141 | + | ||
| 142 | +兼容性:作为额外选项启用,与原检测能力不冲突。 | ||
| 143 | + | ||
| 144 | +可靠性:检测模式固定,仅针对scalar上的DCCI进行检测,A5场景与A2/A3场景检测模式保持一致。 | ||
| 145 | + | ||
| 146 | +## 3.4 编程与调用设计 | ||
| 147 | + | ||
| 148 | +### 3.4.1 编程模型基本设计 | ||
| 149 | + | ||
| 150 | +mssanitizer提供命令行cli,未新增API调用,开发环境直接使用CANN环境。 | ||
| 151 | + | ||
| 152 | +### 3.4.2 接口定义与设计 | ||
| 153 | + | ||
| 154 | +#### 3.4.2.1 寄存器检测支持展示使用非默认值mask寄存器的vector指令 | ||
| 155 | + | ||
| 156 | +- 命令行参数:使用子命令开启mask寄存器检测功能 | ||
| 157 | + | ||
| 158 | +#### 3.4.2.2 支持DCCI检测 | ||
| 159 | + | ||
| 160 | +- 命令行参数:`--dcci-check <yes/no>`,默认值:`no` | ||
| 161 | + | ||
| 162 | +### 3.4.3 使用说明 | ||
| 163 | + | ||
| 164 | +以上新增参数均不影响原有参数使用。 | ||
| 165 | + | ||
| 166 | +# 4.测试设计 | ||
| 167 | + | ||
| 168 | +*介绍该功能的测试方法以及测试用例设计,包括单元测试(unit test),集成测试(integration test),端到端测试(e2e test)等。* | ||
| 169 | + | ||
| 170 | +## 4.1 单元测试 | ||
| 171 | + | ||
| 172 | +按照原UT测试框架满足覆盖率要求即可。 | ||
| 173 | + | ||
| 174 | +## 4.2 端到端测试 | ||
| 175 | + | ||
| 176 | +- 算子类型:mix、cube、vec、simt | ||
| 177 | +- 编程语言:AscendC、Triton、CATLASS、SHMEM | ||
| 178 | +- 调起方式 :<<<>>>、ACLNN、PTA | ||
| 179 | +- 款型:A2/A3/A5/950 | ||
| 180 | + | ||
| 181 | +### 4.2.1 支持纯SIMT算子异常检测 | ||
| 182 | + | ||
| 183 | +参考asc样例算子仓纯SIMT算子样例,构造越界、非对齐、线程间踩踏、线程间竞争、读未初始化内存、sync_thread同步异常场景。 | ||
| 184 | + | ||
| 185 | +### 4.2.2 支持CATLASS DSL算子异常检测 | ||
| 186 | + | ||
| 187 | +构造使用CATLASS DSL的算子用例,覆盖越界、非对齐、线程间踩踏、线程间竞争、读未初始化内存、同步异常场景。 | ||
| 188 | + | ||
| 189 | +### 4.2.3 ops-transformer算子仓检测准确率提升 | ||
| 190 | + | ||
| 191 | +以RP2 release版本为基线,全量扫描ops-transformer算子仓,统计误报率并回归验证,验收平台为Ascend950。 | ||
| 192 | + | ||
| 193 | +### 4.2.4 寄存器检测支持展示使用非默认值mask寄存器的vector指令 | ||
| 194 | + | ||
| 195 | +构造AscendC算子,vector指令调用前配置mask,覆盖normal/counter模式,验收平台为A2/A3。 | ||
| 196 | + | ||
| 197 | +### 4.2.5 支持DCCI检测 | ||
| 198 | + | ||
| 199 | +构造"核A SetValue + DCCI;核B DCCI + GetValue"、"核A MTE3;核B DCCI + GetValue"、"核A SetValue + DCCI;核B MTE2"三类场景,构造DCCI缺失,验证可检出,验收平台为A2/A3/A5。 | ||
| 200 | + | ||
| 201 | +# 5.缺点和风险(可选) | ||
| 202 | + | ||
| 203 | +无。 | ||
| 204 | + | ||
| 205 | +# 6.现有技术(可选) | ||
| 206 | + | ||
| 207 | +内存检测算法参考valgrind,采用shadow memory维护内存状态。 | ||
| 208 | + | ||
| 209 | +# 7.未解决问题(可选) | ||
| 210 | + | ||
| 211 | +无。 | ||
| 212 | + | ||
| 213 | +--- | ||
| 214 | + | ||
| 215 | +附录 | ||
| 216 | + | ||
| 217 | +* **参考资料链接** | ||
| 218 | + * [MindStudio-Sanitizer Roadmap 2026 Q3](https://gitcode.com/Ascend/mssanitizer/issues/177) | ||
| 219 | +* **术语表** | ||
| 220 | +* **文档更新计划** | ||
| @@ -0,0 +1,507 @@ | |||
| 1 | +# MindStudio Ops Profiler 功能设计说明书 | ||
| 2 | + | ||
| 3 | +状态 (Status): Approved | ||
| 4 | +作者 (Authors): @MTQ | ||
| 5 | +创建日期 (Created): 2025-08-06 | ||
| 6 | +更新日期 (Updated): 2025-08-06 | ||
| 7 | +相关 Issue/PR: [129](https://gitcode.com/Ascend/msopprof/issues/129) | ||
| 8 | + | ||
| 9 | +--- | ||
| 10 | + | ||
| 11 | +# 1. 概述 | ||
| 12 | + | ||
| 13 | +## 1.1 简介 | ||
| 14 | + | ||
| 15 | +算子调优是算子开发工具链的关键一环。本工具根据算子运行的环境和目的将数据划分为以下两类:算子仿真和算子上板。 算子仿真:运行在昇腾仿真器上,通过仿真器对于指令级性能的详细仿真输出详细的算子性能数据,例如流水图和代码热点图。 算子上板:开发者所开发的算子运行在真实昇腾设备上的性能数据结果,反映的是算子在硬件设备上的真实性能,是算子性能最可靠的数据。 | ||
| 16 | + | ||
| 17 | +## 1.2 动机 | ||
| 18 | + | ||
| 19 | +算子调优作为算子开发工具链的关键一环,是算子开发者获取性能数据和优化方向的主要工具,算子调优工具主要用户群体是昇腾算子的开发人员,包括客户算子开发工程师,公司内部算子开发工程师。用户可根据工具提供的性能指标评估当前算子的性能瓶颈,当前工具也会根据采集的性能指标通过建模、专家系统的方式直接告知用户性能瓶颈,以帮助用户优化其算子。 | ||
| 20 | + | ||
| 21 | +## 1.3 目标 | ||
| 22 | + | ||
| 23 | +本文目的是对算子开发工具进行功能设计,明确算子调优工具主要功能及方案,作为今后的编码阶段的输入和编码人员、测试人员的指导。 | ||
| 24 | + | ||
| 25 | +# 2. 用例分析 | ||
| 26 | + | ||
| 27 | +| 类型 | 功能清单 | 功能描述 | 支撑的调优类型 | | ||
| 28 | +| --------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------- | | ||
| 29 | +| 业务功能 | 计算内存热力图 | 以资源维度展示算子基础信息、计算负载分析和内存负载分析的数据 | 上板调优 | | ||
| 30 | +| 业务功能 | Roofline瓶颈分析图 | 构建出性能模型,然后利用该性能模型快速评估出算子的理论性能极限 | 上板调优 | | ||
| 31 | +| 业务功能 | Cache热力图 | 可视化呈现Cache热力图,可显示对应指令信息,以便用户优化L2Cache命中率 | 上板调优 | | ||
| 32 | +| 业务功能 | 通算流水图(MC2算子) | 直观看到MC2算子的通算运行情况、指令耗时等信息,协助开发者识别通算瓶颈 | 上板调优 | | ||
| 33 | +| 业务功能 | 指令流水图 | 以指令维度展示时序关系并关联调用栈快速追踪瓶颈位置,展示信息为指令发射时长以及执行时长。在simt算子中会detail中会显示simt vf信息例如线程数、warpId、schId等。 | 仿真调优 | | ||
| 34 | +| 业务功能 | 算子代码热点图 | 支持查看算子源码与指令集的映射关系、耗时情况等功能,可协助开发者识别热点代码分布,并分析热点函数优化的可行性 | 上板调优/仿真调优 | | ||
| 35 | +| 业务功能 | 性能数据文件 | 展示指令耗时情况、L2cache命中率、内存带宽读写速率、L0读写带宽率、UB读写带宽速率、算子基础信息、计算/搬运单元耗时占比、资源冲突占比 | 上板调优 | | ||
| 36 | +| 业务功能 | 搬运带宽图 | 展示GM<->L1,GM<->UB,GM<->other间数据搬运的带宽图 | 仿真调优 | | ||
| 37 | +| 业务功能 | 指令流水图(上板) | 以指令维度展示时序关系并关联调用栈 | 上板调优 | | ||
| 38 | +| 业务功能 | warp耗时展示 | simt算子展示每个 warp运行的起始、终止时间 | 上板调优 | | ||
| 39 | +| 业务功能 | warp基本信息展示 | 展示simt vf IPC信息、simt vf state信息、 warp执行时长等信息 | 上板调优 | | ||
| 40 | +| dfx功能 | Ctrl+C功能 | 提前终止算子进程,工具可根据当前已采集的数据解析结果 | 上板调优/仿真调优 | | ||
| 41 | +| dfx功能 | 提前终止进程 | 用户可定时结束算子进程 | 上板调优 | | ||
| 42 | +| dfx功能 | 指定仿真器版本 | 用户可直接设置仿真器版本 | 仿真调优 | | ||
| 43 | + | ||
| 44 | +***约束说明:*** | ||
| 45 | + | ||
| 46 | +1. 上板流水图功能 | ||
| 47 | + | ||
| 48 | + a. 中无法显示simt vf和simd vf的指令细节, | ||
| 49 | + | ||
| 50 | + b. 当前只有A5代际提供该功能、A2/A3未提供此功能。 | ||
| 51 | + | ||
| 52 | + c. 该功能依赖编译器,要求工具与编译器(cann)版本配套。 | ||
| 53 | + | ||
| 54 | + d. 当前指令流水信息由硬件返回,若硬件有信息丢失工具需要提醒用户。 | ||
| 55 | + | ||
| 56 | +2. warp耗时展示 | ||
| 57 | + | ||
| 58 | + a. 该功能依赖编译器,要求工具与编译器(cann)版本配套。 | ||
| 59 | + | ||
| 60 | + **代码热点图详细功能列举** | ||
| 61 | + | ||
| 62 | +| 特性名称 | msprof op | msprof op simulator | | ||
| 63 | +| ------------------------------------------- | --------- | ------------------- | | ||
| 64 | +| 查看寄存器使用情况 (Gpr Count) | 不支持 | 支持 | | ||
| 65 | +| 模拟代码行和指令维度的 L2Cache命中率 | 支持 | 不支持 | | ||
| 66 | +| 查看与GM有关的数据搬运量(Process Bytes) | 支持 | 支持 | | ||
| 67 | +| Vector计算类指令在UB Bank上读和写的冲突情况 | 不支持 | 支持 | | ||
| 68 | +| Vector计算单元利用率 | 不支持 | 支持 | | ||
| 69 | +| 查看算子源码与指令的耗时情况(cycles) | 不支持 | 支持 | | ||
| 70 | +| 查看算子源码与指令的执行次数 | 支持 | 支持 | | ||
| 71 | +| 查看算子源码与指令集的映射关系 | 支持 | 支持 | | ||
| 72 | +| 查看源码、指令PC地址、Pipe、Source | 支持 | 支持 | | ||
| 73 | +| 查看core信息 | 不支持 | 支持 | | ||
| 74 | + | ||
| 75 | +# 3.方案设计 | ||
| 76 | + | ||
| 77 | +## 3.1 总体方案 | ||
| 78 | + | ||
| 79 | +### 3.1.1 上板 | ||
| 80 | + | ||
| 81 | +#### 3.1.1.1 指令流水图 | ||
| 82 | + | ||
| 83 | +A5代际下硬件提供dfx_region功能,可在对应的pipe上打点(而非A2/A3代际的scalar打点)获取准确的执行时间,故当前方案为将计算类、搬运类指令的前后加入dfx_region指令,拉起算子时硬件会返回该指令的执行时间。工具获取硬件返回的数据并解析生成所有搬运类、计算类指令的流水信息。 | ||
| 84 | + | ||
| 85 | +**其中涉及组件 :** | ||
| 86 | + | ||
| 87 | +编译器:负责插dfx_region桩,并返回每个region_id与pc的对应情况(便于工具将dfx_region与pc对应起来,流水图中显示pc对应的执行时间以及调用栈) | ||
| 88 | + | ||
| 89 | +硬件:负责返回数据 | ||
| 90 | + | ||
| 91 | +工具:负责拉起编译器插桩得到目标二进制、拉起算子、从硬件获取数据、解析数据并调用llvm-symbolizer完成调用栈的生成。 | ||
| 92 | + | ||
| 93 | +| 阶段 | 角色 | 关键动作 | 时序关系 | | ||
| 94 | +| ------------ | ---------------- | ------------------------------------------------------------ | ------------------------------ | | ||
| 95 | +| **前置插桩** | 编译器 | 对程序执行`dfx_region`插桩,植入监控点;返回region_id与pc的对应情况 | 发生在算子下发**之前** | | ||
| 96 | +| **运行算子** | 工具(基础组件) | 拉起已插桩的程序 → 程序运行时自动产出所需数据 | 运行插桩生效后的算子 | | ||
| 97 | +| **数据返回** | 硬件 | 接收原始数据 → 格式化处理 → 返回给C | 算子结束后触发 | | ||
| 98 | +| **最终展示** | 工具(解析侧) | 获取格式化数据并完成展示(包括解析硬件返回的指令执行时间信息以及调用栈信息) | 最后一步,解析侧解析并展示数据 | | ||
| 99 | + | ||
| 100 | +<img src="./img/上板指令流水图.png" style="zoom:15%;" /> | ||
| 101 | + | ||
| 102 | +#### 3.1.1.2 warp耗时展示 | ||
| 103 | + | ||
| 104 | +默认在流水图中显示每个warp的开始时间和终止时间。 | ||
| 105 | + | ||
| 106 | +本功能需要编译器提供在simt vf 的开始和结尾提供插桩功能,工具会将桩插入到算子simt vf 的开始和结尾处,桩中的功能为记录当前的warp信息和时刻信息。运行时动态获取这些信息,并将信息记录到GM中。工具解析侧获取每个warp的执行时间信息,并画出流水图,呈现在当前代码流水图界面上。 | ||
| 107 | + | ||
| 108 | +```markdown | ||
| 109 | +│ ┌────────────────────────────────────────────────────────────────┐ │ | ||
| 110 | +│ │ 插桩工具 (Instrumentation) │ │ | ||
| 111 | +│ │ - 识别 SIMT VF 区域边界 │ │ | ||
| 112 | +│ │ - 在 BEGIN 处插入: 记录 warp_id + start_timestamp │ │ | ||
| 113 | +│ │ - 在 END 处插入: 记录 warp_id + end_timestamp │ │ | ||
| 114 | +│ └────────────────────────────────────────────────────────────────┘ │ | ||
| 115 | +│ │ │ | ||
| 116 | +│ ▼ │ | ||
| 117 | +│ ┌────────────────────────────────────────────────────────────────┐ │ | ||
| 118 | +│ │ 插桩后 Kernel (带桩代码) │ │ | ||
| 119 | +│ │ ... │ │ | ||
| 120 | +│ │ BEGIN_STUB: │ │ | ||
| 121 | +│ │ warp_id = getWarpId(); │ │ | ||
| 122 | +│ │ start_ts = readCycle(); │ │ | ||
| 123 | +│ │ storeToGM(warp_id, start_ts); // 写入 Global Memory │ │ | ||
| 124 | +│ │ SIMT_VF_BEGIN: │ │ | ||
| 125 | +│ │ // 原始计算逻辑 │ │ | ||
| 126 | +│ │ SIMT_VF_END: │ │ | ||
| 127 | +│ │ END_STUB: │ │ | ||
| 128 | +│ │ warp_id = getWarpId(); │ │ | ||
| 129 | +│ │ end_ts = readCycle(); │ │ | ||
| 130 | +│ │ storeToGM(warp_id, end_ts); │ │ | ||
| 131 | +│ │ ... │ │ | ||
| 132 | +│ └────────────────────────────────────────────────────────────────┘ │ | ||
| 133 | +│ │ │ | ||
| 134 | +│ ▼ │ | ||
| 135 | +│ ┌─────────────────────────────────────────────────────────────────┐ │ | ||
| 136 | +│ │ 硬件 │ │ | ||
| 137 | +│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ | ||
| 138 | +│ │ │ Warp 0 │ │ Warp 1 │ │ Warp 2 │ │ Warp N │ │ │ | ||
| 139 | +│ │ │ 执行VF │ │ 执行VF │ │ 执行VF │ │ 执行VF │ │ │ | ||
| 140 | +│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ | ||
| 141 | +│ │ │ │ │ │ │ │ | ||
| 142 | +│ │ ▼ ▼ ▼ ▼ │ │ | ||
| 143 | +│ │ ┌─────────────────────────────────────────────────────────┐ │ │ | ||
| 144 | +│ │ │ Global Memory (GM) │ │ │ | ||
| 145 | +│ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ | ||
| 146 | +│ │ │ │ Warp Record Table │ │ │ │ | ||
| 147 | +│ │ │ ├─────────┬───────────────────┬───────────────────┤ │ │ │ | ||
| 148 | +│ │ │ │ Warp ID │ Start Timestamp │ End Timestamp │ │ │ │ | ||
| 149 | +│ │ │ ├─────────┼───────────────────┼───────────────────┤ │ │ │ | ||
| 150 | +│ │ │ │ 0 │ 1000 │ 2500 │ │ │ │ | ||
| 151 | +│ │ │ │ 1 │ 1100 │ 2600 │ │ │ │ | ||
| 152 | +│ │ │ │ 2 │ 1020 │ 2520 │ │ │ │ | ||
| 153 | +│ │ │ │ ... │ ... │ ... │ │ │ │ | ||
| 154 | +│ │ │ └─────────┴───────────────────┴───────────────────┘ │ │ │ | ||
| 155 | +│ │ └─────────────────────────────────────────────────────────┘ │ │ | ||
| 156 | +│ └─────────────────────────────────────────────────────────────────┘ │ | ||
| 157 | +``` | ||
| 158 | + | ||
| 159 | +#### 3.1.1.3 warp基本信息展示 | ||
| 160 | + | ||
| 161 | +需要在detail信息中展示warp总的IPC信息,以及warp stall的top排序。 | ||
| 162 | + | ||
| 163 | +warp stall的top排序通过采样得到,硬件通过在采样周期内轮询着对每个warp做pc采样,获取当前的stall信息。工具通过这个信息获取当前所有的stall信息,并进行排序、显示。 | ||
| 164 | + | ||
| 165 | +### 3.1.2 仿真 | ||
| 166 | + | ||
| 167 | +#### 3.1.2.1 指令流水图 | ||
| 168 | + | ||
| 169 | +**仿真流水图展示某指令在scalar上经历的时间** | ||
| 170 | + | ||
| 171 | + a. 当前没有ccu日志,所以只能增加显示指令从icache->IQ pop的时间,若未来仿真器有开放计划可以增加显示进入IQ的时刻(从IB弹出的时刻)。 | ||
| 172 | + | ||
| 173 | + b. 涉及到的日志有icache.log | ||
| 174 | + | ||
| 175 | + c. 需要注意的是仿真日志同步传输场景和落盘场景都需要适配。 | ||
| 176 | + | ||
| 177 | + d. 当前仅支持A2/A3 | ||
| 178 | + | ||
| 179 | +<img src="./img/仿真scalar流水.png" style="zoom: 80%;" /> | ||
| 180 | + | ||
| 181 | +**imt算子增加显示使用的线程信息** | ||
| 182 | + | ||
| 183 | + a. 仿真流水图中增加显示当前的timeline所用到的线程数。 | ||
| 184 | + | ||
| 185 | + b. 使用instr.log中的prdctMask和execMask,两者相与得到线程数。 | ||
| 186 | + | ||
| 187 | +## 3.2 技术选型(可选) | ||
| 188 | + | ||
| 189 | +/ | ||
| 190 | + | ||
| 191 | +## 3.3 安全隐私与DFX设计 | ||
| 192 | + | ||
| 193 | +### 3.3.1 上板 | ||
| 194 | + | ||
| 195 | +#### 3.3.1.1 指令流水图 | ||
| 196 | + | ||
| 197 | +**DFX设计** | ||
| 198 | + | ||
| 199 | +**可靠性** | ||
| 200 | + | ||
| 201 | +1. 由于scalar指令多且对算子优化帮助不大,所以当前不插scalar pipe指令,即不显示纯scalar指令流水。当前仅仅关注simd vf/simt vf/MTE1/MTE2/MTE3/CUBE(PIPE_M)/FIXP(PIPE_F) | ||
| 202 | + | ||
| 203 | +2. 由于dfx_region使用数目有限制(当前每个Pipe仅能用512个),故存在极端情况某个Pipe指令数超过512个,发生时需要让用户感知。当前设计为编译器插桩时如果感知到有超过512的情况时会通过返回值或者日志让工具感知,工具再将结果呈现给用户。 | ||
| 204 | + | ||
| 205 | +3. 由于硬件原因,在dfx_region插入多、算子复杂时 时间信息可能会丢失,提出两个缓解措施: | ||
| 206 | + | ||
| 207 | + a. 编译器提供参数(工具也需要提供选项给用户),插桩可以只插某 特定pipe,工具只显示特点pipe的流水信息。 | ||
| 208 | + | ||
| 209 | + b. 工具从硬件获取数据丢失信息,并呈现给用户,告知用户当前有数据丢失,用户可选择使用仿真流水功能。 | ||
| 210 | + | ||
| 211 | +**性能** | ||
| 212 | + | ||
| 213 | +1. 由于算子文件中可能存在多个tiling key/kernel name,但是每次算子拉起只会选择其中一个运行。故非目标tiling key/kernel name无需插桩,工具要求编译器提供选项,工具输入目标tiling key/kernel name,编译器只对目标算子进行插桩,故工具需要限制算子必须全部inline,如果存在子函数,子函数流水内容无法呈现。此操作可以减少region_id的使用以及大大缩短插桩时间。 | ||
| 214 | + | ||
| 215 | +**可测试性** | ||
| 216 | + | ||
| 217 | +1. 解析硬件功能应封装为一个接口,该接口只接收原始数据并解析。 | ||
| 218 | + | ||
| 219 | +#### 3.3.1.2 warp耗时展示 | ||
| 220 | + | ||
| 221 | +**DFX设计** | ||
| 222 | + | ||
| 223 | +**安全** | ||
| 224 | + | ||
| 225 | +1. 该功能需要生成新交付件,用于保存桩内容,需要按照要求生成特定权限的交付件 | ||
| 226 | + | ||
| 227 | +2. 桩中需要访问外部传入的GM内存,访问前需要确认该内存的合法性以及大小。 | ||
| 228 | + | ||
| 229 | +### 3.3.2 仿真 | ||
| 230 | + | ||
| 231 | +#### 3.3.2.1 指令流水图 | ||
| 232 | + | ||
| 233 | +**可靠性** | ||
| 234 | + | ||
| 235 | +1. 当仿真器日志缺少无法绘制某pc完整流水信息时,需要报错给用户并显示异常pc,此时不可终止程序影响其他pc流水的生成。 | ||
| 236 | +2. 落盘场景、日志传输场景都需要支持此功能。 | ||
| 237 | + | ||
| 238 | +## 3.4 编程与调用设计 | ||
| 239 | + | ||
| 240 | +### 3.4.1 编程模型基本设计 | ||
| 241 | + | ||
| 242 | +### 3.4.1.1 上板 | ||
| 243 | + | ||
| 244 | +#### 3.4.1.1.1 指令流水图 | ||
| 245 | + | ||
| 246 | +1. 数据获取部分:需要按照硬件返回信息规定数据结构,编码时将数据结构定义好,不可只获取当前使用到的信息,需要考虑到将来的功能拓展。 | ||
| 247 | + | ||
| 248 | + 例如可定义28-31位数据结构体: | ||
| 249 | + | ||
| 250 | + Struct { | ||
| 251 | + | ||
| 252 | + kickstart, | ||
| 253 | + | ||
| 254 | + status, | ||
| 255 | + | ||
| 256 | + dispatch, | ||
| 257 | + | ||
| 258 | + execute | ||
| 259 | + | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + // 涉及到的pipe有 | ||
| 263 | + | ||
| 264 | + Struct { | ||
| 265 | + | ||
| 266 | + pipe_s, | ||
| 267 | + | ||
| 268 | + pipe_m, | ||
| 269 | + | ||
| 270 | + pipe_v, | ||
| 271 | + | ||
| 272 | + mte1, | ||
| 273 | + | ||
| 274 | + mte2, | ||
| 275 | + | ||
| 276 | + mte3, | ||
| 277 | + | ||
| 278 | + pipe_f | ||
| 279 | + | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | +#### 3.4.1.1.2 warp耗时展示 | ||
| 283 | + | ||
| 284 | +此功能需要插入两个桩,需要注意的是: | ||
| 285 | + | ||
| 286 | +1. 写插桩代码时需要注意扩展性,可扩展至插多个桩,注意接口封装。 | ||
| 287 | +2. 需要注意不可与其他功能桩共用,例如不可参与到重放中。 | ||
| 288 | + | ||
| 289 | +#### 3.4.1.1.3 warp基本信息展示 | ||
| 290 | + | ||
| 291 | +当前基本信息展示的不全需要在界面设计时预留未来数据。 | ||
| 292 | + | ||
| 293 | +### 3.4.1.2 仿真 | ||
| 294 | + | ||
| 295 | +#### 3.4.1.2.1 指令流水图 | ||
| 296 | + | ||
| 297 | +/ | ||
| 298 | + | ||
| 299 | +### 3.4.2 接口定义与设计 | ||
| 300 | + | ||
| 301 | +#### 3.4.2.1 bisheng-tune | ||
| 302 | + | ||
| 303 | +* 接口描述:编译器提供的插桩二进制 | ||
| 304 | +* 接口原型:bisheng-tune二进制 | ||
| 305 | +* 输入/输出参数: | ||
| 306 | + | ||
| 307 | +| 参数名称 | 输入/输出 | 类型 | 描述 | 取值范围 | | ||
| 308 | +| --- | --- | --- | --- | --- | | ||
| 309 | +| --tiling-key | 输入 | String | 从.o中选择特定算子进行插桩 | / | | ||
| 310 | +| --kernel-name | 输入 | String | 从.o中选择特定算子进行插桩 | / | | ||
| 311 | + | ||
| 312 | +* 异常处理: | ||
| 313 | + | ||
| 314 | + 1. 当插桩失败是返回错误码。 | ||
| 315 | + 2. 当dfx_region插桩成功但是region_id用光导致无法继续插桩时返回特点错误码。 | ||
| 316 | + 3. 当输入的tiling-key/kernel-name不存在时报错返回,视为异常1。 | ||
| 317 | + | ||
| 318 | +* 约束说明:/ | ||
| 319 | + | ||
| 320 | +* 变更说明:增加--kernel-name=xxxx参数,编译器会从.o中选择特定算子进行插桩。 | ||
| 321 | + | ||
| 322 | +* 调用参考代码: | ||
| 323 | + | ||
| 324 | + 1. bisheng-tune --action=block-count-instr --tune-bbbend-offset --tune-argsize=x oldKernelFile -o newKernelFile --tiling-key=0 | ||
| 325 | + | ||
| 326 | + 2. bisheng-tune --action=block-count-instr --tune-bbbend-offset --tune-argsize=x oldKernelFile -o newKernelFile --kernel-name=add | ||
| 327 | + | ||
| 328 | +#### 3.4.2.2 ICacheLog | ||
| 329 | + | ||
| 330 | +* 接口描述:仿真器传输icache数据接口。 | ||
| 331 | +* *接口原型:*void ICacheLog(uint64_t time, const DvcIcacheLogEntry_t *iCacheLog) | ||
| 332 | +* 输入/输出参数: | ||
| 333 | + | ||
| 334 | +| 参数名称 | 输入/输出 | 类型 | 描述 | 取值范围 | | ||
| 335 | +| --------- | --------- | --------------------- | ------------------- | -------- | | ||
| 336 | +| time | 输入 | uint64_t | 日志产生的时刻 | / | | ||
| 337 | +| iCacheLog | 输入 | DvcIcacheLogEntry_t * | struct DvciCacheLog | / | | ||
| 338 | + | ||
| 339 | +* 异常处理:当数据有丢失时仿真器会日志打印。 | ||
| 340 | + | ||
| 341 | +* 约束说明: | ||
| 342 | + | ||
| 343 | + DvciCacheLog结构体详细定义为: | ||
| 344 | + | ||
| 345 | + struct DvciCacheLog { | ||
| 346 | + | ||
| 347 | + uint64_t time; | ||
| 348 | + | ||
| 349 | + uint64_t addr; | ||
| 350 | + | ||
| 351 | + uint32_t coreId; | ||
| 352 | + | ||
| 353 | + uint32_t subCoreId; | ||
| 354 | + | ||
| 355 | + uint32_t size; | ||
| 356 | + | ||
| 357 | + uint32_t type; | ||
| 358 | + | ||
| 359 | + uint8_t last; | ||
| 360 | + | ||
| 361 | + }; | ||
| 362 | + | ||
| 363 | +* 变更说明:此接口为新增接口 | ||
| 364 | + | ||
| 365 | +* 调用参考代码:/ | ||
| 366 | + | ||
| 367 | +### 3.4.3 使用说明 | ||
| 368 | + | ||
| 369 | +### 3.4.3.1 上板 | ||
| 370 | + | ||
| 371 | +#### 3.4.3.1.1 指令流水图 | ||
| 372 | + | ||
| 373 | +**使用:** | ||
| 374 | + | ||
| 375 | +1. 需要使用--aic-metrics=instrTimeline使能上板流水图。 | ||
| 376 | +2. 工具增加--pipe=simd/simt/MTE1/MTE2/MTE3/CUBE/FIXP选项让用户自行选择需要展示的pipe,当用户未用当前参数时则默认全部展示。 | ||
| 377 | + | ||
| 378 | +**约束与限制:** | ||
| 379 | + | ||
| 380 | +1. 当前仅限A5机器可以使用该功能,A2/A3无此功能。 | ||
| 381 | +2. 当总线负载过高时,硬件有丢数据的情况,工具会提示用户数据丢失,用户可自行选择使用pipe级流水或者仿真流水 。 | ||
| 382 | +3. 确定当前编译器(cann)版本,需配套使用。 | ||
| 383 | +4. Simt vf/simd vf 内部详细指令无法呈现。 | ||
| 384 | + | ||
| 385 | +#### 3.4.3.1.2 warp耗时展示 | ||
| 386 | + | ||
| 387 | +**使用:** | ||
| 388 | + | ||
| 389 | +工具会自行识别当前是否为simt算子时,若是simt算子工具将会自动插桩并生成数据展示。 | ||
| 390 | + | ||
| 391 | +**约束与限制:** | ||
| 392 | + | ||
| 393 | +1. 仅限A5 simt算子 | ||
| 394 | +2. 确定当前编译器(cann)版本,需配套使用。 | ||
| 395 | + | ||
| 396 | +#### 3.4.3.1.3 warp基本信息展示 | ||
| 397 | + | ||
| 398 | +**使用:** | ||
| 399 | + | ||
| 400 | +涉及到warp stall原因展示时需要增加--aic-metrics=pcsampling,使能硬件采样。 | ||
| 401 | + | ||
| 402 | +**约束与限制:** | ||
| 403 | + | ||
| 404 | +1. 仅限A5 simt算子 | ||
| 405 | + | ||
| 406 | +### 3.4.3.2 仿真 | ||
| 407 | + | ||
| 408 | +#### 3.4.3.2.1 指令流水图 | ||
| 409 | + | ||
| 410 | +**使用:** | ||
| 411 | + | ||
| 412 | +默认使能 | ||
| 413 | + | ||
| 414 | +**约束与限制:** | ||
| 415 | + | ||
| 416 | +1. warp相关参数时仅限A5 simt算子显示。 | ||
| 417 | +2. scalar相关时间线当前仅在A2/A3上支持。 | ||
| 418 | + | ||
| 419 | +# 4.测试设计 | ||
| 420 | + | ||
| 421 | +## 4.1 上板 | ||
| 422 | + | ||
| 423 | +### 4.1.1 指令流水图 | ||
| 424 | + | ||
| 425 | +**单元测试** | ||
| 426 | + | ||
| 427 | +1. 需要测试解析硬件数据接口,构造全部硬件返回数据类型。 | ||
| 428 | +2. 其他接口按照UT覆盖率要求即可。 | ||
| 429 | + | ||
| 430 | +**用例测试** | ||
| 431 | + | ||
| 432 | +1. 算子类型:mix、cube、vec、simt算子。 | ||
| 433 | +2. 特殊算子:模板库算子、多tilingkey算子、单tilingkey算子。(需要测试编译器--tilingkey、--kernename参数) | ||
| 434 | +3. 调起方式 :需要包含全类型例如torch算子、aclnn算子等。 | ||
| 435 | +4. 特殊场景:某pipe指令数量超过512个;测试数据丢失时硬件是否会返回 | ||
| 436 | +5. 款型:A5 | ||
| 437 | + | ||
| 438 | +#### 4.1.2 warp耗时展示 | ||
| 439 | + | ||
| 440 | +**单元测试** | ||
| 441 | + | ||
| 442 | +1. 接口按照UT覆盖率要求即可。 | ||
| 443 | + | ||
| 444 | +**用例测试** | ||
| 445 | + | ||
| 446 | +1. 算子类型:simt算子。其他算子需要打印不支持日志 | ||
| 447 | +2. 调起方式 :需要包含全类型例如torch算子、aclnn算子等。 | ||
| 448 | +3. 特殊场景:非simt算子使用时需要打印不支持日志 | ||
| 449 | +4. 款型:A5 | ||
| 450 | + | ||
| 451 | +#### 4.1.3 warp基本信息展示 | ||
| 452 | + | ||
| 453 | +**单元测试** | ||
| 454 | + | ||
| 455 | +1. 接口按照UT覆盖率要求即可。 | ||
| 456 | + | ||
| 457 | +**用例测试** | ||
| 458 | + | ||
| 459 | +1. 算子类型:simt算子 | ||
| 460 | +2. 调起方式 :需要包含全类型例如torch算子、aclnn算子等。 | ||
| 461 | +3. 特殊场景:非simt算子使用时需要打印不支持日志 | ||
| 462 | +4. 款型:A5 | ||
| 463 | + | ||
| 464 | +### 4.2 仿真 | ||
| 465 | + | ||
| 466 | +#### 4.2.1 指令流水图 | ||
| 467 | + | ||
| 468 | +##### Scalar流水信息显示 | ||
| 469 | + | ||
| 470 | +**单元测试** | ||
| 471 | + | ||
| 472 | +1. 接口按照UT覆盖率要求即可。 | ||
| 473 | + | ||
| 474 | +**用例测试** | ||
| 475 | + | ||
| 476 | +1. 算子类型:simt算子。其他算子需要打印不支持日志 | ||
| 477 | +2. 调起方式 :需要包含全类型例如torch算子、aclnn算子等。 | ||
| 478 | +3. 特殊场景:缺少仿真器日志时需要打印异常日志,程序继续运行。 | ||
| 479 | +4. 款型:A2/A3 | ||
| 480 | + | ||
| 481 | +# 5.缺点和风险 | ||
| 482 | + | ||
| 483 | +## 5.1 上板 | ||
| 484 | + | ||
| 485 | +### 5.1.1 指令流水图 | ||
| 486 | + | ||
| 487 | +当前A5代际硬件在数据量大总线忙碌的情况下,存在概率性丢包,当前工具需要获取丢包信息返回给用户,让用户感知并能自行使用其他替代功能例如仿真流水图或上板pipe级别流水图。 | ||
| 488 | + | ||
| 489 | +# 6.现有技术 | ||
| 490 | + | ||
| 491 | +/ | ||
| 492 | + | ||
| 493 | +# 7.未解决问题 | ||
| 494 | + | ||
| 495 | +## 7.1 上板 | ||
| 496 | + | ||
| 497 | +### 7.1.1 指令流水图 | ||
| 498 | + | ||
| 499 | +当前A5代际硬件在数据量大总线忙碌的情况下,存在概率性丢包,当前工具需要获取丢包信息返回给用户,让用户感知并能自行使用其他替代功能例如仿真流水图或上板pipe级别流水图。 | ||
| 500 | + | ||
| 501 | +--- | ||
| 502 | + | ||
| 503 | +附录 | ||
| 504 | + | ||
| 505 | +* **参考资料链接** | ||
| 506 | +* **术语表** | ||
| 507 | +* **文档更新计划** | ||
| @@ -0,0 +1,139 @@ | |||
| 1 | +# MindStudio Debugger 功能设计说明书 | ||
| 2 | + | ||
| 3 | +状态 (Status): Approved | ||
| 4 | +作者 (Authors): @msot | ||
| 5 | +创建日期 (Created): 2025-08-06 | ||
| 6 | +更新日期 (Updated): 2025-08-06 | ||
| 7 | +相关 Issue/PR: [https://gitcode.com/Ascend/msdebug/issues/124](https://gitcode.com/Ascend/msdebug/issues/124) | ||
| 8 | + | ||
| 9 | +--- | ||
| 10 | + | ||
| 11 | +# 1. 概述 | ||
| 12 | + | ||
| 13 | +## 1.1 简介 | ||
| 14 | + | ||
| 15 | +本提案旨在设计并实现一款专为 NPU (Neural-network Processing Unit) 算子开发打造的调试工具。该工具类比 CPU 领域的 GDB/LLDB,旨在解决当前 NPU 算子开发过程中“黑盒化”、调试手段匮乏的痛点。它将提供断点设置、单步执行、变量实时查看、Core 文件解析及多核状态可视化等核心能力,将算子开发从“猜错”转变为“查错”,大幅提升开发效率与易用性。 | ||
| 16 | + | ||
| 17 | +## 1.2 动机 | ||
| 18 | + | ||
| 19 | +背景与痛点: | ||
| 20 | + | ||
| 21 | +目前 NPU 算子开发主要依赖 printf 风格的日志输出或基于仿真器的有限调试。而在真实上板调试上,开发者面临以下问题: | ||
| 22 | + | ||
| 23 | +1. AI Core 分析缺失: 无法获知程序具体崩溃在哪一行代码,只能看到 AI Core Error, 无法回溯调用栈 | ||
| 24 | +2. 部分内存不可见: 当前printf不支持L0内存和寄存器值的打印 | ||
| 25 | +3. printf风格打印易用性低:每次需要修改代码重新编译才能打印想看的变量,且printf容易影响算子同步逻辑,多核多线程场景下查看变量也不方便,需要精细化控制打印逻辑 | ||
| 26 | + | ||
| 27 | +通过引入该工具,开发者可以: | ||
| 28 | + | ||
| 29 | +- 精确定位代码行导致的内存越界或计算错误。 | ||
| 30 | +- 直观查看每个 NPU Core的执行位置。 | ||
| 31 | +- 像调试 C++ 程序一样调试算子,提升算子开发的易用性。 | ||
| 32 | + | ||
| 33 | +不做此提案的影响: | ||
| 34 | +NPU 算子开发将继续维持低效的“修改-编译-运行-看日志”循环,阻碍新算子的快速落地和业务迭代。 | ||
| 35 | + | ||
| 36 | +## 1.3 目标 | ||
| 37 | + | ||
| 38 | +本提案针对NPU算子上板调试功能进行开发,当前目标: | ||
| 39 | + | ||
| 40 | +1. AI Core 算子调试,只涉及910B, 950,310P芯片; | ||
| 41 | +2. AI Core Error生成的core文件的解析 | ||
| 42 | +3. 每次只能对单张卡做调试 | ||
| 43 | + | ||
| 44 | +非目标: | ||
| 45 | + | ||
| 46 | +1. AI CPU以及cpu程序的调试。 | ||
| 47 | +2. core文件的生成 | ||
| 48 | + | ||
| 49 | +# 2. 用例分析 | ||
| 50 | + | ||
| 51 | +| 场景描述 | 功能清单 | 功能描述 | 限制 | | ||
| 52 | +| --------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------- | | ||
| 53 | +| 程序控制 | 断点设置 | 软、硬断点增删管理,其中硬断点只用于simt vf/simd vf| 硬断点只用于simt vf/simd vf, 个数不超过4个; | | ||
| 54 | +| 程序控制 | 单步调试 | step over: 代码行级别单行往下运行; step in: 进入函数 ; step out: 跳出函数 | NA | | ||
| 55 | +| 程序控制 | 恢复运行 | 用于命中断点后的恢复运行,让程序继续运行下去 | NA | | ||
| 56 | +| 程序控制 | 中断运行 | 用于程序卡死在device侧时, 中断运行后查看卡死的代码行位置 | 中断后只支持查看调用栈和上下文切换功能 | | ||
| 57 | +| 信息打印 | 打印变量 | 打印变量的内容,会根据变量类型展示对应的结构体成员, 支持在host代码上打印申请的GM变量内容 | 不支持表达式计算的打印 | | ||
| 58 | +| 信息打印 | 打印寄存器 | 打印寄存器的内容| NA | | ||
| 59 | +| 信息打印 | 打印内存 | 打印不同类型的内存数据,包括UB,GM,L0A,L0B,L0C等 | NA | | ||
| 60 | +| 信息打印 | 上下文切换 | AI Core之间切换,或者Simt vf 里的线程切换,与配合状态信息展示功能或程序控制类功能配合使用 | NA | | ||
| 61 | +| 信息打印 | 状态信息展示 | 展示当前算子使用到的AI Core、Block、Device、Task、Stream、Thread等信息;展示当前AI Core停住位置的代码行信息 | NA | | ||
| 62 | +| 信息打印 | 调用栈回溯 | 展示当前AI Core所在代码行的调用栈 | simt_vf, simd_vf下断点的调用栈不会展示main scalar上;main scalar上的调用栈不会展示出host侧代码 | | ||
| 63 | +| core文件解析 | 信息打印场景所有功能 | 包含上述所有信息打印场景下的所有功能 | NA | | ||
| 64 | + | ||
| 65 | +# 3.方案设计 | ||
| 66 | + | ||
| 67 | +## 3.1 总体方案 | ||
| 68 | + | ||
| 69 | +本工具基于LLDB源码进行二次开发,基于代码仓本身的Client-Server结构。 | ||
| 70 | + | ||
| 71 | +系统由3个核心部分组成:调试客户端 (Client)、调试服务端 (Server)以及用于劫持用户进程的动态库(Preload Dynamic Library): | ||
| 72 | + | ||
| 73 | +<img src="./images/solution_arch.png" style="zoom: 80%;" /> | ||
| 74 | + | ||
| 75 | +Client: 负责解析用户输入的命令,解析ELF里的调试信息,把简化后的命令通过socket-pair方式进行进程间通信发送给Server侧 | ||
| 76 | +Server: 负责与驱动通信,通过ioctl把控制消息发送到驱动,获取或控制NPU设备上AI Core的执行状态;接收劫持库发送的pid, device_id, kernel object等信息 | ||
| 77 | +Preload Dynamic Library: 实现runtime的桩函数,通过劫持SetDevice,Register Kernel Object,Launch Kernel Object等函数,获取相应的信息,并发送给工具侧。 | ||
| 78 | + | ||
| 79 | +## 3.2 技术选型(可选) | ||
| 80 | + | ||
| 81 | +考虑到GDB的开源协议不适合商用,这里选择lldb代码仓进行二次开发 | ||
| 82 | + | ||
| 83 | +## 3.3 安全隐私与DFX设计 | ||
| 84 | + | ||
| 85 | +1. 安全:使用调试功能时,需要root用户打开驱动的通道开关。 | ||
| 86 | +2. 可维护性:DeviceContext类可派生出不同芯片类型下的子类,屏蔽底层硬件感知 | ||
| 87 | +3. 可靠性:调试工具的劫持库不改变用户算子行为,只做信息收取 | ||
| 88 | +4. 可测试性:交互式测试用例以及UT | ||
| 89 | + | ||
| 90 | +## 3.4 编程与调用设计 | ||
| 91 | + | ||
| 92 | +### 3.4.1 编程模型基本设计 | ||
| 93 | + | ||
| 94 | +环境: Linux Host, NPU Driver v26.0+. | ||
| 95 | +语言: C++ (核心引擎). | ||
| 96 | +约束: 被调试的算子二进制必须带有 -g(DWARF) -O0 调试信息。 | ||
| 97 | + | ||
| 98 | +### 3.4.2 接口定义与设计 | ||
| 99 | + | ||
| 100 | +控制AI Core执行状态的结构体定义设计参考arch文档(https://gitcode.com/Ascend/msdebug/blob/master/docs/zh/development_guide/architecture.md) | ||
| 101 | + | ||
| 102 | +Coredump文件的结构体定义设置参考[architecture.md](https://gitcode.com/Ascend/msdebug/blob/master/docs/zh/development_guide/architecture.md#4312-%E5%85%B3%E9%94%AE%E5%AD%97%E6%AE%B5%E8%AF%B4%E6%98%8E) | ||
| 103 | + | ||
| 104 | +### 3.4.3 使用说明 | ||
| 105 | + | ||
| 106 | +编译算子: 确保编译时加入 -g -O0选项保留调试符号。 | ||
| 107 | +打开驱动通道: `echo 1 > /proc/debug_switch` | ||
| 108 | +启动调试: 执行 `msdebug <app>`,进入交互界面后输入 `b <file_name>:<line_no>`设置断点,然后 `run`. | ||
| 109 | + | ||
| 110 | +# 4.测试设计 | ||
| 111 | + | ||
| 112 | +*介绍该功能的测试方法以及测试用例设计,包括单元测试(unit test),集成测试(integration test),端到端测试(e2e test)等。* | ||
| 113 | + | ||
| 114 | +| 测试类型 | 算子场景 | 描述 | 示例 | | ||
| 115 | +| ------- | ------- | ---- | ---- | | ||
| 116 | +| 单元测试 | NA | 测试Server测功能函数 | HandleStubDevice测试能否处理收到的device_id信息 | ||
| 117 | +| E2E测试 | Simt算子 | 测试上述所有功能是否成功 | 断点设置在simt算子里,能否恢复运行,变量打印等功能 | ||
| 118 | +| E2E测试 | Simd算子 | 测试上述所有功能是否成功 | 断点设置在simd算子里,能否恢复运行,变量打印等功能 | ||
| 119 | +| E2E测试 | cube算子 | 测试上述所有功能是否成功 | 断点设置在simd算子里,能否恢复运行,变量打印等功能 | ||
| 120 | + | ||
| 121 | +# 5.缺点和风险(可选) | ||
| 122 | + | ||
| 123 | +缺点:当前需要Simt/Simd VF函数,无法做到O0优化,可能部分代码行无法断住 | ||
| 124 | + | ||
| 125 | +# 6.现有技术(可选) | ||
| 126 | + | ||
| 127 | +lldb本身仓库对gpu的支持 | ||
| 128 | + | ||
| 129 | +# 7.未解决问题(可选) | ||
| 130 | + | ||
| 131 | +无 | ||
| 132 | + | ||
| 133 | +--- | ||
| 134 | + | ||
| 135 | +附录 | ||
| 136 | + | ||
| 137 | +* **参考资料链接** | ||
| 138 | +* **术语表** | ||
| 139 | +* **文档更新计划** | ||