Pull Request已成功合入, 合并人@ascend-robot
(感谢 zzll 的贡献)变更摘要
此 PR 为 Ascend NPU Inductor 后端的图优化通道引入了符号化动态形状(symbolic dynamic-shape)支持,主要面向 reduction 操作。核心思路是新增 symbolic_shape_util 模块,提供无 guard 的三值逻辑(可证明为真/假/不确定),使原先仅在静态整数维度上触发的 fold/slice/expand/cat-to-view 等图优化,在动态符号维度上也能安全地触发(仅当可证明时)。同时在 codegen 层面为动态 reduction 增加了安全检查和分桶分组自调优(group autotune)能力,避免在 SIMT 模板上对 argmax/argmin/Welford 等不安全 reduction 类型错误计算。
主要改动
-
新增
symbolic_shape_util.py符号形状工具模块:提供statically_known_eq、is_statically_one、shapes_statically_equal、resolve_size_arg、materialize_shape、statically_fits_int32等三值逻辑原语,以及refresh_fake_meta、dynamic_fx_pass_enabled全局开关等辅助函数,为图优化 pass 提供无 guard 的符号推理基础。 -
图优化 pass 全面符号化适配:
ascend_graph_pass.py中fold_expand、fold_reduce、fold_slice、cat_to_view_pass、repeat_to_expand_pass、fold_iota_arithmetic_pass、batch_embedding_fusion_pass等多个 pass 从原本仅处理静态int维度改为调用符号化三值比较,在动态形状可证明时触发优化;get_node_shape新增allow_symbolic=True选项以返回含SymInt的形状。 -
动态 reduction codegen 安全策略:
ir.py(codegen)新增_SIMT_TEMPLATE_UNSAFE_REDUCTION_TYPES集合与is_linear_dynamic_reduction函数,检测 ModularIndexing/FloorDiv 中的符号界和 argmax/argmin/Welford 等不安全 reduction 类型,强制回退到社区 SIMT_ONLY 路径;ir.py(主)的num_splits对仅含单个动态 reduction 轴的情况保持split==1,配合 tail mask 循环运行时 numel。 -
动态 reduction 分桶分组自调优:
split_tiling.py新增_dynamic_reduction_tiling_axis与分桶边界(_REDUCTION_BUCKETS、_OUTER_BUCKETS),对含动态轴的 reduction 按运行时大小进行分组自调优;同时防止全 reduction 动态轴被错误设为 grid split axis(避免 grid>1 导致标量输出被覆盖);triton_heuristics.py的build_grouped_launch_policy支持 reduction tiling 轴作为 primary group axis 时无 grid block 的场景。 -
新增动态形状图优化单元测试:
test_dynamic_shape_fx_passes.py提供不依赖 NPU/CUDA 的纯 FX 级别测试,覆盖symbolic_shape_util三值检查、形状物化、值域分析以及各 pass 在动态形状下的可证明优化与边界安全(不确定情况不误折叠);test_sum.py新增 1D 动态 sum 正确性测试(含 group autotune 开关)。


代码审查
现在我已经全面审查了所有 9 个文件。让我来完成最终汇总。
审查总结
我逐一审查了以下每个文件:
-
test/_inductor/test_dynamic_shape_fx_passes.py(新增,+471 行)— 通过。测试套件结构良好,覆盖了三值逻辑、规范化、物化、范围、开关边界、以及每个 pass 在动态 shape 上的行为。"shim" 函数正确地隔离了缺失的 torch 内部组件。 -
test/_inductor/test_sum.py(+36 行)— 通过。为 sum 操作添加了动态 shape 测试和分组自动调优测试。eval('torch.' + dtype)使用方式对其硬编码常量列表来说是安全的。 -
torch_npu/_inductor/codegen/ir.py(+48 行)— 发现 1 个问题。新增函数is_linear_dynamic_reduction、其辅助函数_loop_body_has_unsafe_reduction以及常量_SIMT_TEMPLATE_UNSAFE_REDUCTION_TYPES(约 40 行)在仓库中没有任何调用者。这是死代码,应该接入调用链或移除。 -
torch_npu/_inductor/codegen/split_tiling.py(+110/-28 行)— 通过。动态全规约的 grid==1 保护、用于 reduction tiling 轴分桶的_dynamic_reduction_tiling_axis、以及仅在动态轴存在时才生成特征的条件_build_group_features,逻辑设计良好且自洽。_build_grouped_meta中新增的else分支正确地处理了无动态 split 轴的情况,并与triton_heuristics.py中build_grouped_launch_policy的修改后契约对齐。 -
torch_npu/_inductor/fx_passes/ascend_custom_passes/ascend_graph_pass.py(+189/-136 行)— 通过。所有 pass(fold_expand、fold_reduce、fold_slice、cat_to_view_pass、repeat_to_expand_pass、pad_slice_fold、cat_slice_cat_fold_pass、dtype_optimal_pass、fold_iota_arithmetic_pass、batch_embedding_fusion_pass 等)已正确适配为使用symbolic_shape_util中的三值逻辑。静态 shape 路径保持不变,动态 shape 路径在可证明时安全地进行优化。 -
torch_npu/_inductor/fx_passes/utils/get_binary_fold_result.py(+70/-35 行)— 通过。get_node_shape的allow_symbolic参数是一个向后兼容的添加。_fold_slice、_fold_slice_scatter和get_pad_dim_and_size的修改正确使用了三值比较。新增的shape is None防护是一个良好的防御性修正。 -
torch_npu/_inductor/fx_passes/utils/symbolic_shape_util.py(新增,+435 行)— 通过。设计良好的符号 shape 原语模块,提供无 guard 的三值逻辑、shape 物化、size 参数解析和 fake meta 刷新。全局开关dynamic_fx_pass_enabled()提供干净的降级行为。 -
torch_npu/_inductor/ir.py(+9 行)— 通过。num_splits的修改正确处理了单动态 reduction 轴的情况(保持 split=1 让运行时循环处理,而非退化分割)。 -
torch_npu/_inductor/runtime/triton_heuristics.py(+17/-10 行)— 通过。移除的 guard 和修改后的build_grouped_launch_policy正确地处理了 reduction tiling 轴缺少 grid block 的情况,与split_tiling.py中的新 case 保持一致。
按优先级统计发现问题数:
- P0:0
- P1:0
- P2:1(ir.py 中的死代码)
- P3:0
整体风险评估:
此次变更是一次中等风险的合入(仅因死代码问题)。核心动态 shape 分组和 pass 适配逻辑是健全的、设计良好的,并通过测试充分覆盖。唯一的缺陷是 ir.py 中的死代码块,应在后续修订中接入或清理。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 0 |
| 🟡 建议 | 4 |
💬 仅评论




Pull Request 已合并或已关闭。
If you want to solve this problem, you can click here to do it in the FAQs.


#3428
【合入来源】
【修改方案】
【资料变更】
【接口变更】
【功能验证】
【CheckList】