DataCopyPad(ISASI)
产品支持情况
功能说明
该接口提供数据非对齐搬运的功能,其中从Global Memory搬运数据至Local Memory时,可以根据开发者的需要自行填充数据。
函数原型
-
dataCopyParams为DataCopyExtParams类型,相比于DataCopyParams类型,支持的操作数步长等参数取值范围更大
-
通路:Global Memory->Local Memory
template <typename T, PaddingMode mode = PaddingMode::Normal> __aicore__ inline void DataCopyPad(const LocalTensor<T>& dst, const GlobalTensor<T>& src, const DataCopyExtParams& dataCopyParams, const DataCopyPadExtParams<T>& padParams)template <typename T> __aicore__ inline void DataCopyPad(const LocalTensor<T>& dst, const GlobalTensor<T>& src, const DataCopyExtParams& dataCopyParams, const DataCopyPadExtParams<T>& padParams) -
通路:Local Memory->Global Memory
template <typename T, PaddingMode mode = PaddingMode::Normal> __aicore__ inline void DataCopyPad(const GlobalTensor<T>& dst, const LocalTensor<T>& src, const DataCopyExtParams& dataCopyParams)template <typename T> __aicore__ inline void DataCopyPad(const GlobalTensor<T>& dst, const LocalTensor<T>& src, const DataCopyExtParams& dataCopyParams) -
通路:Local Memory->Local Memory,实际搬运过程是VECIN/VECOUT->GM->TSCM
template <typename T> __aicore__ inline void DataCopyPad(const LocalTensor<T>& dst, const LocalTensor<T>& src, const DataCopyExtParams& dataCopyParams, const Nd2NzParams& nd2nzParams)
-
-
dataCopyParams为DataCopyParams类型
-
通路:Global Memory->Local Memory
template<typename T, PaddingMode mode = PaddingMode::Normal> __aicore__ inline void DataCopyPad(const LocalTensor<T>& dst, const GlobalTensor<T>& src, const DataCopyParams& dataCopyParams, const DataCopyPadParams& padParams)template<typename T> __aicore__ inline void DataCopyPad(const LocalTensor<T>& dst, const GlobalTensor<T>& src, const DataCopyParams& dataCopyParams, const DataCopyPadParams& padParams) -
通路:Local Memory->Global Memory
template<typename T, PaddingMode mode = PaddingMode::Normal> __aicore__ inline void DataCopyPad(const GlobalTensor<T>& dst, const LocalTensor<T>& src,const DataCopyParams& dataCopyParams)template<typename T> __aicore__ inline void DataCopyPad(const GlobalTensor<T>& dst, const LocalTensor<T>& src,const DataCopyParams& dataCopyParams) -
通路:Local Memory->Local Memory,实际搬运过程是VECIN/VECOUT->GM->TSCM
template<typename T> __aicore__ inline void DataCopyPad(const LocalTensor<T>& dst, const LocalTensor<T>& src, const DataCopyParams& dataCopyParams, const Nd2NzParams& nd2nzParams)
-
不同产品型号对函数原型的支持存在差异,请参考下表中的支持度信息,选择产品型号支持的函数原型进行开发。
表 1 不同产品型号对函数原型的支持度
GM->VECIN/VECOUT、GM->A1/B1、GM->TSCM、VECIN/VECOUT->GM、A1/B1->GM、VECIN/VECOUT->TSCM、 GM->VECCALC |
||
参数说明
表 2 模板参数说明
表 3 接口参数说明
从Global Memory搬运数据至Local Memory时,可以根据开发者需要,在搬运数据左边或右边填充数据。padParams是用于控制数据填充过程的参数。 |
||
从VECIN/VECOUT->TSCM进行数据搬运时,可以进行ND到NZ的数据格式转换。nd2nzParams是用于控制数据格式转换的参数,Nd2NzParams类型,具体参数请参考表3。 |
下文表格中列出的结构体参数定义请参考{INSTALL_DIR}/include/ascendc/basic_api/interface/kernel_struct_data_copy.h,\{INSTALL\_DIR\}/include/ascendc/basic\_api/interface/kernel\_struct\_data\_copy.h,{INSTALL_DIR}请替换为CANN软件安装后文件存储路径。
表 4 DataCopyExtParams结构体参数定义
表 5 DataCopyParams结构体参数定义
表 6 DataCopyPadExtParams<T>结构体参数定义
表 7 DataCopyPadParams结构体参数定义
下面分别给出如下场景的配置示例:
-
-
参数解释
- 当blockLen+leftPadding+rightPadding满足32字节对齐时,若isPad为false,左右两侧填充的数据值会默认为随机值;否则为paddingValue。
- 当blockLen+leftPadding+rightPadding不满足32字节对齐时,框架会填充一些假数据dummy,保证左右填充的数据和blockLen、假数据为32字节对齐。若leftPadding、rightPadding都为0:dummy会默认填充待搬运数据块的第一个元素值;若leftPadding/rightPadding不为0:isPad为false,左右两侧填充的数据值和dummy值均为随机值;否则为paddingValue。
-
配置示例1:
- blockLen为64,每个连续传输数据块包含64字节;srcStride为1,因为源操作数的逻辑位置为GM,srcStride的单位为字节,也就是说源操作数相邻数据块之间间隔1字节;dstStride为1,因为目的操作数的逻辑位置为VECIN/VECOUT,dstStride的单位为DataBlock数量(每DataBlock为32字节),也就是说目的操作数相邻数据块之间间隔1个dataBlock。
- blockLen+leftPadding+rightPadding满足32字节对齐,isPad为false,左右两侧填充的数据值会默认为随机值;否则为paddingValue。此处示例中,leftPadding、rightPadding均为0,则不填充。
- blockLen+leftPadding+rightPadding不满足32字节对齐时,框架会填充一些假数据dummy,保证左右填充的数据和blockLen、假数据为32字节对齐。leftPadding/rightPadding不为0:若isPad为false,左右两侧填充的数据值和dummy值均为随机值;否则为paddingValue。

