已关闭
[Bug-Report|缺陷反馈]: RoiAlignV2 Host 侧未校验 features/rois rank 并读取不存在的维度 #795
KaranocaVe创建于  27 天前关闭于  24 天前
KaranocaVe
KaranocaVe
27 天前 创建

一、问题描述

cann/ops-cv 的 commit 902202c68246f41b0efa06a3a3a849b426c5d372 中,
experimental/objdetect/roi_align_v2/README.md 明确要求 features
[N,C,H,W]rois[numRois,5]。但是 roi_align_v2_infershape.cpp 只读取
features 的第 1 维和 rois 的第 0 维,roi_align_v2_tiling.cpp 直接读取固定的
0 至 3 维/0 至 1 维,两个入口均没有检查输入 rank。

因此 rank-2 的 features=[1,3] 和 rank-1 的 rois=[5] 都被返回成功。tiling 对
rank-2 feature 继续读取不存在的 H/W 维度,生成的 featureTotalSize
featureMapSize 等字段在重复运行中变化,说明非法输入没有被拒绝且存在未定义维度读取。

二、环境信息

  • 仓库/commit:cann/ops-cv / 902202c68246f41b0efa06a3a3a849b426c5d372
  • 主机:Linux 5.10.0/aarch64
  • 硬件:Ascend 910B3;本次为 Host infer-shape/tiling 验证
  • Driver/Toolkit/OPP:验证环境 CANN 9.1.0;源码 README/配置声明支持 ascend910b
  • 编译器/Python/CMake:GCC/G++ 11.4.0、Python 3.12.13、CMake 3.22.1
  • 版本说明:源码位于 9.2.0-beta.2 开发线,本次仅验证 Host 逻辑,未宣称匹配版本
    NPU 端到端结果

三、重现步骤

  1. 使用上述 commit 的 ops-cv 源码,在已配置 CANN Toolkit 的环境执行:

    env ASCEND_INSTALL_PATH="${CANN_ROOT}/cann-9.1.0" \
      bash build.sh --experimental --ophost_test --ops=roi_align_v2 \
      --soc=ascend910b --noexec
    

    构建退出码为 0。

  2. 使用仓库 Host UT 上下文,设置 pooled_height=2pooled_width=2
    spatial_scale=1.0sampling_ratio=1,分别运行以下输入:

    • 合法对照:features=[1,3,4,4]rois=[1,5]
    • 非法 feature rank:features=[1,3]rois=[1,5]
    • 非法 ROI rank:features=[1,3,4,4]rois=[5]
  3. 对比 infer-shape 返回值和 tiling 的 blockDim/RoiAlignV2TilingData 字段。

四、预期结果

合法对照应返回 GRAPH_SUCCESS 并生成 [1,3,2,2] 输出。违反 README 约束的
features/rois rank 应返回明确的失败状态,不应生成 tiling 数据;至少不能读取输入
不存在的维度。

五、实际结果

  • 合法对照:infer-shape 返回 GRAPH_SUCCESS、输出 [1,3,2,2];tiling 返回成功、
    blockDim=1featureTotalSize=48featureMapSize=48roiLength=5
  • features=[1,3]:infer-shape 返回 GRAPH_SUCCESS、输出 [1,3,2,2]
  • rois=[5]:infer-shape 返回 GRAPH_SUCCESS、输出 [5,3,2,2]
  • 两个非法 rank 同时进入 tiling 时仍返回 GRAPH_SUCCESSblockDim=5,并生成
    numRois=5roiLength=0。rank-2 feature 不存在的 H/W 被读取为非零值,
    featureTotalSize/featureMapSize/H/W 在重复运行中变化。
  • 五个 Host UT 均通过,运行退出码为 0;日志中记录了实际字段和对照结果。

日志摘要:

control: GRAPH_SUCCESS, blockDim=1, featureTotalSize=48, roiLength=5
invalid_feature_rank: GRAPH_SUCCESS, output=[1,3,2,2]
invalid_rois_rank: GRAPH_SUCCESS, output=[5,3,2,2]
invalid_rank_tiling: GRAPH_SUCCESS, blockDim=5, numRois=5, roiLength=0
invalid_rank_tiling: featureTotalSize/height/width vary between repeated runs

