已合并
fix: 修复模型 While 条件子图输出映射错误 #4198
fix: 修复模型 While 条件子图输出映射错误 #4198
已合并
Chang-an-HW创建于 7月30日
Chang-an-HW成员
7月30日

Pull Request

描述

问题背景

构图阶段,While 算子的两个静态子图使用标准逻辑名 condbody 注册,但子图实例图名分别设置为 cond_graphbody_graph

IR 逻辑名:cond       body
实例图名: cond_graph body_graph
实例槽位: slot 0     slot 1

图保存为 AIR 模型时,ModelSerializeImp::SerializeOpDesc 会通过 FixOpDefSubgraphInstanceName 将子图实例名写入 OpDef.subgraph_name。ATC 加载 AIR 模型时,ModelSerializeImp::UnserializeOpDesc 遍历同一个 subgraph_name 字段,并同时调用:

  • AddSubgraphName(name):将名称写入子图 IR 名到槽位的映射;
  • SetSubgraphInstanceName(index, name):将名称写入子图实例名列表。

因此,反序列化后的 While 父节点同时得到:

subgraph_names_to_index_ = {
  cond_graph: 0,
  body_graph: 1
}
subgraph_instance_names_ = [cond_graph, body_graph]

DataPass::ParseSubgraphPostFnWhile 仅通过字符串是否等于 cond 判断条件子图。当处理实例名为 cond_graph 的 cond 子图时,无法识别其条件子图角色,错误地按 body 子图处理。

这会使 cond 子图 NetOutput anchor 0 对应输入 TensorDesc 的 ATTR_NAME_PARENT_NODE_INDEX 被设置为父节点 while_01 的 output index 0;正确行为应为 -1,即不建立 cond 输出到父 While 输出的映射。与此同时,body 子图 NetOutput anchor 0 也会正确映射到 while_01 output 0。

后续 InferShapePass::UpdateOutputFromSubgraphs 发现 cond 子图 anchor 0 和 body 子图 anchor 0 都映射到同一个父节点 output 0。当两者 dtype 不一致时,输出描述更新失败,最终导致 ATC 将 AIR 模型转换为 OM 文件时报错。

修改方案

  • 保留标准模型的逻辑名优先判断:
    • cond 识别为条件子图;
    • body 识别为循环体子图。
  • 当子图名不是标准逻辑名时,从父 While 节点的 subgraph_names_to_index_ 获取该实例名对应的槽位并回退判断:
    • slot 0 识别为 cond;
    • 其余槽位按 body 处理。
  • cond 子图的 NetOutput 输出映射返回 -1,不写入 ATTR_NAME_PARENT_NODE_INDEX;body 子图继续按输出 index 映射到父 While 输出。
  • 增加日志,记录通过逻辑名或实例槽位识别出的 While 子图角色。

兼容性与影响范围

  • 标准 {cond: 0, body: 1} 映射仍走原有逻辑名路径,行为不变。
  • 兼容 AIR 反序列化后形成的 {cond_graph: 0, body_graph: 1} 等实例名映射。
  • 修改仅作用于图编译归一化阶段的 While 子图输入输出映射,不改变图执行阶段的 While 运行语义。
  • 采用“逻辑名优先 + 子图实例槽位 index 回退”的最小兼容方案,不修改或重写节点已有的 IR 子图元数据。

变更类型

关联的 Issue

暂无关联 Issue。

如何测试

新增和完善以下回归用例:

  • DataPass UT:
    • WhileCondWithLogicalNameDoesNotMapOutput
    • WhileBodyWithLogicalNameMapsOutput
    • WhileCondWithLegacyInstanceNameDoesNotMapOutput
    • WhileBodyWithLegacyInstanceNameMapsOutput
  • While ST:
    • 增强 TestControlOp_While,直接校验标准 cond/body NetOutput 上的 ATTR_NAME_PARENT_NODE_INDEX
    • 新增 TestControlOp_WhileWithLegacySubgraphNames,覆盖 cond_graph/body_graph 的 index 回退路径。

