Skip to content

Mmad

说明

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

产品支持情况

  • 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

Mmad接口用于完成L0A Buffer上左矩阵A和L0B Buffer上右矩阵B的矩阵乘加,结果写入L0C Buffer上结果矩阵C。默认模式为普通矩阵计算。流水类型:PIPE_M。数学表达式为:

Text
C = A * B

带bias输入时,bias作为结果矩阵C初始值参与计算,等价于:

Text
C = A * B + Bias

Mmad的矩阵乘加关系可参考下图:

图1 Mmad矩阵乘加公式

Mmad矩阵乘加公式

Mmad使用显式传入的MmadAtom配置矩阵计算功能。左矩阵A、右矩阵B、结果矩阵C的图示说明如下:

图2 Mmad矩阵布局

Mmad矩阵布局

矩阵计算说明

矩阵物理位置维度数据格式数据类型
左矩阵AL0A Bufferm × kNZ参见数据类型
右矩阵BL0B Bufferk × nZN参见数据类型
结果矩阵CL0C Bufferm × nNZ参见数据类型

函数原型

  • 执行不传bias的矩阵计算。

    C++
    template <typename AtomType, typename DstTensor, typename FmTensor, typename FilterTensor>
    __aicore__ inline void Mmad(
        const MmadAtom<AtomType>& atomMmad, const DstTensor& dst, const FmTensor& fm, const FilterTensor& filter)
    
  • 执行传入bias的矩阵计算。

    C++
    template <typename AtomType, typename DstTensor, typename FmTensor, typename FilterTensor, typename BiasTensor,
        Std::enable_if_t<IsAttrTensorV<BiasTensor>, int> Enable>
    __aicore__ inline void Mmad(
        const MmadAtom<AtomType>& atomMmad, const DstTensor& dst, const FmTensor& fm, const FilterTensor& filter,
        const BiasTensor& bias)
    
  • 构造默认矩阵计算原子对象。

    C++
    template <typename MmadOperationType>
    __aicore__ inline constexpr auto MakeMmad(const MmadOperationType& mmadOperation)
    
  • 构造指定Trait的矩阵计算原子对象。

    C++
    template <typename MmadOperationType, typename MmadTraitType>
    __aicore__ inline constexpr auto MakeMmad(
        const MmadOperationType& mmadOperation, const MmadTraitType& mmadTrait)
    

参数说明

表1 Mmad接口参数说明

参数名输入/输出描述
atomMmad输入矩阵计算原子对象。通过MakeMmad(MmadOperation{})MakeMmad(MmadOperation{}, MmadTraitDefault{})可以构造默认原子对象。
dst输出结果矩阵C,存储位置为Location::L0C,数据格式为NZ。
fm输入左矩阵A,存储位置为Location::L0A,数据格式为NZ。
filter输入右矩阵B,存储位置为Location::L0B,数据格式为ZN。
bias输入bias张量,存储位置为Location::BIAS,数据格式为ND。

表2 MakeMmad接口参数说明

参数名输入/输出描述
mmadOperation输入矩阵计算操作对象,通过MmadOperation{}构造。
mmadTrait输入矩阵计算Trait对象,用于指定矩阵计算静态特性。默认使用MmadTraitDefault{}

表3 MmadParams参数说明

参数名类型默认值描述
muint16_t0左矩阵A的高度,结果矩阵C的高度。
nuint16_t0右矩阵B的宽度,结果矩阵C的宽度。
kuint16_t0左矩阵A的宽度,右矩阵B的高度。
unitFlaguint8_t0控制Mmad和后续矩阵数据搬出的细粒度并行。0表示不使能,2表示使能且执行后不复位单元标记位,3表示使能且执行后复位单元标记位。
cmatrixInitValboolfalse不传bias时,控制是否初始化结果矩阵C。true表示C矩阵默认初始化为0,false表示C矩阵不进行默认操作,通过设置cmatrixSource参数进行初始化。