-
配置示例2:
- blockLen为47,每个连续传输数据块包含47字节;srcStride为1,表示源操作数相邻数据块之间间隔1字节;dstStride为1,表示目的操作数相邻数据块之间间隔1个dataBlock。
- blockLen+leftPadding+rightPadding不满足32字节对齐,leftPadding、rightPadding均为0:dummy会默认填充待搬运数据块的第一个元素值。
- blockLen+leftPadding+rightPadding不满足32字节对齐,leftPadding/rightPadding不为0:若isPad为false,左右两侧填充的数据值和dummy值均为随机值;否则为paddingValue。

-
配置示例3:
- blockLen为48,每个连续传输数据块包含48字节;srcStride为-48,表示源操作数相邻数据块之间间隔-48字节,相当于每次传输的连续数据块都是同一块;dstStride为1,表示目的操作数相邻数据块之间间隔1个dataBlock。
- blockLen+leftPadding+rightPadding不满足32字节对齐,leftPadding、rightPadding均为0:dummy会默认填充待搬运数据块的第一个元素值。
- blockLen+leftPadding+rightPadding不满足32字节对齐,leftPadding/rightPadding不为0:若isPad为false,左右两侧填充的数据值和dummy值均为随机值;否则为paddingValue。

-
-
-
当每个连续传输数据块长度blockLen为32字节对齐时,下图呈现了需要传入的DataCopyParams示例,blockLen为64,每个连续传输数据块包含64字节;srcStride为1,因为源操作数的逻辑位置为VECIN/VECOUT,srcStride的单位为dataBlock(32字节),也就是说源操作数相邻数据块之间间隔1个dataBlock;dstStride为1,因为目的操作数的逻辑位置为GM,dstStride的单位为字节,也就是说目的操作数相邻数据块之间间隔1字节。

-
当每个连续传输数据块长度blockLen不满足32字节对齐,由于Unified Buffer要求32字节对齐,框架在搬出时会自动补充一些假数据来保证对齐,但在当搬到GM时会自动将填充的假数据丢弃掉。下图呈现了该场景下需要传入的DataCopyParams示例和假数据补齐的原理。blockLen为47,每个连续传输数据块包含47字节,不满足32字节对齐;srcStride为1,表示源操作数相邻数据块之间间隔1个dataBlock;dstStride为1,表示目的操作数相邻数据块之间间隔1字节。框架在搬出时会自动补充17字节的假数据来保证对齐,搬到GM时再自动将填充的假数据丢弃掉。

