已开启
[Bug-Report|缺陷反馈]: DFX元数据生成未处理0D标量shape,导致源码编译失败,请协助确认 #1977
raoliang_sac创建于  4 天前
raoliang_sac
4 天前 创建

Describe the current behavior / 问题描述

在Relu6Grad质量验证中,使用TTK执行合法的0D标量输入/输出用例,CANN的Ascend C源码编译在生成DFX元数据时抛出异常:

TypeError: reduce() of empty iterable with no initial value

现场同时观察到CST_COMPILE_FAILURE和DYN_COMPILE_FAILURE;相同用例的预编译binary能匹配并执行。异常发生在CANN编译工具的DFXSectionGenerator._set_level_1_input_output_dfx_info,尚未进入待测Kernel的数值计算。

本Issue仅反馈问题、复现证据和修改建议,请asc-devkit相关维护人员协助确认原因、影响范围和处理方案。

触发的关键条件是:编译走到上述DFX方法,且输入或输出的shape为[]或()。0D标量表示1个元素;它与shape=[0]或[3, 0]等包含0维度的空Tensor不同。

Environment / 环境信息

原TTK上板现场日期:2026-10-31;本次函数级最小复现和主线源码核查日期:2026-11-02。

  • CANN:9.3.0,包版本20261028_000328247,Toolkit和对应ops包均已安装;失败现场使用未修改编译工具的独立基线安装。
  • 硬件:运行时报告Ascend950PR_9579,架构arch3510。
  • 驱动:25.7.rc1.10;操作系统:Ubuntu24.04.3 LTS,x86_64;Python:3.12.9。
  • TTK:ops-test-kit提交92496503b70e2e05892d15dd5b78d1f80eae77df;kernel模式,显式--pc=1,串行执行。
  • 待测算子:ops-nn的Relu6Grad,基线提交d1109ae3c31e36eeacd7eb8ab186c33281d2d8af,按标准流程构建安装到custom_nn;未修改算子数值Kernel。
  • asc-devkit早期源码核对基点:91c071aff07f93b7e4b9afbc43ddccb07e529b86。
  • 2026-11-02再次fetch主仓master,实际核查SHA:f16994e64df8936ea1e6cbcc47c7944f62fc2264;下面两份实现仍有同样的无初值乘积表达式。这里对该SHA的结论仅为源码核查,不声称已将整套最新asc-devkit构建部署上板。
  • 该DFX异常的现场命令没有添加op_debug_config=oom;不能将本Issue理解为仅开启OOM调试才触发。

Steps to reproduce the issue / 重现步骤

1. 函数级最小复现:无需TTK或NPU

在CANN9.3.0环境中,将下面代码保存为repro_dfx_rank0.py,加载该CANN的set_env.sh后使用匹配的Python执行:

source "$CANN_ROOT/set_env.sh"
python3 repro_dfx_rank0.py

代码只mock设备/OpInfo支持判定,实际调用安装包内的DFX方法;没有替换shape乘积表达式,不进行算子编译或NPU调用。

"""Exercise installed DFX metadata generation without compiling or using an NPU."""

import sys
import traceback
from unittest.mock import patch

from asc_op_compile_base.asc_op_compiler import ascendc_compile_dfx as dfx


def main():
    failures = 0
    print("DFX module:", dfx.__file__, flush=True)
    for shape in ([], ()):
        for kind in (dfx.DFXParamType.INPUT, dfx.DFXParamType.OUTPUT):
            generator = dfx.DFXSectionGenerator()
            # Isolate this method from device/OpInfo detection only.
            with patch.object(generator, "is_support_dfx", return_value=True):
                generator.dfx_info_reset(None)
            parameter = dfx.DFXArgInfo("x", kind)
            generator.insert_param(parameter)
            print(f"shape={shape!r}, kind={kind}, dtype=float32", flush=True)
            try:
                generator._set_level_1_input_output_dfx_info(
                    {"param_name": "x", "shape": shape, "dtype": "float32"}
                )
                assert parameter.param_size == 4, parameter.param_size
                assert parameter.param_dim == 0, parameter.param_dim
                assert parameter.param_shape == shape, parameter.param_shape
                print("PASS: bytes=4, rank=0, original shape retained", flush=True)
            except Exception:
                failures += 1
                traceback.print_exc(file=sys.stdout)
    print(f"cases=4, failures={failures}", flush=True)
    return 1 if failures else 0


