Skip to content

Copy(L0C Buffer到Global Memory数据搬运)

说明

本接口为试验接口,在后续版本中可能会调整或改进,不保证后续兼容性。请开发者在使用过程中关注后续版本更新。

产品支持情况

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

功能说明

头文件路径为:tensor_api/tensor.h

Tensor API通过Copy接口统一执行不同通路数据搬运。该接口用于将L0C Buffer中的矩阵计算结果搬运到Global Memory。L0C Buffer中的数据通常为Mmad的输出,数据格式为NZ。搬运到Global Memory时,接口会根据目的张量布局自动选择NZNDDNNZNC1HWC0NHWCNCHW的随路格式转换。其中NC1HWC0NHWCNCHW用于卷积输出特征图。

L0C Buffer到Global Memory搬运支持不量化输出、floathalfbfloat16_t的直接转换输出,以及配合标量或张量量化参数的随路量化输出。随路Relu、通道拆分和量化舍入方式通过CopyL0C2GMTrait配置。MmadFixpipe细粒度并行相关的unitFlag通过FixpipeParams配置。

接口支持batch模式。batch模式用于一次完成多块矩阵计算结果的搬运。Layout在原矩阵Layout最外层增加Batch维度。源张量为NZ格式,分形固定为16×16,可通过MakeFrameLayout<NZLayoutPtn>(batch, m, n)构造。目的张量可通过MakeFrameLayout<NDLayoutPtn>(batch, m, n)MakeFrameLayout<DNLayoutPtn>(batch, m, n)MakeFrameLayout<NDExtLayoutPtn>(batch, m, n)MakeFrameLayout<DNExtLayoutPtn>(batch, m, n)MakeFrameLayout<NZLayoutPtn, DstType>(batch, m, n)构造。NZ格式可通过模板参数DstType指定目的数据类型,C0表示NZ格式的列分形大小,默认为16。卷积输出通路当前仅支持N为1,不支持batch模式。

随路量化、随路Relu、随路格式转换、随路通道拆分以及随路通道合并的有效组合、中间数据类型和数据路径如下图所示。图中的F32到F16、F32到BF16为非量化模式,仅进行cast。其余路径为不量化模式、随路scalar量化模式或随路tensor量化模式。

针对Ascend 950PR/Ascend 950DT:

图1 L0C2GM流程图

L0C2GM流程图

函数原型

  • 执行L0C Buffer到Global Memory的非量化搬运。

    C++
    template <typename AtomType, typename DstTensor, typename SrcTensor>
    __aicore__ inline void Copy(const CopyAtom<AtomType>& atomCopy, const DstTensor& dst, const SrcTensor& src)
    
  • 执行L0C Buffer到Global Memory的量化搬运。

    C++
    template <typename AtomType, typename DstTensor, typename SrcTensor, typename QuantParam,
        Std::enable_if_t<IsCopyQuantParamV<QuantParam>, int> Enable>
    __aicore__ inline void Copy(const CopyAtom<AtomType>& atomCopy, const DstTensor& dst, const SrcTensor& src,
        const QuantParam& quant)
    
  • 使用默认trait构造搬运原子对象。

    C++
    template <typename CopyOperationType>
    __aicore__ inline constexpr auto MakeCopy(const CopyOperationType& copyOperation)
    
  • 使用指定trait构造搬运原子对象。

    C++
    template <typename CopyOperationType, typename CopyTraitType>
    __aicore__ inline constexpr auto MakeCopy(const CopyOperationType& copyOperation, const CopyTraitType& copyTrait)
    

参数说明

表1 Copy接口参数说明

参数名输入/输出描述
atomCopy输入搬运原子对象,可由MakeCopy(CopyL0C2GM{})MakeCopy(CopyL0C2GM{}, CopyL0C2GMTraitDefault{})构造。
dst输出目的张量,存储位置为Location::GM。支持NDDNNZNC1HWC0NHWCNCHW数据格式。
src输入源张量,存储位置为Location::L0C,数据格式为NZ,通常为Mmad的计算结果。
quant输入可选量化参数。传入uint64_t时表示scalar量化参数,传入张量时表示tensor量化参数,张量位于L1 Buffer,元素类型为uint64_t
fixpipeParams输入可选搬运参数,类型为FixpipeParams,通过atomCopywith接口绑定到搬运原子对象,未绑定时使用默认值。

表2 MakeCopy接口参数说明

