已开启
增加 Autofuse V2 Broadcast 性能建模 #235
高煜博创建于  8月11日
高煜博
高煜博成员
8月11日 创建

简介

目的

本文档描述 Autofuse V2 Broadcast 的性能建模方案。目标是使 ATT 性能公式与实际生成的
BroadcastExtend 和独立 Duplicate 路径一致,并将
BroadcastExtend 内部 helper 完整下钻到实际执行的 Reg::*。

目标读者包括 Autofuse codegen、ATT、AscendC API 和测试开发人员。本文档只定义设计,不包含实现代码。

范围

本设计包含:

  • V2 普通 Tensor Broadcast 的 BroadcastExtend 性能模型。
  • 常量、UB Scalar 和 Tensor Value 标量广播生成的独立 Duplicate 性能模型。
  • codegen 到 ATT 的最小原始参数透传链路。
  • broadcast_extend_impl.h、broadcast_3510_extend_impl.h 和
    broadcast_gather_3510_extend_impl.h 中全部可达分支的 Reg 调用次数。
  • 静态 shape 和动态 shape 分支表达式。
  • common、codegen、ATT UT,ATT ST 和 codegen E2E 验证。

本设计不包含:

  • 修改 Broadcast 的 AscendC 实现或生成 kernel 行为。
  • 猜测注册表中不存在的 Reg API 耗时。
  • 修改 SuperKernel、Python/C++ 绑定、CMake 安装路径或打包布局。
  • 为失败路径的 assert/log、纯类型声明或非函数标量赋值构造性能成本。成功数据路径上不可继续下钻且性能表
    无对应项的实际函数调用统一使用 kPlaceholder。
  • 将输入 Tensor 生产节点 ApiCall::PostProcess 生成且可能被多个输出/消费者共享的 UB scalar
    同步、GetValue 或 Duplicate 成本重复归属到 Broadcast;这些调用属于生产节点执行边界。
  • 旧 BroadcastApiCall 以 need_tmp_buf=true 生成的 B64 四参数 Duplicate 路径。V2
    BroadcastRegApiCall 仅复用 BroadcastScalar(..., false),不会进入仓内 DuplicateInt64 四参数实现;本任务
    不为未注册到 V2 ATT 的旧 codegen 路径建模。
  • Vector Function 内生成的 MicroAPI::Duplicate 性能模型。VF 不进入 BroadcastRegApiCall 或
    BroadcastExtend,继续使用既有 parser 类型和 VF 性能路径;本任务不修改 VF parser 或公共 VF 计数接口。

总体概述

软件概述

项目介绍

Broadcast 属于 Autofuse V2 向量计算节点。当前 V2 注册仍通过 GetPerfFunc(kBroadcast) 复用 V1
BroadcastApi,V1 公式主要按合并后的输入输出 shape 区分 1D 至 4D 场景,无法反映 V2 codegen 实际调用的
BroadcastExtend 及其 E2B、Gather、对齐、非对齐、64-bit 和 more-dim 分支。

源码依据如下:

  • codegen impl:autofuse/v35/ascir/generator/v2_ascir_codegen_impl.h:259-296
  • 普通 codegen:autofuse/v35/codegen/reg_api_call/reg_broadcast_api_call.cpp:23-125
  • API 入口:autofuse/v35/ascendc/api_regbase/broadcast.h:16-22
  • tiling 和顶层分支:autofuse/v35/ascendc/api_regbase/broadcast_extend_impl.h:34-278
  • wrapper 和 leaf:autofuse/v35/ascendc/api_regbase/broadcast_3510_extend_impl.h:20-1324
  • Gather helper:autofuse/v35/ascendc/api_regbase/broadcast_gather_3510_extend_impl.h:19-482
  • 当前 V2 注册:autofuse/v35/att/api_perf_register/ascir_api_perf_v2.cpp:512-514
  • 参考实现:GitCode PR 1580,Where V2 参数透传和 Reg 性能建模。

产品环境介绍

本功能位于 Autofuse 编译期 ATT/codegen 链路,使用仓内 AscendC RegBase Broadcast 源码作为语义依据。
不新增 CANN Toolkit、runtime 或 Python 依赖,不修改外部接口。实际 Reg API latency/throughput 仅使用
PerfParamTableV2::GetVfInstructPerfTable() 中已有数据。

软件功能

  • 从 codegen 透传 BroadcastExtend 的原始 dst_shape/src_shape 或独立 Duplicate 的原始 count。
  • 在 ATT 内复现 Broadcast tiling、rank 合并、64-bit 扩维和 wrapper 选择。
  • 将每个 wrapper/helper 继续下钻到实际执行的 Reg::* 或 MicroAPI::*。
  • 按源码循环层级计算每个 Reg API 的调用次数。
  • 对动态 shape 构造与源码条件一致的性能分支表达式。
  • 对缺失性能数据的 API 使用可追溯的独立 kPlaceholder,不猜耗时。

设计约束

  • BroadcastExtend rank 必须位于 [1, 9]。
  • 性能参数必须与实际 API 原始参数一致,不透传预计算 branch_id、repeat_time 或 Reg 次数。
  • 不能保存 tpipe.tiler.Size(...) 或 ActualSize(...) 字符串,必须保存原始表达式配方。
  • 所有含 Load 的实际 Reg API统一使用 kLoad;所有含 Store 的实际 Reg API统一使用 kStore。
  • 性能表中不存在的实际函数必须按真实 API、方向/模式和 dtype 分开使用 kPlaceholder;包括但不限于
    CreateMask、Arange、Gather、GatherB、PopStackBuffer、GetPhyAddr 和同步管理函数。
  • Div<int16/int32> 保留真实 kDiv 和真实 dtype;在获得权威性能数据前不得猜测或替换 dtype。
  • 最终 cost 必须使用 VFHead + max_latency + sum(throughput * count)。
  • 所有构建和测试命令并行度不超过 8。