if __name__ == "__main__":
    sys.exit(main())

2026-11-02在未修改工具的基线CANN实际执行结果:[]、()分别作为INPUT和OUTPUT,共4个场景均抛出上述TypeError,汇总cases=4, failures=4,进程退出码1。

2. 实际TTK调用链复现

最小场景取自原上板测试的两个用例,所有输入、输出均为0D标量。下面保留复现所需的关键CSV字段;完整现场结果对应同名原始用例:

testcase_name,op_name,input_shapes,input_dtypes,input_formats,output_shapes,output_dtypes,output_formats,input_data_ranges,absolute_precision
Relu6Grad_L0_006,Relu6Grad,"((),(),)","('bfloat16','bfloat16',)","('ND','ND',)","((),)","('bfloat16',)","('ND',)","((float(""-inf""),float(""-inf""),),(-10.0,-2.0,),)",1e-08
Relu6Grad_L0_007,Relu6Grad,"((),(),)","('float16','float16',)","('ND','ND',)","((),)","('float16',)","('ND',)","((0.01,1.0,),(0.01,1.0,),)",1e-08

前提:已加载正确的CANN环境、安装该版本Relu6Grad算子包并加载对应vendor环境;TTK_ROOT指向上述TTK版本,OPS_NN_ROOT指向对应ops-nn源码,CASE_CSV指向保存的用例文件。原现场还配置了Torch参考端,TTK_CONFIG指向其配置;该参考端配置用于精度交叉检查,不是DFX异常的产生位置。无需配置参考端即可使用上一节的函数级脚本定位本问题。

原现场TTK调用的参数整理如下,路径改为环境变量,静态、动态、release binary三种配置在同一次TTK调用中请求:

cd "$TTK_ROOT"
python3 -m ttk kernel \
  -i "$CASE_CSV" \
  --plugin "$OPS_NN_ROOT/activation/relu6_grad/tests/assets/golden.py" \
  --pc=1 --device-whitelist=0 --seed=31 \
  --provider torch --config "$TTK_CONFIG" \
  --golden-mode Promote --proc-timeout 180 \
  --task-prof false --run 1 --warmup false \
  -c -d -b release -o result.csv

以上命令参数来自实际执行记录。原现场CSV还包含其他对照用例;本Issue抽出两个稳定触发的0D场景说明问题。本次没有把TTK无执行模式或仅准备数据模式计作上板通过。

Describe the expected behavior / 预期结果

对于合法的0D标量,DFX元数据应按1个元素计算字节数,保留rank为0及原shape。例如float32标量:param_size=4、param_dim=0、param_shape=[]或()。

对于普通形状及含0维度的空Tensor应保持原语义,例如float32的[2, 3]为24字节,[3, 0]为0字节。请维护者同时确认编译工具层对标量shape的正式约定,以及是否存在应该由更早入口处理的条件。

实际TTK结果

原始用例 输入/输出形状与dtype 动态源码编译 静态源码编译 预编译binary
Relu6Grad_L0_006 两路输入()、输出();BFLOAT16 DYN_COMPILE_FAILURE CST_COMPILE_FAILURE BINARY_MATCH,精度PASS
Relu6Grad_L0_007 两路输入()、输出();FLOAT16 DYN_COMPILE_FAILURE CST_COMPILE_FAILURE BINARY_MATCH,精度PASS

CANN调用栈

