Skip to content

DataCopy(GMToUB多维数据搬运NDDMA)

产品支持情况

  • 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"

多维数据搬运接口,相比于基础数据搬运接口,可更加自由配置搬入的维度信息以及对应的Stride。

具体支持的数据通路为(以逻辑位置TPosition表示):

  • Global Memory -> Unified Buffer
    • GM -> VECIN

函数原型

  • Global Memory -> Unified Buffer,支持多维度搬运

    C++
    template <typename T, uint8_t dim, const NdDmaConfig& config = kDefaultNdDmaConfig>
    __aicore__ inline void DataCopy(const LocalTensor<T>& dst, const GlobalTensor<T>& src, const NdDmaParams<T, dim>& params)
    
  • NDDMA Cache刷新,在使用DataCopy接口进行数据搬运前,需要使用NdDmaDci接口刷新NDDMA Cache缓存保证为最新状态。

    C++
    __aicore__ inline void NdDmaDci()
    

参数说明

表1 模板参数说明

参数名描述
T源操作数或者目的操作数的数据类型。
dim搬运的数据维度,数据类型为uint8_t,支持的维度为[1, 5]。
config搬运配置选项,NdDmaConfig类型,定义如下,具体参数说明请参考表3
struct NdDmaConfig {
static constexpr uint16_t unsetPad = 0xffff;
bool isNearestValueMode = false;
uint16_t loopLpSize = unsetPad; // Left padding size of all dimensions, must be less than 256.
uint16_t loopRpSize = unsetPad; // Right padding size of all dimensions, must be less than 256.
bool ascOptimize = false; // used for Ascend C optimization on special scenario.
};

表2 参数说明

参数名输入/输出描述
dst输出目的操作数,类型为LocalTensor
src输入源操作数,类型为GlobalTensor
params输入搬运参数NdDmaParams类型,定义如下,具体参数说明请参考表4
template <typename T, uint8_t dim>
struct NdDmaParams {
NdDmaLoopInfo<dim> loopInfo;
T constantValue; // 若有左右Padding,且不使能NearestValueMode时,该值将作为Padding值填充。
};

NdDmaLoopInfo类型,定义如下,具体参数说明请参考表5
template <uint8_t dim>
struct NdDmaLoopInfo {
uint64_t loopSrcStride[dim] = {0}; // src stride info per loop.
uint32_t loopDstStride[dim] = {0}; // dst stride info per loop.
uint32_t loopSize[dim] = {0}; // Loop size per loop.
uint8_t loopLpSize[dim] = {0}; // Left padding size per loop.
uint8_t loopRpSize[dim] = {0}; // Right padding size per loop.
};
// 注意:dim的有效范围为[1,5]。

表3 NdDmaConfig结构体参数定义

参数名描述
unsetPad表示未在NdDmaConfig中统一设置PaddingSize,固定为0xFFFF,为uint16_t数据类型的常量。当loopLpSize或loopRpSize取该值时,对应的PaddingSize由NdDmaLoopInfo中的同名参数按维度设置。
isNearestValueMode表示Padding值填取方式,类型为bool。
true:使能最近值填充方式,即左右Padding值会选取当前维度最左或最右的值进行填充,可参考图1
false:使能常数填充方式,即所有Padding值填充为固定值NdDmaParams::constantValue。
当数据类型为b64时,参数isNearestValueMode的值应为false。
loopLpSize所有维度统一使用的左Padding大小,单位为元素个数。取值范围为[0, 255]或unsetPad,默认值为unsetPad。设置为[0, 255]时,所有维度均使用该值,NdDmaLoopInfo::loopLpSize不生效;设置为unsetPad时,按维度使用NdDmaLoopInfo::loopLpSize。
loopRpSize所有维度统一使用的右Padding大小,单位为元素个数。取值范围为[0, 255]或unsetPad,默认值为unsetPad。设置为[0, 255]时,所有维度均使用该值,NdDmaLoopInfo::loopRpSize不生效;设置为unsetPad时,按维度使用NdDmaLoopInfo::loopRpSize。
ascOptimize预留参数,暂不支持。

表4 NdDmaParams结构体参数定义

参数名描述
loopInfo每维进行搬运的信息,类型为NdDmaLoopInfo<dim>。
NdDmaLoopInfo结构中数组类型参数的元素个数由模板参数dim决定。dim的取值范围为[1, 5],数组的有效索引范围为[0, dim - 1]。具体参数介绍可参考表5
constantValue数据类型为T的数值,当存在维度左右Padding,且不使能NearestValueMode时,该值将作为Padding值填充。
当数据类型为b64时,参数constantValue的值应为0。

表5 NdDmaLoopInfo结构体参数定义

参数名描述
loopSrcStride表示每个维度内,该源操作数元素与下一个元素间的间隔。
单位为元素个数。数据类型为uint64_t,loopSrcStride需在[0, 240)。
loopDstStride表示每个维度内,该目的操作数元素与下一个元素间的间隔。
单位为元素个数。数据类型为uint32_t,loopDstStride需在[0, 220)。
loopSize表示每个维度内,处理的元素个数(不包含Padding元素)。
单位为元素个数。数据类型为uint32_t,loopSize需在[1, 220)。
loopLpSize表示每个维度内,左侧需要补齐的元素个数。
单位为元素个数。数据类型为uint8_t,loopLpSize不要超出该数据类型的取值范围:[0, 255]。
loopRpSize表示每个维度内,右侧需要补齐的元素个数。
单位为元素个数。数据类型为uint8_t,loopRpSize不要超出该数据类型的取值范围:[0, 255]。

