已关闭
[Bug-Report|缺陷反馈]: RoiAlignRotated Host 侧未校验 x 的 rank 并继续读取不存在的维度 #796
KaranocaVe创建于  8月24日关闭于  8月28日
KaranocaVe
KaranocaVe
8月24日 创建

问题描述

在 cann/ops-cv 的 commit 902202c68246f41b0efa06a3a3a849b426c5d372 中,
objdetect/roi_align_rotated/README.md 明确要求输入 x 为 [N,C,W,H] 四维
Tensor、rois 为 [n,6]。但是 roi_align_rotated_infershape.cpp 和
roi_align_rotated_tiling.cpp 在读取固定维度前都没有校验输入 rank。

因此,非法 rank-1 输入 x=[4] 仍能通过 Host infer-shape 和 tiling:infer-shape
返回成功并生成 [6,2,2,0],tiling 也返回成功并生成 tiling_key=1 的配置。该行为
将不满足算子协议的输入静默转换成后续可执行配置,且读取了逻辑上不存在的维度。

环境信息

  • 仓库/commit:cann/ops-cv / 902202c68246f41b0efa06a3a3a849b426c5d372
  • OS/架构:Linux 5.10.0/aarch64
  • Ascend 硬件:Ascend 910B3,NPU 架构 dav-2201
  • Driver/Toolkit/OPP:CANN Toolkit/OPP 9.1.0
  • 编译器和 Python:GCC/G++ 11.4.0、Python 3.12.13、CMake 3.22.1
  • 版本边界:本次验证的是 Host 逻辑,未宣称 CANN 9.1.0 与目标源码开发线匹配的
    NPU 端到端结果

重现步骤

  1. 检出上述 commit,并按 Host UT 方式构建:

    bash build.sh --ophost_test --noexec --ops=roi_align_rotated --soc=ascend910b -j2
    

    构建退出码为 0。

  2. 调用 RoiAlignRotated 的 Host infer-shape/tiling 回调,设置
    pooled_h=2、pooled_w=2、spatial_scale=1.0、sampling_ratio=0。

  3. 先运行合法对照:x=[4,8,8,1]、rois=[6,8];再运行触发输入:
    x=[4]、rois=[6,6]。

  4. 对比回调返回值、infer-shape 输出和 tiling 结果。

预期结果

合法对照应返回 GRAPH_SUCCESS 并生成 [8,2,2,1]。违反 README rank 约束的输入
应在 infer-shape 或 tiling 阶段返回明确失败,不应读取不存在的维度或生成有效
tiling 数据。

实际结果

  • 合法对照:infer-shape 返回 GRAPH_SUCCESS、输出 [8,2,2,1];Tiling 返回
    成功,block_dim=1。
  • x=[4]:infer-shape 仍返回 GRAPH_SUCCESS,输出 [6,2,2,0]。
  • 同一非法输入的 Tiling 仍返回 GRAPH_SUCCESS,tiling_key=1、block_dim=1、
    data_size=88。
  • 触发用例重复运行 3 次结果一致,Host UT 进程退出码均为 0。

日志/最小复现

使用上述合法和非法输入运行 Host infer-shape/tiling 回调,结果摘要如下:

control_infershape=GRAPH_SUCCESS output=[8,2,2,1]
trigger_infershape=GRAPH_SUCCESS output=[6,2,2,0]
control_tiling=GRAPH_SUCCESS block_dim=1
trigger_tiling=GRAPH_SUCCESS block_dim=1 data_size=88
trigger_repeat_1/2/3=output=[6,2,2,0] block_dim=1 data_size=88

影响与规避方式

当上层 shape 校验未执行或 Host tiling 被直接调用时,非法 rank 会继续传播,并可能
以错误的通道、空间维度生成 kernel 任务配置。调用方应暂时确保 x 为四维、rois
为二维 [n,6];实现侧应在 infer-shape 和 tiling 入口统一校验 rank 与必要维度,
失败时返回明确错误。

建议的回归测试

保留合法 x=[4,8,8,1]/rois=[6,8] 对照,并新增 x rank-1、rank-2、rank-3
以及 rois rank-1/第二维不为 6 的用例;非法输入在 infer-shape 和 tiling 阶段均
应断言 GRAPH_FAILED,不得生成 tiling 数据。

关联 PR

likedislike
KaranocaVeKaranocaVe
8月24日 添加了label:bug-report
KaranocaVeKaranocaVe
8月24日 关联了pull request:[Fix] 拒绝 RoiAlignRotated 的非法 x rank
liu-wei
liu-wei成员
8月24日 评论:

已确认这是一个有效问题。

在 9.2.0-beta.2 分支的 commit 902202c68246f41b0efa06a3a3a849b426c5d372 上核对到,objdetect/roi_align_rotated/README.md:103-106 明确要求输入 x 为 [N,C,W,H] 四维 Tensor,rois 为二维 ROI Tensor。

