已合并
fix: 修复模型 While 条件子图输出映射错误 #4198
Chang-an-HW创建于 7月30日
fix: 修复模型 While 条件子图输出映射错误 #4198
已合并
Pull Request已成功合入, 合并人@CANN-robot
(感谢 Chang-an-HW 的贡献)7月30日 添加了label:enhancement
7月30日 创建了 pull request,commit d824554e
atomgit-bot
7月30日 评论:
7月30日 评论:
变更摘要
此 PR 主要重构了 ParseSubgraphPostFnWhile 函数中判断 While 子图角色(cond/body)的逻辑。原有实现仅通过字符串比较 subgraph_name == "cond" 来区分,无法兼容某些使用索引而非名称的传统子图格式。变更引入了 WhileSubgraphRole 枚举、ResolveWhileSubgraphRole 和 GetLegacyWhileSubgraphIndex 两个辅助函数,以支持按名称("cond"/"body")和按父节点 OpDesc 中子图实例索引两种方式解析子图角色,提升了兼容性。
主要改动
- 新增
WhileSubgraphRole枚举:定义kUnknown、kCond、kBody三种角色,统一表示 While 子图的类型。 - 新增
GetLegacyWhileSubgraphIndex函数:通过父节点OpDesc的SubgraphInstanceNames和SubgraphNameIndexes反查子图实例索引,支持传统格式的 While 子图索引解析。 - 新增
ResolveWhileSubgraphRole函数:优先按子图名称("cond"/"body")直接匹配角色;匹配失败时回退到父图名称与父节点传统索引方式解析,增强兼容性。 - 重构
ParseSubgraphPostFnWhile函数:将原先硬编码的subgraph_name == "cond"判断替换为调用ResolveWhileSubgraphRole,根据解析出的WhileSubgraphRole决定retval_index映射逻辑(kCond返回 -1,kBody返回原值)。


不准确?
atomgit-bot
7月30日 评论:
7月30日 评论:
代码审查
审查总结
已审查文件:compiler/graph/passes/control_flow_and_stream/data_pass.cc
| 优先级 | 数量 |
|---|---|
| P0 | 0 |
| P1 | 0 |
| P2 | 0 |
| P3 | 1 |
总体风险评估:低风险。 本次变更引入了 ResolveWhileSubgraphRole 和 GetLegacyWhileSubgraphIndex 两个新函数,增强了 While 子图的角色解析能力,支持 legacy IR 格式的回退路径。核心逻辑正确,行为变更(对无法解析角色的子图提前报错而非静默按 body 处理)是向好的改进。唯一发现的问题是一段不可达的防御性检查代码(P3),不影响正确性。
⚠️ 已识别出整体风险,但无法提取行内评论,请参考整体评估。


不准确?
7月30日 添加了label:cann-cla/yes
此处折叠了72条消息 查看更多
8月3日 添加了label:lgtm
CANN-robot
8月4日 评论:
8月4日 评论:
The following users do not have permission to comment /lgtm or /approve on any module in this PR:
tang-haojie


8月4日 添加了label:approved
8月4日 合入了pull request
Pull Request
描述
问题背景
构图阶段,While 算子的两个静态子图使用标准逻辑名
cond、body注册,但子图实例图名分别设置为cond_graph、body_graph:图保存为 AIR 模型时,
ModelSerializeImp::SerializeOpDesc会通过FixOpDefSubgraphInstanceName将子图实例名写入OpDef.subgraph_name。ATC 加载 AIR 模型时,ModelSerializeImp::UnserializeOpDesc遍历同一个subgraph_name字段,并同时调用:AddSubgraphName(name):将名称写入子图 IR 名到槽位的映射;SetSubgraphInstanceName(index, name):将名称写入子图实例名列表。因此,反序列化后的 While 父节点同时得到:
原
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_01output 0。后续
InferShapePass::UpdateOutputFromSubgraphs发现 cond 子图 anchor 0 和 body 子图 anchor 0 都映射到同一个父节点 output 0。当两者 dtype 不一致时,输出描述更新失败,最终导致 ATC 将 AIR 模型转换为 OM 文件时报错。修改方案
cond识别为条件子图;body识别为循环体子图。subgraph_names_to_index_获取该实例名对应的槽位并回退判断:-1,不写入ATTR_NAME_PARENT_NODE_INDEX;body 子图继续按输出 index 映射到父 While 输出。兼容性与影响范围
{cond: 0, body: 1}映射仍走原有逻辑名路径,行为不变。{cond_graph: 0, body_graph: 1}等实例名映射。变更类型
关联的 Issue
暂无关联 Issue。
如何测试
新增和完善以下回归用例:
WhileCondWithLogicalNameDoesNotMapOutputWhileBodyWithLogicalNameMapsOutputWhileCondWithLegacyInstanceNameDoesNotMapOutputWhileBodyWithLegacyInstanceNameMapsOutputTestControlOp_While,直接校验标准 cond/body NetOutput 上的ATTR_NAME_PARENT_NODE_INDEX。TestControlOp_WhileWithLegacySubgraphNames,覆盖cond_graph/body_graph的 index 回退路径。重点验证:
ATTR_NAME_PARENT_NODE_INDEX。ATTR_NAME_PARENT_NODE_INDEX等于对应输出 index。建议执行:
./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 序列化/反序列化造成的子图逻辑名与实例名重合场景,不改变模型序列化格式。