重点验证:

  1. cond NetOutput 输入 TensorDesc 不包含 ATTR_NAME_PARENT_NODE_INDEX
  2. body NetOutput 输入 TensorDesc 的 ATTR_NAME_PARENT_NODE_INDEX 等于对应输出 index。
  3. 标准逻辑名和 AIR 反序列化后的实例名两类映射均得到相同的 cond/body 输出映射语义。

建议执行:

./build_ut/tests/ge/ut/ge/ut_libge_others_utest --gtest_filter="UtestDataPass.While*"
./build_st/tests/ge/st/testcase/graph_engine_test --gtest_filter="DynamicGraphTest.TestControlOp_While*"

当前未执行本地编译和测试,待 CI 环境验证。

核对清单

其他信息

本修改直接兼容 AIR 序列化/反序列化造成的子图逻辑名与实例名重合场景,不改变模型序列化格式。

likedislike
Pull Request已成功合入, 合并人@CANN-robot
(感谢 Chang-an-HW 的贡献)
CChang-an-HW成员
7月30日 添加了label:enhancement
CChang-an-HW成员
7月30日 创建了 pull request,commit d824554e
atomgit-bot
atomgit-bot
7月30日 评论:

变更摘要

此 PR 主要重构了 ParseSubgraphPostFnWhile 函数中判断 While 子图角色(cond/body)的逻辑。原有实现仅通过字符串比较 subgraph_name == "cond" 来区分,无法兼容某些使用索引而非名称的传统子图格式。变更引入了 WhileSubgraphRole 枚举、ResolveWhileSubgraphRoleGetLegacyWhileSubgraphIndex 两个辅助函数,以支持按名称("cond"/"body")和按父节点 OpDesc 中子图实例索引两种方式解析子图角色,提升了兼容性。

主要改动

  • 新增 WhileSubgraphRole 枚举:定义 kUnknownkCondkBody 三种角色,统一表示 While 子图的类型。
  • 新增 GetLegacyWhileSubgraphIndex 函数:通过父节点 OpDescSubgraphInstanceNamesSubgraphNameIndexes 反查子图实例索引,支持传统格式的 While 子图索引解析。
  • 新增 ResolveWhileSubgraphRole 函数:优先按子图名称("cond"/"body")直接匹配角色;匹配失败时回退到父图名称与父节点传统索引方式解析,增强兼容性。
  • 重构 ParseSubgraphPostFnWhile 函数:将原先硬编码的 subgraph_name == "cond" 判断替换为调用 ResolveWhileSubgraphRole,根据解析出的 WhileSubgraphRole 决定 retval_index 映射逻辑(kCond 返回 -1,kBody 返回原值)。
likedislike
不准确?
atomgit-bot
atomgit-bot
7月30日 评论:

代码审查

审查总结

已审查文件:compiler/graph/passes/control_flow_and_stream/data_pass.cc

优先级 数量
P0 0
P1 0
P2 0
P3 1

总体风险评估:低风险。 本次变更引入了 ResolveWhileSubgraphRoleGetLegacyWhileSubgraphIndex 两个新函数,增强了 While 子图的角色解析能力,支持 legacy IR 格式的回退路径。核心逻辑正确,行为变更(对无法解析角色的子图提前报错而非静默按 body 处理)是向好的改进。唯一发现的问题是一段不可达的防御性检查代码(P3),不影响正确性。

⚠️ 已识别出整体风险,但无法提取行内评论,请参考整体评估。

likedislike
不准确?
CANN-robotCANN-robot成员
7月30日 添加了label:cann-cla/yes
此处折叠了72条消息 查看更多
CANN-robotCANN-robot成员
8月3日 添加了label:lgtm
张德鹏成员
8月4日 评论:

/approve

likedislike
CANN-robot
CANN-robot成员
8月4日 评论:

The following users do not have permission to comment /lgtm or /approve on any module in this PR:
tang-haojie

likedislike
CANN-robotCANN-robot成员
8月4日 添加了label:approved
CANN-robotCANN-robot成员
8月4日 合入了pull request