L0C到L1数据搬运(DataCopy)
【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit
产品支持情况
- Ascend 950PR/Ascend 950DT:支持
- Atlas A3 训练系列产品/Atlas A3 推理系列产品:支持
- Atlas A2 训练系列产品/Atlas A2 推理系列产品:支持
- Atlas 200I/500 A2 推理产品:支持
- Atlas 推理系列产品AI Core:不支持
- Atlas 推理系列产品Vector Core:不支持
- Atlas 训练系列产品:不支持
功能说明
头文件路径为:basic_api/kernel_operator_data_copy_intf.h。
矩阵计算的结果存放在L0C Buffer,DataCopy接口用于将结果搬运至L1 Buffer中,并且在搬运过程中支持随路格式转换等操作。
下图展示了随路量化、随路ReLU、随路通道合并的有效组合、中间数据类型和数据路径。下图中的F32->F16与F32->BF16为非量化模式,仅为Cast,其余为随路scalar/tensor量化模式。
图1L0C2L1流程图(NPU架构版本2201)
图2L0C2L1流程图(NPU架构版本3510)
函数原型
DataCopy矩阵搬出接口支持多种随路能力的组合,需要设置不同的寄存器,配合数据搬运指令开启不同的数据搬运能力,对应的接口如下:
数据搬运接口,通路L0C Buffer(CO1)->L1 Buffer(C1),配合设置寄存器实现量化和ReLU激活。
template <typename T, typename U> __aicore__ inline void DataCopy(const LocalTensor<T>& dst, const LocalTensor<U>& src, const DataCopyCO12DstParams& intriParams)SetFixPipeConfig:寄存器设置接口,通过调用该接口设置随路量化,其中tensor的每个元素都代表一个量化参数,使用tensor量化时需要设置。
SetFixpipePreQuantFlag:寄存器设置接口,通过调用该接口设置随路量化参数,此元素代表整个输出矩阵使用的量化参数,使用Scalar量化时需要设置。
SetFixpipeNz2ndFlag:寄存器设置接口,通过调用该接口设置随路NZ2ND格式转换配置,使用随路NZ2ND需要设置。
针对Atlas 200I/500 A2 推理产品,还支持如下两个接口:
SetFixPipeClipRelu:寄存器设置接口,通过调用该接口设置ClipReLU操作的最大值。
SetFixPipeAddr:寄存器设置接口,通过调用该接口设置Elementwise操作时LocalTensor的地址。
参数说明
表1数据搬运DataCopy模板参数说明
| 参数名 | 描述 |
|---|---|
| T | 目的操作数的数据类型。支持的数据类型请参考数据类型。 |
| U | 源操作数的数据类型。支持的数据类型请参考数据类型。 |
表2数据搬运DataCopy接口参数说明
| 参数名称 | 输入/输出 | 含义 |
|---|---|---|
| dst | 输出 | 目的操作数,类型为LocalTensor,数据格式为NZ格式,地址需要满足32字节对齐。 |
| src | 输入 | 源操作数,类型为LocalTensor,支持的物理地址为L0C Buffer(TPosition为CO1),为Mmad接口计算的结果。数据格式为NZ格式,地址需要满足64字节对齐。 |
| intriParams | 输入 | 搬运参数,类型为DataCopyCO12DstParams。 具体定义请参考 ${INSTALL_DIR}/asc/include/basic_api/interface/kernel_struct_data_copy.h,${INSTALL_DIR}请替换为CANN软件安装后文件存储路径。 |
表3DataCopyCO12DstParams结构体参数定义
| 参数名称 | 含义 |
|---|---|
| sid | 此参数用户无需关注,设置为0即可。 |
| nSize | 源NZ矩阵在N方向上的大小。取值范围nSize∈[0, 4095],nSize必须为16的倍数。 注:nSize=0表示不执行搬运,该接口将被视为NOP(空操作)。 |
| mSize | 源NZ矩阵在M方向上的大小。取值范围为mSize∈[0, 65535]。 注:mSize=0表示不执行搬运,该接口将被视为NOP(空操作)。 |
| dstStride | 目的NZ矩阵中相邻Z排布的起始地址偏移,取值不为0,单位为datablock(32字节)。 |
| srcStride | 源NZ矩阵中相邻Z排布的起始地址偏移,取值范围为srcStride∈[0, 65535],单位为C0_Size(16*sizeof(T)),T为src的数据类型,其值应填成mSize对16向上取整。 |
| unitFlag | unitFlag是一种Mmad指令和Fixpipe指令细粒度的并行,开启该功能后,硬件每计算完一个分形,计算结果就会被搬出。取值说明如下: • 0(2'b00):不开启unitFlag。 • 2(2'b10):开启unitFlag,硬件执行完指令之后,不复位单元标记位。 • 3(2'b11):开启unitFlag,硬件执行完指令之后,复位单元标记位。 开启该功能时,须将Mmad指令和Fixpipe指令的unitFlag值设置为2或3。 参数设置方案和特性细节可参考:Mmad计算中关键特性说明的UnitFlag章节。 |
| clipReluPre | 该参数仅在Atlas 200I/500 A2 推理产品支持。 用于配置是否开启ClipReLU操作,参数类型为uint8_t,取值如下:0,不开启ClipReLU;1,开启ClipReLU,此时需要调用SetFixPipeClipRelu来设置ClipReLU的最大值。 •该操作在随路量化后进行,quantPre配置后才能使用,当前支持的量化模式有F322F16/DEQF16/VDEQF16/QF322B8_PRE/VQF322B8_PRE/REQ8/VREQ8。 |
| eltWiseOp | 该参数仅在Atlas 200I/500 A2 推理产品支持。 用于配置是否开启Elementwise操作及操作模式。Elementwise操作是指进行随路量化后,可以逐个元素加/减一个LocalTensor,大小为mSize * nSize,具体LocalTensor地址相关参数需要调用SetFixPipeAddr来设置。 eltWiseOp参数类型为uint8_t,取值如下: • 0:不开启Elementwise; • 1:Elementwise Addition; • 2:Elementwise Subtraction。 |
| quantPre | 用于控制量化模式,QuantMode_t类型,具体定义如下: • half/bfloat16_t输出,此参数需配置为QuantMode_t::F322F16/QuantMode_t::F322BF16。 •配置为scalar量化时,需要调用SetFixpipePreQuantFlag接口来设置scalar量化参数。 •配置为tensor量化时,需要调用SetFixPipeConfig来设置tensor量化参数,其中tensor量化参数需要通过DataCopy从L1 Buffer搬运至Fixpipe Buffer。 注:此参数需要用户手动配置,不会自动推导配置对应量化模式。此通路不支持NoQuant模式。 enum QuantMode_t |
| reluPre | 用于配置ReLU操作的模式,类型为uint8_t,取值如下: • 0:不开启ReLU • 1:Normal ReLU |
| channelSplit | 仅在L0C Buffer(CO1)->GM通路时生效,此通路设置为false即可。 |
| nz2ndEn | 仅在L0C Buffer(CO1)->GM通路时生效,此通路设置为false即可。 |
数据类型
源矩阵与目的矩阵支持的数据类型组合
针对Ascend 950PR/Ascend 950DT,DataCopy接口支持的数据类型组合如下:
| 源矩阵(L0C Buffer) | 目的矩阵(L1 Buffer) |
|---|---|
| float | int8_t、uint8_t、half、bfloat16_t、float。 |
| int32_t | int8_t、uint8_t、half、int32_t。 |
针对Atlas A3 训练系列产品/Atlas A3 推理系列产品,DataCopy接口支持的数据类型组合如下:
| 源矩阵(L0C Buffer) | 目的矩阵(L1 Buffer) |
|---|---|
| float | int8_t、uint8_t、half、bfloat16_t。 |
| int32_t | int8_t、uint8_t、half。 |
针对Atlas A2 训练系列产品/Atlas A2 推理系列产品,DataCopy接口支持的数据类型组合如下:
| 源矩阵(L0C Buffer) | 目的矩阵(L1 Buffer) |
|---|---|
| float | int8_t、uint8_t、half、bfloat16_t。 |
| int32_t | int8_t、uint8_t、half。 |
针对Atlas 200I/500 A2 推理产品,DataCopy接口支持的数据类型组合如下:
| 源矩阵(L0C Buffer) | 目的矩阵(L1 Buffer) |
|---|---|
| float | int8_t、uint8_t、half、bfloat16_t。 |
| int32_t | int8_t、uint8_t、half。 |
返回值说明
无
约束说明
- 对于量化输入为float32数据类型的说明如下:
- 标准的IEEE 754 float32格式为:1bit符号位,8bits指数位,23bits尾数位;当前AI处理器支持的float32格式为:1bit符号位,8bits指数位,10bits尾数位。
- 如果用户提供的是标准的IEEE 754 float32输入,API内部会处理成处理器支持的float32格式进行计算,此时如果golden数据生成过程中使用的是标准的IEEE 754 float32数据,则可能引入精度不匹配问题,需要修正golden数据的生成,将量化参数的23bits尾数位的低13bits数据位清零再参与量化计算。
- 源矩阵NZ格式地址要求64字节对齐,目的矩阵NZ格式地址需要满足32字节对齐。
- 当搬出的mSize或nSize中的任意一个值为0时,该指令不会被执行。
- 量化和ReLU参数不能为inf/nan和非规格化数。
- 目标数据不能有重叠。如果对目的地址有重叠写入,硬件不会报告任何警告和错误,也不保证重叠数据的写入顺序。
- unitFlag特性开启需要配合Mmad同时开启。
针对如下产品型号,特殊值/边界值约束说明如下:
Atlas A3 训练系列产品/Atlas A3 推理系列产品
Atlas A2 训练系列产品/Atlas A2 推理系列产品
对于浮点类型inf/nan输入输出,可以通过CTRL寄存器(控制寄存器)的CTRL[48]比特位进行设置,控制浮点数量化搬出时的饱和模式:
非饱和模式:CTRL[48]设置成1'b1,inf/nan保持原输出。
饱和模式:CTRL[48]设置成1'b0,inf输出会被饱和为±MAX,nan输出会被饱和为0。
// 设置CTRL[48]为0,开启浮点数饱和模式 AscendC::AscendCUtils::SetOverflow(0);
对于整数类型只有饱和模式。
Ascend 950PR/Ascend 950DT特殊值/边界值约束说明:
对于浮点类型inf/nan输入输出,可以通过CTRL寄存器(控制寄存器)的CTRL[48]比特位进行设置,控制浮点数量化搬出时的饱和模式;
对于fp8_e4m3fn_t类型,可以通过CTRL寄存器(控制寄存器)的CTRL[48]比特位进行更精细的设置;
非饱和模式:CTRL[48]设置成1'b1,inf/nan保持原输出。对于fp8_e4m3fn_t类型,若结果的绝对值为inf或大于fp8_e4m3fn_t的最大规格化值,则输出结果为nan。
饱和模式:CTRL[48]设置成1'b0,Inf输出会被饱和为±MAX, NaN输出会被饱和为0。对于fp8_e4m3fn_t类型,当CTRL[50]设置成1'b0时,NaN被转换为零,当CTRL[50]设置成1'b1时,NaN保持不变,若结果的绝对值为Inf或大于fp8_e4m3fn_t的最大规格化值,则结果为最大规格化值。
// 设置CTRL[48]为0,开启浮点数饱和模式 AscendC::AscendCUtils::SetOverflow(0);
对于整数类型只有饱和模式。
调用示例
无
【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考