假设和依赖关系

  • codegen 模板参数 constRank 等于 dst_shapes.size(),合法公开入口为 1..9;动态 shape 指 rank 固定、
    shape 值运行时确定,不把公开入口不可达的 constRank=-1 当成动态 rank。
  • codegen 能从 Tiler::sizes/actual_sizes 和 Tensor 元数据构造与生成 C++ 实参、TensorActualSize、
    TensorVectorizedSize 及 LocalTensor view 大小同源的 ge::Expression。
  • 现有 TernaryOp 能表达比较、相等和 Mod(expr, divisor) == 0 条件。
  • ATT pipeline 继续负责 Broadcast 节点的外层调度循环;BroadcastRegApiCall::Generate 不产生 Where/Compare
    类型的 CreateComputeNodeOuterFor,因此不新增 outer_call_count。
  • 未注册 API 的 kPlaceholder 只保证调用次数可追溯,不代表绝对性能精度已闭环。
  • 固定 rank 5-9 合并后调用 2D/3D/4D wrapper 时模板参数 W=-1,允许 unaligned 分支进入 dynamic
    fallback;这与入口 constRank 固定不矛盾。
  • 执行次数模型只覆盖可达性文档定义的正常域:所有传入 uint16_t wrapper/loop/stride 的值和合轴乘积
    均不超过 65535;普通 Gather/GatherWrapper 最终 index 仅在 B8/B16 的 16-bit index consumer 中受 65535
    限制,GatherB 与 B32/B64-effective 使用真实 32-bit index。所有源码 uint32_t size/乘积 consumer 均不得
    超过 UINT32_MAX。限制按实际 consumer 应用:顶层 Copy 不消费 uint16_t wrapper 值,但其 uint32_t
    srcSize/dstSize 乘积仍不得溢出,且 AlignUp(dstSize, ONE_BLK_SIZE/sizeof(T)) 的加法要求静态
    dstSize <= UINT32_MAX - (ONE_BLK_SIZE/sizeof(T) - 1)。普通、BOOL 和 B64 三参数 Duplicate 最终匹配 CANN
    int32_t count overload,因此 count 不超过 INT32_MAX;仓内 uint8/int8 overload 的第三参数为
    uint32_t,但其下层 int32_t consumer 要求实际参与 size+1 的 uint8 dst_view_size 或 int8 count
    不超过 INT32_MAX-1。对应有效下层 count 为 ceil_div(dst_view_size,2) 或 ceil_div(count,2),允许 65536。
    其余未进入 int32_t consumer 的原始 count/dst_view_size 只受 UINT32_MAX 限制。这里的 16-bit index-consumer 边界只适用于
    B8/B16 ordinary Gather,不适用于 Duplicate。静态可证明某个实际 consumer 超界时返回失败;动态表达式以
    正常域为调用前提,只为满足前提的实例生成公式,超界后的截断、回绕、除零或不终止行为没有有限有效性能
    公式,也不构造伪造的非法分支成本。

需求分析与设计

整体介绍

采用“原始参数透传 + ATT 分层复现分支 + 逐 Reg 计数”的方案:

EnrichAscirGraphNodeParams
  -> 预注册 BroadcastNodeParams{monostate}
BroadcastRegApiCall::Generate
  -> 填 BroadcastExtendParams{dst_shapes, src_shapes}
  -> 或填 BroadcastDuplicateParams{count, dst_view_size, source_kind}
FillSpecificParams
  -> NodeInfo.broadcast_node_params
BroadcastApiV2
  -> NodeDetail.broadcast_node_params
  -> BuildBroadcastTilingModel
  -> SelectBroadcastKernelFamily
  -> AddBroadcastRegPerf
  -> VFHead + max_latency + sum(throughput * count)

Vector Function 不使用上述独立节点参数,也不经过本设计的 BroadcastApiV2 路径。其既有 parser 类型和
VF 性能行为保持不变。

功能需求

功能需求 1:最小原始参数透传

  1. 介绍

    仅透传实际性能公式必需、且 ATT 不能从已有 NodeInfo 精确恢复的 API 原始参数。

  2. 输入

    • BroadcastExtend<T, constRank>(dst, src, dst_shape, src_shape)。
    • Duplicate(dst, scalar, count)。
  3. 处理

    • 排除输入输出 Tensor 后,Extend 保存与生成 C++ 实参同源解析后的 dst_shape/src_shape。
    • Duplicate 保存与 out.actual_size 同源解析后的 count、与传入 LocalTensor view 的 GetSize() 同源的
      dst_view_size,以及决定前置同步和取值调用的输入 source kind。
    • 调用路径由嵌套 variant 类型表示,不新增 route 枚举。
    • rank 由 shape 数组长度得到。
    • Size(expr) 在 codegen 中按 tpipe.tiler.sizes 替换,ActualSize(expr) 先按
      tpipe.tiler.actual_sizes、再按 sizes 替换;ATT 参数必须保存替换后的 ge::Expression,不能只保存 role。
    • Duplicate count 按 Tiler::TensorActualSize 的同一公式构造 ge::Expression,包括各非零 stride 轴的
      actual_size/size 选择、stride 乘积和最终 +1,不能使用只支持乘法的 ParamExprProduct。
    • dst_view_size 按 TensorVectorizedSize(out) - TensorVectorizedOffset(current_axis, out) 的同源表达式构造,
      用于准确复现 uint8_t overload 中忽略 size、改读 dst.GetSize() 的行为。
  4. 输出

struct BroadcastExtendParams {
    std::vector<ge::Expression> dst_shapes;
    std::vector<ge::Expression> src_shapes;
};

enum class BroadcastScalarSourceKind {
    kConstant,
    kUbScalar,
    kTensorVecIn,
    kTensorVecCalc,
    kTensorOther,
};

struct BroadcastDuplicateParams {
    ge::Expression count;
    ge::Expression dst_view_size;
    BroadcastScalarSourceKind source_kind{BroadcastScalarSourceKind::kTensorOther};
};

using BroadcastCallParams =
    std::variant<std::monostate, BroadcastExtendParams, BroadcastDuplicateParams>;

struct BroadcastNodeParams {
    BroadcastCallParams call_params;
};

不透传 const_rank、srcSize/dstSize、stride、loopNum、Extend branch_id、repeat_time、Reg 次数或
outer_call_count。source_kind 不是 Extend 分支 ID,而是 BroadcastScalar 已确定且 ATT 无法从 API 参数恢复的
前置调用语义;dst_view_size 是传入 Tensor 参数在仓内 B8 overload 中实际读取的原始属性,不是派生次数。

功能需求 2:BroadcastExtend tiling 和顶层分支

  1. 介绍

    ATT 按 GetBroadcastTilingInfoExtendImpl 复现 API 内部参数,不按经验重建。

  2. 输入

    dst_shapes、src_shapes 和 NodeDetail 中的真实 dtype。

  3. 处理

    • 计算 srcSize/dstSize。
    • rank 大于 4 时合并连续广播轴和公共轴。
    • 8B dtype 按源码转换为 uint32_t BrcType 并执行扩维或 loopNum 处理。
    • 计算 dstStride/srcStride。
    • 按 srcSize == dstSize、srcSize == 1 和 srcStride[dim-1] 选择顶层路径。
    • 固定 rank4 非 B64 在 Last 或 NLast 路径满足 dstShape[0]==1 && oriSrcShape[0]==1 时,按源码跳过
      首轴并以 dstShape+1/srcStride+1 调用对应 3D wrapper;该判定位于 4D wrapper 前,不能按普通 4D 建模。
    • 所有 rank 的轴类别由 src==1 && dst!=1(B)或 src==dst(E)决定。rank1-4 不合轴,但动态 shape
      仍需先枚举每轴 B/E 状态以构造 stride 并选择 Copy/Duplicate/Last/NLast。rank5-9 若条件为动态,必须在合轴前
      按源码判定顺序递归构造 B/E 条件分支;每个分支先得到确定的规范化 rank、shape 和 stride,再进入
      wrapper/leaf 选择,不能在单一可变长度容器上事后只为 leaf 条件补 ternary。
    • 动态合轴最多枚举 rank9 的有限 B/E 状态;静态可判定条件立即折叠。相同符号 shape 取具体值后的每个
      分支必须与直接使用该静态 shape 构造的模型选择相同规范化结果和 leaf。
  4. 输出

    规范化 tiling 上下文和选中的 wrapper 类型。

