CPU调测功能
功能介绍
- 如果用户需要快速进行代码逻辑调试,可优先选择算子CPU调测。使用通用的打印、gdb调测手段,快速定位代码问题。
- 在NPU板端上板运行之前,可优先选择算子CPU调测初步定位算子精度问题,提高算子NPU上板成功率。
CPU调测主要基于用户输入,生成编译所需的bin文件,自动执行算子CPU编译和运行。
- 自动精度比对:若用户配置了标杆数据(golden数据),工具会自动将实际调测运行结果与标杆数据进行精度比对。
- npucheck功能:通过--npucheck或CpuOptions.npucheck开启,提供CPU内存校验和异常检测功能,不支持与Debug调试功能同时开启。
- printf/PRINTF功能:支持打印Scalar数据,如常量、字符串等信息。
- DumpTensor功能:支持打印Tensor数据。
- assert功能:支持断言打印,当核函数代码中某个条件为假,则中断运行流程并打印相关信息。
使用方法(命令行)
- 完成环境搭建,并准备好输入/标杆数据文件。
- 执行如下命令进行CPU调测,这里仅提供关键参数项,其余参数请参考CPU调测参数按需设置。
ascendebug kernel --backend cpu --json-file ${op_config_json_file} --repo-type ${repo_type} --chip-version ${chip_version} --core-type ${core_type} --install-path ${cann_install_path} --work-dir ${work_dir} ... {其他参数}
CPU调测涉及的所有参数可通过ascendebug kernel -h或ascendebug kernel --help查看。
- 查看调测产物。核函数CPU调测后的结果文件存放在--work-dir目录下,详细说明参见调测产物。
使用方法(API)
- 完成环境搭建,并准备好输入/标杆数据文件。
核函数直调工程场景下,需提前配置好核函数源码信息OpKernelInfo。
- 构建算子信息。调用DebugOp类里input系列接口(如tensor_input、custom_input等),设置算子的输入、输出、属性值等信息。
- 创建调试对象并初始化工作空间。调用create_op_executor接口,创建调试对象op_executor,用户可传入${work_dir}参数手动设置工作空间。
- (可选)参考Tiling调测功能 > 使用方法(API)章节,调用Tiling调测接口生成Tiling Info文件。
本步骤仅适用于没有Tiling Info文件的场景,需调用Tiling调测API生成Tiling Info。
- 调用编译运行接口,在CPU上仿真运行核函数,完成输出数据精度比对。
- 标准自定义算子场景:调用run_custom_cpu接口。
- 核函数直调场景:调用run_call_kernel_cpu接口。
- ops_adv算子场景:调用run_ops_adv_cpu接口。
- 查看调测产物。核函数CPU调测后的结果文件存放在${work_dir}目录下,详细说明参见调测产物。
调测产物
无论是命令行方式或API方式,CPU调测结果存放在${root}/${work_dir}/cpu路径下,包含src、build、output三个文件子目录。其中${root}表示当前操作路径,${work_dir}表示调测工作空间,默认为/debug_workspace/${op_type}目录,${op_type}为算子名。目录结构示例如下,精度比对结果文件的说明参见表1。
├ ${op_type}(算子名) ├── cpu │ ├── build(存放CPU编译生成的中间文件) │ ├── xxx_cpu (CPU编译生成的算子可执行程序) │ ├── npuchk (npucheck结果存放路径) │ ├── auto_gen_${op_kernel_type}_kernel_${block_num}_${sblock_num}_${kernel_type}_npuchk.log │ ├── output(存放CPU编译运行的输出文件及精度比对结果) │ ├── y.bin (运行输出原始数据) │ ├── y.txt (精度比对结果文件) │ ├── src(存放CPU编译生成的临时代码文件) │ ├── CMakeLists.txt │ ├── data_definition.txt │ ├── add_custom_main.cpp │ ├── add_custom_tiling.h │ ├── _gen_kernel_${op_type}.cpp
- 查看精度比对结果
- 在output目录下,查看是否生成输出文件(bin)和精度比对文件(txt)。
- 根据精度比对文件(txt),确认算子精度比对结果。
精度比对结果输出样例如下,主要展示两份数据的均值、部分误差对比以及成功/失败的最终比对结论。若结果是失败,会将最大误差的部分数据展示出来。
data_cmp mean is -1.41e-05 data_gd mean is -1.41e-05 split_count:2359296.0; max_diff_hd:0.1; --------------------------------------------------------------------------------------- Loop ExpectOut RealOut FpDiff RateDiff --------------------------------------------------------------------------------------- 00000001 0.0395813 0.0395813 0.0000000 0.0000000 00000002 0.0160980 0.0160980 0.0000000 0.0000000 00000003 -0.0443420 -0.0443420 0.0000000 0.0000000 00000004 -0.0847778 -0.0847778 0.0000000 0.0000000 00000005 -0.0066605 -0.0066605 0.0000000 0.0000000 00000006 0.0880737 0.0880737 0.0000000 0.0000000 00000007 0.0848389 0.0848389 0.0000000 0.0000000 00000008 0.1083374 0.1083374 0.0000000 0.0000000 00000009 0.0838623 0.0838623 0.0000000 0.0000000 00000010 0.0887451 0.0887451 0.0000000 0.0000000 00000011 0.0572205 0.0572205 0.0000000 0.0000000 00000012 0.0741577 0.0741577 0.0000000 0.0000000 00000013 -0.0762329 -0.0762329 0.0000000 0.0000000 00000014 -0.0957642 -0.0957642 0.0000000 0.0000000 00000015 0.0102234 0.0102234 0.0000000 0.0000000 ... ... ... ... ... --------------------------------------------------------------------------------------- DiffThd PctThd PctRlt Result --------------------------------------------------------------------------------------- 0.0050 99.50% 100.000000% Pass Success Success Success Success Success
表1 精度比对结果说明 信息项
说明
data_cmp mean
运行输出数据的均值信息。
data_gd mean
标杆数据的均值信息。
split_count
统计输出数据的个数。
max_diff_hd
输出数据和golden数据的最大误差值阈值。
详细对比数据展示(部分)
Loop(数据位置)、ExpectOut(期望输出值)、RealOut(实际输出值)、FpDiff (绝对误差值)、RateDiff(相对误差值)。
整体对比结果展示
DiffThd(相对误差值阈值)、PctThd (精度达标数据占比阈值)、PctRlt(实际精度达标数据占比)、Result(对比结果)。
Error Line展示项
若精度比对结果为Failed,会追加展示部分误差较大的数据的详细信息,信息格式与"详细对比数据展示(部分)"一致。
- (可选)查看npucheck结果
- 若开启npucheck功能,检查屏显日志是否出现“ascendc npuchk report”,同时build目录下是否有npucheck目录。
- 查看npucheck结果文件。
CPU调测开启npucheck后,算子Kernel运行时会记录每一个算子OP指令,涉及的指令分类参见表2。
表2 npucheck检测的OP指令类 OP指令类别
指令说明
npucheck检测内容
OP_DMA
DMA(Direct Memory Access)数据搬运类指令。负责在Global Memory和Local Memory之间搬运数据,包含搬运单元MTE2(Memory Transfer Engine,数据搬入单元)指令,MTE3(数据搬出单元)指令等。
- 数据读、写、多核踩踏等内存校验。
- 同步合法性校验。
OP_VEC
vector向量相关操作指令。
根据vector指令配置,检测内存读、写、多核踩踏合法性。
OP_CUBE
cube矩阵相关操作指令。
根据cube指令配置,检测内存读、写、多核踩踏合法性。
OP_SETFLAG
set同步指令。
- 检测数据同步合法性。
- 配合OP_WAITFLAG指令,检测set/wait配对校验。
OP_WAITFLAG
wait同步指令。
配合OP_SETFLAG指令,检测set/wait配对校验。
Ascend C Buffer操作指令
包括tbuff的alloc、free、pers、init操作指令。
使用未初始化内存、重复释放内存、内存泄漏等异常操作的校验。
记录的算子OP指令详细信息会保存在${root}/${work_dir}/cpu/build/npuchk路径,文件名为auto_gen_${op_kernel_type}_kernel_${block_num}_${sblock_num}_${kernel_type}_npuchk.log。其中${op_kernel_type}是算子核函数名,${block_num}是block编号,${sblock_num}是子block编号,${kernel_type}是核类型标识(如cub、vec)。
记录的信息文件内容示例如下:
### copy_ubuf_to_gm((__gm__ void*)0x7f75ef657fe0, (__ubuf__ void*)0x7f75c3358010, (uint8_t)0, (uint16_t)1, (uint16_t)4, (uint16_t)0, (uint16_t)0); [MTE3] [RECV_INST] copy_ubuf_to_gm type 0 [MTE3] [EXECUTE] copy_ubuf_to_gm type 0 [MTE3] read data 0x7f75c3358010 0x80 B type UB [MTE3] checking synced queue [MTE3] [CHECK_DATA] 0x7f75c3358010 0x80 B type UB [MTE3] [ErrorRead2] on read 0x7f75c3358010 0x80 B
若检测到内存异常信息,log日志中会显示检测到的异常信息,示例如下:
---------------------- ERROR STATISTICS ---------------------- 1, ErrorRead4, 读取地址非32字节对齐 1, ErrorRead2, [可疑问题]读取无效数据:读取的内存部分/全部从未被写过,读取的数据可能是无效数据 1, ErrorRead1, 非法内存读取数据: 整段内存未经过AscendC框架的alloc_buf申请或者已free 1, ErrorWrite4, 写入地址非32字节对齐 1, ErrorWrite1, 非法内存写入数据: 未经过AscendC框架的alloc_buf申请过或者已经free了 1, ErrorRead3, 读取越界, 长度超出经AscendC框架的alloc_buf申请实际有效的数据(开始/结尾)
全量的异常检测上报信息字段说明参见表3。
表3 npucheck常见异常检测信息 ERROR标识
异常可能得原因
ErrorRead1
非法内存读取数据:整段内存未经过Ascend C框架的alloc_buf申请或者已经free。
ErrorRead2
[可疑问题]读取无效数据:读取的内存部分/全部从未被写过,读取的数据可能是无效数据。
ErrorRead3
读取越界,长度超出经Ascend C框架的alloc_buf申请实际有效的数据(开始/结尾)。
ErrorRead4
读取地址非32字节对齐。
ErrorWrite1
非法内存写入数据:未经过Ascend C框架的alloc_buf申请或者已经free。
ErrorWrite2
写入越界,长度超出经Ascend C框架的alloc_buf申请实际有效的数据(开始/结尾)。
ErrorWrite3
[可疑问题]重复写入,前一次写入的内存没有被读取走,重复写入。
ErrorWrite4
写入地址非32字节对齐。
ErrorSync1
写入存在同步问题,pipe内缺少pipe barrier/pipe间缺少set/wait。
ErrorSync2
读取存在同步问题,pipe内缺少pipe barrier/pipe间缺少set/wait。
ErrorSync3
set/wait使用不配对,缺少set或者wait。
ErrorSync4
出现set/wait的eventID重复,比如mte2: set0/set0,vector: wait0/wait0。
ErrorLeak
内存泄露,存在申请内存未释放问题,详细见auto_gen_${op_kernel_type}_kernel_${block_num}_${sblock_num}_${kernel_type}_npuchk.log。
ErrorFree
内存重复释放,调用free_buf释放过,再次调用free_buf。
ErrorBuffer0
tensor内存未使用Ascend C框架的bufInit。
ErrorBuffer1
tensor的que类型与初始化时不一致。
ErrorBuffer2
VECIN/VECOUT/VECCALC的操作不合规。
ErrorBuffer3
tensor的操作内存不合法,可能原因是内存未alloc/内存越界。