参数名输入/输出描述
copyOperation输入搬运操作对象。L0C Buffer到Global Memory搬运采用CopyL0C2GM{}
copyTrait输入搬运静态特性对象。L0C Buffer到Global Memory搬运默认采用CopyL0C2GMTraitDefault{}

CopyL0C2GMTrait说明

CopyL0C2GMTrait用于配置L0C Buffer到Global Memory搬运的静态特性。

C++
struct CopyL0C2GMTrait {
    RoundMode roundMode = RoundMode::DEFAULT;
    bool enableRelu = false;
    bool enableChannelSplit = false;
};

表3 CopyL0C2GMTrait成员说明

成员默认值描述
roundModeRoundMode::DEFAULT舍入模式。RoundMode::HYBRID仅在源类型为float、目的类型为hifloat8_t的量化输出场景支持。
enableRelufalse是否使能随路Relu。
enableChannelSplitfalse是否使能输出数据通道拆分。只支持NZ格式且源类型和目的类型均为float的场景。

使用自定义trait的示例:

C++
constexpr CopyL0C2GMTrait l0c2gmTrait = {
    RoundMode::DEFAULT,
    false,
    true
};

struct CopyL0C2GMTraitCustom {
    using TraitType = CopyL0C2GMTrait;
    static constexpr const TraitType value = l0c2gmTrait;
};

FixpipeParams说明

FixpipeParams用于配置运行时搬运参数。

C++
struct FixpipeParams {
    uint8_t unitFlag = 0;
    bool subBlockId = false;
};

表4 FixpipeParams成员说明

成员默认值描述
unitFlag0控制Mmad指令和Fixpipe指令的细粒度并行。0表示不使能,2表示使能且执行后不复位单元标记位,3表示使能且执行后复位单元标记位。开启时,MmadParamsFixpipeParams中的unitFlag需要配套设置为23
subBlockIdfalse在启用单目标模式时指示目标UB的编号,L0C Buffer到Global Memory数据搬运时该参数无效。

数据类型

L0C Buffer到Global Memory搬运根据是否传入量化参数自动选择量化模式。

表5 数据类型说明

源张量类型(L0C Buffer)目的张量类型(Global Memory)调用形式说明
int32_tint8_tuint8_tCopy(atom, dst, src, quant)scalar或tensor量化输出。
floatint8_tuint8_tCopy(atom, dst, src, quant)scalar或tensor量化输出。
floatfp8_e4m3fn_thifloat8_tCopy(atom, dst, src, quant)scalar或tensor量化输出。hifloat8_t支持RoundMode::DEFAULTRoundMode::HYBRID
int32_thalfbfloat16_tCopy(atom, dst, src, quant)scalar或tensor量化输出。
floathalfCopy(atom, dst, src)直接转换输出。
floatbfloat16_tCopy(atom, dst, src)直接转换输出。
floathalfbfloat16_tCopy(atom, dst, src, quant)scalar或tensor量化输出。
int32_tint32_tCopy(atom, dst, src)不量化输出。
floatfloatCopy(atom, dst, src)不量化输出。
floatfloatCopy(atom, dst, src, quant)scalar或tensor量化输出。

不传入quant时,接口选择不量化或直接转换模式,传入uint64_t时选择scalar量化模式,传入张量时选择tensor量化模式。

返回值说明

Copy无返回值。MakeCopy返回CopyAtom对象。

约束说明

  • 源矩阵NZ格式,地址要求64字节对齐。目的矩阵DNND格式时,地址要求1字节对齐,NZ格式时,地址要求32字节对齐。
  • 目的矩阵为NZ输出时,N方向大小需要为16的倍数;b8类型通道合并场景为32的倍数,float使能enableChannelSplit通道拆分场景为8的倍数。
  • tensor量化参数张量应位于L1 Buffer,元素类型为uint64_t,地址要求32字节对齐。详情参见随路量化
  • 使能unitFlag时,需要配合Mmad同时使能。
  • 使用RoundMode::HYBRID时,源类型必须为float,目的类型必须为hifloat8_t
  • enableChannelSplit仅在源类型和目的类型均为float,且目的格式为NZ时生效。详情参见F32 Channel Split
  • 通道合并特性硬件自动使能,不能通过参数配置。详情参见Int8 Channel Merge
  • NZNC1HWC0NHWCNCHW的卷积输出通路当前仅支持N为1。NZNHWCNCHW仅支持不传入quant的调用形式。
  • 卷积输出通路中,源NZ张量的逻辑Shape需要为(H * W, C)。目的张量为NC1HWC0时需要满足C = C1 * C0