表4 MmadTrait参数说明

参数名类型默认值描述
fmOffsetint32_t0左矩阵offset,当前Tensor API实现中作为兼容参数保留。
kDirectionAlignboolfalseK方向对齐控制,当前Tensor API实现中作为兼容参数保留。
cmatrixSourceboolfalse配置C矩阵初始值是否来源于BT Buffer,带bias调用时该配置无效。false表示C矩阵不进行初始化操作,true表示使用BT Buffer的数据对C矩阵进行初始化操作。
disableGemvbooltrueM=1场景下是否关闭GEMV模式。false表示开启GEMV,true表示关闭GEMV。
mmadTypeMmadTypeMmadType::NORMAL矩阵计算类型。默认使用MmadType::NORMAL。使用MmadType::MX表示MX场景Mmad计算。

数据类型

支持如下左矩阵A、右矩阵B、结果矩阵C的数据类型组合:

左矩阵A右矩阵B结果矩阵C
int8_tint8_tint32_t
halfhalffloat
floatfloatfloat
bfloat16_tbfloat16_tfloat
fp8_e4m3fn_tfp8_e4m3fn_tfloat
fp8_e4m3fn_tfp8_e5m2_tfloat
fp8_e5m2_tfp8_e4m3fn_tfloat
fp8_e5m2_tfp8_e5m2_tfloat
hifloat8_thifloat8_tfloat

传入bias的场景中,int8_t * int8_t -> int32_t的组合要求bias数据类型为int32_t,其余组合要求bias数据类型为float

返回值说明

Mmad无返回值。MakeMmad返回MmadAtom对象。

约束说明

  • dst必须位于L0C Buffer,fm必须位于L0A Buffer,filter必须位于L0B Buffer。
  • 结果矩阵C起始地址需要满足64Byte地址对齐要求。
  • 左矩阵A和右矩阵B起始地址需要满足512Byte地址对齐要求。
  • 上述地址对齐要求属于硬件访问约束,编译器和运行时不对所有场景单独检查,用户需要保证入参满足约束。
  • mnk需要与实际参与Mmad计算的数据尺寸一致。
  • 开启unitFlag功能时,需要结果矩阵C搬出接口的FixpipeParams::unitFlagMmad计算的MmadParams::unitFlag参数配合设置。
  • 连续两次Mmad沿K方向累加时,需要关注结果矩阵C的写读依赖。同步优化的阈值关系可参考结果矩阵C初始化中的图示。
  • 当M、K、N不是16的倍数时,硬件仍以16×16分形块组织数据,尾块中的无效数据会占用分形块空间但不参与有效计算。有效数据与无效数据排布方式如下图所示:

图3 尾块有效数据排布

尾块有效数据排布

关键特性说明

结果矩阵C初始化

不传bias时,cmatrixInitVal控制是否初始化结果矩阵C。通常第一次K方向累加时设置为true,后续K分块累加设置为false。如果多K分块累加场景中首次Mmad如果设为false,将导致C矩阵包含L0C Buffer残留数据,计算结果错误。

连续两次Mmad沿K方向累加时,通常需要关注中间结果的写读依赖。同步优化的阈值关系可参考下图:

图4 PipeBarrier阈值关系

PipeBarrier阈值关系

UnitFlag

unitFlag用于控制Mmad与后续Fixpipe的细粒度并行。启用时,MmadParams::unitFlag和结果搬出的FixpipeParams::unitFlag需要配合设置,常见取值为23

GEMV模式

当M=1时,可通过MmadTrait::disableGemv控制是否开启GEMV模式。默认值为true,表示关闭GEMV。

MX Mmad模式

MX Mmad模式没有单独的函数接口,而是通过MmadTrait::mmadType设置。执行MX Mmad时,需要将MmadTrait::mmadType设置为MmadType::MX,并通过MakeMmad(MmadOperation{}, MmadTraitMX{})构造矩阵计算原子对象。

