Skip to content

DataCopyPad(UBToL1非对齐数据搬运)

产品支持情况

  • Ascend 950PR/Ascend 950DT:支持
  • Atlas A3 训练系列产品/Atlas A3 推理系列产品:支持
  • Atlas A2 训练系列产品/Atlas A2 推理系列产品:支持
  • Atlas 200I/500 A2 推理产品:不支持
  • Atlas 推理系列产品AI Core:不支持
  • Atlas 推理系列产品Vector Core:不支持
  • Atlas 训练系列产品:不支持

功能说明

说明

本接口为软件仿真实现,是在Matmul高阶API的基础上,利用Matmul高阶API中的workspace GM空间作为数据中转空间,数据先搬入GM,再搬入L1 Buffer。因此,在使用本接口时,需要先使用REGISTER_MATMUL注册高阶API。

该接口提供从Unified Buffer到L1 Buffer的数据非对齐搬运功能。

函数原型

  • 通路:Local Memory->Local Memory,实际搬运过程是UB->GM->L1 Buffer(TSCM)。

    C++
    template <typename T>
    __aicore__ inline void DataCopyPad(const LocalTensor<T>& dst, const LocalTensor<T>& src, const DataCopyExtParams& dataCopyParams, const Nd2NzParams& nd2nzParams)
    

参数说明

表1 模板参数说明

参数名描述
T操作数以及paddingValue(待填充数据值)的数据类型。

表2 接口参数说明

参数名输入/输出描述
dst输出目的操作数,类型为LocalTensor。
LocalTensor的起始地址需要保证32字节对齐。
src输入源操作数,类型为LocalTensor。
LocalTensor的起始地址需要保证32字节对齐。
dataCopyParams输入搬运参数。
  • DataCopyExtParams类型,具体参数说明请参考表4
nd2nzParams输入从UB->L1 Buffer(VECIN/VECOUT->TSCM)进行数据搬运时,可以进行ND到NZ的数据格式转换。nd2nzParams是用于控制数据格式转换的参数,Nd2NzParams类型,具体参数请参考DataCopy(UBToL1随路转换-ND2NZ搬运)中的介绍。
注意:本接口Nd2NzParams的ndNum仅支持设置为1

表3 DataCopyExtParams结构体参数定义

参数名称含义
blockCount指定该指令包含的连续传输数据块个数,数据类型为uint16_t,取值范围:blockCount∈[1, 4095]。
blockLen指定该指令每个连续传输数据块长度,该指令支持非对齐搬运每个连续传输数据块长度单位为字节。数据类型为uint32_t,取值范围:blockLen∈[1, 2097151],blockLen必须是sizeof(T)的整数倍,需要注意UB不要超限
srcStride源操作数,相邻连续数据块的间隔(前面一个数据块的尾与后面数据块的头的间隔)。单位为dataBlock(32字节)。
数据类型为uint32_t,srcStride不要超出该数据类型的取值范围。
dstStride目的操作数,相邻连续数据块间的间隔(前面一个数据块的尾与后面数据块的头的间隔)。单位为dataBlock(32字节)。数据类型为uint32_t,dstStride不要超出该数据类型的取值范围。
rsv保留字段。

下面给出如下场景的配置示例:

  • UB->L1 Buffer(VECIN/VECOUT->TSCM)

    注意

    内部实现涉及AIC和AIV之间的通信,实际搬运路径为UB(VECIN/VECOUT)->GM->L1 Buffer(TSCM),发送通信消息会有开销,性能会受到影响

    图1 UB->L1 Buffer(VECIN/VECOUT->TSCM)搬运示意图所示,展示了从UB搬运到GM,再搬运到L1 Buffer的过程:示例中数据类型为half,单个datablock(32字节)含有16个half元素,源操作数中的A1~A6、B1~B6、C1~C6为需要进行搬运的数据。

    • 从UB->GM的搬运,数据存储格式没有发生转变,依然是ND。

      • blockCount为需要搬运的连续传输数据块个数,设置为3;
      • blockLen为一个连续传输数据块的大小(单位为字节),设置为6 * 32 = 192;
      • srcStride为源操作数相邻连续数据块的间隔(前面一个数据块的尾与后面数据块的头的间隔),源操作数物理位置为UB,其单位为datablock,两个连续传输数据块(A1~A6、B1~B6)中间相隔1个A7,因此srcStride设置为1;
      • dstStride为目的操作数,相邻连续数据块间的间隔(前面一个数据块的尾与后面数据块的头的间隔),目的操作数逻辑位置为GM,其单位为字节,两个连续传输数据块(A1~A6、B1~B6)中间相隔2个空白的datablock,因此dstStride设置为64字节。
    • 从GM->L1 Buffer的搬运,数据存储格式由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矩阵,所以可以填为0。

    图1 UB->L1 Buffer(VECIN/VECOUT->TSCM)搬运示意图