-
-
**注意:**内部实现涉及AIC和AIV之间的通信,实际搬运路径为VECIN/VECOUT->GM->TSCM,发送通信消息会有开销,性能会受到影响。
如图1 VECIN/VECOUT->TSCM搬运示意图所示,展示了从VECIN/VECOUT搬运到GM,再搬运到TSCM的过程:示例中数据类型为half,单个datablock(32字节)含有16个half元素,源操作数中的A1~A6、B1~B6、C1~C6为需要进行搬运的数据。
-
从VECIN/VECOUT->GM的搬运,数据存储格式没有发生转变,依然是ND。
- blockCount为需要搬运的连续传输数据块个数,设置为3;
- blockLen为一个连续传输数据块的大小(单位为字节),设置为6 * 32 = 192;
- srcStride为源操作数相邻连续数据块的间隔(前面一个数据块的尾与后面数据块的头的间隔),源操作数逻辑位置为VECIN/VECOUT,其单位为datablock,两个连续传输数据块(A1~A6、B1~B6)中间相隔1个A7,因此srcStride设置为1;
- dstStride为目的操作数,相邻连续数据块间的间隔(前面一个数据块的尾与后面数据块的头的间隔),目的操作数逻辑位置为GM,其单位为字节,两个连续传输数据块(A1~A6、B1~B6)中间相隔2个空白的datablock,因此dstStride设置为64字节。
-
从GM->TSCM的搬运,数据存储格式由ND转换为NZ。
- ndNum固定为1,即A1~A6、B1~B6、C1~C6视作一整个ndMatrix;
- nValue为ndMatrix的行数,即为3行;
- dValue为ndMatrix中一行包含的元素个数,即为6 * 16 = 96个元素;
- srcNdMatrixStride为相邻ndMatrix之间的距离,因为仅涉及1个ndMatrix,所以可填为0;
- srcDValue表明ndMatrix的第x行和第x+1行所相隔的元素个数,如A1~B1的距离,即为8个datablock,8 * 16 = 128个元素;
- dstNzC0Stride为src同一行的相邻datablock在NZ矩阵中相隔datablock数,如A1~A2的距离,即为7个datablock (A1 + 空白 + B1 + 空白 + C1 + 空白 * 2);
- dstNzNStride为src中ndMatrix的相邻行在NZ矩阵中相隔多少个datablock,如A1~B1的距离,即为2个datablock(A1 + 空白);
- dstNzMatrixStride为相邻NZ矩阵之间的元素个数,因为仅涉及1个NZ矩阵,所以可以填为1。
-
-
-
Normal模式
blockLen为48,每个连续传输数据块包含48字节;srcStride为0,因为源操作数的逻辑位置为GM,srcStride的单位为字节,即源操作数相邻数据块之间紧密排列;dstStride为0,因为目的操作数的逻辑位置为VECIN、VECOUT,dstStride的单位为DataBlock(32字节),目的操作数相邻数据块之间无间隔,注意数据块包含leftPadding/rightPadding数据。
blockLen + leftPadding + rightPadding满足32字节对齐,isPad为false,左右两侧填充的数据值会默认为随机值,否则为paddingValue。此处示例中,leftPadding为0,rightPadding为16,每个连续传输数据块都会在右侧填充16字节。目的操作数的总长度为192字节。
-
Compact模式
blockLen为48,每个连续传输数据块包含48字节;srcStride为0,因为源操作数的逻辑位置为GM,srcStride的单位为字节,即源操作数相邻数据块之间紧密排列;dstStride为0,因为目的操作数的逻辑位置为VECIN、VECOUT,dstStride的单位为DataBlock(32字节),目的操作数相邻数据块之间紧密排列,不会填充数据
blockLen * blockCount + leftPadding + rightPadding 满足32字节对齐,isPad为false,左右两侧填充的数据值会默认为随机值,否则为paddingValue。此处示例中,leftPadding为0,rightPadding为16,在最后一个数据块右侧填充16字节。目的操作数的总长度为160字节。

-
返回值说明
无
约束说明
- leftPadding、rightPadding的字节数均不能超过32字节。
- 针对Ascend 950PR/Ascend 950DT,VECIN/VECOUT->TSCM通路,仅支持如下数据类型:half、bfloat16_t、int16_t、uint16_t、float、int32_t、uint32_t、int8_t、uint8_t、int64_t、uint64_t、double。
调用示例
本示例实现了GM->VECIN->GM的非对齐搬运过程。
#include "kernel_operator.h"
AscendC::TPipe pipe;
AscendC::TQue<AscendC::TPosition::VECIN, 1> inQueueSrc;
AscendC::TQue<AscendC::TPosition::VECOUT, 1> outQueueDst;
AscendC::GlobalTensor<half> srcGlobal;
AscendC::GlobalTensor<half> dstGlobal;
AscendC::DataCopyPadExtParams<half> padParams;
AscendC::DataCopyExtParams copyParams;
half scalar = 0;
AscendC::LocalTensor<half> srcLocal = inQueueSrc.AllocTensor<half>();
AscendC::DataCopyExtParams copyParams{1, 20 * sizeof(half), 0, 0, 0}; // 结构体DataCopyExtParams最后一个参数是rsv保留位
AscendC::DataCopyPadExtParams<half> padParams{true, 0, 2, 0};
AscendC::DataCopyPad(srcLocal, srcGlobal, copyParams, padParams); // 从GM->VECIN搬运40字节
inQueueSrc.EnQue<half>(srcLocal);
AscendC::LocalTensor<half> srcLocal = inQueueSrc.DeQue<half>();
AscendC::LocalTensor<half> dstLocal = outQueueDst.AllocTensor<half>();
AscendC::Adds(dstLocal, srcLocal, scalar, 20);
outQueueDst.EnQue(dstLocal);
inQueueSrc.FreeTensor(srcLocal);
AscendC::LocalTensor<half> dstLocal = outQueueDst.DeQue<half>();
AscendC::DataCopyExtParams copyParams{1, 20 * sizeof(half), 0, 0, 0};
AscendC::DataCopyPad(dstGlobal, dstLocal, copyParams); // 从VECIN->GM搬运40字节
outQueueDst.FreeTensor(dstLocal);
结果示例:
输入数据src0Global: [1 2 3 ... 32]
输出数据dstGlobal:[1 2 3 ... 20]
