已关闭
[Bug] clamp_npu_output_size 空张量短路导致 broadcast shape 计算错误 #367
wangqi_ai创建于  8月7日关闭于  27 天前
wangqi_ai
8月7日 创建

一、问题描述

op_plugin/utils/KernelNpuOutputSize.cpp 中的 clamp_npu_output_size 函数在 self.numel() == 0 时直接返回 self.sizes(),跳过了与 min/max 的 broadcast 计算。

该函数通过 op_plugin_functions.yamlsize: clamp_npu_output_size(self, min, max) 配置被 gen_opapi 自动生成的 clamp.Tensor / clamp.Tensor_out 调用,bug 会真实触发。

二、重现步骤

调用 torch.clamp(input, min, max)(Tensor 版本),当 input 为空张量且 min/max 的维度需要 broadcast 扩展时:

import torch
# self.ndim=1, min.ndim=2 → broadcast 应扩展为 2D
input = torch.tensor([], dtype=torch.float32).reshape(1, 0)  # shape (1, 0)
min_val = torch.tensor([[0.0]] * 3)  # shape (3, 1)
# 期望输出 shape: (3, 0)
# 实际输出 shape: (1, 0) ← 错误
result = torch.clamp(input, min=min_val)

三、根因分析

短路分支 if (self.numel() == 0) 只复制 self.dim() 个维度,不做 left-pad 和逐维 broadcast 比较。导致:

  1. shape 错误self=(0,), min=(3,1) → 正确 (3, 0),短路返回 (0,)
  2. 吞掉校验:不可 broadcast 的非法输入(self=(0,), min=(3,))被静默接受

broadcast_ops_npu_output_size 内部使用 at::infer_size,已正确处理 0 维、left-pad 和合法性校验,短路分支完全多余。

四、预期结果

删除空张量短路分支,统一走 broadcast_ops_npu_output_size,与 PyTorch 上游 torch.clamp.Tensor 的 broadcast 语义一致。

修复后行为:

self min/max 修复前 修复后
(0,) (3, 1) (0,) (3, 0)
(1, 0) (3, 1) (1, 0) (3, 0)
(0,) (3,) (0,) ❌(吞错) 抛 broadcast 错误 ✅
(0,) () 标量 (0,) (0,)

关联 PR: https://gitcode.com/Ascend/op-plugin/merge_requests/5687

likedislike
Wwangqi_ai
8月7日 添加了label:bug
wangqi_ai
8月7日 评论:

/assign @wangqi_ai

likedislike
ascend-robotascend-robot成员
8月7日 将 wangqi_ai 设为负责人
ascend-robotascend-robot成员
27 天前 关闭了 issue
ascend-robotascend-robot成员
27 天前 添加了label:resolved