Skip to content

连续对齐搬入(LoadAlign)

产品支持情况

  • 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/reg_compute/kernel_reg_compute_datacopy_intf.h"

LoadAlign能够实现数据从Unified Buffer(UB)连续搬运至RegTensor。支持单搬入模式和双搬入模式:

  • 单搬入模式:从UB读取VL数据量,搬入到一个RegTensor(VL)中。
  • 双搬入模式:从UB读取2*VL数据量,交错搬运,将偶数索引和奇数索引的元素分别搬入两个RegTensor(2*VL)中。

连续对齐搬运有三类接口:普通搬运接口、PostUpdate扩展搬运接口、使用AddrReg寄存器存储偏移量接口。

RegTensor的模板参数regTrait支持RegTraitNumOne及RegTraitNumTwo,具体支持情况如下:

RegTensor模板参数regTrait普通搬运接口PostUpdate扩展搬运接口使用AddrReg寄存器存储偏移量接口
RegTraitNumOne(单搬入/双搬入)完成一次搬运后,UB地址不会自动更新,每次迭代需要手动更新地址。• POST_MODE_NORMAL模式:不支持。
• POST_MODE_UPDATE模式:完成一次搬运后,UB地址会自动更新,每次迭代不需要手动更新地址。
在每次迭代中,需要先调用CreateAddrReg手动设定地址偏移量,再调用搬运指令。
RegTraitNumTwo(单搬入)完成一次搬运后,UB地址不会自动更新,每次迭代需要手动更新地址。• POST_MODE_NORMAL模式:不支持。
• POST_MODE_UPDATE模式:完成一次搬运后,UB地址会自动更新,每次迭代不需要手动更新地址。
不支持
RegTraitNumTwo(双搬入)不支持不支持不支持

数据搬入时,可以通过模板参数配置搬运的数据分布模式,能够实现broadcast、上采样、下采样、解压缩等功能,分布模式具体介绍请参考表3 LoadDist参数说明(单搬入模式)表6 LoadDist参数说明(双搬入模式)

图1 连续对齐搬入分布模式图示展示了DIST_NORM、DIST_BRC_B16、DIST_UNPACK_B16分布模式。

图 1 数据搬入分布模式图示

连续对齐搬入/搬出的三类搬运接口在迭代内的调用方式请参考:关键特性说明

函数原型

  • 单搬入模式:普通搬运接口

    C++
    template <typename T = DefaultType, LoadDist dist = LoadDist::DIST_NORM, typename U>
    __simd_callee__ inline void LoadAlign(U& dstReg, __ubuf__ T* srcAddr)
    
  • 单搬入模式:PostUpdate扩展搬运接口

    C++
    template <typename T = DefaultType, PostLiteral postMode, LoadDist dist = LoadDist::DIST_NORM, typename U>
    __simd_callee__ inline void LoadAlign(U& dstReg, __ubuf__ T*& srcAddr, int32_t postUpdateStride)
    
  • 单搬入模式:使用AddrReg存储偏移量接口,需要配合CreateAddrReg接口使用。

    C++
    template <typename T = DefaultType, LoadDist dist = LoadDist::DIST_NORM, typename U>
    __simd_callee__ inline void LoadAlign(U& dstReg, __ubuf__ T* srcAddr, AddrReg offset)
    
  • 双搬入模式:普通搬运接口

    C++
    template <typename T = DefaultType, LoadDist dist, typename U>
    __simd_callee__ inline void LoadAlign(U& dstReg0, U& dstReg1, __ubuf__ T* srcAddr)
    
  • 双搬入模式:PostUpdate扩展搬运接口

    C++
    template <typename T = DefaultType, PostLiteral postMode, LoadDist dist, typename U>
    __simd_callee__ inline void LoadAlign(U& dstReg0, U& dstReg1, __ubuf__ T*& srcAddr, int32_t postUpdateStride)
    
  • 双搬入模式:使用AddrReg存储偏移量接口,需要配合CreateAddrReg接口使用。

    C++
    template <typename T = DefaultType, LoadDist dist, typename U>
    __simd_callee__ inline void LoadAlign(U& dstReg0, U& dstReg1, __ubuf__ T* srcAddr, AddrReg offset)
    

参数说明

表 1 模板参数说明(单搬入模式)