C++
struct MmadTraitMX {
    using TraitType = MmadTrait;
    static constexpr const TraitType value = MmadTrait(0, false, false, true, MmadType::MX);
};

MX Mmad支持如下左矩阵A、右矩阵B、结果矩阵C的数据类型组合:

左矩阵A右矩阵B结果矩阵C
fp4x2_e2m1_tfp4x2_e2m1_tfloat
fp4x2_e2m1_tfp4x2_e1m2_tfloat
fp4x2_e1m2_tfp4x2_e2m1_tfloat
fp4x2_e1m2_tfp4x2_e1m2_tfloat
fp8_e4m3fn_tfp8_e4m3fn_tfloat
fp8_e4m3fn_tfp8_e5m2_tfloat
fp8_e5m2_tfp8_e4m3fn_tfloat
fp8_e5m2_tfp8_e5m2_tfloat

MX Mmad通常需要在调用Mmad前完成左矩阵缩放数据ScaleA和右矩阵缩放数据ScaleB的搬运。ScaleA搬运可参考L1到L0ScaleA数据搬运,ScaleB搬运可参考L1到L0ScaleB数据搬运。矩阵缩放数据不作为Mmad函数参数传入,而是通过Copy接口提前搬运到L0ScaleA Buffer和L0ScaleB Buffer。

相关接口

调用示例

  • Mmad调用示例

    C++
    #include "tensor_api/tensor.h"
    
    __aicore__ inline void NormalMmadExample()
    {
        using namespace AscendC::Te;
    
        constexpr uint16_t m = 16;
        constexpr uint16_t n = 16;
        constexpr uint16_t k = 16;
    
        __ca__ half l0aBuf[m * k];
        __cb__ half l0bBuf[k * n];
        __cc__ float l0cBuf[m * n];
    
        auto l0A = MakeTensor(MakeMemPtr(l0aBuf), MakeFrameLayout<NZLayoutPtn, half>(m, k));
        auto l0B = MakeTensor(MakeMemPtr(l0bBuf), MakeFrameLayout<ZNLayoutPtn, half>(k, n));
        auto l0C = MakeTensor(MakeMemPtr(l0cBuf), MakeFrameLayout<NZLayoutPtn, 16>(m, n));
    
        MmadParams params(m, n, k, 0, true);
        auto atom = MakeMmad(MmadOperation{}, MmadTraitDefault{}).with(params);
        Mmad(atom, l0C, l0A, l0B);
    }
    
  • MX场景Mmad调用示例

    C++
    #include "tensor_api/tensor.h"
    
    struct MmadTraitMX {
        using TraitType = AscendC::Te::MmadTrait;
        static constexpr const TraitType value = AscendC::Te::MmadTrait(0, false, false, true, AscendC::Te::MmadType::MX);
    };
    
    __aicore__ inline void MxMmadExample()
    {
        using namespace AscendC::Te;
    
        constexpr uint16_t m = 16;
        constexpr uint16_t n = 16;
        constexpr uint16_t k = 16;
    
        __ca__ fp8_e5m2_t l0aBuf[m * k];
        __cb__ fp8_e5m2_t l0bBuf[k * n];
        __cc__ float l0cBuf[m * n];
    
        auto l0A = MakeTensor(MakeMemPtr(l0aBuf), MakeFrameLayout<NZLayoutPtn, fp8_e5m2_t>(m, k));
        auto l0B = MakeTensor(MakeMemPtr(l0bBuf), MakeFrameLayout<ZNLayoutPtn, fp8_e5m2_t>(k, n));
        auto l0C = MakeTensor(MakeMemPtr(l0cBuf), MakeFrameLayout<NZLayoutPtn, 16>(m, n));
    
        MmadParams params(m, n, k, 0, true);
        auto atom = MakeMmad(MmadOperation{}, MmadTraitMX{}).with(params);
        Mmad(atom, l0C, l0A, l0B);
    }
    

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