【2023 · CANN训练营第一季】课堂笔记3-算子的开发及验证
【2023 · CANN训练营第一季】课堂笔记3-算子的开发及验证
一、动态shape算子与固定shape算子
引入动态shape算子的背景条件:
当算子shape固定时,开发者使用不同shape时需要重新对算子进行编译,带来大量的算子二进制文件。
动态shape的算子可以将形状通过核函数的入参传入核函数内,参与内部逻辑计算,从而符合不同shape下的使用场景。
(资料图片仅供参考)
二者对比:
对固定算子的修改:
之前的固定算子,按照上节课的例子,是把数据分别分给8个核进行计算
而转换为动态算子,就需要将这些全局变量,都通过动态的形式作为可变的变量,这就代表着我们需要将这些全局变量作为入参进行输入进来。
基于现有的固定shape算子,将其改装为动态shape的算子。将控制形状的BLOCK DIM,TOTAL_LENGTH,TILE NUM这些变量依靠外界输入得到,在核
函数中额外传入一个tiling,它将指向控制核函数逻辑处理的至关重要的这几个变量
1.tiling结构体
根据上面的信息,我们可以分析得到结构体需要如下的内容
BLOCK DIM: 并行计算使用的核数
TOTAL LENGTH: 总共需要计算的数据个数
TILE NUM:每个核上计算数据分块的个数
但是前面文章内容中我们可以看出,入参需要统一为__gm__ uinit8_t*的形式,于是我们将结构体按照这种指针进行传入后,需要对该结构体进行解析,并
且还要区分是CPU侧和NPU侧的代码不同的执行
2.核函数对比
固定shape算子的核函数实现:
动态shape算子的核函数实现:
如上一小点所说,实际函数设计时,我们也需要的是将一些参数进行传入,并且进行解析,这样可以使我们随时改动传入的参数值
3.Init函数对比
在固定算子中,我们做逻辑地址区别时的参数也是由全局变量去决定的
在动态算子中,我们可以在相应的类中添加一些private的变量,以便可以从类中的函数直接调用其值
4.不同功能代码文件的区别
二、功能调试方法
TKC++提供孪生调试技术即在CPU模式下进行运实际上会创建个NPU的模型并模拟它的计算行为以此进行业务功能的调试。
相同的算子代码可以在CPU模式下进行精度调试,并无缝切换到NPU模式下运行
1.使用GDB调试
相关命令如下:
2.打印调试
在CPU代码侧直接插入C/C++的打印命令,如printf、std::cout,
PS:NPU模式下不支持打印语句,所以需要添加内置宏 CCE_KT_TEST 予以区分
三、测试验证
1.UT测试
按照一、4.点的不同功能代码的功能内容,我们可以做按照如下步骤
添加UT测试步骤:
1.cann_op_contrib/community/ops中新建用例目录并添加代码实现文件
2.cann_op_contrib/community/tests中新建用例目录并添加代码测试文件
3.在cann_op_contrib目录下执行./build.sh -u tik2
2.ST测试
1.cann_op_contrib/community/ops中新建用例目录并添加代码实现文件
2.cann_op_contrib/community/tests中新建用例目录并添加代码测试文件
3.在cann_op_contrib目录下执行后续打包算子,安装部署算子包和编译并执行测试用例的操作
3.对部分文件实现的简单讲解
(1)op_host/add_tik2_tiling.h
UT测试代码的tiling定义:
改写自动态shape的tiling解析函数:
只保留CPU模式下的处理逻辑,即将传入的tiling指针转化为tiling的结构体指针
ST测试代码的tiling定义:
提供了基于宏的封装模式: BEGIN_TILING_DATA_DEF定义了tiling结构体名称
TILING_DATA_FIELD_DEF定义了tiling中的成员变量
END_TILING_DATA DEF是结束定义的标志
REGISTER_TILING_DATA_CLASS完成注册,将算子类型与定义的tiling结构体绑定算子类型一般都是核函数名的大驼峰形式(核函数名一般为内核形式)
(2)op_host/add_tik2.cpp
host侧算子实现开发,包括算子原型注册、Shape推导等函数实现与注册、Tiling实现与注册和信息库配置
算子原型注册
算子原型描述了算子的输入输出,属性等信息,算子原型注册用于将算子注册到算子原型库中
Shape推导等函数实现与注册
根据算子的输入张量描述、算子逻辑及算子属性,推理出算子的输出张量描述,包括张量的Shape、数据类型及数据排布格式等信息。这样算子构图准备阶段就可以为所有的张量静态分配内存,避免动态内存分配带来的开销
推导函数的实现:
推导函数的注册:
Infershape:推理形状的函数
InfershapeRange: 推理形状中每个维度的范围的函数
InferDataType: 推理数据类型的函数
Tiling实现与注册
计算数据切分过程相关的参数,比如每次计算的数据量大小
TilingFunc: Tiling定义函数
TilingPrepare: Tiling解析函数
CheckOpsupport: 算子参数校验函数
OP_ADD:注册算子的原型定义
Tiling实现:
Tiling注册:
信息库配置(根据运行平台进行配置)
算子开发者需要通过配置算子信息库文件,将算子在昇腾AI处理器上相关实现信息注册到算子信息库中
(3)run_case.sh与test_add_tik2_data.py
CANN开发套件包中提供了ST测试工具: msopst,支持生成算子的ST测试用例并在硬件环境中执行
根据算子信息库定义文件(.ini)生成算子测试用例定义文件 (.json),作为算子ST测试用例的输入
根据算子测试用例定义文件生成ST测试数据及测试用例执行代码,在硬件环境上执行算子测试用例
自动生成运行报表 (st_report.son)功能,报表记录了测试用例信息及各阶段运行情况
根据用户定义并配置的算子期望数据生成函数,回显期望算子输出和实际算子输出的对比测试结果
(4)add_tik2.json
(5)生成测试用例与报告st_report.json
四、性能采集工具-msprof
性能采集步骤: 1.设置环境变量(异腾实际安装的位置): source /usr/local/Ascend/ascend-toolkit/../set_env.sh
2.测试NPU模式下的TIK C++算子,保证其精度正确,生成对应的二进制可执行文件: bash runsh add_tik2 ascend910 Aicore npu
3.使用msprof工具采集性能
4.使用命令(用户可以根据自身的需要灵活组合性能分析指令)
eg:
5.在当前目录会生成out文件夹,在device_0/summary/op_summary_0_1.csv能够看到一些具体的数据
ps:该文仅是为了记录CANN训练营的学习过程所用,不参与任何商业用途