参数名描述
T源操作数的数据类型。支持的数据类型请参考数据类型
postMode用于控制是否使能UB地址会自动更新功能(post update),PostLiteral类型。具体参数说明请参考PostLiteral
dist数据分布模式,LoadDist类型。具体参数说明请参考表3 LoadDist参数说明(单搬入模式)
U目的操作数的RegTensor类型。例如RegTensor<half>,由编译器自动推导,用户不需要手动填写。

表 2 参数说明(单搬入模式)

参数名输入/输出描述
dstReg输出目的操作数,类型为RegTensor
srcAddr输入/输出源操作数,UB起始地址。
postUpdateStride输入地址更新步长,int32_t类型,单位:元素个数。postUpdateStride * sizeof(T)的对齐约束请参考表3 LoadDist参数说明(单搬入模式)。根据postMode的取值有两种情况:
• POST_MODE_NORMAL:不支持。
• POST_MODE_UPDATE:实际搬运UB起始地址为srcAddr,搬运后执行地址更新 srcAddr += postUpdateStride。
offset输入地址偏移寄存器,AddrReg类型。需要在搬运前调用CreateAddrReg设定地址偏移量,实际搬运UB地址为srcAddr + 寄存器中存储的偏移量。AddrReg寄存器中存储的偏移量 * sizeof(T)的对齐约束请参考表3 LoadDist参数说明(单搬入模式)

表 3 LoadDist参数说明(单搬入模式)

LoadDist取值含义搬运对齐约束(Byte)
DIST_NORM正常模式,搬运VL数据。可参考图1 连续对齐搬入分布模式图示32
DIST_BRC_B8搬运一个b8类型的数据,并Broadcast到所有元素位置。1
DIST_BRC_B16搬运一个b16类型的数据,并Broadcast到所有元素位置。可参考图1 连续对齐搬入分布模式图示2
DIST_BRC_B32搬运一个b32类型的数据,并Broadcast到所有元素位置。4
DIST_US_B8数据2倍上采样,加载数据量为VL/2,每个输入元素重复两次,数据类型为b8。min(32, VL/2)
DIST_US_B16数据2倍上采样,加载数据量为VL/2,每个输入元素重复两次,数据类型为b16。min(32, VL/2)
DIST_DS_B8数据2倍下采样,加载数据量为2*VL,数据每隔一个保留,数据类型为b8。32
DIST_DS_B16数据2倍下采样,加载数据量为2*VL,数据每隔一个保留,数据类型为b16。32
DIST_UNPACK_B8解压缩模式,按无符号整型u8加载VL/2数据量,每个元素后会补1个值为0元素,即unpack到VL。
例如VL=256B:
src: [0x00, 0x01, 0x02, 0x03, ..., 0xFF, ...]。
dst: [0x00, 0x00, 0x01, 0x00, 0x02, 0x00, ..., 0x7F, 0x00]。
min(32, VL/2)
DIST_UNPACK_B16解压缩模式,按无符号整型u16加载VL/2数据量,每个元素后会补1个值为0元素,即unpack到VL。可参考图1 连续对齐搬入分布模式图示
例如VL=256B:
src: [0x0000, 0x0001, 0x0002, 0x0003, ..., 0x007F, ...]。
dst: [0x0000, 0x0000, 0x0001, 0x0000, 0x0002, 0x0000, ..., 0x003F, 0x0000]。
min(32, VL/2)
DIST_BLK读取一个DataBlock(32B),并广播到VL。32
DIST_E2B_B16加载(VL/DataBlock)个B16的数据,并将每个元素(16bit)广播到一个DataBlock(32B)中。VL/16
DIST_E2B_B32加载(VL/DataBlock)个B32的数据,并将每个元素(32bit)广播到一个DataBlock(32B)中。VL/8
DIST_UNPACK_B32解压缩模式,按无符号整型u32加载VL/2数据量,每个元素后会补1个值为0元素,即unpack到VL。
例如VL=256B:
src: [0x00000000, 0x00000001, 0x00000002, ..., 0x000003F, ...]。
dst: [0x00000000, 0x00000000, 0x00000001, 0x00000000, ..., 0x0000001F, 0x00000000]。
min(32, VL/2)
DIST_UNPACK4_B8解压缩模式,按无符号整型u8加载VL/4数据量,unpack到VL,每个元素后会补3个值为0的元素。
例如VL=256B:
src: [0x00, 0x01, 0x02, 0x03, ..., 0xFF, ...]。
dst: [0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,..., 0x3F, 0x00, 0x00, 0x00]。
min(32, VL/4)