功能需求 3:wrapper 分支覆盖

  1. 介绍

    所有静态和动态 wrapper 条件必须与源码一致。

  2. 输入

    规范化 shape、stride、BrcType、rank 和 loopNum。

  3. 处理

Last 分支:

wrapper 条件族 leaf
2D last == BLK && T != B8 E2B
2D last < HALF_VL GatherOne/GatherTwo
2D HALF_VL <= last <= VL LessUnaligned
2D last > VL LargeAligned/LargeUnaligned/dynamic fallback
3D E2B 完整条件 E2BSmall/E2BLarge
3D last < HALF_VL GatherWrapper
3D last <= VL LessAligned/LessUnaligned/fallback
3D last > VL LargeAligned/LargeUnaligned/fallback
4D E2B 完整条件 E2B
4D last < HALF_VL && T != B8 GatherWrapperForFourDim
4D last <= VL LessAligned/LessUnaligned/fallback
4D last > VL LargeAligned/LargeUnaligned/fallback
more-dim dim > 4 或 wrapper 返回 true dynamic Last 4D leaf

dynamic Last 不重新选择 E2B、Gather 或 aligned leaf,只按 last<=VL 进入 4D less unaligned,或进入
4D large unaligned。

3D E2B 条件保持为:

last == BLK && T != B8 && middle * last > HALF_VL &&
middle % DEFAULT_BLK_NUM == 0 && stride[1] != 0

4D E2B 条件保持为:

last == BLK && T != B8 && stride[2] != 0 &&
size[2] % DEFAULT_BLK_NUM == 0

NLast 分支:

wrapper 条件族 leaf
2D last < HALF_VL && last % BLK == 0 GatherBOne/GatherBTwo
2D last < HALF_VL && last % BLK != 0 GatherOne/GatherTwo
2D HALF_VL <= last <= VL LessUnaligned
2D large aligned 且 last % VL == 0 && size0 > DEFAULT_BLK_NUM AlignedWithVL
2D 其他 large aligned AlignedWithBlock
2D large unaligned static leaf/dynamic fallback
3D last < HALF_VL GatherWrapper
3D last <= VL LessUnaligned
3D large aligned AlignedWithVL/AlignedWithBlock
3D large unaligned static leaf/dynamic fallback
4D last < HALF_VL && T != B8 GatherWrapperForFourDim
4D last <= VL LessAligned/LessUnaligned/fallback
4D large aligned AlignedWithVL/AlignedWithBlock
4D large unaligned static leaf/dynamic fallback
64-bit constRank 4 扩维 dim != constRank NLastWrapperForMoreDim
more-dim dim > 4 或 wrapper 返回 true dynamic NLast 4D leaf

dynamic NLast 的 large aligned 分支固定使用 WithBlock,不重新选择 WithVL。B64 原末轴 Broadcast 会追加公共
轴 2:固定 rank1 进入 NLast2,rank2/3 分别进入 NLast3/NLast4,rank4 固定进入 NLast more-dim 并逐次执行
Gather4;rank9 还需乘被移除原首轴形成的 loopNum。

  1. 输出

    唯一 leaf 和 leaf 外层循环乘数。动态 shape 输出对应 TernaryOp,不默认选择任何分支。

功能需求 4:完整下钻到 Reg/MicroAPI

  1. 介绍

    helper 只有在到达实际执行的 Reg::*、MicroAPI::* 或仓内无实现源码的基础 API 时才能停止。仓内有实现
    的 helper 只计算展开后的终端调用,不能同时计算 helper 自身和内部调用。

  2. 输入

    wrapper 选择结果和 leaf 参数。

  3. 处理

调用图闭合规则:

helper 必须继续下钻至
E2bLoad Reg::LoadAlign
BrcLoad Reg::LoadAlign
GatherWrapper GenGatherIndex -> VfGenIndex/VfGenIndexB8 -> Reg::* 和 VfGatherBrc/VfGatherBrcB8 -> Reg::*
GatherWrapperForFourDim GenGatherIndexForFourDim -> VfGenIndexForFourDim -> Reg::* 和 VfGatherBrcForFourDim -> Reg::*
BrcNlastWrapperForMoreDim 每次循环完整下钻 GatherWrapperForFourDim
dynamic more-dim wrapper 每次循环完整下钻选中的 4D leaf

不可继续下钻的成功路径函数边界同样必须计数:DataCopy、PopStackBuffer、LocalTensor::GetPhyAddr、
GetTPipePtr、FetchEventID、SetFlag 和 WaitFlag。其中 load/store 语义分别映射 kLoad/kStore,
其余性能表无项时使用互相独立、可追溯的 kPlaceholder。失败时才执行的 assert/log 不计。

以下声明不产生性能成本:

Reg::RegTensor<T> srcReg;
Reg::MaskReg pregCnt;
Reg::UnalignReg ureg0;

Reg::CreateMask 是实际函数调用,必须计数。

  1. 输出

    按真实 API、方向、模式和 dtype 区分的终端调用次数集合。

功能需求 5:循环次数和统一 cost

  1. 介绍

    每条 Reg API 的 count 等于其实际外围循环乘积,循环外初始化、复用 load 和 tail 调用单独计算。

  2. 输入

    设 2D 为 (a,b)、3D 为 (a,b,c)、4D 为 (a,b,c,d)。

  3. 处理

独立 Duplicate:

路径 执行次数/终端调用
独立非 uint8/int8 Duplicate(dst, scalar, count) 外部终端函数 call_count=1;kDuplicate 性能组件 component_count=ceil_div(count,V_T);包括 bool
独立 uint8_t Duplicate ReinterpretCast<uint16_t>、GetSize、下层外部 Duplicate<uint16_t> 的 call_count 各 1;下层参数 n=ceil_div(dst_view_size,2),kDuplicate<uint16> 组件次数 ceil_div(n,V_uint16)
独立 int8_t Duplicate ReinterpretCast<uint16_t>、下层外部 Duplicate<uint16_t> 的 call_count 各 1;下层参数 n=ceil_div(count,2),kDuplicate<uint16> 组件次数 ceil_div(n,V_uint16)
独立 B64 三参数 Duplicate 不命中仓内四参数 overload;外部终端函数 call_count=1,kDuplicate<int64/uint64> 组件次数 ceil_div(count,V_T)
constant / UB scalar 无额外终端函数
Tensor Value VecIn GetTPipePtr=1、FetchEventID(MTE2_S)=1、SetFlag(MTE2_S)=1、WaitFlag(MTE2_S)=1、GetValue=1
Tensor Value VecCalc GetTPipePtr=1、FetchEventID(V_S)=1、SetFlag(V_S)=1、WaitFlag(V_S)=1、GetValue=1
其他 Tensor Value GetValue=1

ReinterpretCast、GetSize 无性能表项,分别使用独立 kPlaceholder。外部 Duplicate 保留一次真实 API 调用;
其性能组件按公开 count 参数和向量宽度映射为 kDuplicate repeat,不把 repeat 误写成 API 调用次数。
独立 Duplicate 的 count 和 dst_view_size 均允许为动态表达式,并使用本节统一 cost 结构。

这里的执行边界从 BroadcastRegApiCall::Generate 实际生成的语句开始。UB scalar 的变量初始化由其生产节点
ApiCall::PostProcess 生成,同一生产节点多个 UB scalar 输出还共享一次同步,因此 Broadcast 只计算读取已准备
标量后的 Duplicate,不重复计算生产节点同步/GetValue;普通 Tensor Value 的同步/GetValue 由
BroadcastScalar 自身生成,仍归 Broadcast 计数。
本设计不修改生产节点 ATT 模型,也不宣称整图已包含 PostProcess 总成本;该排除只用于确定 Broadcast 的唯一
执行边界,避免把共享成本按消费者数量重复计入。

基础和 E2B:

leaf Reg count
BrcDuplicate(dstSize) Load=1;UpdateMask=Store=ceil_div(dstSize,VL)
BrcLastE2B(a,b) r=ceil_div(a,VL/b);UpdateMask=Load=Store=r
BrcLastE2BLargerThanVL(a,b,c) r=ceil_div(b,VL/c);三者为 a*r
BrcLastE2BLessThanVL(a,b,c) UpdateMask=1;Load=Store=a
BrcLastE2B(a,b,c,d) r=ceil_div(c,VL/d);三者为 a*b*r

Less 和 Large:

leaf Reg count
Last Less Aligned 3D/4D UpdateMask=1;Load=Store=a*b / a*b*c
NLast Less Aligned 4D UpdateMask=1;Load=Store=a*b*c
Last Less Unaligned 2D/3D/4D Load=StoreUnAlign=a / a*b / a*b*c;Post=1
NLast Less Unaligned 2D UpdateMask=1, Load=1, Store=a, Post=1
NLast Less Unaligned 3D/4D UpdateMask=1;LoadPre=Load=Store=a*b / a*b*c;Post=1
Last Large Aligned 2D CreateMask=1;Load=a;UpdateMask=Store=a*r
Last Large Aligned 3D CreateMask=1;Load=a*b;UpdateMask=Store=a*b*r
Last Large Aligned 4D CreateMask=1;UpdateMask=a*c*r;Load=Store=a*b*c*r
NLast Large Block 2D CreateMask=1;UpdateMask=Load=Store=a*r
NLast Large Block 3D CreateMask=1;UpdateMask=a*r;Load=Store=a*b*r
NLast Large Block 4D CreateMask=1;UpdateMask=b*r;Load=Store=a*b*c*r
NLast Large VL 2D CreateMask=1;Load=r;Store=a*r
NLast Large VL 3D/4D CreateMask=1;Load=Store=a*b*r / a*b*c*r
Last Large Unaligned 2D/3D/4D Load=a / a*b / a*b*c;Store=LoadCount*(q+1);Post=1
NLast Large Unaligned 2D tail Load=1,main Load=a*q;Store=a*(q+1);Post=1
NLast Large Unaligned 3D/4D LoadPre=a*b / a*b*c;Load=Store=outer*(q+1);Post=1

普通 large 分支中 r=ceil_div(last,VL),q=floor(last/VL)。E2B 使用其源码专属 repeat 公式。

Gather index 固定次数:

helper Reg count
GenLastGatherIndex CreateMask=1, Duplicate=1, Arange=1, Div=1, Store=1
GenNlastGatherIndex 上述基础增加 Mul=1, Sub=1
VfGenIndex CreateMask=1, Arange=1, Duplicate=6, Div=3, Mul=4, Sub=3, MulAddDst=2, Store=1
VfGenIndexB8 CreateMask=1, Arange=2, Duplicate=6, Div=6, Mul=8, Sub=6, MulAddDst=4, Store=2
VfGenIndexForFourDim CreateMask=1, Arange=1, Duplicate=8, Div=4, Mul=5, Sub=4, MulAddDst=3, Store=1

Gather 正文:

helper Reg count
GatherOne 非 B8 CreateMask=1, Load=1, UpdateMask=1, Gather=1, Store=1
GatherOne B8 CreateMask=1, Load=2, UpdateMask=1, Gather=2, DeInterleave=1, Store=1
LastGatherTwo 非 B8 CreateMask=1, Duplicate=1, Load=1, Muls=r, Add=r, Adds=1, Gather=r+1, Store=r+1, Post=1
LastGatherTwo B8 Load=2, Add=2r, Adds=2, Gather=2(r+1), DeInterleave=r+1,其余同非 B8
NLastGatherTwo 非 B8 CreateMask=1, Load=1, Gather=1, Store=r+1, Post=1
NLastGatherTwo B8 Load=2, Gather=2, DeInterleave=1,其余同非 B8
NLastGatherBOne CreateMask=1, Load=1, GatherB=1, UpdateMask=1, Store=1
NLastGatherBTwo CreateMask=1, Load=1, GatherB=1, UpdateMask=2, Store=r+1

其中 r=ceil_div(size0,VL/size1)-1。

GatherWrapper 正文:

VfGatherBrc(m,n):
  CreateMask=1, Duplicate=2, Load=1
  Muls=Add=m*(n+2)
  Gather=Store=m*(n+1), Post=1

VfGatherBrcB8(m,n):
  CreateMask=1, Duplicate=2, Load=2
  Muls=m*(n+2), Add=2*m*(n+2)
  Gather=2*m*(n+1)
  DeInterleave=Store=m*(n+1), Post=1