以下以2维的例子介绍几个典型使用场景。

图1 2D Padding场景

图2 2D Transpose场景

图3 2D BroadCast场景

图4 2D Slice场景

数据类型

源操作数和目的操作数支持的数据类型保持一致。

Ascend 950PR/Ascend 950DT支持的数据类型为:bool、int8_t、uint8_t、int16_t、uint16_t、half、bfloat16_t、int32_t、uint32_t、float、complex32、int64_t、uint64_t、double、complex64。

返回值说明

约束说明

  • 一条指令所能获取的所有数据的地址范围宽度不能超过40位(1TB),即:

    源操作数的每一次循环的大小为:(loopLpSize + loopSize + loopRpSize -1 ) * loopSrcSize,目的操作数的每一次循环的大小为:(loopLpSize + loopSize + loopRpSize -1 ) * loopDstSize,所有的循环的大小加起来不超过2的40次方位。

  • 当每层循环的dstStride为升序序列,则不同循环间的地址空间不能交织或者重叠。以一个2D Padding场景为例,loopSrcStride、loopDstStride第二个维度的stride值最小是3,数据3不能落在维度1的循环中。

  • 该接口通过NDDMA进行数据搬运,对应的NDDMA Cache大小为32KB,在使用DataCopy接口进行数据搬运前,需要使用NdDmaDci接口刷新缓存,否则多核场景下读写同一块Global Memory地址可能会导致部分核读取数据错误。

调用示例

  • 场景1:2D Padding场景,常数填充方式

    C++
    // xGmShape:[16, 32],搬运8列2行数据,左Padding 15,上Padding 13,右Padding 17,下Padding 3,xLocalShape:[32, 64]。
    AscendC::NdDmaLoopInfo<2> loopInfo{{1, 32}, {1, 64}, {32, 16}, {15, 13}, {17, 3}};
    AscendC::NdDmaParams<T, 2> params{loopInfo, 0};  // padding的值为0
    AscendC::NdDmaDci();  // 刷新cache
    static constexpr AscendC::NdDmaConfig dmaConfig;  // 使用默认参数,也可以不传。
    AscendC::DataCopy<T, 2, dmaConfig>(xLocal, xGm, params);
    
  • 场景2:2D Padding场景,最近值填充方式

    C++
    // xGmShape:[28, 15],搬运3列4行数据,左Padding 11,上Padding 3,右Padding 6,下Padding 1,xLocalShape:[32, 32]。
    AscendC::NdDmaLoopInfo<2> loopInfo{{1, 15}, {1, 32}, {15, 28}, {11, 3}, {6, 1}};
    AscendC::NdDmaParams<T, 2> params{loopInfo, 0};
    AscendC::NdDmaDci();  // 刷新cache
    // isNearestValueMode = true左右Padding值会选取当前维度最左或最右的值进行填充。
    static constexpr AscendC::NdDmaConfig dmaConfig = {true};
    AscendC::DataCopy<T, 2, dmaConfig>(xLocal, xGm, params);
    
  • 场景3:2D Transpose场景

    C++
    // xGmShape:[16, 64],搬运8列4行数据,xLocalShape:[64, 16]。
    AscendC::NdDmaLoopInfo<2> loopInfo{{1, 64}, {16, 1}, {64, 16}, {0, 0}, {0, 0}};
    AscendC::NdDmaParams<T, 2> params{loopInfo, 0};
    AscendC::NdDmaDci();  // 刷新cache
    static constexpr AscendC::NdDmaConfig dmaConfig;  // 使用默认参数,也可以不传。
    AscendC::DataCopy<T, 2, dmaConfig>(xLocal, xGm, params);
    
  • 场景4:2D BroadCast场景

    C++
    // xGmShape:[1, 16],搬运16列1行数据并进行广播,xLocalShape:[3, 16]。
    AscendC::NdDmaLoopInfo<2> loopInfo{{1, 0}, {1, 16}, {16, 3}, {0, 0}, {0, 0}};
    AscendC::NdDmaParams<T, 2> params{loopInfo, 0};
    AscendC::NdDmaDci();  // 刷新cache
    static constexpr AscendC::NdDmaConfig dmaConfig;  // 使用默认参数,也可以不传。
    AscendC::DataCopy<T, 2, dmaConfig>(xLocal, xGm, params);
    
  • 场景5:2D Slice场景

    C++
    // xGmShape:[32, 64],将16*10的矩阵截取为一个5*7的矩阵,xLocalShape:[16, 16]。
    AscendC::NdDmaLoopInfo<2> loopInfo{{1, 64}, {1, 16}, {16, 16}, {0, 0}, {0, 0}};
    AscendC::NdDmaParams<T, 2> params{loopInfo, 0};
    AscendC::NdDmaDci();  // 刷新cache
    static constexpr AscendC::NdDmaConfig dmaConfig;  // 使用默认参数,也可以不传。
    AscendC::DataCopy<T, 2, dmaConfig>(xLocal, xGm, params);
    

完整样例请参考:多维数据搬运样例

免责声明:本站内容由 asc-devkit 仓 master 分支自动编译生成,属于持续开发版本,可能存在缺陷,仅供预览与参考。如需稳定及商用资料,请查阅官方 昇腾社区