表 4 模板参数说明(双搬入模式)

参数名描述
T源操作数的数据类型。支持的数据类型请参考数据类型
postMode用于控制是否使能UB地址会自动更新功能(post update),PostLiteral类型。具体参数说明请参考PostLiteral
dist搬运模式,LoadDist类型。具体参数说明请参考表6 LoadDist参数说明(双搬入模式)
U目的操作数的RegTensor类型。例如RegTensor<half>,由编译器自动推导,用户不需要手动填写。

表 5 参数说明(双搬入模式)

参数名输入/输出描述
dstReg0输出第一个目的操作数,类型为RegTensor
dstReg1输出第二个目的操作数,类型为RegTensor
srcAddr输入/输出源操作数,UB起始地址。
postUpdateStride输入地址更新步长,int32_t类型,单位:元素个数。postUpdateStride * sizeof(T)需要32字节对齐。
根据postMode的取值有两种情况:
• POST_MODE_NORMAL:不支持。
• POST_MODE_UPDATE:实际搬运UB起始地址为srcAddr,搬运后执行地址更新srcAddr += postUpdateStride。
offset输入地址偏移寄存器,AddrReg类型。需要在搬运前调用CreateAddrReg设定地址偏移量,实际搬运UB地址为srcAddr + 寄存器中存储的偏移量。 AddrReg寄存器中存储的偏移量 * sizeof(T)需要32字节对齐。

表 6 LoadDist参数说明(双搬入模式)

LoadDist取值含义搬运对齐约束(Byte)
DIST_DINTLV_B8双搬入模式,基于元素的交错搬运,从src中读取2*VL数据量,将偶数索引的元素存入dst0,将奇数索引的元素存入dst1,数据类型为b8。32
DIST_DINTLV_B16双搬入模式,基于元素的交错搬运,从src中读取2*VL数据量,将偶数索引的元素存入dst0,将奇数索引的元素存入dst1,数据类型为b16。32
DIST_DINTLV_B32双搬入模式,基于元素的交错搬运,从src中读取2*VL数据量,将偶数索引的元素存入dst0,将奇数索引的元素存入dst1,数据类型为b32。32

数据类型

目的操作数与源操作数的数据类型需要保持一致。

  • 当RegTensor模板参数regTrait为RegTraitNumOne时,支持的数据类型为:b8、b16、b32、b64。
  • 当RegTensor模板参数regTrait为RegTraitNumTwo时,支持的数据类型为:complex32、b64。

返回值说明

约束说明

  • 位于Unified Buffer的地址约束、postUpdateStride * sizeof(T)对齐约束、AddrReg寄存器中存储的偏移量 * sizeof(T)对齐约束与分布模式LoadDist有关,具体地址约束请参考表3 LoadDist参数说明(单搬入模式)表6 LoadDist参数说明(双搬入模式)

  • 当RegTrait为RegTraitNumOne时,单搬入正常模式(DIST_NORM)下,若源UB的剩余空间不足256B,会发生UB越界访问。

  • 单搬入模式:b64数据类型只支持LoadDist中的DIST_NORM模式。

  • 当RegTensor模板参数RegTrait为RegTraitNumOne和RegTraitNumTwo时,支持情况如下:

    RegTensor模板参数RegTrait取值支持的接口支持的数据类型
    RegTraitNumOne所有单搬入接口和双搬入接口b8/b16/b32/b64
    RegTraitNumTwo• 单搬入 普通搬运接口
    • 单搬入 PostUpdate扩展搬运接口
    complex32/b64

关键特性说明

连续对齐搬入搬出三类搬运接口调用方式

图2 regTrait为RegTraitNumOne时的三类搬运接口调用方式展示了连续对齐搬入/搬出的三类搬运模式在迭代内使用调用方式:

  • 普通搬运接口:完成一次搬运后,UB地址不会自动更新,每次迭代需要手动更新地址。
  • PostUpdate扩展搬运接口:完成一次搬运后,UB地址会自动更新,每次迭代不需要手动更新地址。
  • 使用AddrReg存储偏移量接口:在每次迭代中,需要先调用CreateAddrReg手动设定地址偏移量,再调用搬运指令。

图 2 regTrait为RegTraitNumOne时的三类搬运接口调用方式

