已合并
【PR】: elmwise 双输入时为 compact reduce 兜底检查插入 pad #1963
【PR】: elmwise 双输入时为 compact reduce 兜底检查插入 pad #1963
已合并
JacsonPile创建于 13 天前
JacsonPile
JacsonPile成员
13 天前

Pull Request

描述

修复 compact Reduce 输出与 aligned Broadcast 输入在 EleWise 汇聚时的精度错误(PR1760 场景)。

问题场景:一个 EleWise 节点的两个输入分别来自 Broadcast(kAligned)与 ReduceSum(compact,尾轴 stride==0)。两者物理布局不一致,EleWise 按 aligned 语义读取 compact 数据,产生错值。

此前 SetAlignInfoForNodeInputs 中的 is_compact_reduce 判定基于传播途中的对齐元数据状态举旗插 Pad:元数据状态会被传播过程改写,判定依赖遍历顺序,且不区分传播发起者,在其他图上会误判。

本 PR 改为显式结构匹配:

  • 删除 is_compact_reduce 冲突标记,SetAlignInfoForNodeInputs 恢复仅对 kFixedNotAligned 举旗;
  • 新增 AddPadForCompactReduce pass(位于 InferAlignmentAddPadForAlignmentConflict 之间),识别目标模式:EleWise 节点恰好 2 个有效输入,其一为 kAligned 的 Broadcast,另一为 compact 的 Sum;命中时在 Sum 输出与该输入之间插入 Pad,仅改接这条边;
  • 插 Pad 前复用 CheckIsNoNeedPad 豁免:Sum 输出本身无需物理转换(如尾轴 repeat 已对齐、或除尾轴外仅剩不承载数据的轴)时不插 Pad。

compact 判定基于物理 stride(StaticCheckEq(strides[axis], kSymbolZero)),不受传播改写影响,无顺序敏感性。

配套修正共享的 CheckIsNoNeedPadstride==0 || repeat==1 的轴视为不承载数据(inactive),与 SetVectorizedStridesForTensor 的判据对齐,避免"判定要 Pad 但下游按无数据轴计算 stride"的不一致;同时补充 repeats/strides 下标边界断言。该函数同时服务 AddPadForAlignmentConflictOneNode 路径,修正方向均为豁免误判的无效 Pad 或更保守地插 Pad。

变更类型

如何测试

  1. 编译并运行对齐 UT:

    cmake --build build --target optimize_ut -j 8
    build/autofuse/tests/ut/optimize/optimize_ut \
      --gtest_filter='VectorizedAlignmentUT.*compact*pad*:VectorizedAlignmentUT.scalar_reduce_skips*'
    

    验证点:

    • compact_reduce_pad_for_aligned_broadcast_add:命中双输入模式,图中存在 reduce_sum_0_pad 节点且 add 输入已改接 Pad;
    • scalar_reduce_skips_pad_for_aligned_broadcast_add(含 unit-repeat 变体):Sum 输出全 [1,1] 时不插 Pad,add 仍直连 reduce_sum
  2. 完整 optimize_ut 回归:620 PASS / 0 FAIL(8 SKIP 为环境性跳过)。

  3. 精度验证:

    • torch.compile 训练场景(Sum → Add(+1e-20) → Broadcast → TrueDiv,requires_grad):修复前输出 inf,修复后与 eager 比对 maxdiff=0;
    • TF 全链路(test_graph_big.pb,ATC 编译 + NPU 执行):修复前 6/8 错值,修复后 0/8 差异;device kernel 中可见 Sum → Pad → Add,Pad 仅连接 Add 的 Sum 输入边,Store 仍按紧凑布局落盘。

核对清单

其他信息

变更范围

生产逻辑(+113/-8 行):

  • autofuse/optimize/platform/common/base_alignment_strategy.cpp
    • SetAlignInfoForNodeInputs:删除 is_compact_reduce 判定;
    • 新增 FindCompactReduceInput:双输入结构模式匹配(aligned Broadcast + 物理 compact Sum);
    • 新增 InsertPadForCompactReduce:no-pad 豁免 + dtype 校验 + 插入 Pad 节点(输出标 kAligned)+ 精确改接单边;
    • 新增 AddPadForCompactReduce:pass 入口,注册于 InferAlignmentAddPadForAlignmentConflict 之间;
    • CheckIsNoNeedPad:inactive 轴判据与 SetVectorizedStridesForTensor 对齐(stride==0 || repeat==1),补充边界断言。
  • autofuse/optimize/platform/common/base_alignment_strategy.h:新增三个私有方法声明。

