该接口提供数据非对齐搬运的功能,支持的数据传输通路如下:
GM->VECIN/VECOUT
VECIN/VECOUT->GM
其中从GM->VECIN/VECOUT进行数据搬运时,可以根据开发者的需要自行填充数据。
通路:GM->VECIN/VECOUT
template<typename T> __aicore__ inline void DataCopyPad(const LocalTensor<T>& dstLocal, const GlobalTensor<T>& srcGlobal, const DataCopyParams& dataCopyParams, const DataCopyPadParams& padParams)
通路:VECIN/VECOUT->GM
template<typename T> __aicore__ inline void DataCopyPad(const GlobalTensor<T>& dstGlobal, const LocalTensor<T>& srcLocal,const DataCopyParams& dataCopyParams)
参数名 |
输入/输出 |
描述 |
---|---|---|
dstLocal, dstGlobal |
输出 |
目的操作数,类型为LocalTensor或GlobalTensor。 Atlas A2训练系列产品,支持的数据类型为:half/int16_t/uint16_t/float/int32_t/uint32_t/int8_t/uint8_t |
srcLocal, srcGlobal |
输入 |
源操作数,类型为LocalTensor或GlobalTensor。 Atlas A2训练系列产品,支持的数据类型为:half/int16_t/uint16_t/float/int32_t/uint32_t/int8_t/uint8_t |
dataCopyParams |
输入 |
搬运参数。DataCopyParams类型,DataCopyParams结构定义请参考表2。 |
padParams |
输入 |
从GM->VECIN/VECOUT进行数据搬运时,可以根据开发者需要,在搬运数据左边或右边填充数据。padParams是用于控制数据填充过程的参数,DataCopyPadParams类型,DataCopyPadParams结构定义请参考表3。 |
参数名称 |
含义 |
---|---|
blockCount |
指定该指令包含的连续传输数据块个数,取值范围:blockCount∈[1, 4095]。 |
blockLen |
指定该指令每个连续传输数据块长度,该指令支持非对齐搬运,每个连续传输数据块长度单位为Byte。取值范围:blockLen∈[1, 65535]。 |
srcStride |
源操作数,相邻连续数据块的间隔(前面一个数据块的尾与后面数据块的头的间隔),如果源操作数的逻辑位置为VECIN/VECOUT,则单位为dataBlock(32Bytes), 如果源操作数的逻辑位置为GM,则单位为Byte。 |
dstStride |
目的操作数,相邻连续数据块间的间隔(前面一个数据块的尾与后面数据块的头的间隔),如果目的操作数的逻辑位置为VECIN/VECOUT,则单位为dataBlock(32Bytes),如果目的操作数的逻辑位置为GM,则单位为Byte。 |
参数名称 |
含义 |
---|---|
isPad |
是否需要填充数据,取值范围:true,false。 |
leftPadding |
连续搬运数据块左侧需要补充的数据范围,单位为元素个数。leftPadding+rightPadding的字节数之和不能超过32Bytes。 |
rightPadding |
连续搬运数据块右侧需要补充的数据范围,单位为元素个数。leftPadding+rightPadding的字节数之和不能超过32Bytes。 |
paddingValue |
左右两侧需要填充的数据值,需要保证在数据占用字节范围内。 |
无
Atlas A2训练系列产品
leftPadding+rightPadding的字节数之和不能超过32Bytes。
#include "kernel_operator.h" namespace AscendC { class TestDataCopyPad { public: __aicore__ inline TestDataCopyPad()() {} __aicore__ inline void Init(__gm__ uint8_t* srcGm, __gm__ uint8_t* dstGm) { srcGlobal.SetGlobalBuffer((__gm__ half *)srcGm); dstGlobal.SetGlobalBuffer((__gm__ half *)dstGm); pipe.InitBuffer(inQueueSrcVecIn, 1, 64 * sizeof(half)); } __aicore__ inline void Process() { CopyIn(); CopyOut(); } private: __aicore__ inline void CopyIn() { LocalTensor<half> srcLocal = inQueueSrcVecIn.AllocTensor<half>(); DataCopyParams copyParams{1, 20 * sizeof(half), 0, 0}; DataCopyPadParams padParams{true, 0, 2, 0}; DataCopyPad(srcLocal, srcGlobal, copyParams, padParams); // 从GM->VECIN搬运20Bytes inQueueSrcVecIn.EnQue<half>(srcLocal); } __aicore__ inline void CopyOut() { LocalTensor<half> ubLocal = inQueueSrcVecIn.DeQue<half>(); DataCopyParams copyParams{1, 20 * sizeof(half), 0, 0}; DataCopyPad(dstGlobal, ubLocal, copyParams); // 从VECIN->GM搬运20Bytes inQueueSrcVecIn.FreeTensor(ubLocal); } private: TPipe pipe; TQue<QuePosition::VECIN, 1> inQueueSrcVecIn; GlobalTensor<T> srcGlobal; GlobalTensor<T> dstGlobal; }; } extern "C" __global__ __aicore__ void kernel_data_copy_pad_kernel(__gm__ uint8_t* src_gm, __gm__ uint8_t* dst_gm) { AscendC::TestDataCopyPad op; op.Init(src_gm, dst_gm); op.Process(); }
输入数据(src0Global): [1 2 3 ... 64] 输出数据(dstGlobal):[1 2 3 ... 20]