调用示例

  • 单搬入/单搬出模式:普通搬运接口

    C++
    template <typename T>
    __simd_vf__ inline void ComputeMode01(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, uint32_t dstSize, uint16_t oneRepeatSize, uint16_t repeatTimes)
    {
        AscendC::Reg::RegTensor<T> dstReg;
        AscendC::Reg::MaskReg mask;
        for (uint16_t i = 0; i < repeatTimes; ++i) {
            mask = AscendC::Reg::UpdateMask<T>(dstSize);
            AscendC::Reg::LoadAlign(dstReg, srcAddr + i * oneRepeatSize);
            AscendC::Reg::StoreAlign(dstAddr + i * oneRepeatSize, dstReg, mask);
        }
    }
    
  • 单搬入/单搬出模式:PostUpdate扩展搬运接口

    C++
    template <typename T>
    __simd_vf__ inline void ComputeMode02(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, uint32_t dstSize, uint16_t oneRepeatSize, uint16_t repeatTimes)
    {
        AscendC::Reg::RegTensor<T> dstReg;
        AscendC::Reg::MaskReg mask;
        for (uint16_t i = 0; i < repeatTimes; ++i) {
            mask = AscendC::Reg::UpdateMask<T>(dstSize);
            AscendC::Reg::LoadAlign<T, AscendC::Reg::PostLiteral::POST_MODE_UPDATE>(dstReg, srcAddr, oneRepeatSize);
            AscendC::Reg::StoreAlign<T, AscendC::Reg::PostLiteral::POST_MODE_UPDATE>(dstAddr, dstReg, oneRepeatSize, mask);
        }
    }
    
  • 单搬入/单搬出模式:使用AddrReg存储偏移量

    C++
    template <typename T>
    __simd_vf__ inline void ComputeMode03(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, uint16_t oneRepeatSize, uint16_t repeatTimes)
    {
        AscendC::Reg::RegTensor<T> dstReg;
        AscendC::Reg::MaskReg mask = AscendC::Reg::CreateMask<T>();
        AscendC::Reg::AddrReg aReg;
        for (uint16_t i = 0; i < repeatTimes; ++i) {
            aReg = AscendC::Reg::CreateAddrReg<T>(i, oneRepeatSize);
            AscendC::Reg::LoadAlign(dstReg, srcAddr, aReg);
            AscendC::Reg::StoreAlign(dstAddr, dstReg, aReg, mask);
        }
    }
    
  • 双搬入/双搬出模式:普通搬运接口

    C++
    template <typename T>
    __simd_vf__ inline void ComputeMode04(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, uint16_t oneRepeatSize, uint16_t repeatTimes)
    {
        AscendC::Reg::RegTensor<T> srcReg0;
        AscendC::Reg::RegTensor<T> srcReg1;
        AscendC::Reg::MaskReg mask = AscendC::Reg::CreateMask<T>();
        for (uint16_t i = 0; i < repeatTimes; ++i) {
            AscendC::Reg::LoadAlign<T, AscendC::Reg::LoadDist::DIST_DINTLV_B8>(srcReg0, srcReg1, srcAddr + i * oneRepeatSize);
            AscendC::Reg::StoreAlign<T, AscendC::Reg::StoreDist::DIST_INTLV_B8>(dstAddr + i * oneRepeatSize, srcReg0, srcReg1, mask);
        }
    }
    
  • 双搬入/双搬出模式:使用AddrReg存储偏移量,需要配合CreateAddrReg接口使用

    C++
    template <typename T>
    __simd_vf__ inline void ComputeMode05(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, uint16_t oneRepeatSize, uint16_t repeatTimes)
    {
        AscendC::Reg::RegTensor<T> srcReg0;
        AscendC::Reg::RegTensor<T> srcReg1;
        AscendC::Reg::MaskReg mask = AscendC::Reg::CreateMask<T>();
        AscendC::Reg::AddrReg aReg;
        for (uint16_t i = 0; i < repeatTimes; ++i) {
            aReg = AscendC::Reg::CreateAddrReg<T>(i, oneRepeatSize);
            AscendC::Reg::LoadAlign<T, AscendC::Reg::LoadDist::DIST_DINTLV_B8>(srcReg0, srcReg1, srcAddr, aReg);
            AscendC::Reg::StoreAlign<T, AscendC::Reg::StoreDist::DIST_INTLV_B8>(dstAddr, srcReg0, srcReg1, aReg, mask);
        }
    }
    

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