下列栈来自未修改CANN工具的TTK日志,仅将安装前缀改为${CANN_ROOT}:

  File "${CANN_ROOT}/python/site-packages/asc_op_compile_base/common/register/operation_func_mgr.py", line 57, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "${CANN_ROOT}/python/site-packages/asc_op_compile_base/common/utils/para_check.py", line 636, in _in_wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "${CANN_ROOT}/vendors/custom_nn/op_impl/ai_core/tbe/custom_nn_impl/dynamic/relu6_grad_apt.py", line 224, in relu6_grad
    compile_op(src, origin_func_name, op_info, options, code_channel, '{}')
  File "${CANN_ROOT}/python/site-packages/asc_op_compile_base/asc_op_compiler/compile_op.py", line 1362, in compile_op
    compile_op_common_part(
  File "${CANN_ROOT}/python/site-packages/asc_op_compile_base/asc_op_compiler/compile_op.py", line 1224, in compile_op_common_part
    compile_kernel_and_meta(compile_info, op_info, compile_option_tuple, tiling_info)
  File "${CANN_ROOT}/python/site-packages/asc_op_compile_base/asc_op_compiler/compile_op.py", line 891, in compile_kernel_and_meta
    DFXSectionGenerator().generate_dfx_binary(compile_info, op_info, tiling_info)
  File "${CANN_ROOT}/python/site-packages/asc_op_compile_base/asc_op_compiler/ascendc_compile_dfx.py", line 281, in generate_dfx_binary
    self._generate_binary_section_for_static(compile_info, op_info, tiling_info)
  File "${CANN_ROOT}/python/site-packages/asc_op_compile_base/asc_op_compiler/ascendc_compile_dfx.py", line 254, in _generate_binary_section_for_static
    self._set_size_and_dim(compile_info, op_info, tiling_info)
  File "${CANN_ROOT}/python/site-packages/asc_op_compile_base/asc_op_compiler/ascendc_compile_dfx.py", line 189, in _set_size_and_dim
    self._set_level_1_input_output_dfx_info(op_param)
  File "${CANN_ROOT}/python/site-packages/asc_op_compile_base/asc_op_compiler/ascendc_compile_dfx.py", line 162, in _set_level_1_input_output_dfx_info
    reduce(lambda x, y: x * y, param_info.get("shape")) * INPUT_OUTPUT_DTYPE_LEN[(param_info.get("dtype"))]
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: reduce() of empty iterable with no initial value

根因分析与当前主线位置

实际出错表达式为:

reduce(lambda x, y: x * y, param_info.get("shape"))

当shape=[]或()时,没有元素供无初值的reduce执行,Python直接抛TypeError。这与前述函数级脚本及TTK真实调用栈一致。

本次核查的主仓master提交f16994e64df8936ea1e6cbcc47c7944f62fc2264中,以下两份文件的同名方法均保留该表达式:

Special notes for this issue / 备注

修改建议,请相关人员确认

建议维护者评估按“0D标量元素数为1”处理乘积,例如使用位置参数形式的初值:

reduce(lambda x, y: x * y, param_info.get("shape"), 1)

也可根据编译工具的正式shape约定选择等价的显式分支。若采用上述方向,建议同时核对当前编译器与兼容adapter,避免只修复其中一份。

建议回归:

  • 输入、输出各自的[]和(),确认rank及shape不被改成[1]。
  • FLOAT16、BFLOAT16、FLOAT32、INT64等DFX字节数计算;其中INT64仅是函数级元数据验证,不代表本Issue验证了Relu6Grad支持INT64。
  • [1]、[2, 3]等普通形状以及[0, 3]、[3, 0]等空Tensor。
  • 上述合法标量的静态、动态编译及已有binary执行对照。

已做的候选处理对照及边界

此前仅在隔离验证环境中,用乘积初值1做过候选处理对照:两份实现的4个测试方法、40个子场景通过;保留原算子计算实现的情况下,30个原Relu6Grad标量用例的静态、动态、release binary共90种配置通过。

本次另在原有独立基线和候选处理环境执行同一份函数级最小脚本:基线4个场景均失败,候选环境4个场景通过。这些结果用于帮助定界;90种配置的通过结果使用了候选工具处理,不能表述为原版CANN已通过,更不代表本仓或正式发布包已经修复。

本Issue没有将全部算子、全部芯片或全部编译配置判定为受影响。已确认的是:上述环境下Relu6Grad的真实编译失败,以及实际DFX方法对空shape的异常;其他可达通路请维护人员进一步确认。

请asc-devkit相关维护人员协助确认:

  1. 0D标量的上述DFX元数据处理是否符合工具层正式约定,能否在维护环境复现。
  2. 两份实现及其他相似元素数计算点是否需要统一处理。
  3. 受影响版本、产品/编译路径,以及合适的修复和回归方案。
  4. 如已有处理计划或后续包含修复的版本,请告知,便于算子侧安排验证。

本次只提交问题反馈与建议,由相关维护人员确认和修改,不提交代码修复PR。

likedislike
Rraoliang_sac
4 天前 添加了label:bug-report
liuliu876成员
4 天前 评论:

您好,感谢反馈。经核实,本 Issue 与 #1896 反映的是同一个问题,该问题已在 #1896 跟踪处理,建议您关注 #1896 获取后续修复进展。本 Issue 将作为重复项关闭,详述如下:

一、与 #1896 的问题本质完全一致

对比项 #1896(14天前) #1977(本Issue)
报错信息 TypeError: reduce() of empty iterable with no initial value TypeError: reduce() of empty iterable with no initial value
缺陷位置 ascendc_compile_dfx.py L162 _set_level_1_input_output_dfx_info 同一方法 DFXSectionGenerator._set_level_1_input_output_dfx_info
触发条件 0维标量张量 shape=() 0D标量输入/输出 shape=[] 或 ()
失败现象 DYN_COMPILE_FAILURE CST_COMPILE_FAILURE + DYN_COMPILE_FAILURE
复现场景 TTK kernel模式(-d 动态shape),Threshold算子 TTK kernel模式,Relu6Grad算子
调用路径 compile_dynamic_shape → ... → _set_size_and_dim(L189) → _set_level_1_input_output_dfx_info(L162) 同样在DFX元数据生成阶段、进入Kernel数值计算之前

两者根因相同:tools/build/asc_op_compile_base/asc_op_compiler/ascendc_compile_dfx.py 中
_set_level_1_input_output_dfx_info 对 shape 执行 reduce(lambda x, y: x * y, param_info.get("shape"))
未设置初值,当输入/输出为 0D 标量(shape 为 () 或 [],元素个数为 1)时,空序列 reduce 直接抛出 TypeError。

以上结论我们已在当前主线源码中复核确认,该处无初值乘积表达式仍然存在。

二、处理安排

该缺陷(0D标量shape导致DFX生成崩溃、动态编译路径不可用)已在 #1896 中跟踪,修复方案(如 reduce(..., initializer=1) 或对空 shape 特判)将在 #1896 中评审和合入。

为避免重复跟踪和分散讨论,本 Issue 将标记为 #1896 的重复项并关闭。您提供的函数级最小复现脚本(repro_dfx_rank0.py)和现场信息很有价值,我们会将其作为 #1896 的补充验证材料。

后续进展、修复版本和影响范围说明请关注 #1896。感谢您对 asc-devkit 的关注。

likedislike
Lliuliu876成员
4 天前 将 liuliu876 设为负责人
NUAA_wqyNUAA_wqy
4 天前 关联了pull request:fix(compile): give the DFX shape product an initial value so 0D scalars compile
Rraoliang_sac
3 天前 关联了pull request:fix: harden SGD validation and test references