VfGatherBrcForFourDim(m,n,p):
  CreateMask=1, Duplicate=3, Load=1
  Muls=Add=m + m*n + m*n*(p+1)
  Gather=Store=m*n*(p+1), Post=1

外围基础调用次数:

路径 终端基础调用次数
每次 BroadcastExtend CheckTensorPos=2,顶层 GetPhyAddr=2
2D Gather/GatherTwo PopStackBuffer=1;两个 base GetPhyAddr 使用不同 call_site 且各 1 次;offset call_site 1 次
3D/4D GatherWrapper PopStackBuffer=1,GetPhyAddr=2
NLast GatherB PopStackBuffer=1,GetPhyAddr=1,GetTPipePtr=2,FetchEventID=2,两组 SetFlag/WaitFlag

这些次数与对应 wrapper 的实际调用次数相乘。8 次 UB 标量 index 写入不是函数调用,不构造 Placeholder。

动态 more-dim 外层乘数:

outer = normalized_loopNum * product(dstShape[0 ... dim-5])

选中的 4D leaf 中每条实际 Reg count 分别乘 outer。BrcNlastWrapperForMoreDim 对 helper 内全部 Reg
count 乘 dstShape[0]。每次 BroadcastExtend 固定执行的 CheckTensorPos/GetPhyAddr prelude 独立于 leaf body,
始终只附加一次,不乘 wrapper、prefix、loopNum 或 dynamic outer。

  1. 输出

先生成独立于性能表的调用计数账本:

struct BroadcastPerfComponent {
    std::string perf_type;
    std::string perf_dtype;
    Expr component_count;
};

struct BroadcastApiParam {
    std::string role;
    Expr value;
};

struct BroadcastCallCount {
    std::string call_site;
    std::string real_api;
    std::string data_dtype;
    std::string index_dtype;
    std::string mode;
    std::vector<BroadcastApiParam> api_params;
    Expr call_count;
    std::vector<BroadcastPerfComponent> perf_components;
};

call_site 使用稳定的源码 helper + semantic slot 名识别调用位置,例如
VfGenIndexB8.ArangeLow/ArangeHigh,不能使用源码行号或对象地址。每个源码 slot 独立成行,禁止跨
call_site 合并;同一 slot 位于循环内时用 call_count 表达循环次数。api_params 只保存仓外高层终端中
用于派生 component count 的参数。仓内已下钻 Reg、地址、栈和同步 slot 不保存逐次 offset/scalar 参数序列。
账本验收执行位置、mode、dtype 和次数,不追踪循环中每次调用的完整实参轨迹。

Canonical role 按下表命名和排序,不允许实现自行使用同义名称:

终端 API 有序 roles 排除项
DataCopy copy_length dst/src Tensor
外部 Duplicate count dst Tensor、scalar value
所有仓内 Reg/地址/栈/同步终端 无 Tensor、offset、scalar、event id;差异由 call_site/mode/dtype 区分
其他已入账终端 API 无 除非本表显式列出,否则参数不进入数量账本

call_count 只表示真实终端函数调用次数;component_count 表示该函数映射到性能表后的内部处理次数,两者
禁止混用。data_dtype/index_dtype 保存真实模板语义;无 index 的调用将 index_dtype 留空。账本是执行数量
验收的唯一事实来源。随后逐组件调用 AddVfInstructPerf 生成成本;性能表存在函数但缺少 perf_dtype 时,
仍以真实 perf_type + perf_dtype 调用,允许既有查询返回零成本,但不得从账本删除、改 dtype
或改成 Placeholder。

动态分支先对所有静态分支的终端调用身份
(call_site,real_api,data_dtype,index_dtype,mode,api_params roles) 取并集。每个身份只保留一行,参数 value、call_count 和每个
component_count 用与源码保序分支相同的嵌套 TernaryOp 表达;该分支不存在此调用时取 0。动态表达式
特化后删除零 count 行,再与对应静态账本逐项比较。禁止只为最终总成本建 ternary 而丢失条件化账本。

条件化 union 账本只用于数量追踪和特化验收,不能直接逐行调用 AddVfInstructPerf,否则 count 为 0 的
分支独有 API 仍会污染 max_latency。成本计算必须在每个静态分支内独立得到
VFHead + branch_max_latency + branch_throughput,再按相同源码条件顺序用 TernaryOp 合并分支总成本。

Expr res = VfPerfUtils::GetVFHeadCost() + max_latency + all_vf_instruct_cost;
res.Simplify();
perf.pipe_res[PipeType::AIV_VEC] = res;

例如 4D E2B 的 L=size0*size1*repeatTimes,其成本为最大 latency 加三项分别乘 L 的 throughput,
而不是 L * max_latency。

功能需求 6:Reg API 映射

  1. 介绍

    只使用已确认的 VF 表项;无表项时不猜耗时。

  2. 输入

    下钻所得真实 Reg API、模式、方向和 dtype。

  3. 处理

真实 Reg API perf 类型
顶层 DataCopy 一个 real_api=DataCopy,call_count=1 账本项并保存 copy_length=AlignUp(dstSize,ONE_BLK_SIZE/sizeof(T));按用户规则附 kLoad、kStore 两个性能组件,各 component_count=ceil_div(copy_length,V_T)
所有包含 Load 的 API,包括 E2B 和 unaligned kLoad
所有包含 Store 的 API,包括 unaligned 和 post kStore
Duplicate kDuplicate
UpdateMask kUpdateMask
Add/Adds/Sub/Mul/Muls/MulAddDst/Div/DeInterleave 对应 k*
CreateMask/Arange/Gather/GatherB 按真实 API、模式和 dtype 分开的 kPlaceholder
PopStackBuffer/GetPhyAddr/GetTPipePtr/FetchEventID 每种真实函数独立 kPlaceholder
SetFlag/WaitFlag 按同步方向和真实函数独立 kPlaceholder
LocalTensor::GetValue 独立 kPlaceholder
LocalTensor::ReinterpretCast/GetSize 每个真实函数独立 kPlaceholder
CheckTensorPos 独立 kPlaceholder,每次 BroadcastExtend 固定 2 次

dtype 必须来自 impl 中每个终端调用的真实模板实例,不能统一使用节点输入 dtype:

