Pull Request已成功合入, 合并人@ascend-robot
(感谢 rain-666 的贡献)变更摘要
此 PR 为 inductor 的 welford 归约引入了 SIMD 向量化支持。核心思路是在持久化归约 kernel 中选取一个非归约轴(靠近归约维度的 split axis)进行向量化拆分,将归约循环折叠为 tl.sum(..., axis=1, keep_dims=True) 的单次 SIMD 操作,从而消除显式的 for loop_r 归约循环。同时新增了后归约代码生成缓冲区机制,用于在归约循环结束后生成均值、M2 和权重的后处理计算。默认将 enable_welford 配置开启。
主要改动
-
enable_welford默认值切换:torch_npu/_inductor/config.py中enable_welford的默认值从"0"改为"1",使 SIMD welford 路径默认生效。 -
向量化 Welford 轴选择逻辑: 在
NPUIndexTritonKernel._select_vectorized_welford_axis()中新增轴选择算法:在 welford_reduce 类型且归约维度均为静态长度时,选取最靠近归约维度的非归约 split axis,标记is_vectorized_split = True,并将 kernel 类型设为NPUKernelType.SIMD。 -
后归约代码生成缓冲区: 新增
post_reduction_loads、post_reduction_compute、post_reduction_stores三个独立缓冲区,以及_activate_post_reduction_codegen()和重写的disable_reduction()方法。在归约循环结束后将 welford 的mean、m2、weight后处理计算放入这些缓冲区,与主循环代码分离。 -
Welford SIMD 归约代码生成重写:
_gen_reduction_code()中 welford_reduce 分支从直接抛异常改为完整的 SIMD 实现:使用tl.sum沿归约轴一次性累积acc_sum和acc_sum_sq,在post_loop_combine中计算均值、M2 和权重,并通过reduction_resize()广播回原始形状。 -
静态尾部掩码优化:
IterationRangesEntryNPUIndex._codegen_mask()中新增use_static_vector_mask路径:当维度静态可整除时直接设_mask = True,仅不可整除时生成if N % BLOCK_SUB != 0条件掩码,避免了运行时的逐元素比较开销。 -
测试覆盖:
test_var_mean.py新增test_welford_simd_codegen(验证 SIMD 代码特征如axis=1, keep_dims=True、_acc_sum、X1BLOCK_SUB等)、test_welford_simd_codegen_disabled(验证关闭时不出现向量化标记)和test_welford_simd_tail_codegen(验证非整除维度的尾部处理分支)。


代码审查
审查总结
本次审查覆盖了 3 个文件的变更,每份文件均已逐一审查。
审查结果
| 文件 | 审查结论 |
|---|---|
test/_inductor/test_var_mean.py |
无问题(新增的 3 个 SIMD codegen 测试用例逻辑正确,资源清理得当) |
torch_npu/_inductor/codegen/triton.py |
发现 1 个 P2 问题 |
torch_npu/_inductor/config.py |
发现 1 个 P3 问题 |
按优先级统计
- P2: 1 个 —
_select_vectorized_welford_axis未排除 tiling 轴可能导致生成的 Triton 代码引用未定义变量 - P3: 1 个 —
enable_welford默认值已启用但注释仍称"默认禁用"
整体风险评估
本次变更为 welford 归约引入了 SIMD 代码生成路径,涉及约 500 行新增代码,逻辑较复杂。主要风险在于 _select_vectorized_welford_axis 方法的轴选择逻辑缺少对 tiling 轴的排除检查(P2),在某些图配置下可能导致 kernel 编译失败。其余代码(包括测试用例)逻辑一致,无明显缺陷。建议在合入前修复 P2 问题并更新 config.py 的过时注释。
⚠️ 已识别出整体风险,但无法提取行内评论,请参考整体评估。




此 PR 为 inductor 的 welford 归约引入了 SIMD 向量化支持。核心思路是在持久化归约 kernel 中选取一个非归约轴(靠近归约维度的 split axis)进行向量化拆分,将归约循环折叠为 tl.sum(..., axis=1, keep_dims=True) 的单次 SIMD 操作,从而消除显式的 for loop_r 归约循环。同时新增了后归约代码生成缓冲区机制,用于在归约循环结束后生成均值、M2 和权重的后处理计算。默认将 enable_welford 配置关闭。