| [CANNBOT] DataFormatDimMap 算子适配Ascend950 AscendC实现 Co-authored-by: StoneChan_<chensitong2@huawei.com> # message auto-generated for no-merge-commit merge: !6151 merge restore/data-format-dim-map into master [CANNBOT] DataFormatDimMap 算子适配Ascend950 AscendC实现 Created-by: StoneChan_ Commit-by: StoneChan_ Merged-by: cann-robot Description: ## 描述 <!--在这里详细描述你的改动,包括改动的原因和所采取的方法。--> DataFormatDimMap 根据源数据格式和目标数据格式的维度映射关系,将输入的维度索引转换为目标格式下的对应维度索引。兼容 TensorFlow DataFormatDimMap 算子语义。 **计算公式**: $$ y_j = \text{table}\!\left[\,(x_j + N) \bmod N\,\right] $$ 其中: - $\text{table}[i]$ = src_format[i] 在 dst_format 中的位置索引 - $N$ = 格式字符串长度(支持 1~5) - $x_j$ = 输入张量中第 $j$ 个元素(维度索引值),取值范围 $[-N, N)$ - $(x_j + N) \bmod N$ 将负索引归一化到 $[0, N)$,支持 Python 风格负索引语义 **参数说明**: | 参数 | 类型 | 说明 | |------|------|------| | x (输入) | INT32/INT64, ND | 维度索引张量,取值范围 $[-N, N)$ | | src_format (属性) | STRING, 默认 "NHWC" | 源数据格式,长度 1~5 | | dst_format (属性) | STRING, 默认 "NCHW" | 目标数据格式,长度 1~5 | | y (输出) | INT32/INT64, ND | 映射结果,shape 与 x 相同 | **约束**: - src_format 与 dst_format 必须包含相同字符集(顺序可不同) - 格式字符串长度 1~5 - 输入 shape 维度数不超过 8 **示例**:输入 [0, 1, 2, 3],src=NHWC,dst=NCHW - 构建映射表:N→0, H→2, W→3, C→1 → table = [0, 2, 3, 1] - 逐元素查表:x=0→table[0]=0, x=1→table[1]=2, x=2→table[2]=3, x=3→table[3]=1 - 输出:[0, 2, 3, 1] **实现要点**: - Tiling 阶段(Host 侧):构建 expandedTable 映射表(长度 2×formatLen,后半段为前半段副本,用于负索引查表);多核切分 blockFactor = CeilAlign(CeilDiv(totalNum, coreNum), ubBlockSize);UB 切分 ubFactor = FloorAlign(ubSize / bytesPerElement, ubBlockSize) - Kernel 阶段(Device 侧):向量化实现取模运算(Cast → Adds(+N) → Muls(×1/N) → Floor → Muls(×N) → Sub)+ Compares/Select 链完成查表映射;双缓冲流水线(CopyIn/Compute/CopyOut 重叠);INT64 通过 INT32 中转再转 float,因取值范围 [-5,5) 无精度损失 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。例如:关联Issue #000--> https://gitcode.com/cann/ops-nn/issues/3375 ## 测试 <!--描述进行了哪些测试来验证你的改动。--> DataFormatDimMap 共 47 条 UT 测试用例 + 1 条图模式调用样例,全部通过。 **op_host InferShape UT(8 条)** | 用例 | 输入 shape | 数据类型 | 验证点 | |------|-----------|---------|--------| | infershape_1d | [128] | INT32 | 1D 输出 shape 正确 | | infershape_2d | [64, 128] | INT32 | 2D 输出 shape 正确 | | infershape_4d | [4, 16, 4, 4] | INT32 | 4D 输出 shape 正确 | | infershape_5d | [2, 4, 8, 16, 32] | INT32 | 5D 输出 shape 正确 | | infershape_scalar | [] | INT32 | 标量输出 shape 正确 | | infershape_int64 | [256, 512] | INT64 | INT64 类型 shape 正确 | | infershape_large_tensor | [1024, 2048] | INT32 | 大张量 shape 正确 | | infershape_8d | [1,2,3,4,5,6,7,8] | INT32 | 最大维度数 8D | **op_host Tiling UT(35 条)** 按测试类别: | 类别 | 数量 | 说明 | |------|------|------| | 映射表构造 | 5 条 | NHWC↔NCHW、NDHWC↔NCDHW、HWNC↔NHWC、NCHW→NHWC(int64)、NDHWC→NCDHW(int64) | | 数据大小边界 | 8 条 | 空张量[0]、单元素[1]、小数据[100]、边界[1023/1024/2048]、大数据[10000/100000] | | TilingKey 一致性 | 4 条 | 同 dtype 不同数据量 tilingKey 相同、不同 dtype tilingKey 不同 | | 多核切分对齐 | 4 条 | blockFactor 对齐(int32 对齐 8、int64 对齐 4)、整除核数、多核拆分 | | INT64 dtype 路径 | 5 条 | 小数据/大数据/ubFactor 计算/边界 1023 vs 1024/NCHW→NHWC | | 多维 shape | 2 条 | [4,8] 展平为 32、[100] 单核 | | 格式长度分支 | 4 条 | N=4 expandedTable 尾部填充、N=5 映射表/大数据/N4 vs N5 tilingKey | | 非法格式校验 | 2 条 | dstFormat 非 srcFormat 排列("NNNN")、部分字符不匹配("NCHX") | | 反向映射 | 1 条 | HWNC→NHWC 大张量 int64 | **op_kernel UT(4 条,CANN Simulator 仿真验证)** | 用例 | 数据类型 | 核数 | 耗时 | 验证点 | |------|---------|------|------|--------| | nhwc_to_nchw_int32_256elem | INT32 | 1 | 383ms | 正索引 [0,1,2,3]→[0,2,3,1],256 元素 | | nhwc_to_nchw_int64_256elem | INT64 | 1 | 290ms | INT64 正索引映射正确 | | nhwc_to_nchw_int32_negative_256elem | INT32 | 1 | 274ms | 负索引 [-1,-2,-3,-4]→[1,3,2,0] | | nhwc_to_nchw_int32_multicore | INT32 | 2 | 376ms | 多核切分执行,1024 元素 | **图模式调用样例(1 条)** | 调用方式 | 输入 | 格式映射 | 输出 | 结果 | |---------|------|---------|------|------| | graph 模式 | [0,1,2,3] INT32 | NHWC→NCHW | [0,2,3,1] | ✅ 通过 | ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> 新增 index/data_format_dim_map/README.md 算子说明文档。 ## 类型标签 <!-- [x] 表示选中 --> - [ ] Bug修复 - [x] 新特性 - [ ] 性能优化 - [ ] 文档更新 - [ ] 其他,请描述: See merge request: cann/ops-nn!6151 | 1 个月前 |