| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
style: 统一 Autofuse 代码格式 Co-authored-by: Ling-DT<lingxing@huawei.com> # message auto-generated for no-merge-commit merge: !921 merge style/clang-format-autofuse-20260611 into develop style: 统一 Autofuse 代码格式 Created-by: ling-DT Commit-by: Ling-DT Merged-by: cann-robot Description: # Pull Request ## 描述 基于 cann/graph-autofusion:develop 最新提交 46a23b0,使用仓库根目录 .clang-format 对 autofuse/ 目录内受版本管理的 C/C++/AscendC 源文件执行统一格式化。 本 PR 仅包含 autofuse/ 目录格式化变更;super_kernel/ 目录格式化变更按要求暂留本地,未提交到本 PR。 格式化工具:clang-format 18.1.8,参数:--style=file。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [ ] ✨ 新功能 - [x] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue 无。 ## 如何测试 描述测试此变更的步骤和前提条件: 1. /tmp/opencode/clang-format-18-venv/bin/clang-format -i --style=file <autofuse C/C++/AscendC files> 2. git diff --cached --check 3. git diff --name-only HEAD~1..HEAD | cut -d/ -f1 | sort | uniq -c 确认 PR 提交仅包含 autofuse/。 ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如:feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 本 PR 为纯格式化变更,不涉及功能逻辑、接口、构建脚本或打包内容修改。 See merge request: cann/graph-autofusion!921 | 3 个月前 | |
【fix】针对各轴repeat均为1的brodcast算子获取broadcast轴失败的场景进行兼容处理 Co-authored-by: nikson<nisong1@huawei.com> # message auto-generated for no-merge-commit merge: !2364 merge devlop-local-ns into develop 【fix】针对各轴repeat均为1的brodcast算子获取broadcast轴失败的场景进行兼容处理 Created-by: tourse Commit-by: nikson Merged-by: cann-robot Description: # Pull Request ## 描述 bugfix:针对各轴repeat均为1的broc算子获取broc失败的场景进行兼容处理 原先问题点: 前端传入的hintGraph中存在这类broadcast节点其Output的repeat在各轴上均为1;虽然其在后端语义上为scalar但当前不兼容会使得直接faill 修改点:针对该场景兼容修改,全1的broadcast做兼容,不报错而是不返回broc轴 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [x] 🐛 Bug 修复 - [ ] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 原用例运行失败;修改后用例执行成功,且broadcast后移逻辑正常生效 ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 在此添加任何其他关于本次 PR 的说明。 See merge request: cann/graph-autofusion!2364 | 1 天前 | |
【PR】feat: broadcast backward Co-authored-by: czways<chengzhiwei5@huawei.com> # message auto-generated for no-merge-commit merge: !2059 merge revert-mr-2023-1789107028331-auto into develop 【PR】feat: broadcast backward Created-by: czways Commit-by: czways Merged-by: cann-robot Description: # Pull Request broadcast backward ## 描述 请清晰准确地描述本次 Pull Request 的意图和变更内容。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [x] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 描述测试此变更的步骤和前提条件: 1. 2. ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 在此添加任何其他关于本次 PR 的说明。 # BroadcastBackwardPass:GE 侧与 graph-autofusion PR 侧对比分析 ## 简介 ### 目的 本文档对比 GE 仓库与 graph-autofusion PR #2059 中 broadcast_backward_pass 的实现差异与相同之处,为代码审查、后续维护和跨仓库同步提供参考。 > **版本说明**:PR #2059(head 0ae756e6)是 BroadcastBackwardPass 落地 graph-autofusion 的**最终完整版实现**,覆盖早期的 PR #1830 及后续修复(IndirectLoad 下游防护、pass 注册顺序调整、UT/ST 测试框架)。本文所有 PR 侧行号均以 PR #2059 为准。 ### 范围 - **GE 侧**:ge_0728/compiler/graph/optimize/autofuse/autofuse/post_process/pass/broadcast_backward_pass.cpp(1515 行)。该文件已从 ge_0728 工作树删除(git status 显示 D,pass 调用在 asc_graph_pass.cpp:21 处注释停用),本文 GE 侧行号基于删除前最后一个完整版本(commit 97f8a3246)。 - **PR 侧(PR #2059)**: - graph-autofusion/autofuse/optimize/graph_pass/broadcast_backward_pass.cpp(1477 行) - graph-autofusion/autofuse/optimize/graph_pass/broadcast_backward_pass.h(24 行) - graph-autofusion/autofuse/optimize/graph_pass/broadcast_backward_shared_split.cpp(388 行) - graph-autofusion/autofuse/optimize/graph_pass/broadcast_backward_shared_split.h(20 行) - graph-autofusion/autofuse/optimize/platform/v1/pass_runner_v1.h + v35/optimize/pass_runner_v2.h(pass 注册顺序调整) - 测试框架:tests/framework/broadcast_backward/(broadcast_backward_test_utils.h 99 行 + broadcast_backward_ut_utils.h 378 行)、UT tests/ut/optimize/test_broadcast_backward_pass.cpp(1955 行,73 个用例)、ST tests/st/optimize/test_broadcast_backward_pass.cpp(132 行,8 个用例) - 仅覆盖 Broadcast 后移 pass 本身及其注册,不含 optimize.cpp 重构、frontend_shape_vars 移除等 PR 中的其他变更。 ## 总体概述 PR 侧本质上是 GE 侧的**移植 + 增强**: 1. 去掉 asc_adapt:: 适配层,直接使用 af::GraphUtils、af::NodeUtils、ScheduleUtils:: 原生接口。 2. 移除 topo id 管理(约 190 行),改为 pass 入口和结尾统一 TopologicalSorting。 3. 新增 broadcast_backward_shared_split 预处理模块(388 行)。 4. 重写 GetBroAxisFromNode 轴匹配逻辑,支持 axis 不对齐和隐式广播维度。 5. CheckBackwardCommon 新增控制边、IndirectLoadBoundary、RemovePad 三个屏障。 6. MoveBroadcastAfterMerge 支持多后继。 7. CollectBroNodes 新增控制边检查,ProcessOriginalBackwardLogic 新增起点去重。 8. **(最终版新增)IndirectLoad 下游防护**:ChainReachesIndirectLoad 全下游可达性 DFS + HasMultipleInputsBroadcastBehind 兄弟 broadcast 检测,在两个改写入口整体拒绝到达 IndirectLoad 的链路。 9. **(最终版新增)pass 注册顺序**:BroadcastBackwardPass 注册进 V1/V2 两个 pass runner,CSE 类 pass(DuplicateElewiseCse、SameSourceBroadcastCse)调整到其之前执行。 10. **(最终版新增)独立测试框架**:graph builder 工具 + 73 个 UT 用例 + 8 个 ST 用例。 ## 差异分析 ### 一、架构层差异(适配层不同) | 维度 | GE 侧 | PR 侧 | |------|-------|-------| | 命名空间 | namespace ge | namespace optimize | | 图操作封装 | 全部通过 asc_adapt:: 适配层(GetPeerInNodes、GetPeerOutNode、IsSingleInAndOutNode、GetOutputTensorAttr、CreateBroadcastNode 等 20+ 函数) | 直接使用 af::GraphUtils、af::NodeUtils、ScheduleUtils:: 原生接口,无中间层 | | 节点类型 | ge::NodePtr 直接使用 | af::NodePtr 基类指针,需 ToAscNode() 向下转型 std::dynamic_pointer_cast<AscNode> | | 类型常量 | kTransposeType、kBroadcastType 等全局宏 | Transpose::Type、Broadcast::Type 等类静态成员 | | 数据类型 | DataType(GE 命名空间) | af::DataType | | 接口入口 | Run(ComputeGraphPtr) → asc_adapt::ProcessAscBackendNodes 遍历 | RunPass(AscGraph &) 直接操作(broadcast_backward_pass.cpp:1471) | **原因分析**: - **命名空间**:graph-autofusion 是独立组件,不属于 GE 命名空间,使用自己的 optimize 命名空间隔离代码。 - **图操作封装**:GE 侧 AscGraph 是 GE ComputeGraph 的子图,节点操作需通过 asc_adapt:: 适配层桥接两种图模型;graph-autofusion 中 AscGraph 是原生图结构,直接调用 af::GraphUtils 即可,无需中间层。 - **节点类型**:GE 侧节点类型统一在 ge::Node 下;graph-autofusion 中 af::NodePtr 是基类指针,AscNode 是携带 tensor attr 的派生类,需 dynamic_pointer_cast 转型后才能访问 outputs[i].attr 等扩展字段。 - **类型常量**:graph-autofusion 使用 ASCIR op 定义体系,类型常量绑定在 op 类上(如 Broadcast::Type),比全局宏更符合面向对象设计且避免命名冲突。 - **接口入口**:GE 侧 pass 注册在 ComputeGraph 层级,需通过 ProcessAscBackendNodes 遍历找到 AscBackend 子图再执行;graph-autofusion 的 pass runner 直接在 AscGraph 层级注册和调用,无需遍历。 ### 二、PR 侧新增功能(GE 侧没有) #### 1. broadcast_backward_shared_split 模块(388 行,全新) PR 侧在 BroadcastBackward 入口最先调用: cpp GE_ASSERT_SUCCESS(broadcast_backward_shared_split::SplitSharedBroadcastBranches(graph)); GE_ASSERT_SUCCESS(broadcast_backward_shared_split::SplitSharedBroadcastConsumers(graph)); 功能:在执行后移前,先**克隆拆分**共享同一条 Broadcast 链的多分支/多消费者场景,避免改写时边冲突。GE 侧无此预处理步骤,直接在原图上改写。 **原因分析**: graph-autofusion 的图结构中,一条 Broadcast 链的输出可能同时被多个分支或多个消费者引用。如果不先拆分,后移时 ReorderBroadcasts 需要断开 Broadcast 输出边,但该边连接了多个消费者,无法同时断开所有边,会导致改写失败或图结构损坏。通过预处理阶段克隆 Broadcast 链,使每个分支/消费者拥有独立的 Broadcast 副本,后续后移可以独立操作每条链。GE 侧可能这类共享场景较少,或通过其他 pass 在更早阶段已经拆分。 **根本原因:GE 融合反推机制不可移植到 AF** GE 的 Broadcast 处理与子图融合深度绑定,采用 **"消除 → 融合 → 恢复"** 三段式流程: GE: UpdateBroadcastInfoToLoad(消除Brc,写入Load) → MergeAscGraphByLoop(融合两个子图) → OptimizedFallback(从Load读出,按消费者重建Brc) - **融合前**(UpdateBroadcastBeforeMerge):沿 Load → Broadcast 路径,把广播轴信息"折叠"进 Load 输出属性(repeats[i]=1, strides[i]=0),然后删除 Brc 节点。目的是让不同子图在融合前统一布局。 - **融合**(MergeAscGraphByLoop):按循环轴合并两个 AscGraph。 - **融合后**(OptimizedFallback):遍历融合后图中每个计算节点的每个输入,从 Load 属性和图级 AscGraphAttr 倒推 broadcast_info,按消费者实际需求重新插入 Brc。 OptimizedFallback 的核心是 **从消费者需求倒推**(bottom-up):对每个消费者输入,比较消费者所需布局 vs Load 当前布局,差异轴即为 broadcast_info,若非空则在消费者输入前新建 Brc。一个共享源有多个消费者时,每个消费者独立判断需要哪些广播轴,只插需要的轴,不产生冗余: 原始: P → B{A,B} → C0(需要轴A) P → B{A,B} → C1(需要轴B) GE 重建:P → B0{A} → C0 P → B1{B} → C1 GE 这一机制依赖大量 GE 特有结构: | GE 反推机制 | 依赖的 GE 特有结构 | |-------------|---------------------| | UpdateBroadcastInfoToLoad | AscBackendSubGraphFusionDecider、MergeAscGraphByLoop、NodeFuseInfo、ViewOpAttrInfo | | TuningSubgraphBeforeMerge | 融合决策器、AscGraphAxisMapping | | OptimizedFallbackPro | 融合后 AscGraphAttr、AutoFuseAttrs、FusedAscBackend 节点、ProcessAscBackendNodes | 这些结构在 AF 中均不存在。AF 不走子图融合路径,直接在单个 AscGraph 上做图优化和 codegen。因此 GE 的融合反推机制 **不可移植到 AF**。 当前 GE 侧的 BroadcastBackwardPass 已被注释停用(asc_graph_pass.cpp:21)且源文件已从 ge_0728 工作树删除,AF PR #2059 是在 AF 侧重新实现,替代 GE 侧旧实现。broadcast_backward_shared_split 正是为了弥补 GE 融合反推机制缺失后的共享链场景处理:GE 通过融合后 OptimizedFallback 按消费者需求精确重建 Brc,AF 无法走这条路径,只能在融合前先把共享 Brc 链拆分为独立副本,再逐条执行后移。 #### 2. CheckBackwardCommon 新增三个屏障 PR 侧 broadcast_backward_pass.cpp:484-509: cpp if (!HasNoControlEdges(next_node)) { return false; } // 控制边屏障 L485-487 if (next_node->GetType() == kStoreType) { return false; } if (IsIndirectLoadBoundary(next_node)) { return false; } // IndirectLoad 边界屏障(增强)L493-495 if (ScheduleUtils::IsRemovePad(next_node)) { return false; } if (IsNextViewOp(next_node)) { return false; } if (IsDtypeNotSupportOp(next_node, output_dtype)) { return false; } 注意:最终版 CheckBackwardCommon 签名为 bool CheckBackwardCommon(const NodePtr &next_node),output_dtype 在函数内部声明,不再通过参数外传。 GE 侧(L308-325)只检查 Store、ViewOp、DtypeNotSupport 三种,无控制边和 IndirectLoad/RemovePad 屏障。PR 侧额外屏蔽以下三类: | 屏障 | PR 实现 | 说明 | |------|---------|------| | HasNoControlEdges | L485-487 | 节点存在控制边时不后移,避免控制依赖被破坏 | | IsIndirectLoadBoundary | L493-495(实现 L146-162) | 不仅检查 next_node 本身是 IndirectLoad,还检查 next_node 的输出是否喂给 IndirectLoad(遍历所有输出锚点的 peer in 节点) | | IsRemovePad | L496-498 | padding 逆操作边界 | **原因分析**: - **控制边屏障**:graph-autofusion 的 AscGraph 允许计算节点之间存在控制依赖边。Broadcast 后移会断开并重连数据边,如果节点同时有控制边,后移后控制依赖的语义可能不再成立。GE 侧的 asc_adapt:: 适配层在 IsSingleInAndOutNode 中隐含了控制边检查(GE 的 AscGraph 不允许控制边出现在 Brc 链中),PR 侧显式检查更清晰。 - **IndirectLoad 边界(增强)**:IsIndirectLoadBoundary(L146-162)不仅判断 next_node 自身是否为 IndirectLoad,还遍历 next_node 的所有输出锚点,检查是否有 peer in 节点是 IndirectLoad。注释说明:"直接喂给 IndirectLoad 的 compute 同样不能后移,否则 broadcast 会紧贴 IL"。IndirectLoad 的输出轴属于独立的物理视图(通过索引间接加载,轴语义与普通 Load 不同),Broadcast 后移跨过此边界会破坏轴对应关系。GE 侧不存在此算子类型。 - **RemovePad**:该算子涉及 padding 的逆操作,Broadcast 后移跨过此边界会导致 padding 区域的广播语义不一致。GE 侧不存在此算子类型。 这三个屏障是 graph-autofusion 特有图结构和算子语义决定的,不是通用优化,无法回传 GE 侧。 #### 3. MoveBroadcastAfterMerge 支持多后继 | | GE 侧 L1089-1108 | PR 侧 L1045-1064 | |---|---|---| | merge 后继 | 只处理 at(0) 单个后继 | 复制 GetPeerInDataAnchors() 全部后继,逐个断开、逐个重连 | PR 侧支持 merge_node 输出连接到多个下游节点,GE 侧只处理单后继。 **原因分析**: graph-autofusion 的图结构允许 merge 节点(如 Add)输出后继续 fork 到多个下游分支(fork-join-fork 模式),这在融合图中较常见。GE 侧假设 merge 后只有单后继,这在 GE 的图结构中成立(GE 的融合图通常在 merge 后接 Store)。如果 merge 有多个后继,GE 侧只重连第一个后继会导致其他后继丢失数据边,造成图改写不等价。 **根因定位:GE 侧 MoveBroadcastAfterMerge 的 Bug** PR 侧支持多后继的直接原因是修复了从 GE 移植时发现的 MoveBroadcastAfterMerge Bug。以下是根因分析: **图结构**: Load_0 → Broadcast_0 ─┬→ Abs_0 → Cast_0 ──┐ └→ Cast_1 → Relu_0 ──┤→ Add_0(merge) ─┬→ Sigmoid_0 → Store_0 └→ Sqrt_0 → Store_1 **触发路径**: 1. **多引用后移触发**:CollectCandidateMultiRefNodes(L897)选中 Broadcast_0(单输出锚点、2 个消费者、类型是 Broadcast)。 2. **分支汇聚判定通过**:CheckAllBranchesCanBackward(L978)从 Abs0 和 Cast1 分别 trace,两条分支都在 Add0 处汇聚(Add0 是多输入→merge),first_merge_node == current_merge_node == Add_0 → 返回 true。 3. **执行后移**:BackwardMultiRefBroadcast(L1066)调用 MoveBroadcastAfterMerge(L1045)。 **Bug**:GE 侧 MoveBroadcastAfterMerge 只处理了 merge 的第一个消费者: cpp // GE broadcast_backward_pass.cpp:1094 auto merge_next_in_anchor = merge_out_anchor->GetPeerInDataAnchors().at(0); // 只取 Sigmoid_0 GE_ASSERT_GRAPH_SUCCESS(GraphUtils::RemoveEdge(merge_out_anchor, merge_next_in_anchor)); // Add_0 → Broadcast_0 → Sigmoid_0 ✓ // Add_0 → Sqrt_0(仍然直连) ✗ 没有被处理 Add_0 有两个消费者 Sigmoid_0 和 Sqrt_0,但 GetPeerInDataAnchors().at(0) 只取了第一个(Sigmoid_0)。Sqrt0 仍然直接连在 Add0 上。 4. **属性更新导致不一致**:UpdateComputeNodesAscTensorAttr(L706)把 Add_0 的输出 attr 更新为 Load0 的 attr(z1 维 repeat=1,广播前)。Sqrt0 的输入继承 Add0 的新输出 attr(repeat=1),但 Sqrt0 的输出 attr 仍保持原来的 repeat=18 → codegen 校验失败: ``` Node Sqrt: input tensor 0 vectoriz See merge request: cann/graph-autofusion!2059 | 14 天前 | |
【PR】feat: broadcast backward Co-authored-by: czways<chengzhiwei5@huawei.com> # message auto-generated for no-merge-commit merge: !2059 merge revert-mr-2023-1789107028331-auto into develop 【PR】feat: broadcast backward Created-by: czways Commit-by: czways Merged-by: cann-robot Description: # Pull Request broadcast backward ## 描述 请清晰准确地描述本次 Pull Request 的意图和变更内容。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [x] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 描述测试此变更的步骤和前提条件: 1. 2. ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 在此添加任何其他关于本次 PR 的说明。 # BroadcastBackwardPass:GE 侧与 graph-autofusion PR 侧对比分析 ## 简介 ### 目的 本文档对比 GE 仓库与 graph-autofusion PR #2059 中 broadcast_backward_pass 的实现差异与相同之处,为代码审查、后续维护和跨仓库同步提供参考。 > **版本说明**:PR #2059(head 0ae756e6)是 BroadcastBackwardPass 落地 graph-autofusion 的**最终完整版实现**,覆盖早期的 PR #1830 及后续修复(IndirectLoad 下游防护、pass 注册顺序调整、UT/ST 测试框架)。本文所有 PR 侧行号均以 PR #2059 为准。 ### 范围 - **GE 侧**:ge_0728/compiler/graph/optimize/autofuse/autofuse/post_process/pass/broadcast_backward_pass.cpp(1515 行)。该文件已从 ge_0728 工作树删除(git status 显示 D,pass 调用在 asc_graph_pass.cpp:21 处注释停用),本文 GE 侧行号基于删除前最后一个完整版本(commit 97f8a3246)。 - **PR 侧(PR #2059)**: - graph-autofusion/autofuse/optimize/graph_pass/broadcast_backward_pass.cpp(1477 行) - graph-autofusion/autofuse/optimize/graph_pass/broadcast_backward_pass.h(24 行) - graph-autofusion/autofuse/optimize/graph_pass/broadcast_backward_shared_split.cpp(388 行) - graph-autofusion/autofuse/optimize/graph_pass/broadcast_backward_shared_split.h(20 行) - graph-autofusion/autofuse/optimize/platform/v1/pass_runner_v1.h + v35/optimize/pass_runner_v2.h(pass 注册顺序调整) - 测试框架:tests/framework/broadcast_backward/(broadcast_backward_test_utils.h 99 行 + broadcast_backward_ut_utils.h 378 行)、UT tests/ut/optimize/test_broadcast_backward_pass.cpp(1955 行,73 个用例)、ST tests/st/optimize/test_broadcast_backward_pass.cpp(132 行,8 个用例) - 仅覆盖 Broadcast 后移 pass 本身及其注册,不含 optimize.cpp 重构、frontend_shape_vars 移除等 PR 中的其他变更。 ## 总体概述 PR 侧本质上是 GE 侧的**移植 + 增强**: 1. 去掉 asc_adapt:: 适配层,直接使用 af::GraphUtils、af::NodeUtils、ScheduleUtils:: 原生接口。 2. 移除 topo id 管理(约 190 行),改为 pass 入口和结尾统一 TopologicalSorting。 3. 新增 broadcast_backward_shared_split 预处理模块(388 行)。 4. 重写 GetBroAxisFromNode 轴匹配逻辑,支持 axis 不对齐和隐式广播维度。 5. CheckBackwardCommon 新增控制边、IndirectLoadBoundary、RemovePad 三个屏障。 6. MoveBroadcastAfterMerge 支持多后继。 7. CollectBroNodes 新增控制边检查,ProcessOriginalBackwardLogic 新增起点去重。 8. **(最终版新增)IndirectLoad 下游防护**:ChainReachesIndirectLoad 全下游可达性 DFS + HasMultipleInputsBroadcastBehind 兄弟 broadcast 检测,在两个改写入口整体拒绝到达 IndirectLoad 的链路。 9. **(最终版新增)pass 注册顺序**:BroadcastBackwardPass 注册进 V1/V2 两个 pass runner,CSE 类 pass(DuplicateElewiseCse、SameSourceBroadcastCse)调整到其之前执行。 10. **(最终版新增)独立测试框架**:graph builder 工具 + 73 个 UT 用例 + 8 个 ST 用例。 ## 差异分析 ### 一、架构层差异(适配层不同) | 维度 | GE 侧 | PR 侧 | |------|-------|-------| | 命名空间 | namespace ge | namespace optimize | | 图操作封装 | 全部通过 asc_adapt:: 适配层(GetPeerInNodes、GetPeerOutNode、IsSingleInAndOutNode、GetOutputTensorAttr、CreateBroadcastNode 等 20+ 函数) | 直接使用 af::GraphUtils、af::NodeUtils、ScheduleUtils:: 原生接口,无中间层 | | 节点类型 | ge::NodePtr 直接使用 | af::NodePtr 基类指针,需 ToAscNode() 向下转型 std::dynamic_pointer_cast<AscNode> | | 类型常量 | kTransposeType、kBroadcastType 等全局宏 | Transpose::Type、Broadcast::Type 等类静态成员 | | 数据类型 | DataType(GE 命名空间) | af::DataType | | 接口入口 | Run(ComputeGraphPtr) → asc_adapt::ProcessAscBackendNodes 遍历 | RunPass(AscGraph &) 直接操作(broadcast_backward_pass.cpp:1471) | **原因分析**: - **命名空间**:graph-autofusion 是独立组件,不属于 GE 命名空间,使用自己的 optimize 命名空间隔离代码。 - **图操作封装**:GE 侧 AscGraph 是 GE ComputeGraph 的子图,节点操作需通过 asc_adapt:: 适配层桥接两种图模型;graph-autofusion 中 AscGraph 是原生图结构,直接调用 af::GraphUtils 即可,无需中间层。 - **节点类型**:GE 侧节点类型统一在 ge::Node 下;graph-autofusion 中 af::NodePtr 是基类指针,AscNode 是携带 tensor attr 的派生类,需 dynamic_pointer_cast 转型后才能访问 outputs[i].attr 等扩展字段。 - **类型常量**:graph-autofusion 使用 ASCIR op 定义体系,类型常量绑定在 op 类上(如 Broadcast::Type),比全局宏更符合面向对象设计且避免命名冲突。 - **接口入口**:GE 侧 pass 注册在 ComputeGraph 层级,需通过 ProcessAscBackendNodes 遍历找到 AscBackend 子图再执行;graph-autofusion 的 pass runner 直接在 AscGraph 层级注册和调用,无需遍历。 ### 二、PR 侧新增功能(GE 侧没有) #### 1. broadcast_backward_shared_split 模块(388 行,全新) PR 侧在 BroadcastBackward 入口最先调用: cpp GE_ASSERT_SUCCESS(broadcast_backward_shared_split::SplitSharedBroadcastBranches(graph)); GE_ASSERT_SUCCESS(broadcast_backward_shared_split::SplitSharedBroadcastConsumers(graph)); 功能:在执行后移前,先**克隆拆分**共享同一条 Broadcast 链的多分支/多消费者场景,避免改写时边冲突。GE 侧无此预处理步骤,直接在原图上改写。 **原因分析**: graph-autofusion 的图结构中,一条 Broadcast 链的输出可能同时被多个分支或多个消费者引用。如果不先拆分,后移时 ReorderBroadcasts 需要断开 Broadcast 输出边,但该边连接了多个消费者,无法同时断开所有边,会导致改写失败或图结构损坏。通过预处理阶段克隆 Broadcast 链,使每个分支/消费者拥有独立的 Broadcast 副本,后续后移可以独立操作每条链。GE 侧可能这类共享场景较少,或通过其他 pass 在更早阶段已经拆分。 **根本原因:GE 融合反推机制不可移植到 AF** GE 的 Broadcast 处理与子图融合深度绑定,采用 **"消除 → 融合 → 恢复"** 三段式流程: GE: UpdateBroadcastInfoToLoad(消除Brc,写入Load) → MergeAscGraphByLoop(融合两个子图) → OptimizedFallback(从Load读出,按消费者重建Brc) - **融合前**(UpdateBroadcastBeforeMerge):沿 Load → Broadcast 路径,把广播轴信息"折叠"进 Load 输出属性(repeats[i]=1, strides[i]=0),然后删除 Brc 节点。目的是让不同子图在融合前统一布局。 - **融合**(MergeAscGraphByLoop):按循环轴合并两个 AscGraph。 - **融合后**(OptimizedFallback):遍历融合后图中每个计算节点的每个输入,从 Load 属性和图级 AscGraphAttr 倒推 broadcast_info,按消费者实际需求重新插入 Brc。 OptimizedFallback 的核心是 **从消费者需求倒推**(bottom-up):对每个消费者输入,比较消费者所需布局 vs Load 当前布局,差异轴即为 broadcast_info,若非空则在消费者输入前新建 Brc。一个共享源有多个消费者时,每个消费者独立判断需要哪些广播轴,只插需要的轴,不产生冗余: 原始: P → B{A,B} → C0(需要轴A) P → B{A,B} → C1(需要轴B) GE 重建:P → B0{A} → C0 P → B1{B} → C1 GE 这一机制依赖大量 GE 特有结构: | GE 反推机制 | 依赖的 GE 特有结构 | |-------------|---------------------| | UpdateBroadcastInfoToLoad | AscBackendSubGraphFusionDecider、MergeAscGraphByLoop、NodeFuseInfo、ViewOpAttrInfo | | TuningSubgraphBeforeMerge | 融合决策器、AscGraphAxisMapping | | OptimizedFallbackPro | 融合后 AscGraphAttr、AutoFuseAttrs、FusedAscBackend 节点、ProcessAscBackendNodes | 这些结构在 AF 中均不存在。AF 不走子图融合路径,直接在单个 AscGraph 上做图优化和 codegen。因此 GE 的融合反推机制 **不可移植到 AF**。 当前 GE 侧的 BroadcastBackwardPass 已被注释停用(asc_graph_pass.cpp:21)且源文件已从 ge_0728 工作树删除,AF PR #2059 是在 AF 侧重新实现,替代 GE 侧旧实现。broadcast_backward_shared_split 正是为了弥补 GE 融合反推机制缺失后的共享链场景处理:GE 通过融合后 OptimizedFallback 按消费者需求精确重建 Brc,AF 无法走这条路径,只能在融合前先把共享 Brc 链拆分为独立副本,再逐条执行后移。 #### 2. CheckBackwardCommon 新增三个屏障 PR 侧 broadcast_backward_pass.cpp:484-509: cpp if (!HasNoControlEdges(next_node)) { return false; } // 控制边屏障 L485-487 if (next_node->GetType() == kStoreType) { return false; } if (IsIndirectLoadBoundary(next_node)) { return false; } // IndirectLoad 边界屏障(增强)L493-495 if (ScheduleUtils::IsRemovePad(next_node)) { return false; } if (IsNextViewOp(next_node)) { return false; } if (IsDtypeNotSupportOp(next_node, output_dtype)) { return false; } 注意:最终版 CheckBackwardCommon 签名为 bool CheckBackwardCommon(const NodePtr &next_node),output_dtype 在函数内部声明,不再通过参数外传。 GE 侧(L308-325)只检查 Store、ViewOp、DtypeNotSupport 三种,无控制边和 IndirectLoad/RemovePad 屏障。PR 侧额外屏蔽以下三类: | 屏障 | PR 实现 | 说明 | |------|---------|------| | HasNoControlEdges | L485-487 | 节点存在控制边时不后移,避免控制依赖被破坏 | | IsIndirectLoadBoundary | L493-495(实现 L146-162) | 不仅检查 next_node 本身是 IndirectLoad,还检查 next_node 的输出是否喂给 IndirectLoad(遍历所有输出锚点的 peer in 节点) | | IsRemovePad | L496-498 | padding 逆操作边界 | **原因分析**: - **控制边屏障**:graph-autofusion 的 AscGraph 允许计算节点之间存在控制依赖边。Broadcast 后移会断开并重连数据边,如果节点同时有控制边,后移后控制依赖的语义可能不再成立。GE 侧的 asc_adapt:: 适配层在 IsSingleInAndOutNode 中隐含了控制边检查(GE 的 AscGraph 不允许控制边出现在 Brc 链中),PR 侧显式检查更清晰。 - **IndirectLoad 边界(增强)**:IsIndirectLoadBoundary(L146-162)不仅判断 next_node 自身是否为 IndirectLoad,还遍历 next_node 的所有输出锚点,检查是否有 peer in 节点是 IndirectLoad。注释说明:"直接喂给 IndirectLoad 的 compute 同样不能后移,否则 broadcast 会紧贴 IL"。IndirectLoad 的输出轴属于独立的物理视图(通过索引间接加载,轴语义与普通 Load 不同),Broadcast 后移跨过此边界会破坏轴对应关系。GE 侧不存在此算子类型。 - **RemovePad**:该算子涉及 padding 的逆操作,Broadcast 后移跨过此边界会导致 padding 区域的广播语义不一致。GE 侧不存在此算子类型。 这三个屏障是 graph-autofusion 特有图结构和算子语义决定的,不是通用优化,无法回传 GE 侧。 #### 3. MoveBroadcastAfterMerge 支持多后继 | | GE 侧 L1089-1108 | PR 侧 L1045-1064 | |---|---|---| | merge 后继 | 只处理 at(0) 单个后继 | 复制 GetPeerInDataAnchors() 全部后继,逐个断开、逐个重连 | PR 侧支持 merge_node 输出连接到多个下游节点,GE 侧只处理单后继。 **原因分析**: graph-autofusion 的图结构允许 merge 节点(如 Add)输出后继续 fork 到多个下游分支(fork-join-fork 模式),这在融合图中较常见。GE 侧假设 merge 后只有单后继,这在 GE 的图结构中成立(GE 的融合图通常在 merge 后接 Store)。如果 merge 有多个后继,GE 侧只重连第一个后继会导致其他后继丢失数据边,造成图改写不等价。 **根因定位:GE 侧 MoveBroadcastAfterMerge 的 Bug** PR 侧支持多后继的直接原因是修复了从 GE 移植时发现的 MoveBroadcastAfterMerge Bug。以下是根因分析: **图结构**: Load_0 → Broadcast_0 ─┬→ Abs_0 → Cast_0 ──┐ └→ Cast_1 → Relu_0 ──┤→ Add_0(merge) ─┬→ Sigmoid_0 → Store_0 └→ Sqrt_0 → Store_1 **触发路径**: 1. **多引用后移触发**:CollectCandidateMultiRefNodes(L897)选中 Broadcast_0(单输出锚点、2 个消费者、类型是 Broadcast)。 2. **分支汇聚判定通过**:CheckAllBranchesCanBackward(L978)从 Abs0 和 Cast1 分别 trace,两条分支都在 Add0 处汇聚(Add0 是多输入→merge),first_merge_node == current_merge_node == Add_0 → 返回 true。 3. **执行后移**:BackwardMultiRefBroadcast(L1066)调用 MoveBroadcastAfterMerge(L1045)。 **Bug**:GE 侧 MoveBroadcastAfterMerge 只处理了 merge 的第一个消费者: cpp // GE broadcast_backward_pass.cpp:1094 auto merge_next_in_anchor = merge_out_anchor->GetPeerInDataAnchors().at(0); // 只取 Sigmoid_0 GE_ASSERT_GRAPH_SUCCESS(GraphUtils::RemoveEdge(merge_out_anchor, merge_next_in_anchor)); // Add_0 → Broadcast_0 → Sigmoid_0 ✓ // Add_0 → Sqrt_0(仍然直连) ✗ 没有被处理 Add_0 有两个消费者 Sigmoid_0 和 Sqrt_0,但 GetPeerInDataAnchors().at(0) 只取了第一个(Sigmoid_0)。Sqrt0 仍然直接连在 Add0 上。 4. **属性更新导致不一致**:UpdateComputeNodesAscTensorAttr(L706)把 Add_0 的输出 attr 更新为 Load0 的 attr(z1 维 repeat=1,广播前)。Sqrt0 的输入继承 Add0 的新输出 attr(repeat=1),但 Sqrt0 的输出 attr 仍保持原来的 repeat=18 → codegen 校验失败: ``` Node Sqrt: input tensor 0 vectoriz See merge request: cann/graph-autofusion!2059 | 14 天前 | |
【PR】feat: broadcast backward Co-authored-by: czways<chengzhiwei5@huawei.com> # message auto-generated for no-merge-commit merge: !2059 merge revert-mr-2023-1789107028331-auto into develop 【PR】feat: broadcast backward Created-by: czways Commit-by: czways Merged-by: cann-robot Description: # Pull Request broadcast backward ## 描述 请清晰准确地描述本次 Pull Request 的意图和变更内容。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [x] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 描述测试此变更的步骤和前提条件: 1. 2. ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 在此添加任何其他关于本次 PR 的说明。 # BroadcastBackwardPass:GE 侧与 graph-autofusion PR 侧对比分析 ## 简介 ### 目的 本文档对比 GE 仓库与 graph-autofusion PR #2059 中 broadcast_backward_pass 的实现差异与相同之处,为代码审查、后续维护和跨仓库同步提供参考。 > **版本说明**:PR #2059(head 0ae756e6)是 BroadcastBackwardPass 落地 graph-autofusion 的**最终完整版实现**,覆盖早期的 PR #1830 及后续修复(IndirectLoad 下游防护、pass 注册顺序调整、UT/ST 测试框架)。本文所有 PR 侧行号均以 PR #2059 为准。 ### 范围 - **GE 侧**:ge_0728/compiler/graph/optimize/autofuse/autofuse/post_process/pass/broadcast_backward_pass.cpp(1515 行)。该文件已从 ge_0728 工作树删除(git status 显示 D,pass 调用在 asc_graph_pass.cpp:21 处注释停用),本文 GE 侧行号基于删除前最后一个完整版本(commit 97f8a3246)。 - **PR 侧(PR #2059)**: - graph-autofusion/autofuse/optimize/graph_pass/broadcast_backward_pass.cpp(1477 行) - graph-autofusion/autofuse/optimize/graph_pass/broadcast_backward_pass.h(24 行) - graph-autofusion/autofuse/optimize/graph_pass/broadcast_backward_shared_split.cpp(388 行) - graph-autofusion/autofuse/optimize/graph_pass/broadcast_backward_shared_split.h(20 行) - graph-autofusion/autofuse/optimize/platform/v1/pass_runner_v1.h + v35/optimize/pass_runner_v2.h(pass 注册顺序调整) - 测试框架:tests/framework/broadcast_backward/(broadcast_backward_test_utils.h 99 行 + broadcast_backward_ut_utils.h 378 行)、UT tests/ut/optimize/test_broadcast_backward_pass.cpp(1955 行,73 个用例)、ST tests/st/optimize/test_broadcast_backward_pass.cpp(132 行,8 个用例) - 仅覆盖 Broadcast 后移 pass 本身及其注册,不含 optimize.cpp 重构、frontend_shape_vars 移除等 PR 中的其他变更。 ## 总体概述 PR 侧本质上是 GE 侧的**移植 + 增强**: 1. 去掉 asc_adapt:: 适配层,直接使用 af::GraphUtils、af::NodeUtils、ScheduleUtils:: 原生接口。 2. 移除 topo id 管理(约 190 行),改为 pass 入口和结尾统一 TopologicalSorting。 3. 新增 broadcast_backward_shared_split 预处理模块(388 行)。 4. 重写 GetBroAxisFromNode 轴匹配逻辑,支持 axis 不对齐和隐式广播维度。 5. CheckBackwardCommon 新增控制边、IndirectLoadBoundary、RemovePad 三个屏障。 6. MoveBroadcastAfterMerge 支持多后继。 7. CollectBroNodes 新增控制边检查,ProcessOriginalBackwardLogic 新增起点去重。 8. **(最终版新增)IndirectLoad 下游防护**:ChainReachesIndirectLoad 全下游可达性 DFS + HasMultipleInputsBroadcastBehind 兄弟 broadcast 检测,在两个改写入口整体拒绝到达 IndirectLoad 的链路。 9. **(最终版新增)pass 注册顺序**:BroadcastBackwardPass 注册进 V1/V2 两个 pass runner,CSE 类 pass(DuplicateElewiseCse、SameSourceBroadcastCse)调整到其之前执行。 10. **(最终版新增)独立测试框架**:graph builder 工具 + 73 个 UT 用例 + 8 个 ST 用例。 ## 差异分析 ### 一、架构层差异(适配层不同) | 维度 | GE 侧 | PR 侧 | |------|-------|-------| | 命名空间 | namespace ge | namespace optimize | | 图操作封装 | 全部通过 asc_adapt:: 适配层(GetPeerInNodes、GetPeerOutNode、IsSingleInAndOutNode、GetOutputTensorAttr、CreateBroadcastNode 等 20+ 函数) | 直接使用 af::GraphUtils、af::NodeUtils、ScheduleUtils:: 原生接口,无中间层 | | 节点类型 | ge::NodePtr 直接使用 | af::NodePtr 基类指针,需 ToAscNode() 向下转型 std::dynamic_pointer_cast<AscNode> | | 类型常量 | kTransposeType、kBroadcastType 等全局宏 | Transpose::Type、Broadcast::Type 等类静态成员 | | 数据类型 | DataType(GE 命名空间) | af::DataType | | 接口入口 | Run(ComputeGraphPtr) → asc_adapt::ProcessAscBackendNodes 遍历 | RunPass(AscGraph &) 直接操作(broadcast_backward_pass.cpp:1471) | **原因分析**: - **命名空间**:graph-autofusion 是独立组件,不属于 GE 命名空间,使用自己的 optimize 命名空间隔离代码。 - **图操作封装**:GE 侧 AscGraph 是 GE ComputeGraph 的子图,节点操作需通过 asc_adapt:: 适配层桥接两种图模型;graph-autofusion 中 AscGraph 是原生图结构,直接调用 af::GraphUtils 即可,无需中间层。 - **节点类型**:GE 侧节点类型统一在 ge::Node 下;graph-autofusion 中 af::NodePtr 是基类指针,AscNode 是携带 tensor attr 的派生类,需 dynamic_pointer_cast 转型后才能访问 outputs[i].attr 等扩展字段。 - **类型常量**:graph-autofusion 使用 ASCIR op 定义体系,类型常量绑定在 op 类上(如 Broadcast::Type),比全局宏更符合面向对象设计且避免命名冲突。 - **接口入口**:GE 侧 pass 注册在 ComputeGraph 层级,需通过 ProcessAscBackendNodes 遍历找到 AscBackend 子图再执行;graph-autofusion 的 pass runner 直接在 AscGraph 层级注册和调用,无需遍历。 ### 二、PR 侧新增功能(GE 侧没有) #### 1. broadcast_backward_shared_split 模块(388 行,全新) PR 侧在 BroadcastBackward 入口最先调用: cpp GE_ASSERT_SUCCESS(broadcast_backward_shared_split::SplitSharedBroadcastBranches(graph)); GE_ASSERT_SUCCESS(broadcast_backward_shared_split::SplitSharedBroadcastConsumers(graph)); 功能:在执行后移前,先**克隆拆分**共享同一条 Broadcast 链的多分支/多消费者场景,避免改写时边冲突。GE 侧无此预处理步骤,直接在原图上改写。 **原因分析**: graph-autofusion 的图结构中,一条 Broadcast 链的输出可能同时被多个分支或多个消费者引用。如果不先拆分,后移时 ReorderBroadcasts 需要断开 Broadcast 输出边,但该边连接了多个消费者,无法同时断开所有边,会导致改写失败或图结构损坏。通过预处理阶段克隆 Broadcast 链,使每个分支/消费者拥有独立的 Broadcast 副本,后续后移可以独立操作每条链。GE 侧可能这类共享场景较少,或通过其他 pass 在更早阶段已经拆分。 **根本原因:GE 融合反推机制不可移植到 AF** GE 的 Broadcast 处理与子图融合深度绑定,采用 **"消除 → 融合 → 恢复"** 三段式流程: GE: UpdateBroadcastInfoToLoad(消除Brc,写入Load) → MergeAscGraphByLoop(融合两个子图) → OptimizedFallback(从Load读出,按消费者重建Brc) - **融合前**(UpdateBroadcastBeforeMerge):沿 Load → Broadcast 路径,把广播轴信息"折叠"进 Load 输出属性(repeats[i]=1, strides[i]=0),然后删除 Brc 节点。目的是让不同子图在融合前统一布局。 - **融合**(MergeAscGraphByLoop):按循环轴合并两个 AscGraph。 - **融合后**(OptimizedFallback):遍历融合后图中每个计算节点的每个输入,从 Load 属性和图级 AscGraphAttr 倒推 broadcast_info,按消费者实际需求重新插入 Brc。 OptimizedFallback 的核心是 **从消费者需求倒推**(bottom-up):对每个消费者输入,比较消费者所需布局 vs Load 当前布局,差异轴即为 broadcast_info,若非空则在消费者输入前新建 Brc。一个共享源有多个消费者时,每个消费者独立判断需要哪些广播轴,只插需要的轴,不产生冗余: 原始: P → B{A,B} → C0(需要轴A) P → B{A,B} → C1(需要轴B) GE 重建:P → B0{A} → C0 P → B1{B} → C1 GE 这一机制依赖大量 GE 特有结构: | GE 反推机制 | 依赖的 GE 特有结构 | |-------------|---------------------| | UpdateBroadcastInfoToLoad | AscBackendSubGraphFusionDecider、MergeAscGraphByLoop、NodeFuseInfo、ViewOpAttrInfo | | TuningSubgraphBeforeMerge | 融合决策器、AscGraphAxisMapping | | OptimizedFallbackPro | 融合后 AscGraphAttr、AutoFuseAttrs、FusedAscBackend 节点、ProcessAscBackendNodes | 这些结构在 AF 中均不存在。AF 不走子图融合路径,直接在单个 AscGraph 上做图优化和 codegen。因此 GE 的融合反推机制 **不可移植到 AF**。 当前 GE 侧的 BroadcastBackwardPass 已被注释停用(asc_graph_pass.cpp:21)且源文件已从 ge_0728 工作树删除,AF PR #2059 是在 AF 侧重新实现,替代 GE 侧旧实现。broadcast_backward_shared_split 正是为了弥补 GE 融合反推机制缺失后的共享链场景处理:GE 通过融合后 OptimizedFallback 按消费者需求精确重建 Brc,AF 无法走这条路径,只能在融合前先把共享 Brc 链拆分为独立副本,再逐条执行后移。 #### 2. CheckBackwardCommon 新增三个屏障 PR 侧 broadcast_backward_pass.cpp:484-509: cpp if (!HasNoControlEdges(next_node)) { return false; } // 控制边屏障 L485-487 if (next_node->GetType() == kStoreType) { return false; } if (IsIndirectLoadBoundary(next_node)) { return false; } // IndirectLoad 边界屏障(增强)L493-495 if (ScheduleUtils::IsRemovePad(next_node)) { return false; } if (IsNextViewOp(next_node)) { return false; } if (IsDtypeNotSupportOp(next_node, output_dtype)) { return false; } 注意:最终版 CheckBackwardCommon 签名为 bool CheckBackwardCommon(const NodePtr &next_node),output_dtype 在函数内部声明,不再通过参数外传。 GE 侧(L308-325)只检查 Store、ViewOp、DtypeNotSupport 三种,无控制边和 IndirectLoad/RemovePad 屏障。PR 侧额外屏蔽以下三类: | 屏障 | PR 实现 | 说明 | |------|---------|------| | HasNoControlEdges | L485-487 | 节点存在控制边时不后移,避免控制依赖被破坏 | | IsIndirectLoadBoundary | L493-495(实现 L146-162) | 不仅检查 next_node 本身是 IndirectLoad,还检查 next_node 的输出是否喂给 IndirectLoad(遍历所有输出锚点的 peer in 节点) | | IsRemovePad | L496-498 | padding 逆操作边界 | **原因分析**: - **控制边屏障**:graph-autofusion 的 AscGraph 允许计算节点之间存在控制依赖边。Broadcast 后移会断开并重连数据边,如果节点同时有控制边,后移后控制依赖的语义可能不再成立。GE 侧的 asc_adapt:: 适配层在 IsSingleInAndOutNode 中隐含了控制边检查(GE 的 AscGraph 不允许控制边出现在 Brc 链中),PR 侧显式检查更清晰。 - **IndirectLoad 边界(增强)**:IsIndirectLoadBoundary(L146-162)不仅判断 next_node 自身是否为 IndirectLoad,还遍历 next_node 的所有输出锚点,检查是否有 peer in 节点是 IndirectLoad。注释说明:"直接喂给 IndirectLoad 的 compute 同样不能后移,否则 broadcast 会紧贴 IL"。IndirectLoad 的输出轴属于独立的物理视图(通过索引间接加载,轴语义与普通 Load 不同),Broadcast 后移跨过此边界会破坏轴对应关系。GE 侧不存在此算子类型。 - **RemovePad**:该算子涉及 padding 的逆操作,Broadcast 后移跨过此边界会导致 padding 区域的广播语义不一致。GE 侧不存在此算子类型。 这三个屏障是 graph-autofusion 特有图结构和算子语义决定的,不是通用优化,无法回传 GE 侧。 #### 3. MoveBroadcastAfterMerge 支持多后继 | | GE 侧 L1089-1108 | PR 侧 L1045-1064 | |---|---|---| | merge 后继 | 只处理 at(0) 单个后继 | 复制 GetPeerInDataAnchors() 全部后继,逐个断开、逐个重连 | PR 侧支持 merge_node 输出连接到多个下游节点,GE 侧只处理单后继。 **原因分析**: graph-autofusion 的图结构允许 merge 节点(如 Add)输出后继续 fork 到多个下游分支(fork-join-fork 模式),这在融合图中较常见。GE 侧假设 merge 后只有单后继,这在 GE 的图结构中成立(GE 的融合图通常在 merge 后接 Store)。如果 merge 有多个后继,GE 侧只重连第一个后继会导致其他后继丢失数据边,造成图改写不等价。 **根因定位:GE 侧 MoveBroadcastAfterMerge 的 Bug** PR 侧支持多后继的直接原因是修复了从 GE 移植时发现的 MoveBroadcastAfterMerge Bug。以下是根因分析: **图结构**: Load_0 → Broadcast_0 ─┬→ Abs_0 → Cast_0 ──┐ └→ Cast_1 → Relu_0 ──┤→ Add_0(merge) ─┬→ Sigmoid_0 → Store_0 └→ Sqrt_0 → Store_1 **触发路径**: 1. **多引用后移触发**:CollectCandidateMultiRefNodes(L897)选中 Broadcast_0(单输出锚点、2 个消费者、类型是 Broadcast)。 2. **分支汇聚判定通过**:CheckAllBranchesCanBackward(L978)从 Abs0 和 Cast1 分别 trace,两条分支都在 Add0 处汇聚(Add0 是多输入→merge),first_merge_node == current_merge_node == Add_0 → 返回 true。 3. **执行后移**:BackwardMultiRefBroadcast(L1066)调用 MoveBroadcastAfterMerge(L1045)。 **Bug**:GE 侧 MoveBroadcastAfterMerge 只处理了 merge 的第一个消费者: cpp // GE broadcast_backward_pass.cpp:1094 auto merge_next_in_anchor = merge_out_anchor->GetPeerInDataAnchors().at(0); // 只取 Sigmoid_0 GE_ASSERT_GRAPH_SUCCESS(GraphUtils::RemoveEdge(merge_out_anchor, merge_next_in_anchor)); // Add_0 → Broadcast_0 → Sigmoid_0 ✓ // Add_0 → Sqrt_0(仍然直连) ✗ 没有被处理 Add_0 有两个消费者 Sigmoid_0 和 Sqrt_0,但 GetPeerInDataAnchors().at(0) 只取了第一个(Sigmoid_0)。Sqrt0 仍然直接连在 Add0 上。 4. **属性更新导致不一致**:UpdateComputeNodesAscTensorAttr(L706)把 Add_0 的输出 attr 更新为 Load0 的 attr(z1 维 repeat=1,广播前)。Sqrt0 的输入继承 Add0 的新输出 attr(repeat=1),但 Sqrt0 的输出 attr 仍保持原来的 repeat=18 → codegen 校验失败: ``` Node Sqrt: input tensor 0 vectoriz See merge request: cann/graph-autofusion!2059 | 14 天前 | |
【PR】: [fix] [autofuse] adapt reform of the same-named header files of ge. Co-authored-by: xingzhixiong<xingzhixiong@huawei.com> # message auto-generated for no-merge-commit merge: !1149 merge develop_change_dir_of_metadef_headers into develop 【PR】: [fix] [autofuse] adapt reform of the same-named header files of ge. Created-by: xingzhixiong Commit-by: xingzhixiong Merged-by: cann-robot Description: # Pull Request ## 描述 metadef在做同名头文件整改,整改完编译发现gaf失败,原因是gaf仓和ge仓也有同名且子目录相同的头文件,故需要将gaf仓的同名头文件的子目录进行整改,只给gaf仓内部使用,避免产生耦合编译问题。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [ ] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [x] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 描述测试此变更的步骤和前提条件: 1. ci流水线pass 2. RDV pass ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 在此添加任何其他关于本次 PR 的说明。 See merge request: cann/graph-autofusion!1149 | 2 个月前 | |
style: 统一 Autofuse 代码格式 Co-authored-by: Ling-DT<lingxing@huawei.com> # message auto-generated for no-merge-commit merge: !921 merge style/clang-format-autofuse-20260611 into develop style: 统一 Autofuse 代码格式 Created-by: ling-DT Commit-by: Ling-DT Merged-by: cann-robot Description: # Pull Request ## 描述 基于 cann/graph-autofusion:develop 最新提交 46a23b0,使用仓库根目录 .clang-format 对 autofuse/ 目录内受版本管理的 C/C++/AscendC 源文件执行统一格式化。 本 PR 仅包含 autofuse/ 目录格式化变更;super_kernel/ 目录格式化变更按要求暂留本地,未提交到本 PR。 格式化工具:clang-format 18.1.8,参数:--style=file。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [ ] ✨ 新功能 - [x] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue 无。 ## 如何测试 描述测试此变更的步骤和前提条件: 1. /tmp/opencode/clang-format-18-venv/bin/clang-format -i --style=file <autofuse C/C++/AscendC files> 2. git diff --cached --check 3. git diff --name-only HEAD~1..HEAD | cut -d/ -f1 | sort | uniq -c 确认 PR 提交仅包含 autofuse/。 ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如:feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 本 PR 为纯格式化变更,不涉及功能逻辑、接口、构建脚本或打包内容修改。 See merge request: cann/graph-autofusion!921 | 3 个月前 | |
【feature】: 修改升精度流程:Transpose节点不参与升精度 Co-authored-by: 李玥玮<liyuewei1@huawei.com> # message auto-generated for no-merge-commit merge: !2027 merge 0_local into develop 【feature】: 修改升精度流程:Transpose节点不参与升精度 Created-by: liyuewei Commit-by: 李玥玮 Merged-by: cann-robot Description: # Pull Request ## 描述 1、修改升精度流程:Transpose节点不参与升精度。 2、进一步扩展Transpose融合使用Compact模式的场景。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [x] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 描述测试此变更的步骤和前提条件: NA ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 在此添加任何其他关于本次 PR 的说明。 See merge request: cann/graph-autofusion!2027 | 15 天前 | |
【feature】: 修改升精度流程:Transpose节点不参与升精度 Co-authored-by: 李玥玮<liyuewei1@huawei.com> # message auto-generated for no-merge-commit merge: !2027 merge 0_local into develop 【feature】: 修改升精度流程:Transpose节点不参与升精度 Created-by: liyuewei Commit-by: 李玥玮 Merged-by: cann-robot Description: # Pull Request ## 描述 1、修改升精度流程:Transpose节点不参与升精度。 2、进一步扩展Transpose融合使用Compact模式的场景。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [x] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 描述测试此变更的步骤和前提条件: NA ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 在此添加任何其他关于本次 PR 的说明。 See merge request: cann/graph-autofusion!2027 | 15 天前 | |
【feat】: 支持norm融合R轴分tile Co-authored-by: wang-yan-male<wangyan220@huawei.com> # message auto-generated for no-merge-commit merge: !1626 merge develop into develop 【feat】: 支持norm融合R轴分tile Created-by: WangYanMale Commit-by: wang-yan-male Merged-by: cann-robot Description: # Pull Request ## 描述 1、norm类也生成双切分模板; 2、增加重复sub消除pass; 3、后移softmax pattern pass。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [x] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 1、inductor的norm算子开启自动融合,观察生成模板; 2、layernorm算子开启自动融合,观察pass前后是否存在重复的sub节点(输入一样); 3、softmax开启自动融合,观察是否是全载模板,模板里直接调用softmax api。 ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [ ] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 NA See merge request: cann/graph-autofusion!1626 | 1 个月前 | |
【feat】: 支持norm融合R轴分tile Co-authored-by: wang-yan-male<wangyan220@huawei.com> # message auto-generated for no-merge-commit merge: !1626 merge develop into develop 【feat】: 支持norm融合R轴分tile Created-by: WangYanMale Commit-by: wang-yan-male Merged-by: cann-robot Description: # Pull Request ## 描述 1、norm类也生成双切分模板; 2、增加重复sub消除pass; 3、后移softmax pattern pass。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [x] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 1、inductor的norm算子开启自动融合,观察生成模板; 2、layernorm算子开启自动融合,观察pass前后是否存在重复的sub节点(输入一样); 3、softmax开启自动融合,观察是否是全载模板,模板里直接调用softmax api。 ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [ ] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 NA See merge request: cann/graph-autofusion!1626 | 1 个月前 | |
【PR】: AF日志易用性整改 Co-authored-by: s00357600sgd<shenguodong1@huawei.com> # message auto-generated for no-merge-commit merge: !1864 merge autofusion_log_daily_develop into develop 【PR】: AF日志易用性整改 Created-by: s003576sgd Commit-by: s00357600sgd Merged-by: cann-robot Description: # Pull Request ## 描述 整改工具扫描的日志中存在的拼写错误、中文、缺少度量单位等低级问题,并排查类似问题统一修改 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [x] 🐛 Bug 修复 - [ ] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 描述测试此变更的步骤和前提条件: 1. 2. ## 核对清单 <!-- [x] 表示选中 --> - [ ] 我的代码遵循了项目的代码风格 - [ ] 我已对代码进行了自测 - [ ] 我已更新了相关的文档 - [ ] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [ ] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 在此添加任何其他关于本次 PR 的说明。 See merge request: cann/graph-autofusion!1864 | 27 天前 | |
style: 统一 Autofuse 代码格式 Co-authored-by: Ling-DT<lingxing@huawei.com> # message auto-generated for no-merge-commit merge: !921 merge style/clang-format-autofuse-20260611 into develop style: 统一 Autofuse 代码格式 Created-by: ling-DT Commit-by: Ling-DT Merged-by: cann-robot Description: # Pull Request ## 描述 基于 cann/graph-autofusion:develop 最新提交 46a23b0,使用仓库根目录 .clang-format 对 autofuse/ 目录内受版本管理的 C/C++/AscendC 源文件执行统一格式化。 本 PR 仅包含 autofuse/ 目录格式化变更;super_kernel/ 目录格式化变更按要求暂留本地,未提交到本 PR。 格式化工具:clang-format 18.1.8,参数:--style=file。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [ ] ✨ 新功能 - [x] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue 无。 ## 如何测试 描述测试此变更的步骤和前提条件: 1. /tmp/opencode/clang-format-18-venv/bin/clang-format -i --style=file <autofuse C/C++/AscendC files> 2. git diff --cached --check 3. git diff --name-only HEAD~1..HEAD | cut -d/ -f1 | sort | uniq -c 确认 PR 提交仅包含 autofuse/。 ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如:feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 本 PR 为纯格式化变更,不涉及功能逻辑、接口、构建脚本或打包内容修改。 See merge request: cann/graph-autofusion!921 | 3 个月前 | |
【PR】: [fix] [autofuse] adapt reform of the same-named header files of ge. Co-authored-by: xingzhixiong<xingzhixiong@huawei.com> # message auto-generated for no-merge-commit merge: !1149 merge develop_change_dir_of_metadef_headers into develop 【PR】: [fix] [autofuse] adapt reform of the same-named header files of ge. Created-by: xingzhixiong Commit-by: xingzhixiong Merged-by: cann-robot Description: # Pull Request ## 描述 metadef在做同名头文件整改,整改完编译发现gaf失败,原因是gaf仓和ge仓也有同名且子目录相同的头文件,故需要将gaf仓的同名头文件的子目录进行整改,只给gaf仓内部使用,避免产生耦合编译问题。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [ ] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [x] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 描述测试此变更的步骤和前提条件: 1. ci流水线pass 2. RDV pass ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 在此添加任何其他关于本次 PR 的说明。 See merge request: cann/graph-autofusion!1149 | 2 个月前 | |
feat: 支持 IsInf 和 MaskedFill elementwise 算子自动融合(#51) Co-authored-by: Jett_Woo<wujinteng1@huawei.com> # message auto-generated for no-merge-commit merge: !1000 merge feature/isinf-maskedfill-v3 into develop feat: 支持 IsInf 和 MaskedFill elementwise 算子自动融合(#51) Created-by: Jett_Woo Commit-by: Jett_Woo Merged-by: cann-robot Description: ## 描述 本 PR 为 graph-autofusion 项目添加 IsInf 和 MaskedFill 两个 elementwise 算子的自动融合支持,解决 Issue #51。 ### 主要变更 1. **IsInf 算子支持** - V1 实现:自定义位运算算法(参照 IsNan 实现) - V2 实现:复用 CANN SDK adv_api/math/is_inf.h - 支持 FP16、FP32(V1/V2),BF16(仅 V2) 2. **MaskedFill 算子支持** - 复用 Select 算子的 WhereApiCall 代码生成 - 新增 MaskedFillInputReorderPass 图优化 Pass - 输入重排:(x, mask, value) → (mask, value, x) - 支持 scalar value 和 tensor value 3. **自动融合** - 实现 IsInf + LogicalOr + MaskedFill 的自动融合 - 生成单个 AscBackend kernel,提升性能 ### 修复内容 相比 PR #624,本 PR 修复了以下问题: 1. **Split 算子注册错误**:恢复 REG_ASC_IR(Split) 使用正确的 SplitAscIrAttImplV2 / SplitAscIrCodegenImplV2 实现 2. **Select 算子注册缺失**:补回独立的 REG_ASC_IR(Select) 注册 3. **魔鬼数字**:在 masked_fill_input_reorder_pass.cpp 中使用命名常量替代硬编码数字 ## 变更类型 - [x] ✨ 新功能 - [x] 🐛 Bug 修复(修复 PR #624 引入的回归问题) ## 关联的 Issue Closes #51 ## 如何测试 1. 编译通过:sh build.sh --pkg -j 8 2. 单元测试通过: bash sh build.sh -u --module=autofuse_framework -j 8 ./build/autofuse/tests/ut/ascir/reg_func/test_reg_func_is_inf ./build/autofuse/tests/ut/ascir/reg_func/test_reg_func_masked_fill ./build/autofuse/tests/ut/optimize/test_masked_fill_input_reorder_pass 3. 集成测试通过: bash sh build.sh -s --module=autofuse_e2e -j 8 4. CI 流水线全部通过 5. 包含 Split 算子的融合场景(如 SASRec 模型)不再报错 ## 核对清单 - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档(设计文档已添加 UML 建模和 4+1 视图) - [x] 我在标题中使用了合适的类型标签(feat:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定 ## 其他信息 ### 文件变更统计 - 新增文件:14 个 - 修改文件:22 个 - 总计:36 个文件变更 ### 关键设计决策 1. **IsInf V1 实现**:使用位运算算法,不依赖 CANN SDK 版本 2. **MaskedFill 实现**:通过 GraphPass 将节点类型转换为 Select,完全复用 Select 的 codegen 逻辑 3. **输入重排**:在 GraphPass 阶段统一处理,确保 dtype schema 正确同步 ### 设计文档 见issue [#51](https://gitcode.com/cann/graph-autofusion/issues/51) See merge request: cann/graph-autofusion!1000 | 3 个月前 | |
style: 统一 Autofuse 代码格式 Co-authored-by: Ling-DT<lingxing@huawei.com> # message auto-generated for no-merge-commit merge: !921 merge style/clang-format-autofuse-20260611 into develop style: 统一 Autofuse 代码格式 Created-by: ling-DT Commit-by: Ling-DT Merged-by: cann-robot Description: # Pull Request ## 描述 基于 cann/graph-autofusion:develop 最新提交 46a23b0,使用仓库根目录 .clang-format 对 autofuse/ 目录内受版本管理的 C/C++/AscendC 源文件执行统一格式化。 本 PR 仅包含 autofuse/ 目录格式化变更;super_kernel/ 目录格式化变更按要求暂留本地,未提交到本 PR。 格式化工具:clang-format 18.1.8,参数:--style=file。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [ ] ✨ 新功能 - [x] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue 无。 ## 如何测试 描述测试此变更的步骤和前提条件: 1. /tmp/opencode/clang-format-18-venv/bin/clang-format -i --style=file <autofuse C/C++/AscendC files> 2. git diff --cached --check 3. git diff --name-only HEAD~1..HEAD | cut -d/ -f1 | sort | uniq -c 确认 PR 提交仅包含 autofuse/。 ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如:feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 本 PR 为纯格式化变更,不涉及功能逻辑、接口、构建脚本或打包内容修改。 See merge request: cann/graph-autofusion!921 | 3 个月前 | |
style: 统一 Autofuse 代码格式 Co-authored-by: Ling-DT<lingxing@huawei.com> # message auto-generated for no-merge-commit merge: !921 merge style/clang-format-autofuse-20260611 into develop style: 统一 Autofuse 代码格式 Created-by: ling-DT Commit-by: Ling-DT Merged-by: cann-robot Description: # Pull Request ## 描述 基于 cann/graph-autofusion:develop 最新提交 46a23b0,使用仓库根目录 .clang-format 对 autofuse/ 目录内受版本管理的 C/C++/AscendC 源文件执行统一格式化。 本 PR 仅包含 autofuse/ 目录格式化变更;super_kernel/ 目录格式化变更按要求暂留本地,未提交到本 PR。 格式化工具:clang-format 18.1.8,参数:--style=file。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [ ] ✨ 新功能 - [x] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue 无。 ## 如何测试 描述测试此变更的步骤和前提条件: 1. /tmp/opencode/clang-format-18-venv/bin/clang-format -i --style=file <autofuse C/C++/AscendC files> 2. git diff --cached --check 3. git diff --name-only HEAD~1..HEAD | cut -d/ -f1 | sort | uniq -c 确认 PR 提交仅包含 autofuse/。 ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如:feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 本 PR 为纯格式化变更,不涉及功能逻辑、接口、构建脚本或打包内容修改。 See merge request: cann/graph-autofusion!921 | 3 个月前 | |
Concat split 中 Scalar 节点错误参与轴替换导致断言失败 Co-authored-by: weishitoken<huangqianqian15@huawei.com> # message auto-generated for no-merge-commit merge: !1750 merge fix/concat-axis-replace-diagnostics into develop fix: Concat split 中 Scalar 节点错误参与轴替换导致断言失败 Created-by: wei_shi Commit-by: weishitoken Merged-by: cann-robot Description: ## 描述 修复 Concat split 场景下 Scalar 节点错误进入 ReplaceAxis 导致断言失败的问题。 **根因**: PowEquivSubstitutionPass 通过 CreateOneScalarBrc 动态创建的 Scalar 节点发生在 AscGraphInfoComplete::CompleteApiInfo() 之后,api.type 保持默认 kAPITypeInvalid(2),导致 CloneNonConcatNodes 中 IsBuffer() 返回 false,Scalar 错误进入 ReplaceAxis,在 tensor_attr.axis=[5] 中找不到 Concat 轴 0→6,触发断言。 **修复**:在 CreateOneScalarBrc 中显式设置 scalar_one.attr.api.type = kAPITypeBuffer,使 IsBuffer() 正确返回 true,Scalar 在 CloneNonConcatNodes 中被正确跳过,不进入 ReplaceAxis。 ## 变更类型 - [x] 🐛 Bug 修复 - [ ] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue 无 ## 如何测试 1. 编译 optimize_ut 测试目标通过(cmake --build build --target optimize_ut -j 8) 2. 运行 PowScalarDtypeCheck 测试通过,新增 api.type == kAPITypeBuffer 断言验证修复生效 3. 运行全部 7 个 Pow 相关测试(--gtest_filter='*Pow*')通过,无回归 ## 核对清单 - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档(本次无对应仓库文档变更) - [x] 我在标题中使用了合适的类型标签(fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 **变更文件**: - autofuse/optimize/graph_pass/pass_utils.cpp:CreateOneScalarBrc 中设置 api.type = kAPITypeBuffer - autofuse/tests/v35/ut/optimize/test_optimizer_v2.cpp:PowScalarDtypeCheck 增加 api.type == kAPITypeBuffer 断言 根因分析详见内部报告 013-ConcatFusionCaseGenerator Scalar轴替换断言失败分析报告.md。 See merge request: cann/graph-autofusion!1750 | 1 个月前 | |
【feat】: 支持norm融合R轴分tile Co-authored-by: wang-yan-male<wangyan220@huawei.com> # message auto-generated for no-merge-commit merge: !1626 merge develop into develop 【feat】: 支持norm融合R轴分tile Created-by: WangYanMale Commit-by: wang-yan-male Merged-by: cann-robot Description: # Pull Request ## 描述 1、norm类也生成双切分模板; 2、增加重复sub消除pass; 3、后移softmax pattern pass。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [x] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 1、inductor的norm算子开启自动融合,观察生成模板; 2、layernorm算子开启自动融合,观察pass前后是否存在重复的sub节点(输入一样); 3、softmax开启自动融合,观察是否是全载模板,模板里直接调用softmax api。 ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [ ] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 NA See merge request: cann/graph-autofusion!1626 | 1 个月前 | |
【PR】: [fix] [autofuse] adapt reform of the same-named header files of ge. Co-authored-by: xingzhixiong<xingzhixiong@huawei.com> # message auto-generated for no-merge-commit merge: !1149 merge develop_change_dir_of_metadef_headers into develop 【PR】: [fix] [autofuse] adapt reform of the same-named header files of ge. Created-by: xingzhixiong Commit-by: xingzhixiong Merged-by: cann-robot Description: # Pull Request ## 描述 metadef在做同名头文件整改,整改完编译发现gaf失败,原因是gaf仓和ge仓也有同名且子目录相同的头文件,故需要将gaf仓的同名头文件的子目录进行整改,只给gaf仓内部使用,避免产生耦合编译问题。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [ ] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [x] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 描述测试此变更的步骤和前提条件: 1. ci流水线pass 2. RDV pass ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 在此添加任何其他关于本次 PR 的说明。 See merge request: cann/graph-autofusion!1149 | 2 个月前 | |
style: 统一 Autofuse 代码格式 Co-authored-by: Ling-DT<lingxing@huawei.com> # message auto-generated for no-merge-commit merge: !921 merge style/clang-format-autofuse-20260611 into develop style: 统一 Autofuse 代码格式 Created-by: ling-DT Commit-by: Ling-DT Merged-by: cann-robot Description: # Pull Request ## 描述 基于 cann/graph-autofusion:develop 最新提交 46a23b0,使用仓库根目录 .clang-format 对 autofuse/ 目录内受版本管理的 C/C++/AscendC 源文件执行统一格式化。 本 PR 仅包含 autofuse/ 目录格式化变更;super_kernel/ 目录格式化变更按要求暂留本地,未提交到本 PR。 格式化工具:clang-format 18.1.8,参数:--style=file。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [ ] ✨ 新功能 - [x] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue 无。 ## 如何测试 描述测试此变更的步骤和前提条件: 1. /tmp/opencode/clang-format-18-venv/bin/clang-format -i --style=file <autofuse C/C++/AscendC files> 2. git diff --cached --check 3. git diff --name-only HEAD~1..HEAD | cut -d/ -f1 | sort | uniq -c 确认 PR 提交仅包含 autofuse/。 ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如:feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 本 PR 为纯格式化变更,不涉及功能逻辑、接口、构建脚本或打包内容修改。 See merge request: cann/graph-autofusion!921 | 3 个月前 | |
fix: Autofuse 输出日志和错误提示文案标准化 (#312) Co-authored-by: hamburgerbobo<gaoyubo4@huawei.com> # message auto-generated for no-merge-commit merge: !2098 merge fix/log-output-issue into develop fix: Autofuse 输出日志和错误提示文案标准化 (#312) Created-by: hamburgerbobo Commit-by: hamburgerbobo Merged-by: cann-robot Description: # Pull Request ## 描述 本 PR 整改 Autofuse 输出日志和错误提示文案,提升日志可读性、问题定位能力和统一日志管理一致性。 - 修正日志中的拼写、语法和主谓一致问题。 - 补充越限日志的当前值和合法范围。 - 为 VF 性能日志补充 cycle 单位。 - 将生产 Python 编译流程中的自定义 print 接入已有统一日志接口。 - 翻译计划中指定的中文输出文案,并同步通用求解器生产生成器、source mirror 和 UT 期望。 - 更新统一日志接口相关 Python UT。 本 PR 仅包含本次日志整改涉及的源码和必要测试更新,不包含日志分析 CSV、设计文档、.gitignore 或当前分支中的其他历史提交。 ## 变更类型 - [x] 🐛 Bug 修复 - [ ] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue https://gitcode.com/cann/graph-autofusion/issues/312 Fixes #312 合并后关闭已关联的 Issue。 ## 如何测试 1. 使用 CANN 9.2.0 配置 CMake,执行 cmake --build build --target aihac_codegen -j 8。 2. 执行 cmake --build build --target pyautofuse -j 8。 3. 执行编译相关 Python UT,结果为 113 passed。 4. 执行 ATT Analyze 单测和功能测试,结果分别为 38 passed 和 4 passed。 ## 核对清单 - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [ ] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如:feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 本次仅涉及日志文案和统一日志输出接口,不改变图优化、Codegen 算法、运行时数据流或对外 API/ABI。项目文档无需更新。 See merge request: cann/graph-autofusion!2098 | 8 天前 | |
style: 统一 Autofuse 代码格式 Co-authored-by: Ling-DT<lingxing@huawei.com> # message auto-generated for no-merge-commit merge: !921 merge style/clang-format-autofuse-20260611 into develop style: 统一 Autofuse 代码格式 Created-by: ling-DT Commit-by: Ling-DT Merged-by: cann-robot Description: # Pull Request ## 描述 基于 cann/graph-autofusion:develop 最新提交 46a23b0,使用仓库根目录 .clang-format 对 autofuse/ 目录内受版本管理的 C/C++/AscendC 源文件执行统一格式化。 本 PR 仅包含 autofuse/ 目录格式化变更;super_kernel/ 目录格式化变更按要求暂留本地,未提交到本 PR。 格式化工具:clang-format 18.1.8,参数:--style=file。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [ ] ✨ 新功能 - [x] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue 无。 ## 如何测试 描述测试此变更的步骤和前提条件: 1. /tmp/opencode/clang-format-18-venv/bin/clang-format -i --style=file <autofuse C/C++/AscendC files> 2. git diff --cached --check 3. git diff --name-only HEAD~1..HEAD | cut -d/ -f1 | sort | uniq -c 确认 PR 提交仅包含 autofuse/。 ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如:feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 本 PR 为纯格式化变更,不涉及功能逻辑、接口、构建脚本或打包内容修改。 See merge request: cann/graph-autofusion!921 | 3 个月前 | |
【PR】: [fix] [autofuse] adapt reform of the same-named header files of ge. Co-authored-by: xingzhixiong<xingzhixiong@huawei.com> # message auto-generated for no-merge-commit merge: !1149 merge develop_change_dir_of_metadef_headers into develop 【PR】: [fix] [autofuse] adapt reform of the same-named header files of ge. Created-by: xingzhixiong Commit-by: xingzhixiong Merged-by: cann-robot Description: # Pull Request ## 描述 metadef在做同名头文件整改,整改完编译发现gaf失败,原因是gaf仓和ge仓也有同名且子目录相同的头文件,故需要将gaf仓的同名头文件的子目录进行整改,只给gaf仓内部使用,避免产生耦合编译问题。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [ ] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [x] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 描述测试此变更的步骤和前提条件: 1. ci流水线pass 2. RDV pass ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 在此添加任何其他关于本次 PR 的说明。 See merge request: cann/graph-autofusion!1149 | 2 个月前 | |
style: 统一 Autofuse 代码格式 Co-authored-by: Ling-DT<lingxing@huawei.com> # message auto-generated for no-merge-commit merge: !921 merge style/clang-format-autofuse-20260611 into develop style: 统一 Autofuse 代码格式 Created-by: ling-DT Commit-by: Ling-DT Merged-by: cann-robot Description: # Pull Request ## 描述 基于 cann/graph-autofusion:develop 最新提交 46a23b0,使用仓库根目录 .clang-format 对 autofuse/ 目录内受版本管理的 C/C++/AscendC 源文件执行统一格式化。 本 PR 仅包含 autofuse/ 目录格式化变更;super_kernel/ 目录格式化变更按要求暂留本地,未提交到本 PR。 格式化工具:clang-format 18.1.8,参数:--style=file。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [ ] ✨ 新功能 - [x] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue 无。 ## 如何测试 描述测试此变更的步骤和前提条件: 1. /tmp/opencode/clang-format-18-venv/bin/clang-format -i --style=file <autofuse C/C++/AscendC files> 2. git diff --cached --check 3. git diff --name-only HEAD~1..HEAD | cut -d/ -f1 | sort | uniq -c 确认 PR 提交仅包含 autofuse/。 ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [x] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如:feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 本 PR 为纯格式化变更,不涉及功能逻辑、接口、构建脚本或打包内容修改。 See merge request: cann/graph-autofusion!921 | 3 个月前 | |
feat: 支持Gather后置Norm复合区域识别与融合调度(含SIMT side-input视图适配) Co-authored-by: JaydenChu<zhumin54@huawei.com> # message auto-generated for no-merge-commit merge: !2329 merge reapply/pr-2064-gather-norm into develop feat: 支持Gather后置Norm复合区域识别与融合调度(含SIMT side-input视图适配) Created-by: JaydenChu Commit-by: JaydenChu Merged-by: cann-robot Description: ## 描述 在 IndirectLoad 候选生成链路中支持 Gather 后置 Norm 复合区域(Softmax / LayerNorm 等多个 Reduce + Broadcast + Elementwise 组合)的识别、校验与调度接入,打通 Softmax 专用/通用双路径分流;同时适配 SIMT body 内行级广播 side-input 的坐标重建。 ### 问题场景 含 IndirectLoad 的图后接 Norm 类计算时,现有 Gather+Reduce 候选链存在四类问题: 1. **Gather+Softmax 候选被误杀**:SoftmaxApiCall::Generate 固定把最后一个向量化轴当作 R,且专用 Softmax 节点保持完整输入输出形状;普通 Reduce 的 stride 推导对它推不出归约轴,导致候选在布局校验阶段被淘汰。 2. **多 Reduce 图断言失败**:CollectOutputBoundaries 遇到第二个 Reduce 时触发图级断言,LayerNorm 均值/方差双分支形态直接编译失败。 3. **SIMT body 内行级广播 side-input 编译失败**:带 arange/matmul 的图,softmax 复合区域的行级广播 side-input Load(如 [8,2048,1]/strides=[2048,1,0],每行读一个向量沿尾轴广播)经调度期视图 split 改写后 rank 失配且尺寸符号化,坐标重建断言失败。 4. **IL 模板 merge 后 vectorized_axis 不一致**:tensor merge 只折叠 axis/repeats/strides 不处理 vectorized_axis,中间窗口公共检查打误导性 ERROR。 ### 问题原因 - 现有 RewrittenGraphAnalysis::post_reduce 为单 Reduce 假设,无法表达多统计 Reduce 区域 - Softmax Pattern 替换依赖 ReducePartitionCaseGenerator 的 AllLoad 流程,遇 IndirectLoad 提前返回 - SIMT body 是静态成员函数(无 tiling data 参数),坐标重建要求编译期常量,视图 split 符号化后兜底失效 - tensor merge 与 vectorized_axis remap 分两步执行,中间窗口视图自洽性缺失 ### 修改方案 **复合区域识别与调度**: 1. 新增 norm_utils:NormInfo/NormStage 元数据,基于节点 ExtAttr 随候选图复制传递 2. 抽取 softmax_pattern_fusion_utils:MatchStableStructure/MatchStableDedicated 拆分匹配 3. CollectOutputBoundaries 收集全部 Reduce,逐个校验同轴 Broadcast 配对 4. SIMD 逐 Reduce 独立校验(ValidateSimdCompositeLayouts);SIMT 串行多阶段 5. simt_boundary_sync:SIMT 边界视图 split 同步与 vectorized_axis 两级重映射 6. SIMD padded 视图强制 strided 降级(按视图 strides 逐行写,行内 pad 由 ReduceInit 清中性值) **SIMT side-input 视图适配**: 7. SimtLoadMetadata 增加行级广播标记:generator 在视图改写前按原始结构判定(尾轴 stride==0、其余轴 row-major 稠密递推——从后往前),写入节点 attr 穿透 VF 克隆 8. codegen 坐标重建兜底:rank mismatch 断言前按 output_index / 尾轴宽 去尾维寻址(读[行,列]值沿尾轴广播的正确语义) 9. IL 模板 tensor merge 后,vectorized_axis 中失效旧轴立即替换为 merged 轴(消除中间窗口不一致,RemapOutputVectorizedAxes 的 direct_ancestor 路径无缝衔接到 inner 轴) ### 修改效果 - Gather+Softmax(专用 API)、Gather+LayerNorm(多 Reduce 共享输入)、Gather+串行多阶段均进入正常调度链 - 行级广播 side-input(含带 arange/matmul 图)正确寻址 - SIMD padded 视图降级 strided,消除 index 越界读 - 全部失败路径候选级淘汰并记录日志(原为图级断言失败) - 原有单 Reduce、无 Reduce、SIMD 模板场景行为不变 - 未侵入通用 ScheduleTask 结构 ## 变更类型 - [x] ✨ New feature - [x] 🐛 Bug fix ## 关联的Issue 无 ## 如何测试 1. 已执行:codegen 全量 55/55、optimize_ut 734、optimize_st 213 全部通过 2. 已验证:行级广播兜底(标记/递推/寻址)各环节形态断言通过 3. 待执行:生产带 arange/matmul 图复测 ## 核对清单 - [x] 我的代码遵循了项目的代码风格 - [x] 我已对功能进行了自测(全量回归+形态断言) - [ ] 我已更新了相关的文档 - [x] 我在标题中使用了适当的类型标签(feat:) - [x] 我已仔细阅读贡献指南(CONTRIBUTING.md)并遵循所有规则 See merge request: cann/graph-autofusion!2329 | 2 天前 | |
【feat】: 支持norm融合R轴分tile Co-authored-by: wang-yan-male<wangyan220@huawei.com> # message auto-generated for no-merge-commit merge: !1626 merge develop into develop 【feat】: 支持norm融合R轴分tile Created-by: WangYanMale Commit-by: wang-yan-male Merged-by: cann-robot Description: # Pull Request ## 描述 1、norm类也生成双切分模板; 2、增加重复sub消除pass; 3、后移softmax pattern pass。 ## 变更类型 请选择本次引入的变更类型: <!-- [x] 表示选中 --> - [ ] 🐛 Bug 修复 - [x] ✨ 新功能 - [ ] 💄 代码风格更新(格式化,局部变量) - [ ] ♻️ 重构(既不修复错误也不增加功能的代码变动) - [ ] 📦 构建过程或辅助工具的变动 - [ ] 📝 文档内容更新 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在当前页面的右侧'关联Issue'部分添加相应Issue链接,并勾选'合并后关闭已关联的 Issue'选项。 --> ## 如何测试 1、inductor的norm算子开启自动融合,观察生成模板; 2、layernorm算子开启自动融合,观察pass前后是否存在重复的sub节点(输入一样); 3、softmax开启自动融合,观察是否是全载模板,模板里直接调用softmax api。 ## 核对清单 <!-- [x] 表示选中 --> - [x] 我的代码遵循了项目的代码风格 - [x] 我已对代码进行了自测 - [ ] 我已更新了相关的文档 - [x] 我在标题中使用了合适的类型标签(如: feat:, fix:) - [x] 我已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 ## 其他信息 NA See merge request: cann/graph-autofusion!1626 | 1 个月前 | |
feat: 支持Gather后置Norm复合区域识别与融合调度(含SIMT side-input视图适配) Co-authored-by: JaydenChu<zhumin54@huawei.com> # message auto-generated for no-merge-commit merge: !2329 merge reapply/pr-2064-gather-norm into develop feat: 支持Gather后置Norm复合区域识别与融合调度(含SIMT side-input视图适配) Created-by: JaydenChu Commit-by: JaydenChu Merged-by: cann-robot Description: ## 描述 在 IndirectLoad 候选生成链路中支持 Gather 后置 Norm 复合区域(Softmax / LayerNorm 等多个 Reduce + Broadcast + Elementwise 组合)的识别、校验与调度接入,打通 Softmax 专用/通用双路径分流;同时适配 SIMT body 内行级广播 side-input 的坐标重建。 ### 问题场景 含 IndirectLoad 的图后接 Norm 类计算时,现有 Gather+Reduce 候选链存在四类问题: 1. **Gather+Softmax 候选被误杀**:SoftmaxApiCall::Generate 固定把最后一个向量化轴当作 R,且专用 Softmax 节点保持完整输入输出形状;普通 Reduce 的 stride 推导对它推不出归约轴,导致候选在布局校验阶段被淘汰。 2. **多 Reduce 图断言失败**:CollectOutputBoundaries 遇到第二个 Reduce 时触发图级断言,LayerNorm 均值/方差双分支形态直接编译失败。 3. **SIMT body 内行级广播 side-input 编译失败**:带 arange/matmul 的图,softmax 复合区域的行级广播 side-input Load(如 [8,2048,1]/strides=[2048,1,0],每行读一个向量沿尾轴广播)经调度期视图 split 改写后 rank 失配且尺寸符号化,坐标重建断言失败。 4. **IL 模板 merge 后 vectorized_axis 不一致**:tensor merge 只折叠 axis/repeats/strides 不处理 vectorized_axis,中间窗口公共检查打误导性 ERROR。 ### 问题原因 - 现有 RewrittenGraphAnalysis::post_reduce 为单 Reduce 假设,无法表达多统计 Reduce 区域 - Softmax Pattern 替换依赖 ReducePartitionCaseGenerator 的 AllLoad 流程,遇 IndirectLoad 提前返回 - SIMT body 是静态成员函数(无 tiling data 参数),坐标重建要求编译期常量,视图 split 符号化后兜底失效 - tensor merge 与 vectorized_axis remap 分两步执行,中间窗口视图自洽性缺失 ### 修改方案 **复合区域识别与调度**: 1. 新增 norm_utils:NormInfo/NormStage 元数据,基于节点 ExtAttr 随候选图复制传递 2. 抽取 softmax_pattern_fusion_utils:MatchStableStructure/MatchStableDedicated 拆分匹配 3. CollectOutputBoundaries 收集全部 Reduce,逐个校验同轴 Broadcast 配对 4. SIMD 逐 Reduce 独立校验(ValidateSimdCompositeLayouts);SIMT 串行多阶段 5. simt_boundary_sync:SIMT 边界视图 split 同步与 vectorized_axis 两级重映射 6. SIMD padded 视图强制 strided 降级(按视图 strides 逐行写,行内 pad 由 ReduceInit 清中性值) **SIMT side-input 视图适配**: 7. SimtLoadMetadata 增加行级广播标记:generator 在视图改写前按原始结构判定(尾轴 stride==0、其余轴 row-major 稠密递推——从后往前),写入节点 attr 穿透 VF 克隆 8. codegen 坐标重建兜底:rank mismatch 断言前按 output_index / 尾轴宽 去尾维寻址(读[行,列]值沿尾轴广播的正确语义) 9. IL 模板 tensor merge 后,vectorized_axis 中失效旧轴立即替换为 merged 轴(消除中间窗口不一致,RemapOutputVectorizedAxes 的 direct_ancestor 路径无缝衔接到 inner 轴) ### 修改效果 - Gather+Softmax(专用 API)、Gather+LayerNorm(多 Reduce 共享输入)、Gather+串行多阶段均进入正常调度链 - 行级广播 side-input(含带 arange/matmul 图)正确寻址 - SIMD padded 视图降级 strided,消除 index 越界读 - 全部失败路径候选级淘汰并记录日志(原为图级断言失败) - 原有单 Reduce、无 Reduce、SIMD 模板场景行为不变 - 未侵入通用 ScheduleTask 结构 ## 变更类型 - [x] ✨ New feature - [x] 🐛 Bug fix ## 关联的Issue 无 ## 如何测试 1. 已执行:codegen 全量 55/55、optimize_ut 734、optimize_st 213 全部通过 2. 已验证:行级广播兜底(标记/递推/寻址)各环节形态断言通过 3. 待执行:生产带 arange/matmul 图复测 ## 核对清单 - [x] 我的代码遵循了项目的代码风格 - [x] 我已对功能进行了自测(全量回归+形态断言) - [ ] 我已更新了相关的文档 - [x] 我在标题中使用了适当的类型标签(feat:) - [x] 我已仔细阅读贡献指南(CONTRIBUTING.md)并遵循所有规则 See merge request: cann/graph-autofusion!2329 | 2 天前 | |
feat: 支持Gather后置Norm复合区域识别与融合调度(含SIMT side-input视图适配) Co-authored-by: JaydenChu<zhumin54@huawei.com> # message auto-generated for no-merge-commit merge: !2329 merge reapply/pr-2064-gather-norm into develop feat: 支持Gather后置Norm复合区域识别与融合调度(含SIMT side-input视图适配) Created-by: JaydenChu Commit-by: JaydenChu Merged-by: cann-robot Description: ## 描述 在 IndirectLoad 候选生成链路中支持 Gather 后置 Norm 复合区域(Softmax / LayerNorm 等多个 Reduce + Broadcast + Elementwise 组合)的识别、校验与调度接入,打通 Softmax 专用/通用双路径分流;同时适配 SIMT body 内行级广播 side-input 的坐标重建。 ### 问题场景 含 IndirectLoad 的图后接 Norm 类计算时,现有 Gather+Reduce 候选链存在四类问题: 1. **Gather+Softmax 候选被误杀**:SoftmaxApiCall::Generate 固定把最后一个向量化轴当作 R,且专用 Softmax 节点保持完整输入输出形状;普通 Reduce 的 stride 推导对它推不出归约轴,导致候选在布局校验阶段被淘汰。 2. **多 Reduce 图断言失败**:CollectOutputBoundaries 遇到第二个 Reduce 时触发图级断言,LayerNorm 均值/方差双分支形态直接编译失败。 3. **SIMT body 内行级广播 side-input 编译失败**:带 arange/matmul 的图,softmax 复合区域的行级广播 side-input Load(如 [8,2048,1]/strides=[2048,1,0],每行读一个向量沿尾轴广播)经调度期视图 split 改写后 rank 失配且尺寸符号化,坐标重建断言失败。 4. **IL 模板 merge 后 vectorized_axis 不一致**:tensor merge 只折叠 axis/repeats/strides 不处理 vectorized_axis,中间窗口公共检查打误导性 ERROR。 ### 问题原因 - 现有 RewrittenGraphAnalysis::post_reduce 为单 Reduce 假设,无法表达多统计 Reduce 区域 - Softmax Pattern 替换依赖 ReducePartitionCaseGenerator 的 AllLoad 流程,遇 IndirectLoad 提前返回 - SIMT body 是静态成员函数(无 tiling data 参数),坐标重建要求编译期常量,视图 split 符号化后兜底失效 - tensor merge 与 vectorized_axis remap 分两步执行,中间窗口视图自洽性缺失 ### 修改方案 **复合区域识别与调度**: 1. 新增 norm_utils:NormInfo/NormStage 元数据,基于节点 ExtAttr 随候选图复制传递 2. 抽取 softmax_pattern_fusion_utils:MatchStableStructure/MatchStableDedicated 拆分匹配 3. CollectOutputBoundaries 收集全部 Reduce,逐个校验同轴 Broadcast 配对 4. SIMD 逐 Reduce 独立校验(ValidateSimdCompositeLayouts);SIMT 串行多阶段 5. simt_boundary_sync:SIMT 边界视图 split 同步与 vectorized_axis 两级重映射 6. SIMD padded 视图强制 strided 降级(按视图 strides 逐行写,行内 pad 由 ReduceInit 清中性值) **SIMT side-input 视图适配**: 7. SimtLoadMetadata 增加行级广播标记:generator 在视图改写前按原始结构判定(尾轴 stride==0、其余轴 row-major 稠密递推——从后往前),写入节点 attr 穿透 VF 克隆 8. codegen 坐标重建兜底:rank mismatch 断言前按 output_index / 尾轴宽 去尾维寻址(读[行,列]值沿尾轴广播的正确语义) 9. IL 模板 tensor merge 后,vectorized_axis 中失效旧轴立即替换为 merged 轴(消除中间窗口不一致,RemapOutputVectorizedAxes 的 direct_ancestor 路径无缝衔接到 inner 轴) ### 修改效果 - Gather+Softmax(专用 API)、Gather+LayerNorm(多 Reduce 共享输入)、Gather+串行多阶段均进入正常调度链 - 行级广播 side-input(含带 arange/matmul 图)正确寻址 - SIMD padded 视图降级 strided,消除 index 越界读 - 全部失败路径候选级淘汰并记录日志(原为图级断言失败) - 原有单 Reduce、无 Reduce、SIMD 模板场景行为不变 - 未侵入通用 ScheduleTask 结构 ## 变更类型 - [x] ✨ New feature - [x] 🐛 Bug fix ## 关联的Issue 无 ## 如何测试 1. 已执行:codegen 全量 55/55、optimize_ut 734、optimize_st 213 全部通过 2. 已验证:行级广播兜底(标记/递推/寻址)各环节形态断言通过 3. 待执行:生产带 arange/matmul 图复测 ## 核对清单 - [x] 我的代码遵循了项目的代码风格 - [x] 我已对功能进行了自测(全量回归+形态断言) - [ ] 我已更新了相关的文档 - [x] 我在标题中使用了适当的类型标签(feat:) - [x] 我已仔细阅读贡献指南(CONTRIBUTING.md)并遵循所有规则 See merge request: cann/graph-autofusion!2329 | 2 天前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 3 个月前 | ||
| 1 天前 | ||
| 14 天前 | ||
| 14 天前 | ||
| 14 天前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 15 天前 | ||
| 15 天前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 27 天前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 8 天前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 2 天前 | ||
| 1 个月前 | ||
| 2 天前 | ||
| 2 天前 |