调用类别 dtype 来源
普通 B8/B16/B32 Extend 数据调用 ExtractUnsignedTypeBySize<sizeof(T)> 对应 uint8/uint16/uint32
所有 Extend 顶层 Copy 未进入 BrcType 数据路径,kLoad/kStore 均使用节点原始 dtype
B64 Extend 非 Copy 数据调用 API 内拆分后的有效 BrcType=uint32
B64 Extend 前置调用 CheckTensorPos<T> 和顶层 GetPhyAddr 保持原始 int64/uint64,不随 BrcType 改写
Gather index 生成 data_dtype 使用 VfGenIndex*/Gen*Index 的真实 signed int16/int32,index_dtype 为空
普通 Gather index consumer B8/B16 使用真实 unsigned uint16,B32/B64-effective 使用 uint32
GatherB index consumer 所有数据 dtype 均使用真实 uint32 index
Gather 数据调用 data_dtype 保存真实 source 数据 dtype,index_dtype 保存 uint16/uint32 consumer;perf_dtype 使用实际指令主寄存器 dtype。B8 Gather 明确为 data_dtype=uint8,index_dtype=uint16,perf_dtype=uint16;B8 中间 index 运算以 uint16 记录,DeInterleave/Store 以 uint8 记录
独立非 uint8/int8 Duplicate 生成的 Duplicate impl 模板 dtype,即节点真实输出 dtype;bool 保持 bool
独立 B8 Duplicate 仓内 overload 下钻后的 uint16 Duplicate;外层 Reinterpret/GetSize 注释保留原 B8 路径
地址、栈、同步等无数据模板调用 使用与其所属调用图一致的 impl 数据 dtype,并靠注释区分真实 API/模式
B8 2D Last/NLast/GatherB 栈/index 地址 PopStackBuffer<T> 和 LocalTensor<T> owner dtype 为 uint8;GatherB consumer index 仍为 uint32
B8 3D GatherWrapper 栈/index 地址 PopStackBuffer<BrcIndexType> 和 index Tensor owner dtype 为 BrcIndexType=uint16;数据 Tensor 地址按对应 owner dtype
B8 4D GatherWrapper 从 BroadcastExtend 不可达,不生成任何账本行

Div<int16/int32> 使用 kDiv 和真实 dtype。任何性能表已有函数但缺少该 dtype 的场景,包括 B64
kDuplicate,仍调用真实 k* 和 perf dtype;不改成 kPlaceholder、不替换 dtype、不补猜测性能表数据。
这种缺项可能使最终成本项为 0,但真实 API、dtype 和执行次数必须保留在 BroadcastCallCount 中并由 UT 验证。

  1. 输出

    每个 AddVfInstructPerf 均可追溯到唯一源码 call_site。账本和成本层都禁止跨 call_site 合并;即使 perf
    类型、方向、模式、dtype 和 count 相同,也逐 slot 调用。Placeholder 同样禁止跨真实 API、方向/模式、
    dtype 或 call_site 汇总。

非功能需求

可维护性

  • Broadcast perf 放在独立 broadcast_regbase_perf.cpp/.h,不继续扩大现有
    ascendc_regbase_perf.cpp。
  • 分支选择和 leaf 计数分层,避免逐行复制 AscendC 实现。
  • helper 名称和注释使用真实 AscendC 函数名,便于源码变更后对照。
  • 不重构其他算子或公共性能模型。

可测试性

  • 分支选择器和 leaf 计数器提供可直接构造静态表达式的测试入口。
  • 每个 leaf 至少有一个分支选择 UT 和一个 Reg count UT。
  • 动态条件验证 TernaryOp,不只验证静态 shape。
  • 参数链路分别覆盖预注册、Generate 填充、parser 提取和 perf 使用。

可移植性

不硬编码芯片型号。实现继续由现有 V2/RegBase 注册和平台能力选择进入。性能数据来自当前 V2 表,未注册
API 不引入平台推测。

可靠性

  • rank、shape 数量、shape 合法性、除数和固定整数转换均校验。
  • 失败时返回错误,不生成无效分支表达式。
  • 不新增资源申请和 runtime 生命周期。
  • 静态和动态分支均保持确定性。

特性交叉影响

场景 适用性 分析说明
SuperKernel Python 接口 不适用 不影响 Python 包、选项或 wheel
SuperKernel C++/AOT 接口 不适用 不影响 libascendsk.so 或 ABI/API
Autofuse 图优化 不适用 不修改图、pass 或边关系
Autofuse Codegen/Backend 适用 增加 Broadcast 元数据填充,不改变生成 kernel 文本或 VF parser 行为
AscendC API / Runtime 交互 适用 读取现有 AscendC 语义,不新增调用或资源
Python/C++ 混合绑定 不适用 无绑定变化
构建与打包 适用 新 .cpp 由 glob 收集,无安装布局变化
测试与覆盖率 适用 新增 common、codegen、ATT UT 和 ATT ST
性能与日志 适用 改变 ATT 评分;kernel 执行行为不变
兼容性 适用 V2 tiling 选择可能变化;外部 API/ABI 不变

性能

编译时长

每个 Broadcast 增加最多 9 维 shape 解析和有限分支表达式构造。静态 shape 复杂度为
O(rank + Reg API 类型数);rank5-9 动态轴类别最坏产生 2^rank 个 B/E 状态,rank 上限为 9,静态条件
即时折叠。不新增全图遍历;测试需关注模型生成时长和表达式规模,但首期不引入缓存。

执行性能

不改变 kernel 代码、runtime 调度或内存拷贝。ATT 公式变化可能改变 tiling 候选评分,这是需求预期行为。
含 Placeholder 的分支只保证结构和次数正确,不能宣称绝对性能误差已闭环。
BOOL 的 kDuplicate/kLoad/kStore/kPlaceholder 当前均缺性能表 dtype,按用户约束保留 bool 的真实账本项,
最终成本允许为 0;这是性能数据残余边界,不影响执行次数和分支验收,但不宣称 BOOL 绝对成本闭环。

内存和产物大小

每个 Broadcast 最多保存两组 9 维表达式,或 count/dst_view_size/source_kind。调用计数账本仅存在于一次
性能公式计算中。新增独立 perf 源文件,不改变动态库、run 包、wheel 和安装路径布局。

接口设计

新增/修改接口描述

  • 新增 ascir_param::BroadcastExtendParams。
  • 新增 ascir_param::BroadcastDuplicateParams。
  • 新增 ascir_param::BroadcastNodeParams。
  • NodeInfo 和 NodeDetail 新增 broadcast_node_params 内部字段。
  • 新增内部函数 ascendcperf_v2::BroadcastPerf。
  • V2 Broadcast 注册从 V1 BroadcastApi 切换到 BroadcastApiV2。

所有接口均为仓内编译期内部接口,不导出 C/C++ ABI,不改变 Python API。

接口检查项

检查项 子检查项 是否涉及 说明
接口说明 是否需要接口评审 否 仓内内部结构和函数
接口说明 是否需要补充文档 是 本设计文档记录参数语义
接口兼容 行为是否兼容 是 V2 性能评分预期变化,kernel 行为不变
接口兼容 ABI/API 是否兼容 是 无对外 ABI/API 变化
接口约束 约束不满足时是否清晰报错 是 rank、shape 和参数状态返回错误
接口测试 是否需要独立接口用例 是 参数 variant、parser 和注册 UT