数据类型

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。

Atlas A3 训练系列产品/Atlas A3 推理系列产品,支持的数据类型为:int8_t、uint8_t、int16_t、uint16_t、half、bfloat16_t、int32_t、uint32_t、float、int64_t、uint64_t、double。

Atlas A2 训练系列产品/Atlas A2 推理系列产品,支持的数据类型为:int8_t、uint8_t、int16_t、uint16_t、half、bfloat16_t、int32_t、uint32_t、float、int64_t、uint64_t、double。

返回值说明

约束说明

  • 特别地,针对Ascend 950PR/Ascend 950DT,设置srcStride和dstStride参数时,数据类型为int64_t,取值范围为[0, 65535]。

调用示例

以下示例展示图1所示的场景:数据类型为half,单个DataBlock(32字节)含16个half元素,将UB中的ND格式数据经GM中转后,以NZ格式搬入L1 Buffer。

C++
constexpr uint32_t dataBlockElemCount = 16;
constexpr uint32_t srcElemCount = (3 * 7) * dataBlockElemCount;
constexpr uint32_t dstElemCount = (7 * 6) * dataBlockElemCount;
constexpr uint32_t tscmAddr = 0;

// 源操作数:UB。
AscendC::LocalTensor<half> srcLocal(AscendC::TPosition::VECIN, ubAddr, srcElemCount);

// 目的操作数:L1 Buffer。
AscendC::LocalTensor<half> dstLocal(AscendC::TPosition::TSCM, tscmAddr, dstElemCount);

AscendC::DataCopyExtParams copyParams;
// UB(VECIN)->GM阶段搬运3个连续传输数据块。
copyParams.blockCount = 3;
// 每个连续传输数据块包含6个DataBlock。
copyParams.blockLen = 6 * 32;
// 源操作数在UB,单位为DataBlock;相邻行之间跳过1个DataBlock。
copyParams.srcStride = 1;
// 中转目的端为GM,单位为字节;相邻行之间保留2个空白DataBlock,即64B。
copyParams.dstStride = 64;
// 保留字段,固定填0。
copyParams.rsv = 0;

AscendC::Nd2NzParams nd2nzParams;
// 本接口约束ndNum仅支持设置为1。
nd2nzParams.ndNum = 1;
// ND矩阵高度为3行。
nd2nzParams.nValue = 3;
// 每行宽度为6个DataBlock。
nd2nzParams.dValue = 6 * dataBlockElemCount;
// 仅1个ND矩阵,不涉及相邻ND矩阵间隔。
nd2nzParams.srcNdMatrixStride = 0;
// GM中相邻行起始地址间隔为8个DataBlock。
nd2nzParams.srcDValue = 8 * dataBlockElemCount;
// 目的NZ中同一源行的相邻DataBlock间隔为7个DataBlock。
nd2nzParams.dstNzC0Stride = 7;
// 目的NZ中相邻源行转换后的起始地址间隔为2个DataBlock。
nd2nzParams.dstNzNStride = 2;
// 仅1个NZ矩阵。
nd2nzParams.dstNzMatrixStride = 0;

AscendC::DataCopyPad(dstLocal, srcLocal, copyParams, nd2nzParams);

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