| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
feat: support BoundingboxEncode ascend950 Co-authored-by: ugzhangyiyi<zhangyiyi4@huawei.com> # message auto-generated for no-merge-commit merge: !1049 merge master into master feat: support BoundingboxEncode ascend950 Created-by: ugzhangyiyi Commit-by: ugzhangyiyi Merged-by: cann-robot Description: ## 描述 本 MR 支持 bounding_box_encode 算子,适配 Ascend 950(arch35)平台。 ### 算子功能 计算锚框(anchor box)与真实边界框(ground truth box)之间的编码偏移量,生成目标检测回归目标。计算公式(含 +1 偏移,与 canndev 内置定义一致): pw = px2 - px1 + 1, ph = py2 - py1 + 1 pcx = (px1 + px2) * 0.5, pcy = (py1 + py2) * 0.5 dx = (gcx - pcx) / pw, dy = (gcy - pcy) / ph dw = ln(gw / pw), dh = ln(gh / ph) delta_i = (raw_i - means_i) / stds_i, i ∈ {x, y, w, h} ### 代码结构(commit dabe4550) | 层级 | 文件 | 说明 | |------|------|------| | **op_graph** | bounding_box_encode_proto.h | IR 原型定义:2 INPUT(anchor_box, ground_truth_box) + 2 ATTR(means/stds ListFloat) + 1 OUTPUT(delats),支持 FP16/FP32/BF16,与 canndev nn_detect_ops.h 内置定义保持一致 | | **op_host** | bounding_box_encode_def.cpp | OpDef 注册:Input/Output/Attr 声明,AICore 配置 ascend950,DynamicCompileStatic + DynamicRank + DynamicShape | | | bounding_box_encode_infershape.cpp | InferShape:输出 shape = 输入 shape(anchor_box shape 透传) | | | arch35/bounding_box_encode_tiling_arch35.cpp | Tiling 函数:从 attrs->GetListFloat(0/1) 读取 means/stds 属性,计算 invStds 写入 TilingData;UB 容量感知的 ubFactor 计算 + MAX_DATACOPY_BLOCKLEN(65535) 双重约束防 blockLen 截断 | | **op_kernel** | arch35/bounding_box_encode.h | Kernel 实现:FP16/BF16 输入 Cast→FP32 中间计算→Cast 回原 dtype;Scalar-Vector 交叉流水(S_V/V_S 同步 + FetchEventID);CopyIn/Compute/CopyOut 三级流水 + UB 分块循环 | | | arch35/bounding_box_encode_tiling_data.h | TilingData 结构:dim0/blockFactor/ubFactor + means0-3/invStds0-3(8 个 float) | | | bounding_box_encode_apt.cpp | Kernel 入口:2 input(anchorBox, groundTruthBox) + 1 output(delats),REGISTER_TILING_DEFAULT + GET_TILING_DATA_WITH_STRUCT | | **examples** | test_geir_bounding_box_encode.cpp | GEIR 通路示例:SetAttr("means"/"stds") 设置属性 | | **CMakeLists** | CMakeLists.txt | 算子构建配置:SUPPORT_COMPUTE_UNIT=ascend950, TILING_DIR=arch35 | | **docs** | README.md | 算子说明:功能/支持产品/数据类型/参数/约束 | | | docs/zh/op_list.md | 仓级算子清单条目 | ### 接口定义(与 canndev 一致) cpp // IR 原型(与 canndev nn_detect_ops.h 一致) REG_OP(BoundingBoxEncode) .INPUT(anchor_box, TensorType({DT_FLOAT16, DT_FLOAT})) .INPUT(ground_truth_box, TensorType({DT_FLOAT16, DT_FLOAT})) .OUTPUT(delats, TensorType({DT_FLOAT16, DT_FLOAT})) .ATTR(means, ListFloat, {0.0, 0.0, 0.0, 0.0}) .ATTR(stds, ListFloat, {1.0, 1.0, 1.0, 1.0}) .OP_END_FACTORY_REG(BoundingBoxEncode) ### 关键设计决策 1. **means/stds 使用 ATTR 而非 INPUT**:与 canndev 内置定义保持一致,确保 GEIR 图模式通路兼容(避免 IR 兼容性检查冲突) 2. **DataCopyExtParams**:Kernel 使用 uint32_t blockLen 的 DataCopyExtParams,配合 tiling 侧 MAX_DATACOPY_BLOCKLEN 约束,防止大 UB 场景下 blockLen 截断 3. **+1 偏移**:pw = px2 - px1 + 1,与 canndev tbe 实现一致,保证宽高至少为 1 ## 关联的Issue https://gitcode.com/cann/ops-cv/issues/583 ## 测试 - 冒烟: 23091 - **UT 编译验证**:bash build.sh -u --ops=bounding_box_encode --soc=ascend950 --noexec,全部 target 编译通过(cv_op_host_ut / cv_op_api_ut / cv_op_kernel_ut) - tiling UT:5 例(fp32/fp16/empty/n1) - infershape UT:4 例(fp32/fp16/empty) - aclnn UT:4 例(nullptr/dtype/shape/mismatch 参数校验) - kernel UT:3 例(golden 计算:默认参数/非零参数/退化框) - **TTK 精度验证**:44/44 用例全部通过(fp16/fp32 × 多种 shape),通过率 100% - **GEIR 图模式验证**:test_geir_bounding_box_encode.cpp 执行 Session run ir compute graph success + Precision is ok ## 文档更新 - 新增 objdetect/bounding_box_encode/README.md:算子说明文档 - 更新 docs/zh/op_list.md:添加 bounding_box_encode 条目 ## 类型标签 - [ ] 🐛 Bug修复 - [x] ✨ 新特性 - [ ] ⚡ 性能优化 - [ ] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [x] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [ ] 🧹 代码清理 - [ ] ❓ 其他,请描述: ## 重点说明 为了对齐原cann版本tbe接口,**其拼写错误**delats不进行修复,保持与原版一致。 See merge request: cann/ops-cv!1049 | 1 个月前 | |
fix(bounding_box_encode): add validations in geir path and inferdatatype Co-authored-by: ugzhangyiyi<zhangyiyi4@huawei.com> # message auto-generated for no-merge-commit merge: !1182 merge fix into master fix(bounding_box_encode): add validations in geir path and inferdatatype Created-by: ugzhangyiyi Commit-by: ugzhangyiyi Merged-by: cann-robot Description: 本 PR 针对 bounding_box_encode 算子的 geir(图模式)通路补齐了 5 条缺失的参数校验代码,并通过真实 NPU 负向测试矩阵验证了拦截有效性。 ### 问题背景 经静态分析和 NPU 实测发现,geir 通路的 InferShape/InferDataType 为空壳透传实现,README 中声明的 8 条约束仅有 2 条(dtype 集合、stds≠0)能被拦截,其余 5 条约束(dtype 一致性、shape[1]==4、shape 完全一致、rank==2、means/stds 长度==4)在代码中无任何校验逻辑,导致非法输入静默通过或越界读。 ### 修复方案 在 tiling 层(真实执行路径)补齐全部缺失校验: 1. **ParseMeansStds**:在读取 means[0..3] 和 stds[0..3] 前先调用 GetSize() 验证长度为 4,消除越界读风险 2. **CheckInputsConsistency**(新增函数):在 tiling 入口校验 anchor 与 groundtruth 的 dtype 一致性、rank==2、shape[1]==4、shape 完全相等 3. **InferShape4BoundingBoxEncode**:同步补齐 README 约束校验(注:geir 路径被内置 V1 proto 屏蔽,实际由 tiling 生效,但保留以对齐规范) ### 验证方法 构造 14 例负向/对照测试矩阵(覆盖全部 README 约束 + 边界情况),在真实 NPU 上以完整 AddGraph+RunGraph 流程执行 Before/After 对比: - **Before(基线)**:8 处 silent leak(shape[1]≠4、shape 不匹配、rank≠2、means/stds 长度异常静默通过或越界) - **After(修复后)**:未拦截项从 8 降至 1,仅 dtype 不一致因 FE 自动插入 Cast 节点统一类型的结构性限制无法在算子层拦截(已在报告中实证归因) ## 关联的Issue https://gitcode.com/cann/ops-cv/issues/650 ## 测试 ### 1. 负向拦截测试(NPU 真机) - **测试工程**:tests/geir_intercept/test_geir_intercept.cpp + run_intercept.sh - **测试矩阵**:14 例(控制 1 例 + 负向 13 例) - C0: 对照(全合法输入)→ 预期通过 ✅ - C1: anchor=fp16, gt=fp32(dtype 不一致)→ 结构性不可拦 ⚠️ - C2: dtype=int32(非法 dtype)→ 拦截 ✅ - C3/C4: shape=(N,3)/(N,8)(K≠4)→ 拦截 ✅ - C5: anchor=(10,4), gt=(8,4)(shape 不匹配)→ 拦截 ✅ - C6/C7: rank=1/rank=3(非 rank-2)→ 拦截 ✅ - C8/C9: means 长度=3/5(长度异常)→ 拦截 ✅ - C10/C11: stds 长度=3/5(长度异常)→ 拦截 ✅ - C12: stds=[0,1,1,1](含 0)→ 拦截 ✅ - C13/C14: 动态 shape/rank 正常情况 → 通过 ✅ - **结果**:13/14 达预期(C1 因 FE 框架层自动类型转换无法拦截,已归因) ### 2. 回归测试 - **白盒测试**:原有白盒用例全部通过(包括之前 shape[1]≠4 被误判为"正常"的用例,现在被正确拦截) - **ST 测试**:L0+L1+L2 用例覆盖度保持,正常用例精度不受影响 ### 3. 环境清理验证 - 确认修改后需清除 /root/atc_data/kernel_cache/* 以避免旧 tiling 行为残留 - 重编译+重装 vendors 包后负向用例拦截 100% 生效(除 C1) ## 文档更新 - **新增**:tests/geir_intercept/INTERCEPT_REPORT.md(Before/After 对照 + 根因分析 + 修改清单) - **新增**:tests/geir_intercept/test_geir_intercept.cpp(负向测试工程源码) - **新增**:tests/geir_intercept/run_intercept.sh(NPU 编译执行脚本) ## 类型标签 - [x] 🐛 Bug修复 - [ ] ✨ 新特性 - [ ] ⚡ 性能优化 - [ ] ♻️ 重构 - [x] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [x] 🔒 安全修复 - [ ] 🧹 代码清理 - [ ] ❓ 其他,请描述: See merge request: cann/ops-cv!1182 | 24 天前 | |
feat: support BoundingboxEncode ascend950 Co-authored-by: ugzhangyiyi<zhangyiyi4@huawei.com> # message auto-generated for no-merge-commit merge: !1049 merge master into master feat: support BoundingboxEncode ascend950 Created-by: ugzhangyiyi Commit-by: ugzhangyiyi Merged-by: cann-robot Description: ## 描述 本 MR 支持 bounding_box_encode 算子,适配 Ascend 950(arch35)平台。 ### 算子功能 计算锚框(anchor box)与真实边界框(ground truth box)之间的编码偏移量,生成目标检测回归目标。计算公式(含 +1 偏移,与 canndev 内置定义一致): pw = px2 - px1 + 1, ph = py2 - py1 + 1 pcx = (px1 + px2) * 0.5, pcy = (py1 + py2) * 0.5 dx = (gcx - pcx) / pw, dy = (gcy - pcy) / ph dw = ln(gw / pw), dh = ln(gh / ph) delta_i = (raw_i - means_i) / stds_i, i ∈ {x, y, w, h} ### 代码结构(commit dabe4550) | 层级 | 文件 | 说明 | |------|------|------| | **op_graph** | bounding_box_encode_proto.h | IR 原型定义:2 INPUT(anchor_box, ground_truth_box) + 2 ATTR(means/stds ListFloat) + 1 OUTPUT(delats),支持 FP16/FP32/BF16,与 canndev nn_detect_ops.h 内置定义保持一致 | | **op_host** | bounding_box_encode_def.cpp | OpDef 注册:Input/Output/Attr 声明,AICore 配置 ascend950,DynamicCompileStatic + DynamicRank + DynamicShape | | | bounding_box_encode_infershape.cpp | InferShape:输出 shape = 输入 shape(anchor_box shape 透传) | | | arch35/bounding_box_encode_tiling_arch35.cpp | Tiling 函数:从 attrs->GetListFloat(0/1) 读取 means/stds 属性,计算 invStds 写入 TilingData;UB 容量感知的 ubFactor 计算 + MAX_DATACOPY_BLOCKLEN(65535) 双重约束防 blockLen 截断 | | **op_kernel** | arch35/bounding_box_encode.h | Kernel 实现:FP16/BF16 输入 Cast→FP32 中间计算→Cast 回原 dtype;Scalar-Vector 交叉流水(S_V/V_S 同步 + FetchEventID);CopyIn/Compute/CopyOut 三级流水 + UB 分块循环 | | | arch35/bounding_box_encode_tiling_data.h | TilingData 结构:dim0/blockFactor/ubFactor + means0-3/invStds0-3(8 个 float) | | | bounding_box_encode_apt.cpp | Kernel 入口:2 input(anchorBox, groundTruthBox) + 1 output(delats),REGISTER_TILING_DEFAULT + GET_TILING_DATA_WITH_STRUCT | | **examples** | test_geir_bounding_box_encode.cpp | GEIR 通路示例:SetAttr("means"/"stds") 设置属性 | | **CMakeLists** | CMakeLists.txt | 算子构建配置:SUPPORT_COMPUTE_UNIT=ascend950, TILING_DIR=arch35 | | **docs** | README.md | 算子说明:功能/支持产品/数据类型/参数/约束 | | | docs/zh/op_list.md | 仓级算子清单条目 | ### 接口定义(与 canndev 一致) cpp // IR 原型(与 canndev nn_detect_ops.h 一致) REG_OP(BoundingBoxEncode) .INPUT(anchor_box, TensorType({DT_FLOAT16, DT_FLOAT})) .INPUT(ground_truth_box, TensorType({DT_FLOAT16, DT_FLOAT})) .OUTPUT(delats, TensorType({DT_FLOAT16, DT_FLOAT})) .ATTR(means, ListFloat, {0.0, 0.0, 0.0, 0.0}) .ATTR(stds, ListFloat, {1.0, 1.0, 1.0, 1.0}) .OP_END_FACTORY_REG(BoundingBoxEncode) ### 关键设计决策 1. **means/stds 使用 ATTR 而非 INPUT**:与 canndev 内置定义保持一致,确保 GEIR 图模式通路兼容(避免 IR 兼容性检查冲突) 2. **DataCopyExtParams**:Kernel 使用 uint32_t blockLen 的 DataCopyExtParams,配合 tiling 侧 MAX_DATACOPY_BLOCKLEN 约束,防止大 UB 场景下 blockLen 截断 3. **+1 偏移**:pw = px2 - px1 + 1,与 canndev tbe 实现一致,保证宽高至少为 1 ## 关联的Issue https://gitcode.com/cann/ops-cv/issues/583 ## 测试 - 冒烟: 23091 - **UT 编译验证**:bash build.sh -u --ops=bounding_box_encode --soc=ascend950 --noexec,全部 target 编译通过(cv_op_host_ut / cv_op_api_ut / cv_op_kernel_ut) - tiling UT:5 例(fp32/fp16/empty/n1) - infershape UT:4 例(fp32/fp16/empty) - aclnn UT:4 例(nullptr/dtype/shape/mismatch 参数校验) - kernel UT:3 例(golden 计算:默认参数/非零参数/退化框) - **TTK 精度验证**:44/44 用例全部通过(fp16/fp32 × 多种 shape),通过率 100% - **GEIR 图模式验证**:test_geir_bounding_box_encode.cpp 执行 Session run ir compute graph success + Precision is ok ## 文档更新 - 新增 objdetect/bounding_box_encode/README.md:算子说明文档 - 更新 docs/zh/op_list.md:添加 bounding_box_encode 条目 ## 类型标签 - [ ] 🐛 Bug修复 - [x] ✨ 新特性 - [ ] ⚡ 性能优化 - [ ] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [x] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [ ] 🧹 代码清理 - [ ] ❓ 其他,请描述: ## 重点说明 为了对齐原cann版本tbe接口,**其拼写错误**delats不进行修复,保持与原版一致。 See merge request: cann/ops-cv!1049 | 1 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 1 个月前 | ||
| 24 天前 | ||
| 1 个月前 |