软件设计

关键数据结构

BroadcastNodeParams 使用嵌套 variant 表示 Extend、Duplicate 或未填充状态。其生命周期与 ASCIR 节点扩展属性
一致,由 codegen 前预注册、Generate 填充、ATT parser 复制,不持有外部资源。

内部 tiling 上下文保存解析后的 rank、shape、stride、size、loopNum 和 BrcType,只存在于一次性能公式计算中。

关键技术/算法

  • 复现 GetBroadcastTilingInfoExtendImpl,包括 rank 大于 4 合并和 64-bit 扩维。
  • 复现 BroadcastComputeExtend 的 copy、duplicate、last/nlast 和 dynamic fallback。
  • 保持入口 constRank=C 与 wrapper 模板参数 W 的区别,覆盖固定 rank 5-9 的动态 fallback。
  • 按 wrapper 条件选择 leaf。
  • leaf 计数逐条计算外围循环乘积,区分循环外初始化、复用 load 和 tail。
  • 动态 shape 使用 ternary 条件,不做常见分支近似。

流程设计

正常流程:预注册参数、codegen 填充、parser 提取、V2 perf 解析、分支选择、Reg count、cost 汇总。

兼容流程:仅历史或直接构造的 NodeInfo 缺少参数时使用 V1 公式并记录 debug 日志。新 codegen 已进入但载荷
无效时返回失败,禁止静默回退。

异常流程:shape/rank/表达式无效立即返回错误,不产生部分性能公式。

对子模块的修改

文件 修改内容
autofuse/common/ascir_node_param/ascir_node_param.h 新增 Broadcast 参数结构并加入 variant
autofuse/common/ascir_node_param/ascir_param_builder.cpp 为 Broadcast 预注册空参数
autofuse/v35/codegen/reg_api_call/reg_broadcast_api_call.cpp 与生成实参同源填充 Extend/Duplicate 参数
autofuse/att/gen_model_info/parser/specific_params_builder.cpp 提取 Broadcast 参数
autofuse/att/gen_model_info/parser/tuning_space.h NodeInfo 新增字段
autofuse/att/gen_model_info/api_perf_register/api_perf.h NodeDetail 新增字段
autofuse/v35/att/api_perf_register/ascir_api_perf_v2.cpp 新增 V2 入口和注册
autofuse/v35/att/api_perf_register/broadcast_regbase_perf.h 新增 perf 声明
autofuse/v35/att/api_perf_register/broadcast_regbase_perf.cpp 新增 tiling、branch 和 Reg count 模型

autofuse/v35/att/CMakeLists.txt 已使用递归 glob,无需修改。

错误处理

系统错误

不新增内存、文件、runtime 或动态库资源。表达式或对象创建失败沿现有错误码返回。

接口错误

  • 参数结构错误、rank 越界、shape 数量不一致或同源解析表达式无效返回 af::FAILED。
  • 不支持的动态条件返回错误,不生成零成本结果。
  • 缺失独立 Duplicate dtype 性能数据时仍保留真实 API/dtype;允许性能表按既有行为产生零成本,但账本项不得消失,
    不阻塞执行次数模型验收。

安全检查

  • 不硬编码 Token、账号、公网地址、芯片、框架或性能数据。
  • shape 作为索引、循环次数和除数前校验范围与非零。
  • shape 乘积使用符号表达式;固定整数转换检查溢出和反转。
  • 不新增资源申请或异常释放路径。
  • 不修改图,不影响数据边、控制边和图确定性。
  • 不新增 runtime/aclrt 调用。
  • 不新增高频默认日志。

兼容性检查

  • 外部 C/C++、Python、脚本和配置接口不变。
  • 安装目录、动态库名称、wheel/run 包内容不变。
  • 生成的 Broadcast kernel 文本和运行行为不变。
  • V2 ATT 评分变化可能改变 tiling 选择,属于预期改进。
  • 旧的直接 perf 调用缺少参数时保留明确 V1 fallback;新链路无效载荷不回退。

测试设计

测试边界

  • 参数入口:AscirNodeParams 和 BroadcastRegApiCall::Generate。
  • 性能入口:BroadcastApiV2 和 BroadcastPerf。
  • 验证出口:参数内容、branch leaf、每类 Reg count、最终表达式和 ternary。
  • 不 mock AscendC 执行;计数依据直接来自仓内源码。

测试用例设计

测试类别 关键测试项 测试方法 用例类型
功能 Extend、独立 Duplicate 参数链路和公式断言 UT
功能 顶层 DataCopy API call_count=1,不同静态/动态 copy_length 对应正确 load/store component_count,并覆盖 AlignUp 最大安全值及下一值 UT
功能 独立 Duplicate 五类 source kind 同步方向、GetValue、Placeholder 和外部终端调用次数断言 UT
功能 UB scalar 成本所有权 Broadcast 不重复计算生产节点 PostProcess 的共享同步/GetValue UT
功能 独立 B8 Duplicate overload dst_view_size/count 分流、Reinterpret/GetSize 和下层 uint16 Duplicate 次数 UT
功能 uint8 非零 view offset dst_view_size=TensorVectorizedSize-offset,下层 Duplicate 次数不使用完整 tensor size UT
功能 独立 BOOL Duplicate 仓外 Duplicate<bool> 调用 1 次、dtype 保持 bool、缺项账本不消失 UT
功能 Last/NLast 2D/3D/4D 全 leaf 表驱动 branch 和 Reg count UT
功能 固定 rank4 非 B64 首轴退化 Last/NLast 静态和动态 shape 均跳过首轴进入 3D wrapper UT
功能 B64 rank1 NLast2、2->3、3->4、rank4 NMore、rank9 loopNum 规范化 tiling和分支断言 UT
功能 B64 全可达矩阵 穷举 C=1..9 × 合法原始 B/E pattern × B64 扩维结果,覆盖 T-COPY、N2-、N3-、N4-、固定 NMore->CG-GW4、DN- 全 terminal family,并逐项验证完整账本 UT
功能 非 Gather 全 leaf call_site 每个 leaf 的循环内/外、main/tail、复用 load 逐 slot 断言,不只断言聚合总数 UT
功能 B64 前置与数据 dtype CheckTensorPos/GetPhyAddr 保持 64-bit,进入 BrcType 后的数据终端为 uint32 UT
功能 B8 双 Gather 和 DeInterleave API 类型和次数断言 UT
功能 more-dim dynamic 外层乘数和 4D leaf 次数断言 UT
功能 栈、地址和同步等基础函数 独立 Placeholder 类型和次数断言 UT
功能 全部 large aligned leaf CreateMask=1 及 dynamic outer 乘数断言 UT
异常 缺参、rank 越界、shape 不一致、除 0 状态码断言 UT
异常 窄化正常域边界 wrapper/loop/stride 的 65535/65536;仅 B8/B16 ordinary Gather index consumer 限 16-bit,GatherB/B32/B64-effective 测 32-bit;Copy 不受 uint16 限制,但受 uint32 AlignUp 加法安全上限约束;Duplicate 有效下层 count 65535/65536 均成功 UT
异常 整数正常域边界 srcSize/dstSize、Gather 乘积和未进入 int32 consumer 的 Duplicate 参数覆盖 UINT32_MAX;普通/BOOL/B64 Duplicate count 覆盖 INT32_MAX;B8 size+1 consumer 覆盖 INT32_MAX-1;各自下一值失败,动态未知保留 UT
动态 HALF_VL、VL、BLK/VL 整除条件 ternary 表达式断言 UT/ST
动态 Size、ActualSize 和 TensorActualSize 生成实参与 ATT 参数逐项相等 UT
动态 rank5-9 轴类别切换 正常域内动态模型实例化后,与对应静态模型逐项比较完整调用账本 UT/ST
动态 rank1-4 顶层切换 逐 rank、dtype、合法 B/E pattern 穷举 Copy/Duplicate/Last/NLast,含 B64 扩维/不扩维,并与静态完整账本比较 UT/ST
类型 B8/B16/B32/B64 数据和 index dtype 逐调用断言 signed generator、unsigned consumer、数据 dtype;GatherB index 固定 uint32 UT
类型 各原始 dtype Copy 与非 Copy 所有 Copy 保持原始 dtype;B64 非 Copy 使用有效 B32 UT
性能 E2B 4D 三项均乘 size0*size1*repeatTimes 逐 Reg count 断言 UT
兼容性 V1 fallback 和 V2 注册 直接 perf/注册测试 UT/ST
特性交叉 生成 C++ 文本不变 codegen E2E E2E ST