六、影响与规避方式

当上层 shape 校验未执行或 Host tiling 被直接调用时,非法输入会被静默接受,rank-1
ROI 会被错误解释为 5 个 ROI,rank-2 feature 会产生未定义的 H/W 和内核配置。建议
调用方暂时确保 features 为 4D、rois[numRois,5];实现侧应在 infer-shape
和 tiling 入口统一校验 rank 与 ROI 坐标维,并返回明确错误。

七、建议的回归测试

保留合法 [1,3,4,4]/[1,5] 对照,并新增 features rank-2、rois rank-1、
rois 二维但第二维不是 5 的用例;非法用例在 infer-shape 和 tiling 阶段均应断言
GRAPH_FAILED,不得读取不存在的维度或设置有效 blockDim

likedislike
KaranocaVeKaranocaVe
27 天前 添加了label:bug-report
KaranocaVeKaranocaVe
27 天前 关联了pull request:[Fix] 拒绝 RoiAlignV2 的非法 features/rois rank
liu-wei
liu-wei成员
27 天前 评论:

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

9.2.0-beta.2 分支的 commit 902202c68246f41b0efa06a3a3a849b426c5d372 上核对到,experimental/objdetect/roi_align_v2/README.md:14-17 和参数说明 48-64features 定义为 [N,C,H,W],将 rois 定义为 [numRois,5],输出为 [numRois,C,pooled_height,pooled_width]

但 InferShape 入口没有对这两个输入做 rank/坐标维校验。experimental/objdetect/roi_align_v2/op_host/roi_align_v2_infershape.cpp:39-44 直接读取 rois 第 0 维和 features 第 1 维:

const gert::Shape* features_shape = context->GetInputShape(0);
const gert::Shape* rois_shape = context->GetInputShape(1);
gert::Shape* output_shape = context->GetOutputShape(0);

uint32_t numRois = rois_shape->GetDim(0);
uint32_t channels = features_shape->GetDim(1);

后续同文件 60-64 直接据此设置 4D 输出,因此 features rank 不足或 rois 不是 [numRois,5] 时,也可能被静默推导为成功输出。

tiling 侧问题更直接。experimental/objdetect/roi_align_v2/op_host/roi_align_v2_tiling.cpp:65-73 未检查 GetInputShape 返回值,也未检查 storage shape rank,就读取固定维度:

auto features_shape = context->GetInputShape(0)->GetStorageShape();
auto rois_shape = context->GetInputShape(1)->GetStorageShape();

uint32_t batch = features_shape.GetDim(0);
uint32_t channels = features_shape.GetDim(1);
uint32_t height = features_shape.GetDim(2);
uint32_t width = features_shape.GetDim(3);
uint32_t numRois = rois_shape.GetDim(0);
uint32_t roiLength = rois_shape.GetDim(1);

因此非法 rank 下会继续生成 featureTotalSizefeatureMapSizeroiLengthnumRois 等 tiling 字段,与 README 中的输入契约不一致,并存在读取不存在维度的风险。当前仓库在该 commit 下 experimental/objdetect/roi_align_v2/tests/ut 只有 .gitkeep,没有看到已提交的 infer-shape/tiling 回归用例覆盖这些非法 rank 边界。

建议按缺陷处理:在 InferShape 和 tiling 入口统一补充 features.GetDimNum()==4rois.GetDimNum()==2rois.GetDim(1)==5 的校验;同时补充 features rank-2、rois rank-1、rois 第二维非 5、合法 [1,3,4,4]/[1,5] 对照用例,确保非法输入稳定返回 GRAPH_FAILED,不再读取不存在的维度或生成有效 tiling 数据。

likedislike
liu-weiliu-wei成员
27 天前 将 KaranocaVe 设为负责人
sunhao_hw成员
26 天前 评论:

您好,对应PR麻烦在编译前先本地解决precommit问题后重新提交编译。
precommit可以参考如下配置:precommit配置指南
修改后需要重新执行compile跑CI门禁

likedislike
CANN-robotCANN-robot成员
24 天前 关闭了 issue
CANN-robotCANN-robot成员
24 天前 添加了label:resolved