关键特性

L0C Buffer到Global Memory搬运涉及随路量化随路ReluF32 Channel SplitInt8 Channel Mergebatch搬运等关键特性。

调用示例

卷积输出

以下示例将L0C Buffer中Shape为(H * W, C)的NZ矩阵搬运到Global Memory,并转换为NHWC格式。将目的Layout替换为NCHWLayoutPtnNC1HWC0LayoutPtn,可分别完成NCHW或NC1HWC0格式输出。

C++
#include "tensor_api/tensor.h"

using namespace AscendC::Te;

constexpr uint32_t H = 8;
constexpr uint32_t W = 8;
constexpr uint32_t C = 16;

__aicore__ inline void CopyConvOutputL0CToGM(__gm__ float* gmAddr)
{
    __cc__ float l0cBuf[H * W * C];

    auto l0c = MakeTensor(
        MakeMemPtr(l0cBuf),
        MakeFrameLayout<NZLayoutPtn, 16>(H * W, C));
    auto gm = MakeTensor(
        MakeMemPtr(gmAddr), MakeFrameLayout<NHWCLayoutPtn>(1, H, W, C));

    auto copyL0CToGM = MakeCopy(CopyL0C2GM{}, CopyL0C2GMTraitDefault{});
    Copy(copyL0CToGM, gm, l0c);
}

不量化输出

C++
#include "tensor_api/tensor.h"

using namespace AscendC::Te;

__aicore__ inline void CopyL0CToGM()
{
    auto l0c = MakeTensor(MakeMemPtr(l0cAddr), MakeFrameLayout<NZLayoutPtn, 16>(m, n));
    auto gm = MakeTensor(MakeMemPtr(gmAddr), MakeFrameLayout<NDExtLayoutPtn>(m, n));

    FixpipeParams params;
    auto atom = MakeCopy(CopyL0C2GM{}).with(params);
    Copy(atom, gm, l0c);
}

scalar量化输出

C++
#include "tensor_api/tensor.h"

using namespace AscendC::Te;
__aicore__ inline void CopyL0CToGM()
{
    auto l0c = MakeTensor(MakeMemPtr(l0cAddr), MakeFrameLayout<NZLayoutPtn, 16>(m, n));
    auto gm = MakeTensor(MakeMemPtr(gmAddr), MakeFrameLayout<NDExtLayoutPtn>(m, n));

    uint64_t quant = 1;
    auto atom = MakeCopy(CopyL0C2GM{}).with(FixpipeParams{});
    Copy(atom, gm, l0c, quant);
}

tensor量化输出

C++
#include "tensor_api/tensor.h"

using namespace AscendC::Te;

__aicore__ inline void CopyL0CToGM()
{
    auto l0c = MakeTensor(MakeMemPtr(l0cAddr), MakeFrameLayout<NZLayoutPtn, 16>(m, n));
    auto gm = MakeTensor(MakeMemPtr(gmAddr), MakeFrameLayout<NDExtLayoutPtn>(m, n));
    auto quant = MakeTensor(MakeMemPtr(l1QuantAddr), MakeFrameLayout<NDExtLayoutPtn>(1, n));

    auto atom = MakeCopy(CopyL0C2GM{}).with(FixpipeParams{});
    Copy(atom, gm, l0c, quant);
}

batch模式输出

C++
#include "tensor_api/tensor.h"

using namespace AscendC::Te;

__aicore__ inline void CopyBatchL0CToGM(__gm__ half* gmAddr)
{
    constexpr uint32_t srcBatch = 3;
    constexpr uint32_t dstBatch = 9;
    constexpr uint32_t m = 32;
    constexpr uint32_t n = 64;

    __cc__ float l0cBuf[srcBatch * m * n];

    auto l0c = MakeTensor(MakeMemPtr(l0cBuf), MakeFrameLayout<NZLayoutPtn>(srcBatch, m, n));
    auto gm = MakeTensor(MakeMemPtr(gmAddr), MakeFrameLayout<NDExtLayoutPtn>(dstBatch, m, n));

    auto atom = MakeCopy(CopyL0C2GM{}).with(FixpipeParams{});
    for (uint32_t i = 0; i < dstBatch / srcBatch; ++i) {
        auto gmSlice = gm.Slice(MakeCoord(i * srcBatch, MakeCoord(0, 0)), MakeShape(srcBatch, MakeShape(m, n)));
        Copy(atom, gmSlice, l0c);
    }
}

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