# 算子开发 **Repository Path**: liu-xiqiang/operator-development ## Basic Information - **Project Name**: 算子开发 - **Description**: S2Ascend C 算子大赛算子开发 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-08-23 - **Last Updated**: 2025-01-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 算子开发 #### GroupNormV2的算子的计算逻辑? A1:GroupNormV2算子是一个分组实现归一化的算子。 其中我们先了解一下他的输入输出和ATTR 输入:x、 gamma(上图用r表示) 、 beta(上图用b表示) 输出:y 、 mean 、 rstd Attr: num_groups(在图中用G表示)、 data_format、 esp、 is_training GroupNormV2算子的计算逻辑和计算步骤: 1. 将一个图的C通道分成G份,这样就得到了N*G个小组的数据,其中每个小组的数据含有num_groups个通道数。 2. 将每个小组的所有数据进行求均值、求方差的操作,并将均值和方差输出(该过程如上图蓝色箭头表示): 计算公式如下: 3. 将各小组计算的均值和方差根据归一化公式对原数据进行归一化操作(该过程如上图得到蓝色数据块过程) 计算公式如下: 4. 将归一化得到的各个小组的归一化数据进行仿射变换,这里的r、b与x的通道对应,并将各小组得到的结果合并输出(该过程如上图得到分红色数据块过程) 计算公式如下: #### GroupNormV2的算子的设计思路 一、 可以将数据在GM上进行单点数据的操作。 用户可以将数据搬运至GM上,在kernel侧通过GM的GetValue、SetValue等API对GM上的数据进行直接数据读取和数据设置。在核函数中主要是通过for循环对每组数据进行均值和方差求解。并将完成归一化的和仿射变换的结果直接设置到输出的GM上。 优点:不需要考虑数据对齐和同步问题 缺点:由于是单点计算,直接对GM上数据操作,会出现算子性能低的问题 在较大Shape时,需进行大量的同号累加操作,会出现在算子精度上较低的问题 二、 可以使用Ascend C API进行数据块处理 根据A1中对算子的计算逻辑的讲解中,我们不难看出。需要处理的数据是呈块状分布的,我们可以通过Ascend C的向量相关的API进行数据块之间的计算。相比单点计算,可以减少计算中的循环次数,并能发挥vector核的强大算力。 优点:对数据进行向量块计算,比单点计算的运算效率更高,算子性能更好 在数据进行累加过程使用Ascend C的API能有效减小计算误差,提升算子精度。 #### GroupNormV2的算子的性能调优 A3:通过A2中的算子实现方式我们可以了解到对数据进行向量运算比单点计算可以有效的提升算子性能。所以我们的算子性能调优基于“Ascend C API进行数据块处理”的实现方式进行优化。主要优化方法有: 1. 进行数据多核切分,使数据进行多核计算 通过A1对GroupNormV2算子的实现逻辑的讲述中我们可以发现,算子对每一个小组的数据的处理逻辑都是相同的,且各小组间的数据没有依赖关系。因此可以将每一个小组分成一个核进行处理。减少每个核中重复逻辑的运算量。理论上能提升分核数的性能。(这里只是分核优化的建议,如有更好的分核方法可以使用) 2. 充分使用UB空间,减少单核内的循环次数 在进行核函数可发过程中,我们只需要考虑一个核的计算逻辑。在单核中需要充分使用UB的空间,减少单核中的循环次数。 3. 减少外部存储和内部存储间的数据搬运次数,尽可能保证GM地址512B对齐。 DataCopy的过程是一个较为耗时的过程,尽量减少数据在内、外部存储间的数据搬运。在GM向Local Memory搬运数据时,保证GM地址512B对齐可以最高效的发挥出带宽的效率,减少数据搬运的耗时。 4. 在核函数开发过程中尽可能使用矢量API进行操作 在进行核函数开发中,要尽可能使用矢量API进行数据运算。在进行块状数据求和和数据相乘时能够调用vector计算单元快速完成运算操作。