测试(+78 行):

  • autofuse/tests/ut/optimize/autoschedule/test_vectorized_alignment.cpp
    • compact_reduce_pad_for_aligned_broadcast_add:命中场景断言插 Pad 与改接;
    • scalar_reduce_skips_pad_for_aligned_broadcast_add(含 unit-repeat 变体):豁免场景断言不插 Pad。

设计边界

  • IsOps<ascir_op::Sum> 仅覆盖 Sum,与本 PR"只修 PR1760 场景"的定位一致,其他 reduce 的同型场景按需扩展;
  • 严格双输入限定,三输入及以上的泛化模式不命中;
  • 插 Pad 通过 InsertNodeAfter(reduce_output, {reduce_input}, pad_node) 只改接命中的单边,Sum 输出的其他消费者不受影响;
  • pass 顺序有依赖:必须在 InferAlignment 之后(读取传播完成后的最终对齐状态)、AddPadForAlignmentConflict 之前(避免对同一边重复插 Pad)、SetVectorizedStridesForOneNode 之前(对含 Pad 的新图重算 strides)。
likedislike
Pull Request已成功合入, 合并人@CANN-robot
(感谢 JacsonPile 的贡献)
JacsonPileJacsonPile成员
13 天前 添加了label:enhancement
JacsonPileJacsonPile成员
13 天前 创建了 pull request,commit 068df91a
atomgit-bot
atomgit-bot
13 天前 评论:

变更摘要

本 PR 修复 compact 模式 ReduceSum 输出与 aligned Broadcast 输入在 EleWise 汇聚时的精度错误:当 EleWise 节点的两个输入分别来自 aligned Broadcast 与 compact Reduce(尾轴 stride==0)时,两者物理布局不一致,EleWise 按 aligned 语义读取 compact 数据导致错值。此前 SetAlignInfoForNodeInputs 中基于传播途中的对齐元数据状态(is_compact_reduce)判定插 Pad,因元数据会被传播过程改写、且判定依赖遍历顺序与传播发起者,在其他图上会误判。本 PR 改为显式结构匹配:删除 is_compact_reduce 冲突标记,新增 AddPadForCompactReduce pass(位于 InferAlignmentAddPadForAlignmentConflict 之间),通过物理 stride(StaticCheckEq(strides[axis], kSymbolZero))识别 compact 结构,命中时在 Sum 输出与该输入边之间插入 Pad 节点,仅改接命中单边。

主要改动

  • 删除 is_compact_reduce 冲突标记: SetAlignInfoForNodeInputs 移除基于 IsReducekNotAligned 状态的举旗逻辑,恢复仅对 kFixedNotAligned 设置 conflict_with_output,消除判定对传播顺序和发起者的敏感性。
  • 新增 FindCompactReduceInput 结构匹配: 限定 kComputeElewise 节点且恰好 2 个有效输入,命中"kAligned 的 Broadcast + 尾轴 stride 为零的 compact Sum"组合时输出对应的输入/输出锚点,作为插 Pad 依据。
  • 新增 InsertPadForCompactReduceAddPadForCompactReduce pass: 先经 CallAscirInferDataType 校验 Pad 的 dtype 支持,再创建 reduce_*_pad 节点(输出标 kAligned)并通过 InsertNodeAfter(reduce_output, {reduce_input}, pad_node) 精确改接 Sum→EleWise 单边;AlignVectorizedStrides 流水线中将其插入到 InferAlignment 之后、AddPadForAlignmentConflict 之前执行。
  • 补充头文件声明与 UT: base_alignment_strategy.h 新增三个私有方法声明;test_vectorized_alignment.cpp 新增 compact_reduce_pad_for_aligned_broadcast_add 用例,构造 Sum→Add(←Broadcast) 场景并断言图中存在 reduce_sum_0_padadd 的输入已改接该 Pad。
likedislike
不准确?
atomgit-bot
atomgit-bot
13 天前 评论:

代码审查

✅ 未发现问题

likedislike
不准确?
CANN-robotCANN-robot成员
13 天前 添加了label:stat/needs-squash
此处折叠了56条消息 查看更多
liyuewei
liyuewei成员
12 天前 评论:

/lgtm

likedislike
CANN-robotCANN-robot成员
12 天前 添加了label:lgtm
yangyongqiang
yangyongqiang成员
11 天前 评论:

/approve

likedislike
CANN-robotCANN-robot成员
11 天前 添加了label:approved
CANN-robotCANN-robot成员
11 天前 合入了pull request