但 InferShape 入口在读取固定维度前没有校验 rank。objdetect/roi_align_rotated/op_host/roi_align_rotated_infershape.cpp:51-59 只检查了 shape 指针是否为空,随后直接读取 rois_shape->GetDim(1) 和 input_shape->GetDim(3):

auto input_shape = context->GetInputShape(INPUT_INDEX);
auto rois_shape = context->GetInputShape(ROIS_INDEX);
auto output_shape = context->GetOutputShape(OUTPUT_INDEX);
if (input_shape == nullptr || rois_shape == nullptr || output_shape == nullptr) {
    return ge::GRAPH_FAILED;
}

int32_t rois_num = rois_shape->GetDim(ROIS_NUM_INDEX);
int32_t channels = input_shape->GetDim(CHANNEL_INDEX);

因此 x rank 不足 4 时,InferShape 仍可能继续读取逻辑上不存在的通道维,并在同文件 69-74 生成 4D 输出 shape。

tiling 侧也存在同类问题。objdetect/roi_align_rotated/op_host/roi_align_rotated_tiling.cpp:74-83 只检查 input tensor 指针为空,随后直接读取输入的 0 至 3 维:

auto inputTensorPtr = context->GetInputTensor(INPUT_INDEX);
auto RoisTensorPtr = context->GetInputTensor(ROIS_INDEX);
if (inputTensorPtr == nullptr || RoisTensorPtr == nullptr) {
    return ge::GRAPH_FAILED;
}

uint32_t batch_size = inputTensorPtr->GetStorageShape().GetDim(BS_INDEX);
uint32_t input_h = inputTensorPtr->GetStorageShape().GetDim(H_INDEX);
uint32_t input_w = inputTensorPtr->GetStorageShape().GetDim(W_INDEX);
uint32_t channels = inputTensorPtr->GetStorageShape().GetDim(CHANNEL_INDEX);

同文件 103-106 还直接读取 rois 的第 1 维作为 rois_num,同样缺少 rank 检查。因此直接调用 Host infer-shape/tiling 或绕过上层校验时,非法 rank 可能被静默接受,并生成有效 tiling key/blockDim。

另外这里还有一个需要同步确认的契约点:README 写的是 rois shape 为 [n,6],但当前测试用例 objdetect/roi_align_rotated/tests/ut/op_host/test_RoiAlignRotated_infershape.cpp:31-44 和 test_roi_align_rotated_tiling.cpp:32-52 使用的是 rois={6,8},代码也把 GetDim(1) 当作 rois_num。因此修复时建议先统一 rois 的维度语义,再在 InferShape 和 tiling 两侧补齐一致的 rank/坐标维校验。

当前 UT 只覆盖合法 shape 成功路径,没有看到 x rank-1/rank-2/rank-3、rois rank-1、rois 坐标维异常等失败用例。建议按缺陷处理:补充 x.GetDimNum()==4、rois.GetDimNum()==2 以及 ROI 坐标维约束校验,并增加对应 Host infer-shape/tiling 回归用例,确保非法输入返回 GRAPH_FAILED,不再读取不存在的维度或生成有效 tiling 数据。

likedislike
liu-weiliu-wei成员
8月24日 将 sunhao_hw 设为负责人
sunhao_hw成员
8月25日 评论:

您好,对应PR麻烦在编译前先本地解决precommit问题后重新提交编译。
precommit可以参考如下配置:precommit配置指南

likedislike
Ssunhao_hw成员
8月25日 添加了label:wait-feedback
KaranocaVe
KaranocaVe
8月28日 评论:

已按要求在对应 PR !1368 提交前完成本地 pre-commit,并重新触发 compile。当前 head 为 672bf2804f8a4059f0ce55b041e8ad041e1f1b31,GitCode CI(含 precommit)已通过,请按当前 head 继续复核。

likedislike
CANN-robotCANN-robot成员
8月28日 删除了label:wait-feedback
CANN-robotCANN-robot成员
8月28日 关闭了 issue
CANN-robotCANN-robot成员
8月28日 添加了label:resolved
KaranocaVeKaranocaVe
9月21日 修改了issue 的描述
Ssunhao_hw成员
10 天前 issue状态由 进行中 改变为 已完成
KaranocaVe
KaranocaVe
7 天前 评论:

@liu-wei @sunhao_hw 您好,这个 Issue 对应的修复已经合入:https://gitcode.com/cann/ops-cv/merge_requests/1368

开发者计划反馈,Issue 需要有 Accepted 标签才能计入积分,仅关闭或标记 resolved 还不够。目前这条 Issue 尚未标记 Accepted,麻烦您结合问题和已合入的修复复核一下;确认符合受理条件后,帮忙补上 Accepted 标签。

感谢您的支持!

likedislike