计划修改或新增测试文件:

  • autofuse/tests/ut/common/test_ascir_node_params.cpp
  • autofuse/tests/v35/ut/codegen/reg_api_call/test_codegen_broadcast_reg_api_call.cpp
  • autofuse/tests/ut/att/testcase/gen_model_info/expr_gen/test_pipe_perf_expr.cpp
  • autofuse/tests/v35/ut/att/gen_model_info/api_perf_register/test_broadcast_api_perf_v2.cpp
  • autofuse/tests/v35/st/att/gen_model_info/test_ascir_perf_v2.cpp

测试命令

实现阶段执行:

bash scripts/test/run_autofuse_test.sh -u -m common -j 8
bash scripts/test/run_autofuse_test.sh -u -m codegen -j 8
bash scripts/test/run_autofuse_test.sh -u -m att -j 8
bash scripts/test/run_autofuse_test.sh -s -m att -j 8
sh build.sh -s --module=autofuse_e2e -j 8

预期结果:编译无错误、全部测试通过、无新增 warning、无超时或死循环。

验收标准

  • BroadcastExtend 和独立 Duplicate 两类路径均可追溯到实际 codegen。
  • dst_shapes/src_shapes/count/dst_view_size/source_kind 是唯一新增性能参数,不透传派生次数或 Extend branch id。
  • Extend shape 与 Duplicate count 均由 codegen 按 Size/ActualSize/TensorActualSize 同源解析,动态尾块实参与
    ATT 参数逐项一致。
  • 所有仓内可展开 helper 均下钻至终端函数;Reg 类型、变量声明和非函数标量赋值不计成本。
  • 每条 Reg count 可追溯到准确外围循环,循环外、复用 load 和 tail 分开计算。
  • 仓内 helper 下钻后的每个 Reg 终端行,其 call_count 等于源码真实调用次数;只有仓外高层终端允许
    call_count=1 而组件 repeat 大于 1。
  • 每个终端调用均先进入包含真实 API、data/index dtype、mode、call_count 和性能组件列表的独立账本;性能表 dtype 缺项
    不得导致执行次数记录消失。
  • E2B 4D 的 UpdateMask/Load/Store 均为 size0*size1*repeatTimes。
  • Last/NLast、2D/3D/4D/more-dim、B8、64-bit、aligned/unaligned、Gather/E2B 和动态分支均有 UT。
  • 独立 Duplicate 各 source kind 的同步/GetValue 调用均有静态、动态 UT。
  • 五类 source kind 以接口契约方式覆盖:codegen UT 逐类验证 Tensor -> Generate payload,ATT UT 使用相同
    payload 字段值逐类验证 parser -> ledger;不要求 codegen UT 链接 ATT 库。
  • 独立 B8 Duplicate 完整下钻 Reinterpret/GetSize/uint16 Duplicate,且 uint8 使用 dst_view_size、int8 使用
    count;所有顶层 Copy 保持节点原始 dtype。
  • 固定 rank4 非 B64 首轴同时为 1 的 Last/NLast 路径均按源码进入 3D wrapper,并覆盖静态与动态 shape。
  • 动态 shape 替换为任一正常域具体值后,完整账本的 API、data/index dtype、mode、call_count 及每个组件的
    perf type/dtype/component_count
    均与直接构造的同 shape 静态模型逐项一致。
  • 所有 large aligned leaf 的 CreateMask=1 均被计数,dynamic leaf 按实际 outer 相乘。
  • 所有含 Load 的 Reg API 使用 kLoad,所有含 Store 的 Reg API 使用 kStore。
  • 所有性能表缺项函数按真实 API、方向/模式和 dtype 使用可追溯的独立 Placeholder。
  • 所有真实 API 在性能表缺少 perf dtype 时仍保留真实调用项及组件的 k*/perf dtype,不猜性能数据。
  • 最终 cost 使用 VFHead + max_latency + sum(throughput * count)。
  • common、codegen、ATT UT,ATT ST 和 codegen E2E 全部通过。
  • 无外部 API/ABI、打包、图结构或 kernel 运行行为变化。

设计文档检查结果

likedislike
高煜博高煜博成员
8月11日 添加了label:requirement
czwaysczways成员
8月11日 将 hamburgerbobo 设为负责人
高煜博高煜博成员
8月11日 修改了issue 的描述
高煜博高煜博成员
8月11日 关联了pull request:feat: 支持 Broadcast V2 性能建模(#235)
高煜博高煜博成员
8月14日 关联了pull request:feat: add Broadcast V2 performance modeling (#235)
zqminzqmin成员
8月26日 修改标题为 “增加 Autofuse V2 Broadcast 性能建模”,原标题为“[Requirement|需求建议]: 增加 Autofuse V2 Broadcast 性能建模”