已合并
A5 support transpose drop_out_v3 #539
TangPC创建于 2025年12月27日
A5 support transpose drop_out_v3 #539
已合并
TangPC创建于 2025年12月27日
已删除 :transpose合入到cann/ops-mathmaster
72 个文件变更+9232-395
@@ -173,6 +173,7 @@ set(OP_PROTO_INCLUDE
173 ${METADEF_INCLUDE_DIRS}173 ${METADEF_INCLUDE_DIRS}
174 ${OPBASE_INC_DIRS}174 ${OPBASE_INC_DIRS}
175 ${NPURUNTIME_INCLUDE_DIRS}175 ${NPURUNTIME_INCLUDE_DIRS}
176+ ${OPS_MATH_DIR}/common/inc/
176 ${OPS_MATH_DIR}/common/inc/common177 ${OPS_MATH_DIR}/common/inc/common
177)178)
178 179 
@@ -16,8 +16,8 @@
16#ifndef CANN_OPS_BUILT_IN_OP_UTIL_H_16#ifndef CANN_OPS_BUILT_IN_OP_UTIL_H_
17#define CANN_OPS_BUILT_IN_OP_UTIL_H_17#define CANN_OPS_BUILT_IN_OP_UTIL_H_
18 18 
19-#include "runtime/shape.h"19+#include "exe_graph/runtime/shape.h"
20-#include "runtime/tensor.h"20+#include "exe_graph/runtime/tensor.h"
21 21 
22namespace ops {22namespace ops {
23 23 
@@ -1,20 +1,15 @@
1# ----------------------------------------------------------------------------1# ----------------------------------------------------------------------------
2-# This program is free software, you can redistribute it and/or modify it.
3# Copyright (c) 2025 Huawei Technologies Co., Ltd.2# Copyright (c) 2025 Huawei Technologies Co., Ltd.
4-# This file is a part of the CANN Open Software.3+# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
5-# Licensed under CANN Open Software License Agreement Version 2.0 (the "License").4+# CANN Open Software License Agreement Version 2.0 (the "License").
6# Please refer to the License for details. You may not use this file except in compliance with the License.5# Please refer to the License for details. You may not use this file except in compliance with the License.
7-# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING6+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
8-# BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.7+# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
9# See LICENSE in the root of the software repository for the full text of the License.8# See LICENSE in the root of the software repository for the full text of the License.
10# ----------------------------------------------------------------------------9# ----------------------------------------------------------------------------
11 10 
12-file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)11+# 设置算子定义时支持的芯片类型
13-if(NOT ENABLE_TEST AND NOT BENCHMARK)12+set(SUPPORT_COMPUTE_UNIT "ascend310p" "ascend910_93" "ascend910b" "ascend910_95")
14- list(REMOVE_ITEM CURRENT_DIRS tests)13+# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译
15-endif()14+set(SUPPORT_TILING_DIR "arch32" "arch32" "arch32" "arch35")
16-foreach(SUB_DIR ${CURRENT_DIRS})15+add_all_modules_sources(OPTYPE transpose ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE)
17- if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")
18- add_subdirectory(${SUB_DIR})
19- endif()
20-endforeach()
@@ -1,3 +1,38 @@
1# Transpose1# Transpose
2+## 产品支持情况
2 3 
3-本目录仅包含Transpose算子对应的aclnn接口;如您想要贡献该算子的AscendC实现,请参考[贡献流程](../../CONTRIBUTING.md)。4+| 产品 | 是否支持 |
5+| :----------------------------------------------------------- | :------- |
6+| <term>昇腾910_95 AI处理器</term> | √ |
7+| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |
8+| <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term> | √ |
9+| <term>Atlas 200I/500 A2 推理产品</term> | × |
10+| <term>Atlas 推理系列产品 </term> | × |
11+| <term>Atlas 训练系列产品</term> | √ |
12+| <term>Atlas 200/300/500 推理产品</term> | × |
13+ 
14+## 功能说明
15+ 
16+- 算子功能:对tensor的任意维度进行调换。如输入self是shape为[2, 3, 5]的tensor,dims为(2, 0, 1),则输出是shape为[5, 2, 3]的tensor。
17+ 
18+## 参数说明
19+ 
20+| 参数名 | 输入/输出/属性 | 描述 | 数据类型 | 数据格式 |
21+| :----- | :------------- | :----------------------------------------------------------- | :------- | :------- |
22+| x | 输入张量 | 需要进行维度置换的输入张量。 | 见下方 | ND |
23+| perm | 输入张量 | 表示 x 的维度的排列。取值需在[0,self的维度数量-1]范围内。 | INT64、INT32 | - |
24+| y | 输出 | 维度最大不超过8维,shape由dims和原self的shape共同决定,dtype需要与self一致。 | 同 x | ND |
25+ 
26+- <term>GPU 支持的数据类型</term>:数据类型支持 DT_BF16, DT_FLOAT16, DT_FLOAT, DT_DOUBLE, DT_INT64, DT_INT32, DT_UINT8, DT_UINT16, DT_UINT32, DT_UINT64, DT_INT8, DT_INT16, DT_COMPLEX32, DT_COMPLEX64, DT_COMPLEX128, DT_QINT8, DT_QUINT8, DT_QINT16, DT_QUINT16, DT_QINT32, DT_BOOL, DT_HIFLOAT8, DT_FLOAT8_E5M2, DT_FLOAT8_E4M3FN。
27+- <term>CPU 支持的数据类型</term>:数据类型支持同 GPU。
28+ 
29+## 约束说明
30+ 
31+
32+ 
33+## 调用说明
34+ 
35+| 调用方式 | 样例代码 | 说明 |
36+| :-------- | :----------------------------------------------------------- | :----------------------------------------------------------- |
37+| aclnn接口 | [test_aclnn_channel_shuffle](examples/test_aclnn_channel_shuffle.cpp) | 通过[aclnn_channel_shuffle](docs/aclnnChannelShuffle.md)接口方式调用transpose算子。 |
38+| aclnn接口 | [test_aclnn_permute](examples/test_aclnn_permute.cpp) | 通过[aclnn_permute](docs/aclnnPermute.md)接口方式调用transpose算子。 |
@@ -1,11 +1,18 @@
1# aclnnChannelShuffle1# aclnnChannelShuffle
2 2 
3+[📄 查看源码](https://gitcode.com/cann/ops-math-dev/tree/master/conversion/transpose)
4+ 
3## 产品支持情况5## 产品支持情况
4 6 
5| 产品 | 是否支持 |7| 产品 | 是否支持 |
6| :----------------------------------------------------------- | :------: |8| :----------------------------------------------------------- | :------: |
9+| <term>昇腾910_95 AI处理器</term> | √ |
7| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |10| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |
8-| <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term> | √ |11+| <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term> | √ |
12+ 
13+ 
14+ 
15+ 
9 16 
10## 功能说明17## 功能说明
11 18 
@@ -23,17 +30,20 @@
23- **参数说明:**30- **参数说明:**
24 31 
25 - self(aclTensor*, 计算输入):Device侧的aclTensor,支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND,数据维度大于2且不支持7维以上。32 - self(aclTensor*, 计算输入):Device侧的aclTensor,支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND,数据维度大于2且不支持7维以上。
26- - <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT16、FLOAT、DOUBLE、UINT8、INT8、INT16、INT32、INT64、COMPLEX64、COMPLEX128、BOOL、BFLOAT1633+ - <term>Atlas 训练系列产品</term>:数据类型支持FLOAT16、FLOAT、DOUBLE、UINT8、INT8、INT16、INT32、INT64、COMPLEX64、COMPLEX128、BOOL。
34+ - <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term><term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term><term>昇腾910_95 AI处理器</term>:数据类型支持FLOAT16、FLOAT、DOUBLE、UINT8、INT8、INT16、INT32、INT64、COMPLEX64、COMPLEX128、BOOL、BFLOAT16。
27 35 
28 - groups(int64_t, 计算输入):表示将输入self的channels分成多少组,值需要大于0且要能被self的channels整除。36 - groups(int64_t, 计算输入):表示将输入self的channels分成多少组,值需要大于0且要能被self的channels整除。
29 37 
30 - out(aclTensor*, 计算输出):Device侧的aclTensor,数据维度大于2且不支持7维以上,支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND。38 - out(aclTensor*, 计算输出):Device侧的aclTensor,数据维度大于2且不支持7维以上,支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND。
31- - <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT16、FLOAT、DOUBLE、UINT8、INT8、INT16、INT32、INT64、COMPLEX64、COMPLEX128、BOOL、BFLOAT1639+ - <term>Atlas 训练系列产品</term>:数据类型支持FLOAT16、FLOAT、DOUBLE、UINT8、INT8、INT16、INT32、INT64、COMPLEX64、COMPLEX128、BOOL。
40+ - <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term><term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term><term>昇腾910_95 AI处理器</term>:数据类型支持FLOAT16、FLOAT、DOUBLE、UINT8、INT8、INT16、INT32、INT64、COMPLEX64、COMPLEX128、BOOL、BFLOAT16。
32 41 
33 - workspaceSize(uint64_t*, 出参):返回需要在Device侧申请的workspace大小。42 - workspaceSize(uint64_t*, 出参):返回需要在Device侧申请的workspace大小。
34 43 
35 - executor(aclOpExecutor**, 出参):返回op执行器,包含了算子计算流程。44 - executor(aclOpExecutor**, 出参):返回op执行器,包含了算子计算流程。
36 45 
46+ 
37- **返回值:**47- **返回值:**
38 48 
39 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。49 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
@@ -60,6 +70,7 @@
60 70 
61 - stream(aclrtStream, 入参):指定执行任务的Stream。71 - stream(aclrtStream, 入参):指定执行任务的Stream。
62 72 
73+ 
63- **返回值:**74- **返回值:**
64 75 
65 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。76 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
@@ -69,6 +80,7 @@
69- 确定性计算:80- 确定性计算:
70 - aclnnChannelShuffle默认确定性实现。81 - aclnnChannelShuffle默认确定性实现。
71 82 
83+ 
72## 调用示例84## 调用示例
73 85 
74示例代码如下,仅供参考,具体编译和执行过程请参考[编译与运行样例](../../../docs/zh/context/编译与运行样例.md)。86示例代码如下,仅供参考,具体编译和执行过程请参考[编译与运行样例](../../../docs/zh/context/编译与运行样例.md)。
@@ -1,11 +1,18 @@
1# aclnnPermute1# aclnnPermute
2 2 
3+[📄 查看源码](https://gitcode.com/cann/ops-math-dev/tree/master/conversion/transpose_v2)
4+ 
3## 产品支持情况5## 产品支持情况
4 6 
5| 产品 | 是否支持 |7| 产品 | 是否支持 |
6| :----------------------------------------------------------- | :------: |8| :----------------------------------------------------------- | :------: |
9+| <term>昇腾910_95 AI处理器</term> | √ |
7| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |10| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |
8-| <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term> | √ |11+| <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term> | √ |
12+ 
13+ 
14+ 
15+ 
9 16 
10## 功能说明17## 功能说明
11 18 
@@ -22,16 +29,23 @@
22 29 
23- **参数说明:**30- **参数说明:**
24 31 
25- - self(aclTensor*,计算输入):输入的tensor,支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND,维度最大不超过8维,dtype需要与out一致。32+ - self(aclTensor*,计算输入):输入的tensor,支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/context/数据格式.md)支持ND,维度最大不超过8维,dtype需要与out一致。
26- - <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT、FLOAT16、DOUBLE、UINT64、INT64、UINT32、INT32、UINT16、INT16、UINT8、INT8、BOOL、COMPLEX64、COMPLEX128、BFLOAT1633+ - <term>Atlas 训练系列产品</term>:数据类型支持FLOAT、FLOAT16、DOUBLE、UINT64、INT64、UINT32、INT32、UINT16、INT16、UINT8、INT8、BOOL、COMPLEX64、COMPLEX128。
34+ - <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term><term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT、FLOAT16、DOUBLE、UINT64、INT64、UINT32、INT32、UINT16、INT16、UINT8、INT8、BOOL、COMPLEX64、COMPLEX128、BFLOAT16。
35+ - <term>昇腾910_95 AI处理器</term>:数据类型支持FLOAT、FLOAT16、DOUBLE、UINT64、INT64、UINT32、INT32、UINT16、INT16、UINT8、INT8、BOOL、COMPLEX64、COMPLEX128、BFLOAT16、HIFLOAT8、FLOAT8_E5M2、FLOAT8_E4M3FN。
36+ 
27 - dims(aclIntArray*,计算输入):整型数组,代表原来tensor的维度,指定新的轴顺序。取值需在[-self的维度数量,self的维度数量-1]范围内。37 - dims(aclIntArray*,计算输入):整型数组,代表原来tensor的维度,指定新的轴顺序。取值需在[-self的维度数量,self的维度数量-1]范围内。
28 38 
29 - out(aclTensor*,计算输出):输出的tensor,支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND,维度最大不超过8维,shape由dims和原self的shape共同决定,dtype需要与self一致。39 - out(aclTensor*,计算输出):输出的tensor,支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND,维度最大不超过8维,shape由dims和原self的shape共同决定,dtype需要与self一致。
30- - <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT、FLOAT16、DOUBLE、UINT64、INT64、UINT32、INT32、UINT16、INT16、UINT8、INT8、BOOL、COMPLEX64、COMPLEX128、BFLOAT1640+ - <term>Atlas 训练系列产品</term>:数据类型支持FLOAT、FLOAT16、DOUBLE、UINT64、INT64、UINT32、INT32、UINT16、INT16、UINT8、INT8、BOOL、COMPLEX64、COMPLEX128。
41+ - <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term><term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT、FLOAT16、DOUBLE、UINT64、INT64、UINT32、INT32、UINT16、INT16、UINT8、INT8、BOOL、COMPLEX64、COMPLEX128、BFLOAT16。
42+ - <term>昇腾910_95 AI处理器</term>:数据类型支持FLOAT、FLOAT16、DOUBLE、UINT64、INT64、UINT32、INT32、UINT16、INT16、UINT8、INT8、BOOL、COMPLEX64、COMPLEX128、BFLOAT16、HIFLOAT8、FLOAT8_E5M2、FLOAT8_E4M3FN。
43+ 
31 - workspaceSize(uint64_t*,出参):返回需要在Device侧申请的workspace大小。44 - workspaceSize(uint64_t*,出参):返回需要在Device侧申请的workspace大小。
32 45 
33 - executor(aclOpExecutor**,出参):返回op执行器,包含了算子计算流程。46 - executor(aclOpExecutor**,出参):返回op执行器,包含了算子计算流程。
34 47 
48+ 
35- **返回值:**49- **返回值:**
36 50 
37 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。51 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
@@ -57,6 +71,7 @@
57 71 
58 - stream(aclrtStream,入参):指定执行任务的Stream。72 - stream(aclrtStream,入参):指定执行任务的Stream。
59 73 
74+ 
60- **返回值:**75- **返回值:**
61 76 
62 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。77 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
@@ -66,6 +81,7 @@
66- 确定性计算:81- 确定性计算:
67 - aclnnPermute默认确定性实现。82 - aclnnPermute默认确定性实现。
68 83 
84+ 
69## 调用示例85## 调用示例
70 86 
71示例代码如下,仅供参考,具体编译和执行过程请参考[编译与运行样例](../../../docs/zh/context/编译与运行样例.md)。87示例代码如下,仅供参考,具体编译和执行过程请参考[编译与运行样例](../../../docs/zh/context/编译与运行样例.md)。
@@ -0,0 +1,147 @@
1+/**
2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+#include <iostream>
12+#include <vector>
13+#include "acl/acl.h"
14+#include "aclnnop/aclnn_channel_shuffle.h"
15+ 
16+#define CHECK_RET(cond, return_expr) \
17+ do { \
18+ if (!(cond)) { \
19+ return_expr; \
20+ } \
21+ } while (0)
22+ 
23+#define LOG_PRINT(message, ...) \
24+ do { \
25+ printf(message, ##__VA_ARGS__); \
26+ } while (0)
27+ 
28+int64_t GetShapeSize(const std::vector<int64_t>& shape)
29+{
30+ int64_t shapeSize = 1;
31+ for (auto i : shape) {
32+ shapeSize *= i;
33+ }
34+ return shapeSize;
35+}
36+ 
37+int Init(int32_t deviceId, aclrtStream* stream)
38+{
39+ // 固定写法,资源初始化
40+ auto ret = aclInit(nullptr);
41+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);
42+ ret = aclrtSetDevice(deviceId);
43+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);
44+ ret = aclrtCreateStream(stream);
45+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);
46+ return 0;
47+}
48+ 
49+template <typename T>
50+int CreateAclTensor(
51+ const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, aclDataType dataType,
52+ aclTensor** tensor)
53+{
54+ auto size = GetShapeSize(shape) * sizeof(T);
55+ // 调用aclrtMalloc申请device侧内存
56+ auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);
57+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);
58+ // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上
59+ ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);
60+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);
61+ 
62+ // 计算连续tensor的strides
63+ std::vector<int64_t> strides(shape.size(), 1);
64+ for (int64_t i = shape.size() - 2; i >= 0; i--) {
65+ strides[i] = shape[i + 1] * strides[i + 1];
66+ }
67+ 
68+ // 调用aclCreateTensor接口创建aclTensor
69+ *tensor = aclCreateTensor(
70+ shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(),
71+ *deviceAddr);
72+ return 0;
73+}
74+ 
75+int main()
76+{
77+ // 1. (固定写法)device/stream初始化,参考acl API手册
78+ // 根据自己的实际device填写deviceId
79+ int32_t deviceId = 0;
80+ aclrtStream stream;
81+ auto ret = Init(deviceId, &stream);
82+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);
83+ 
84+ // 2. 构造输入与输出,需要根据API的接口自定义构造
85+ std::vector<int64_t> selfShape = {1, 4, 2, 2};
86+ std::vector<int64_t> outShape = {1, 4, 2, 2};
87+ void* selfDeviceAddr = nullptr;
88+ void* outDeviceAddr = nullptr;
89+ aclTensor* self = nullptr;
90+ aclTensor* out = nullptr;
91+ std::vector<float> selfHostData = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
92+ std::vector<float> outHostData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
93+ // 创建self aclTensor
94+ ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self);
95+ CHECK_RET(ret == ACL_SUCCESS, return ret);
96+ // 创建out aclTensor
97+ ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out);
98+ CHECK_RET(ret == ACL_SUCCESS, return ret);
99+ 
100+ // 3. 调用CANN算子库API,需要修改为具体的Api名称
101+ int64_t groups = 2;
102+ uint64_t workspaceSize = 0;
103+ aclOpExecutor* executor;
104+ // 调用aclnnChannelShuffle第一段接口
105+ ret = aclnnChannelShuffleGetWorkspaceSize(self, groups, out, &workspaceSize, &executor);
106+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnChannelShuffleGetWorkspaceSize failed. ERROR: %d\n", ret);
107+ return ret);
108+ // 根据第一段接口计算出的workspaceSize申请device内存
109+ void* workspaceAddr = nullptr;
110+ if (workspaceSize > 0) {
111+ ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
112+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
113+ }
114+ // 调用aclnnChannelShuffle第二段接口
115+ ret = aclnnChannelShuffle(workspaceAddr, workspaceSize, executor, stream);
116+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnChannelShuffle failed. ERROR: %d\n", ret); return ret);
117+ 
118+ // 4. (固定写法)同步等待任务执行结束
119+ ret = aclrtSynchronizeStream(stream);
120+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
121+ 
122+ // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改
123+ auto size = GetShapeSize(outShape);
124+ std::vector<float> resultData(size, 0);
125+ ret = aclrtMemcpy(
126+ resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr, size * sizeof(resultData[0]),
127+ ACL_MEMCPY_DEVICE_TO_HOST);
128+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
129+ for (int64_t i = 0; i < size; i++) {
130+ LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]);
131+ }
132+ 
133+ // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改
134+ aclDestroyTensor(self);
135+ aclDestroyTensor(out);
136+ 
137+ // 7. 释放device资源,需要根据具体API的接口定义修改
138+ aclrtFree(selfDeviceAddr);
139+ aclrtFree(outDeviceAddr);
140+ if (workspaceSize > 0) {
141+ aclrtFree(workspaceAddr);
142+ }
143+ aclrtDestroyStream(stream);
144+ aclrtResetDevice(deviceId);
145+ aclFinalize();
146+ return 0;
147+}
@@ -0,0 +1,150 @@
1+/**
2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+#include <iostream>
12+#include <vector>
13+#include "acl/acl.h"
14+#include "aclnnop/aclnn_permute.h"
15+ 
16+#define CHECK_RET(cond, return_expr) \
17+ do { \
18+ if (!(cond)) { \
19+ return_expr; \
20+ } \
21+ } while (0)
22+ 
23+#define LOG_PRINT(message, ...) \
24+ do { \
25+ printf(message, ##__VA_ARGS__); \
26+ } while (0)
27+ 
28+int64_t GetShapeSize(const std::vector<int64_t>& shape)
29+{
30+ int64_t shapeSize = 1;
31+ for (auto i : shape) {
32+ shapeSize *= i;
33+ }
34+ return shapeSize;
35+}
36+ 
37+int Init(int32_t deviceId, aclrtStream* stream)
38+{
39+ // 固定写法,初始化
40+ auto ret = aclInit(nullptr);
41+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);
42+ ret = aclrtSetDevice(deviceId);
43+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);
44+ ret = aclrtCreateStream(stream);
45+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);
46+ return 0;
47+}
48+ 
49+template <typename T>
50+int CreateAclTensor(
51+ const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, aclDataType dataType,
52+ aclTensor** tensor)
53+{
54+ auto size = GetShapeSize(shape) * sizeof(T);
55+ // 调用aclrtMalloc申请device侧内存
56+ auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);
57+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);
58+ // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上
59+ ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);
60+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);
61+ 
62+ // 计算连续tensor的strides
63+ std::vector<int64_t> strides(shape.size(), 1);
64+ for (int64_t i = shape.size() - 2; i >= 0; i--) {
65+ strides[i] = shape[i + 1] * strides[i + 1];
66+ }
67+ 
68+ // 调用aclCreateTensor接口创建aclTensor
69+ *tensor = aclCreateTensor(
70+ shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(),
71+ *deviceAddr);
72+ return 0;
73+}
74+ 
75+int main()
76+{
77+ // 1. (固定写法)device/stream初始化,参考acl API文档
78+ // 根据自己的实际device填写deviceId
79+ int32_t deviceId = 0;
80+ aclrtStream stream;
81+ auto ret = Init(deviceId, &stream);
82+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);
83+ 
84+ // 2. 构造输入与输出,需要根据API的接口自定义构造
85+ std::vector<int64_t> selfShape = {4, 2};
86+ std::vector<int64_t> dimsData = {1, 0};
87+ std::vector<int64_t> outShape = {2, 4};
88+ void* selfDeviceAddr = nullptr;
89+ void* outDeviceAddr = nullptr;
90+ aclTensor* self = nullptr;
91+ aclTensor* out = nullptr;
92+ std::vector<float> selfHostData = {1, 2, 3, 4, 5, 6, 7, 8};
93+ std::vector<float> outHostData = {0, 0, 0, 0, 0, 0, 0, 0};
94+ // 创建self aclTensor
95+ ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self);
96+ CHECK_RET(ret == ACL_SUCCESS, return ret);
97+ // 创建dims aclIntArray
98+ aclIntArray* dims = aclCreateIntArray(dimsData.data(), dimsData.size());
99+ // 创建out aclTensor
100+ ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out);
101+ CHECK_RET(ret == ACL_SUCCESS, return ret);
102+ 
103+ // 3. 调用CANN算子库API,需要修改为具体的Api名称
104+ uint64_t workspaceSize = 0;
105+ aclOpExecutor* executor;
106+ // 调用aclnnPermute第一段接口
107+ ret = aclnnPermuteGetWorkspaceSize(self, dims, out, &workspaceSize, &executor);
108+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnPermuteGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);
109+ // 根据第一段接口计算出的workspaceSize申请device内存
110+ void* workspaceAddr = nullptr;
111+ if (workspaceSize > static_cast<uint64_t>(0)) {
112+ ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
113+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
114+ }
115+ // 调用aclnnPermute第二段接口
116+ ret = aclnnPermute(workspaceAddr, workspaceSize, executor, stream);
117+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnPermute failed. ERROR: %d\n", ret); return ret);
118+ 
119+ // 4. (固定写法)同步等待任务执行结束
120+ ret = aclrtSynchronizeStream(stream);
121+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
122+ 
123+ // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改
124+ auto size = GetShapeSize(outShape);
125+ std::vector<float> resultData(size, 0);
126+ ret = aclrtMemcpy(
127+ resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr, size * sizeof(resultData[0]),
128+ ACL_MEMCPY_DEVICE_TO_HOST);
129+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
130+ for (int64_t i = 0; i < size; i++) {
131+ LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]);
132+ }
133+ 
134+ // 6. 释放aclTensor和aclIntArray,需要根据具体API的接口定义修改
135+ aclDestroyTensor(self);
136+ aclDestroyIntArray(dims);
137+ aclDestroyTensor(out);
138+ 
139+ // 7. 释放device 资源
140+ aclrtFree(selfDeviceAddr);
141+ aclrtFree(outDeviceAddr);
142+ if (workspaceSize > static_cast<uint64_t>(0)) {
143+ aclrtFree(workspaceAddr);
144+ }
145+ aclrtDestroyStream(stream);
146+ aclrtResetDevice(deviceId);
147+ aclFinalize();
148+ 
149+ return 0;
150+}
Rconversion/transpose/op_host/op_api/aclnn_channel_shuffle.cppconversion/transpose/op_api/aclnn_channel_shuffle.cpp+8-8
@@ -1,12 +1,12 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3- * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4- * CANN Open Software License Agreement Version 2.0 (the "License").4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5- * Please refer to the License for details. You may not use this file except in compliance with the License.5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7- * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8- * See LICENSE in the root of the software repository for the full text of the License.8+ * See LICENSE in the root of the software repository for the full text of the License.
9- */9+ */
10 10 
11#include "aclnn_channel_shuffle.h"11#include "aclnn_channel_shuffle.h"
12#include "aclnn_kernels/contiguous.h"12#include "aclnn_kernels/contiguous.h"
Rconversion/transpose/op_host/op_api/aclnn_channel_shuffle.hconversion/transpose/op_api/aclnn_channel_shuffle.h+8-8
@@ -1,12 +1,12 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3- * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4- * CANN Open Software License Agreement Version 2.0 (the "License").4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5- * Please refer to the License for details. You may not use this file except in compliance with the License.5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7- * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8- * See LICENSE in the root of the software repository for the full text of the License.8+ * See LICENSE in the root of the software repository for the full text of the License.
9- */9+ */
10 10 
11#ifndef OP_API_INC_LEVEL2_ACLNN_CHANNEL_SHUFFLE_H_11#ifndef OP_API_INC_LEVEL2_ACLNN_CHANNEL_SHUFFLE_H_
12#define OP_API_INC_LEVEL2_ACLNN_CHANNEL_SHUFFLE_H_12#define OP_API_INC_LEVEL2_ACLNN_CHANNEL_SHUFFLE_H_
Rconversion/transpose/op_host/op_api/aclnn_permute.cppconversion/transpose/op_api/aclnn_permute.cpp+8-8
@@ -1,12 +1,12 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3- * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4- * CANN Open Software License Agreement Version 2.0 (the "License").4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5- * Please refer to the License for details. You may not use this file except in compliance with the License.5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7- * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8- * See LICENSE in the root of the software repository for the full text of the License.8+ * See LICENSE in the root of the software repository for the full text of the License.
9- */9+ */
10 10 
11#include "aclnn_permute.h"11#include "aclnn_permute.h"
12#include "aclnn_kernels/contiguous.h"12#include "aclnn_kernels/contiguous.h"
Rconversion/transpose/op_host/op_api/aclnn_permute.hconversion/transpose/op_api/aclnn_permute.h+8-8
@@ -1,12 +1,12 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3- * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4- * CANN Open Software License Agreement Version 2.0 (the "License").4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5- * Please refer to the License for details. You may not use this file except in compliance with the License.5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7- * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8- * See LICENSE in the root of the software repository for the full text of the License.8+ * See LICENSE in the root of the software repository for the full text of the License.
9- */9+ */
10 10 
11#ifndef OP_API_INC_PERMUTE_H_11#ifndef OP_API_INC_PERMUTE_H_
12#define OP_API_INC_PERMUTE_H_12#define OP_API_INC_PERMUTE_H_
Rconversion/transpose/op_host/op_api/transpose.cppconversion/transpose/op_api/transpose.cpp+8-8
@@ -1,12 +1,12 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3- * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4- * CANN Open Software License Agreement Version 2.0 (the "License").4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5- * Please refer to the License for details. You may not use this file except in compliance with the License.5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7- * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8- * See LICENSE in the root of the software repository for the full text of the License.8+ * See LICENSE in the root of the software repository for the full text of the License.
9- */9+ */
10 10 
11#include <memory>11#include <memory>
12#include "opdev/aicpu/aicpu_task.h"12#include "opdev/aicpu/aicpu_task.h"
@@ -1,12 +1,13 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3- * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4- * CANN Open Software License Agreement Version 2.0 (the "License").4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5- * Please refer to the License for details. You may not use this file except in compliance with the License.5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7- * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8- * See LICENSE in the root of the software repository for the full text of the License.8+ * See LICENSE in the root of the software repository for the full text of the License.
9- */9+ */
10+ 
10/*!11/*!
11 * \file transpose_proto.h12 * \file transpose_proto.h
12 * \brief13 * \brief
@@ -16,8 +17,7 @@
16 17 
17#include "graph/operator_reg.h"18#include "graph/operator_reg.h"
18 19 
19-namespace ge20+namespace ge {
20-{
21/**21/**
22* @brief Permutes the dimensions according to perm.22* @brief Permutes the dimensions according to perm.
23 The returned tensor's dimension i will correspond to the input dimension perm[i].23 The returned tensor's dimension i will correspond to the input dimension perm[i].
@@ -39,17 +39,15 @@ namespace ge
39* Compatible with the TensorFlow operator Transpose.39* Compatible with the TensorFlow operator Transpose.
40*/40*/
41REG_OP(Transpose)41REG_OP(Transpose)
42- .INPUT(x, TensorType({DT_BF16, DT_FLOAT16, DT_FLOAT, DT_DOUBLE, DT_INT64, DT_INT32,42+ .INPUT(x, TensorType({DT_BF16, DT_FLOAT16, DT_FLOAT, DT_DOUBLE, DT_INT64, DT_INT32,
43- DT_UINT8, DT_UINT16, DT_UINT32, DT_UINT64, DT_INT8, DT_INT16,43+ DT_UINT8, DT_UINT16, DT_UINT32, DT_UINT64, DT_INT8, DT_INT16,
44- DT_COMPLEX32, DT_COMPLEX64, DT_COMPLEX128, DT_QINT8, DT_QUINT8,44+ DT_COMPLEX32, DT_COMPLEX64, DT_COMPLEX128, DT_QINT8, DT_QUINT8, DT_QINT16,
45- DT_QINT16, DT_QUINT16, DT_QINT32, DT_BOOL, DT_HIFLOAT8, DT_FLOAT8_E5M2,45+ DT_QUINT16, DT_QINT32, DT_BOOL, DT_HIFLOAT8, DT_FLOAT8_E5M2, DT_FLOAT8_E4M3FN}))
46- DT_FLOAT8_E4M3FN}))
47 .INPUT(perm, TensorType::IndexNumberType())46 .INPUT(perm, TensorType::IndexNumberType())
48- .OUTPUT(y, TensorType({DT_BF16, DT_FLOAT16, DT_FLOAT, DT_DOUBLE, DT_INT64, DT_INT32,47+ .OUTPUT(y, TensorType({DT_BF16, DT_FLOAT16, DT_FLOAT, DT_DOUBLE, DT_INT64, DT_INT32,
49- DT_UINT8, DT_UINT16, DT_UINT32, DT_UINT64, DT_INT8, DT_INT16,48+ DT_UINT8, DT_UINT16, DT_UINT32, DT_UINT64, DT_INT8, DT_INT16,
50- DT_COMPLEX32, DT_COMPLEX64, DT_COMPLEX128, DT_QINT8, DT_QUINT8,49+ DT_COMPLEX32, DT_COMPLEX64, DT_COMPLEX128, DT_QINT8, DT_QUINT8, DT_QINT16,
51- DT_QINT16, DT_QUINT16, DT_QINT32, DT_BOOL, DT_HIFLOAT8, DT_FLOAT8_E5M2,50+ DT_QUINT16, DT_QINT32, DT_BOOL, DT_HIFLOAT8, DT_FLOAT8_E5M2, DT_FLOAT8_E4M3FN}))
52- DT_FLOAT8_E4M3FN}))
53 .OP_END_FACTORY_REG(Transpose)51 .OP_END_FACTORY_REG(Transpose)
54 52 
55} // namespace ge53} // namespace ge
@@ -1,12 +0,0 @@
1-# ----------------------------------------------------------------------------
2-# This program is free software, you can redistribute it and/or modify it.
3-# Copyright (c) 2025 Huawei Technologies Co., Ltd.
4-# This file is a part of the CANN Open Software.
5-# Licensed under CANN Open Software License Agreement Version 2.0 (the "License").
6-# Please refer to the License for details. You may not use this file except in compliance with the License.
7-# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
8-# BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
9-# See LICENSE in the root of the software repository for the full text of the License.
10-# ----------------------------------------------------------------------------
11- 
12-add_modules_sources()
@@ -0,0 +1,1129 @@
1+/**
2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+/*!
12+ * \file transpose_tiling_arch35.cpp
13+ * \brief
14+ */
15+ 
16+#include "util/platform_util.h"
17+#include "transpose_tiling_base.h"
18+#include "transpose_tiling_arch35.h"
19+#include "transpose_tiling_with_gather_arch35.h"
20+ 
21+namespace optiling {
22+static int IncreaseCompare(const void* a, const void* b)
23+{
24+ return (*(int64_t*)a - *(int64_t*)b);
25+}
26+ 
27+ge::graphStatus TransposeNddmaTiling::Init(const int64_t& coreNum, const int64_t& ubSize)
28+{
29+ OP_LOGD(tilingContext_->GetNodeName(), "Start init TransposeNddmaTiling.");
30+ coreNum_ = coreNum;
31+ OP_CHECK_IF(
32+ (coreNum_ <= 0), OP_LOGE(tilingContext_->GetNodeName(), "Failed to get core num."), return ge::GRAPH_FAILED);
33+ ubSize_ = ubSize;
34+ OP_CHECK_IF(
35+ (ubSize_ <= 0), OP_LOGE(tilingContext_->GetNodeName(), "Failed to get ub size."), return ge::GRAPH_FAILED);
36+ 
37+ cacheLineSize_ = Ops::Base::GetCacheLineSize(tilingContext_);
38+ OP_CHECK_IF(
39+ (cacheLineSize_ <= 0), OP_LOGE(tilingContext_->GetNodeName(), "Failed to get cache line size."),
40+ return ge::GRAPH_FAILED);
41+ 
42+ ubBlockSize_ = Ops::Base::GetUbBlockSize(tilingContext_);
43+ OP_CHECK_IF(
44+ (ubBlockSize_ <= 0), OP_LOGE(tilingContext_->GetNodeName(), "Failed to get ub block size."),
45+ return ge::GRAPH_FAILED);
46+ return ge::GRAPH_SUCCESS;
47+}
48+ 
49+ge::graphStatus TransposeNddmaTiling::RunTranposelTiling()
50+{
51+ OP_LOGD(tilingContext_->GetNodeName(), "Start running Tiling4Transpose.");
52+ if (!isReleatedTranspsoe_) {
53+ OP_CHECK_IF(
54+ GetShapeInfo() != ge::GRAPH_SUCCESS, OP_LOGE(tilingContext_->GetNodeName(), "Failed to get shape info!"),
55+ return ge::GRAPH_FAILED);
56+ }
57+ 
58+ OP_CHECK_IF(
59+ CheckShapeInfo() != ge::GRAPH_SUCCESS, OP_LOGE(tilingContext_->GetNodeName(), "Failed to check shape info!"),
60+ return ge::GRAPH_FAILED);
61+ // if axis value is 1, remove it.
62+ RemoveAxisV2(shapeInfo_);
63+ // reduce axis
64+ MergeAxisV2(shapeInfo_);
65+ // check reduced shape
66+ OP_CHECK_IF(
67+ CheckReducedShapeInfo() != ge::GRAPH_SUCCESS,
68+ OP_LOGE(tilingContext_->GetNodeName(), "Failed to check reduced shape info!"), return ge::GRAPH_FAILED);
69+ 
70+ SetIsLastAxisTranspose();
71+ if (!isReleatedTranspsoe_ && shapeInfo_.isLastAxisTranspose) {
72+ TransWithGather::PlatInfo platInfo{coreNum_, ubSize_, cacheLineSize_, ubBlockSize_};
73+ TransWithGather::TransposeGatherTiling gatherTiling(tilingContext_, platInfo, shapeInfo_);
74+ OP_CHECK_IF(
75+ gatherTiling.DoTiling() == ge::GRAPH_SUCCESS,
76+ OP_LOGD(tilingContext_->GetNodeName(), "Do gather tiling done!"), return ge::GRAPH_SUCCESS);
77+ }
78+ 
79+ // UB split
80+ CalcSplitInfo();
81+ // block split
82+ CalcBlockSplitInfo();
83+ // dim expand
84+ NDDMADimExpand();
85+ // get in ub shape info
86+ GetInUbShapeInfo();
87+ // cut twice get interval info
88+ GetIntervalInfo();
89+ // fill data
90+ FillTilingData();
91+ // print data
92+ PrintTilingData();
93+ // set block dim and tilingKey
94+ tilingContext_->SetBlockDim(tilingData_.transposeOpTiling.get_realCoreNum());
95+ tilingContext_->SetTilingKey(tilingKey_);
96+ size_t* workspaces = tilingContext_->GetWorkspaceSizes(1);
97+ OP_CHECK_NULL_WITH_CONTEXT(tilingContext_, workspaces);
98+ workspaces[0] = WORK_SPACE_SIZE;
99+ OP_LOGD(tilingContext_->GetNodeName(), "Tiling4Transpose success.");
100+ return ge::GRAPH_SUCCESS;
101+}
102+ 
103+template <typename T>
104+bool TransposeNddmaTiling::GetPerm(const gert::Tensor* permTensor)
105+{
106+ const T* permValue = permTensor->GetData<T>();
107+ if (!permValue) {
108+ OP_LOGE(tilingContext_->GetNodeName(), "Perm GetData is nullptr");
109+ return false;
110+ }
111+ int64_t dims = permTensor->GetShapeSize();
112+ for (int64_t i = 0; i < dims; i++) {
113+ shapeInfo_.perm[i] = permValue[i] < 0 ? permValue[i] + dims : permValue[i];
114+ }
115+ return true;
116+}
117+ 
118+void TransposeNddmaTiling::SetIsLastAxisTranspose()
119+{
120+ int64_t dim = shapeInfo_.dim;
121+ shapeInfo_.isLastAxisTranspose = shapeInfo_.reducedPerm[dim - 1] != dim - 1 ? true : false;
122+}
123+ 
124+void TransposeNddmaTiling::CalcTotalVolumeActual()
125+{
126+ int64_t vol = 1;
127+ for (int64_t i = 0; i < shapeInfo_.dim; i++) {
128+ vol = vol * shapeInfo_.reducedInShape[i];
129+ }
130+ shapeInfo_.totalVolumeActual = vol;
131+}
132+ 
133+ge::graphStatus TransposeNddmaTiling::GetShapeInfo()
134+{
135+ OP_LOGD(tilingContext_->GetNodeName(), "Entering GetShapeInfo.");
136+ 
137+ const gert::Tensor* permTensor = tilingContext_->GetInputTensor(INPUT_IDX_PERM);
138+ OP_CHECK_NULL_WITH_CONTEXT(tilingContext_, permTensor);
139+ shapeInfo_.permSize = permTensor->GetShapeSize();
140+ 
141+ auto permDtype = tilingContext_->GetInputDesc(INPUT_IDX_PERM)->GetDataType();
142+ uint64_t permDtypeSize = ge::GetSizeByDataType(permDtype);
143+ if (permDtypeSize == B32_BYTES) {
144+ if (!GetPerm<int32_t>(permTensor)) {
145+ return ge::GRAPH_FAILED;
146+ }
147+ } else if (permDtypeSize == B64_BYTES) {
148+ if (!GetPerm<int64_t>(permTensor)) {
149+ return ge::GRAPH_FAILED;
150+ }
151+ } else {
152+ OP_LOGE(tilingContext_->GetNodeName(), "Invalid dtype, it should be int32 or int64");
153+ return ge::GRAPH_FAILED;
154+ }
155+ 
156+ auto outputY = tilingContext_->GetOutputShape(OUTPUT_IDX_Y);
157+ OP_CHECK_NULL_WITH_CONTEXT(tilingContext_, outputY);
158+ auto yShape = outputY->GetStorageShape();
159+ auto yDims = yShape.GetDimNum();
160+ auto inputX = tilingContext_->GetInputTensor(INPUT_IDX_X);
161+ OP_CHECK_NULL_WITH_CONTEXT(tilingContext_, inputX);
162+ auto xShape = inputX->GetStorageShape();
163+ auto xDims = xShape.GetDimNum();
164+ 
165+ auto xDtype = tilingContext_->GetInputDesc(INPUT_IDX_X)->GetDataType();
166+ shapeInfo_.eleLenInBytes = ge::GetSizeByDataType(xDtype);
167+ shapeInfo_.inShapeSize = xDims;
168+ shapeInfo_.outShapeSize = yDims;
169+ shapeInfo_.dim = xDims;
170+ shapeInfo_.origDim = xDims;
171+ for (int64_t i = 0; i < shapeInfo_.inShapeSize; i++) {
172+ shapeInfo_.inShape[i] = xShape[i];
173+ shapeInfo_.outShape[i] = yShape[i];
174+ }
175+ 
176+ return ge::GRAPH_SUCCESS;
177+}
178+ 
179+ge::graphStatus TransposeNddmaTiling::CheckShapeInfo()
180+{
181+ OP_LOGD(tilingContext_->GetNodeName(), "Entering CheckShapeInfo.");
182+ int64_t inDims = shapeInfo_.inShapeSize;
183+ int64_t outDims = shapeInfo_.outShapeSize;
184+ int64_t permDims = shapeInfo_.permSize;
185+ if (inDims < 1 || inDims != outDims || inDims != permDims) {
186+ OP_LOGE(
187+ tilingContext_->GetNodeName(), "The dim of inputs is invalid, inDims = %ld, outDims = %ld, permDims = %ld",
188+ inDims, outDims, permDims);
189+ return ge::GRAPH_FAILED;
190+ }
191+ 
192+ for (int64_t i = 0; i < inDims; i++) {
193+ if (shapeInfo_.perm[i] >= inDims) {
194+ OP_LOGE(tilingContext_->GetNodeName(), "Invalid perm value %ld.", shapeInfo_.perm[i]);
195+ return ge::GRAPH_FAILED;
196+ }
197+ if (shapeInfo_.inShape[shapeInfo_.perm[i]] != shapeInfo_.outShape[i]) {
198+ OP_LOGE(tilingContext_->GetNodeName(), "The dim of inputs or outputs conflict with perm.");
199+ return ge::GRAPH_FAILED;
200+ }
201+ }
202+ 
203+ for (int64_t i = 0; i < inDims; i++) {
204+ if (shapeInfo_.inShape[i] <= 0 || shapeInfo_.outShape[i] <= 0) {
205+ OP_LOGE(
206+ tilingContext_->GetNodeName(), "Invalid shape, %ld, %ld, %ld", i, shapeInfo_.inShape[i],
207+ shapeInfo_.outShape[i]);
208+ return ge::GRAPH_FAILED;
209+ }
210+ }
211+ 
212+ return ge::GRAPH_SUCCESS;
213+}
214+ 
215+ge::graphStatus TransposeNddmaTiling::CheckReducedShapeInfo()
216+{
217+ OP_LOGD(tilingContext_->GetNodeName(), "Entering CheckReducedShapeInfo.");
218+ auto dim = shapeInfo_.dim;
219+ if (dim < 1) {
220+ OP_LOGE(tilingContext_->GetNodeName(), "The dim of reducedShape is invalid, dim = %ld", dim);
221+ return ge::GRAPH_FAILED;
222+ }
223+ 
224+ for (int64_t i = 0; i < dim; i++) {
225+ if (shapeInfo_.reducedInShape[i] <= 0 || shapeInfo_.reducedOutShape[i] <= 0) {
226+ OP_LOGE(
227+ tilingContext_->GetNodeName(), "Invalid shape, index is %ld, inShape is %ld, outShape is %ld", i,
228+ shapeInfo_.reducedInShape[i], shapeInfo_.reducedOutShape[i]);
229+ return ge::GRAPH_FAILED;
230+ }
231+ }
232+ 
233+ return ge::GRAPH_SUCCESS;
234+}
235+ 
236+int64_t TransposeNddmaTiling::DoSplitUBInput()
237+{
238+ int64_t remainingTotalElment = shapeInfo_.totalVolumeActual;
239+ for (int64_t i = 0; i < shapeInfo_.dim; i++) {
240+ int64_t currentShapeDim = shapeInfo_.reducedInShape[shapeInfo_.dim - 1 - i];
241+ if (splitInfo_.inUbElement < currentShapeDim) {
242+ splitInfo_.inCutIndex = shapeInfo_.dim - 1 - i;
243+ splitInfo_.inUbFactor = splitInfo_.inUbElement;
244+ splitInfo_.inTailFactor = currentShapeDim % splitInfo_.inUbFactor;
245+ splitInfo_.inUbActual *= splitInfo_.inUbElement;
246+ remainingTotalElment =
247+ remainingTotalElment / currentShapeDim * Ops::Base::CeilDiv(currentShapeDim, splitInfo_.inUbElement);
248+ break;
249+ } else {
250+ splitInfo_.inUbElement /= currentShapeDim;
251+ splitInfo_.inUbActual *= currentShapeDim;
252+ remainingTotalElment /= currentShapeDim;
253+ }
254+ }
255+ splitInfo_.outUbElement = splitInfo_.ubElement / splitInfo_.inUbActual;
256+ return remainingTotalElment;
257+}
258+ 
259+int64_t TransposeNddmaTiling::FindOutIndex(int64_t index)
260+{
261+ for (int64_t i = 0; i < shapeInfo_.dim; i++) {
262+ if (shapeInfo_.reducedPerm[i] == index) {
263+ return i;
264+ }
265+ }
266+ return 0;
267+}
268+ 
269+bool TransposeNddmaTiling::UbOutOfBoundCheck(int64_t currentSplitIndex, int64_t currentSplitValue, bool calcIn)
270+{
271+ int64_t burstLenBlockAlign = 1;
272+ for (int64_t i = currentSplitIndex + 1; i < shapeInfo_.dim; i++) {
273+ burstLenBlockAlign *= shapeInfo_.reducedOutShape[i];
274+ }
275+ burstLenBlockAlign *= currentSplitValue;
276+ if (calcIn && shapeInfo_.reducedPerm[currentSplitIndex] == splitInfo_.inCutIndex) {
277+ burstLenBlockAlign *= splitInfo_.inUbFactor;
278+ }
279+ burstLenBlockAlign =
280+ Ops::Base::CeilAlign(burstLenBlockAlign * shapeInfo_.eleLenInBytes, ubBlockSize_) / shapeInfo_.eleLenInBytes;
281+ int64_t inUbElements = burstLenBlockAlign;
282+ for (int64_t i = 0; i < currentSplitIndex; i++) {
283+ if (shapeInfo_.reducedPerm[i] > splitInfo_.inCutIndex) {
284+ inUbElements *= shapeInfo_.reducedOutShape[i];
285+ } else if (shapeInfo_.reducedPerm[i] == splitInfo_.inCutIndex) {
286+ inUbElements *= splitInfo_.inUbFactor;
287+ }
288+ }
289+ if (inUbElements > splitInfo_.ubElement) {
290+ return true;
291+ }
292+ return false;
293+}
294+ 
295+bool TransposeNddmaTiling::UbOutOfBoundCheckNLast(int64_t currentSplitIndex, int64_t currentSplitValue)
296+{
297+ int64_t burstLenBlockAlign = 1;
298+ if (currentSplitIndex == shapeInfo_.dim - 1) {
299+ burstLenBlockAlign = currentSplitValue;
300+ } else {
301+ burstLenBlockAlign = shapeInfo_.reducedInShape[shapeInfo_.dim - 1];
302+ }
303+ burstLenBlockAlign =
304+ Ops::Base::CeilAlign(burstLenBlockAlign * shapeInfo_.eleLenInBytes, ubBlockSize_) / shapeInfo_.eleLenInBytes;
305+ int64_t inUbElements = burstLenBlockAlign;
306+ for (int64_t i = currentSplitIndex; i < shapeInfo_.dim - 1; i++) {
307+ if (i == currentSplitIndex) {
308+ inUbElements *= currentSplitValue;
309+ } else {
310+ inUbElements *= shapeInfo_.reducedInShape[i];
311+ }
312+ }
313+ if (inUbElements > splitInfo_.ubElement) {
314+ return true;
315+ }
316+ return false;
317+}
318+ 
319+void TransposeNddmaTiling::FindSplitFactorByRateNLast(
320+ int64_t currentSplitIndex, int64_t currentInShapeDim, int64_t remainingTotalElment)
321+{
322+ splitInfo_.inCutIndex = currentSplitIndex;
323+ splitInfo_.inUbFactor = 1;
324+ splitInfo_.inTailFactor = 0;
325+ for (int64_t i = splitInfo_.inUbElement; i >= DIM_TWO; i--) {
326+ int64_t coreNumNew = remainingTotalElment * Ops::Base::CeilDiv(currentInShapeDim, i);
327+ double rate = static_cast<double>(coreNumNew) / coreNum_;
328+ if ((rate >= VEC_CORE_USED_THRES_HOLD) && !UbOutOfBoundCheckNLast(currentSplitIndex, i)) {
329+ splitInfo_.inUbFactor = i;
330+ splitInfo_.inTailFactor = currentInShapeDim % i;
331+ splitInfo_.inUbActual *= i;
332+ break;
333+ }
334+ }
335+}
336+ 
337+void TransposeNddmaTiling::FindSplitFactorByMultiplesLast(
338+ int64_t currentSplitIndex, int64_t currentShapeDim, int64_t remainingTotalElment, int64_t coreNumMultiples)
339+{
340+ splitInfo_.outCutIndex = currentSplitIndex;
341+ int64_t bestI = 1;
342+ for (int64_t i = 1; i <= splitInfo_.outUbElement; i++) {
343+ int64_t coreNumNew = remainingTotalElment * Ops::Base::CeilDiv(currentShapeDim, i);
344+ if ((Ops::Base::FloorDiv(coreNumNew, coreNum_) == coreNumMultiples) &&
345+ !UbOutOfBoundCheck(currentSplitIndex, i, true)) {
346+ splitInfo_.outUbFactor = i;
347+ splitInfo_.outTailFactor = currentShapeDim % i;
348+ splitInfo_.outUbActual *= i;
349+ return;
350+ }
351+ if (!UbOutOfBoundCheck(currentSplitIndex, i, true)) {
352+ bestI = i;
353+ }
354+ }
355+ splitInfo_.outUbFactor = bestI;
356+ splitInfo_.outTailFactor = currentShapeDim % bestI;
357+ splitInfo_.outUbActual *= bestI;
358+}
359+ 
360+void TransposeNddmaTiling::FindSplitFactorByMultiplesNLast(
361+ int64_t currentSplitIndex, int64_t currentInShapeDim, int64_t remainingTotalElment, int64_t coreNumMultiples)
362+{
363+ splitInfo_.inCutIndex = currentSplitIndex;
364+ for (int64_t i = splitInfo_.inUbElement; i >= 1; i--) {
365+ if (!UbOutOfBoundCheckNLast(currentSplitIndex, i)) {
366+ splitInfo_.inUbFactor = i;
367+ splitInfo_.inTailFactor = currentInShapeDim % i;
368+ splitInfo_.inUbActual *= i;
369+ break;
370+ }
371+ }
372+ int64_t coreNumTmp = remainingTotalElment * Ops::Base::CeilDiv(currentInShapeDim, splitInfo_.inUbFactor);
373+ coreNumMultiples = Ops::Base::FloorDiv(coreNumTmp, coreNum_);
374+ for (int64_t i = 1; i < splitInfo_.inUbFactor; i++) {
375+ int64_t coreNumNew = remainingTotalElment * Ops::Base::CeilDiv(currentInShapeDim, i);
376+ if ((Ops::Base::FloorDiv(coreNumNew, coreNum_) == coreNumMultiples) &&
377+ !UbOutOfBoundCheckNLast(currentSplitIndex, i)) {
378+ splitInfo_.inUbFactor = i;
379+ splitInfo_.inTailFactor = currentInShapeDim % i;
380+ splitInfo_.inUbActual = splitInfo_.inUbActual / splitInfo_.inUbElement * i;
381+ break;
382+ }
383+ }
384+}
385+ 
386+void TransposeNddmaTiling::DoSplitUB()
387+{
388+ int64_t remainingTotalElment = DoSplitUBInput();
389+ bool isSplitDifferentAxis = false;
390+ for (int64_t i = 0; i < shapeInfo_.dim; i++) {
391+ int64_t currentSplitIndex = shapeInfo_.dim - 1 - i;
392+ if (shapeInfo_.reducedPerm[currentSplitIndex] > splitInfo_.inCutIndex) { // skip axis full cut by input shape
393+ continue;
394+ }
395+ int64_t currentShapeDim = shapeInfo_.reducedOutShape[currentSplitIndex];
396+ if (shapeInfo_.reducedPerm[currentSplitIndex] == splitInfo_.inCutIndex) {
397+ currentShapeDim =
398+ Ops::Base::CeilDiv(shapeInfo_.reducedInShape[splitInfo_.inCutIndex], splitInfo_.inUbFactor);
399+ }
400+ remainingTotalElment /= currentShapeDim;
401+ int64_t coreNumTmp = remainingTotalElment * Ops::Base::CeilDiv(currentShapeDim, splitInfo_.outUbElement);
402+ if (splitInfo_.outUbElement < currentShapeDim) {
403+ if (coreNumTmp > coreNum_) { // use full coreNum
404+ int64_t coreNumMultiples = Ops::Base::FloorDiv(coreNumTmp, coreNum_);
405+ FindSplitFactorByMultiplesLast(
406+ currentSplitIndex, currentShapeDim, remainingTotalElment, coreNumMultiples);
407+ } else {
408+ splitInfo_.outCutIndex = currentSplitIndex;
409+ splitInfo_.outUbFactor = splitInfo_.outUbElement;
410+ splitInfo_.outTailFactor = currentShapeDim % splitInfo_.outUbElement;
411+ splitInfo_.outUbActual *= splitInfo_.outUbElement;
412+ }
413+ if (currentSplitIndex > FindOutIndex(splitInfo_.inCutIndex)) {
414+ isSplitDifferentAxis = true;
415+ tilingKey_ = static_cast<int64_t>(SplitMode::CUT_TWICE);
416+ }
417+ break;
418+ } else {
419+ splitInfo_.outUbElement /= currentShapeDim;
420+ splitInfo_.outUbActual *= currentShapeDim;
421+ }
422+ }
423+ if (!isSplitDifferentAxis) {
424+ tilingKey_ = static_cast<int64_t>(SplitMode::CUT_ONCE);
425+ }
426+}
427+ 
428+void TransposeNddmaTiling::DoSplitUBBigDim()
429+{
430+ OP_LOGD(tilingContext_->GetNodeName(), "Entering DoSplitUBBigDim.");
431+ int64_t dimSize = NDDMA_MAX_DIM_NUM - 1;
432+ int64_t totalElment = shapeInfo_.totalVolumeActual;
433+ // search split index and calc base number
434+ for (int64_t i = shapeInfo_.dim - 1; i >= 0; i--) {
435+ if (splitInfo_.ubElement < shapeInfo_.reducedOutShape[i]) {
436+ splitInfo_.outCutIndex = i;
437+ splitInfo_.outUbFactor = splitInfo_.ubElement;
438+ splitInfo_.outTailFactor = shapeInfo_.reducedOutShape[i] % splitInfo_.outUbFactor;
439+ break;
440+ } else if (dimSize > 0) {
441+ totalElment = totalElment / shapeInfo_.reducedOutShape[i];
442+ if (totalElment <= coreNum_) {
443+ splitInfo_.outCutIndex = i;
444+ splitInfo_.outUbFactor = splitInfo_.ubElement <= shapeInfo_.reducedOutShape[i] ?
445+ splitInfo_.ubElement :
446+ shapeInfo_.reducedOutShape[i];
447+ splitInfo_.outTailFactor = shapeInfo_.reducedOutShape[i] % splitInfo_.outUbFactor;
448+ break;
449+ }
450+ splitInfo_.ubElement = splitInfo_.ubElement / shapeInfo_.reducedOutShape[i];
451+ dimSize--;
452+ } else if (dimSize == 0) {
453+ splitInfo_.outCutIndex = i;
454+ splitInfo_.outUbFactor = splitInfo_.ubElement <= shapeInfo_.reducedOutShape[i] ?
455+ splitInfo_.ubElement :
456+ shapeInfo_.reducedOutShape[i];
457+ splitInfo_.outTailFactor = shapeInfo_.reducedOutShape[i] % splitInfo_.outUbFactor;
458+ break;
459+ }
460+ }
461+}
462+ 
463+void TransposeNddmaTiling::FlushBaseNumForBigDim()
464+{
465+ OP_LOGD(tilingContext_->GetNodeName(), "Entering FlushBaseNumForBigDim.");
466+ int64_t idxNum = NDDMA_MAX_DIM_NUM - 1;
467+ int64_t baseInNum = 1;
468+ int64_t baseOutNum = 1;
469+ int64_t tmpNddmaShape[NDDMA_MAX_DIM_NUM] = {0};
470+ int64_t oriNddmaIdx[NDDMA_MAX_DIM_NUM] = {-1};
471+ for (int64_t i = shapeInfo_.dim - 1; i >= 0; i--) {
472+ baseInShape_[i] = baseInNum;
473+ baseInNum *= shapeInfo_.reducedInShape[i];
474+ baseOutNum *= shapeInfo_.reducedOutShape[i];
475+ if (i > splitInfo_.outCutIndex) {
476+ nddmaIdx_[idxNum] = shapeInfo_.reducedPerm[i];
477+ oriNddmaIdx[idxNum] = shapeInfo_.reducedPerm[i];
478+ tmpNddmaShape[idxNum] = totalNddmaNum_;
479+ totalNddmaNum_ *= shapeInfo_.reducedOutShape[i];
480+ idxNum--;
481+ } else if (i == splitInfo_.outCutIndex) {
482+ nddmaIdx_[idxNum] = shapeInfo_.reducedPerm[i];
483+ oriNddmaIdx[idxNum] = shapeInfo_.reducedPerm[i];
484+ tmpNddmaShape[idxNum] = totalNddmaNum_;
485+ totalNddmaNum_ *= splitInfo_.outUbFactor;
486+ idxNum--;
487+ } else if (idxNum >= 0) {
488+ nddmaIdx_[idxNum] = shapeInfo_.reducedPerm[i];
489+ oriNddmaIdx[idxNum] = shapeInfo_.reducedPerm[i];
490+ tmpNddmaShape[idxNum] = totalNddmaNum_;
491+ idxNum--;
492+ }
493+ }
494+ 
495+ qsort(nddmaIdx_, NDDMA_MAX_DIM_NUM, sizeof(int64_t), IncreaseCompare);
496+ for (int64_t i = 0; i < NDDMA_MAX_DIM_NUM; i++) {
497+ for (int64_t j = 0; j < NDDMA_MAX_DIM_NUM; j++) {
498+ if (nddmaIdx_[i] == oriNddmaIdx[j]) {
499+ baseNddmaShape_[i] = tmpNddmaShape[j];
500+ }
501+ }
502+ }
503+}
504+ 
505+void TransposeNddmaTiling::CalcSplitInfo()
506+{
507+ OP_LOGD(tilingContext_->GetNodeName(), "Entering CalcSplitInfo.");
508+ SetIsLastAxisTranspose();
509+ CalcTotalVolumeActual();
510+ splitInfo_.ubElement = ubSize_ / shapeInfo_.eleLenInBytes;
511+ int64_t lastAxisByte = shapeInfo_.reducedInShape[shapeInfo_.dim - 1] * shapeInfo_.eleLenInBytes;
512+ if (shapeInfo_.dim == 1) { // just tensor move
513+ splitInfo_.ubElement = ubSize_ / bufferNum / shapeInfo_.eleLenInBytes;
514+ tilingKey_ = static_cast<int64_t>(SplitMode::TENSOR_MOVE);
515+ } else if (shapeInfo_.totalVolumeActual * shapeInfo_.eleLenInBytes <= SMALL_SHAPE_BYTES_THRES_HOLD) { // small shape
516+ tilingKey_ = static_cast<int64_t>(SplitMode::SMALL_SHAPE);
517+ } else if (shapeInfo_.isLastAxisTranspose && shapeInfo_.dim <= NDDMA_MAX_DIM_NUM) { // last axis join tanspose
518+ splitInfo_.inUbElement = sqrt(splitInfo_.ubElement);
519+ DoSplitUB();
520+ } else { // last axis not join tanspose or dim > NDDMA_MAX_DIM_NUM
521+ if (!shapeInfo_.isLastAxisTranspose && lastAxisByte >= cacheLineSize_) {
522+ splitInfo_.ubElement = ubSize_ / bufferNum / shapeInfo_.eleLenInBytes;
523+ tilingKey_ = static_cast<int64_t>(SplitMode::N_LAST_TRANSPOSE);
524+ } else if (shapeInfo_.dim <= NDDMA_MAX_DIM_NUM && lastAxisByte < cacheLineSize_) {
525+ splitInfo_.inUbElement = sqrt(splitInfo_.ubElement);
526+ DoSplitUB();
527+ } else {
528+ tilingKey_ = static_cast<int64_t>(SplitMode::BIG_DIM);
529+ DoSplitUBBigDim();
530+ }
531+ }
532+}
533+ 
534+void TransposeNddmaTiling::CalcBlockSplitInfoForTensorMove()
535+{
536+ OP_LOGD(tilingContext_->GetNodeName(), "Entering CalcBlockSplitInfoForTensorMove.");
537+ if (shapeInfo_.totalVolumeActual < coreNum_) {
538+ realCoreNum_ = 1;
539+ blkFactor_ = shapeInfo_.totalVolumeActual;
540+ blkTailFactor_ = 0;
541+ splitInfo_.inUbFactor = splitInfo_.ubElement;
542+ } else {
543+ realCoreNum_ = coreNum_;
544+ blkFactor_ = shapeInfo_.totalVolumeActual / coreNum_;
545+ blkTailFactor_ = shapeInfo_.totalVolumeActual % coreNum_;
546+ splitInfo_.inUbFactor = splitInfo_.ubElement;
547+ }
548+}
549+ 
550+int64_t TransposeNddmaTiling::CalcBlockSplitInfoForNoCutForMultiCore(
551+ int64_t i, int64_t shapeSizeByte, int64_t& totalElment)
552+{
553+ for (int64_t j = 2; j <= shapeInfo_.reducedOutShape[i]; j++) {
554+ if ((shapeInfo_.reducedOutShape[i] % j == 0) &&
555+ (shapeSizeByte / shapeInfo_.reducedOutShape[i] * j > cacheLineSize_)) {
556+ if (j == shapeInfo_.reducedOutShape[i] && i == 0) {
557+ // 素数且切到了最后,正常切
558+ splitInfo_.outCutIndex = i;
559+ splitInfo_.outUbFactor =
560+ Ops::Base::CeilDiv(cacheLineSize_ + 1, shapeSizeByte / shapeInfo_.reducedOutShape[i]);
561+ splitInfo_.outTailFactor = shapeInfo_.reducedOutShape[i] % splitInfo_.outUbFactor;
562+ totalElment *= Ops::Base::CeilDiv(shapeInfo_.reducedOutShape[i], splitInfo_.outUbFactor);
563+ break;
564+ } else if (j == shapeInfo_.reducedOutShape[i] && i != 0) {
565+ // 素数但还没切到最后,全切,剩下的轴开多核
566+ splitInfo_.outCutIndex = i;
567+ splitInfo_.outUbFactor = shapeInfo_.reducedOutShape[i];
568+ splitInfo_.outTailFactor = 0;
569+ break;
570+ } else {
571+ // 其他场景,按最小因数切
572+ splitInfo_.outCutIndex = i;
573+ splitInfo_.outUbFactor = j;
574+ splitInfo_.outTailFactor = 0;
575+ totalElment *= Ops::Base::CeilDiv(shapeInfo_.reducedOutShape[i], splitInfo_.outUbFactor);
576+ break;
577+ }
578+ }
579+ }
580+ return totalElment;
581+}
582+ 
583+void TransposeNddmaTiling::CalcBlockSplitInfoForSmallShape()
584+{
585+ OP_LOGD(tilingContext_->GetNodeName(), "Entering CalcBlockSplitInfoForSmallShape.");
586+ int64_t totalElements = shapeInfo_.totalVolumeActual;
587+ if (totalElements < coreNum_) {
588+ realCoreNum_ = totalElements;
589+ blkFactor_ = 1;
590+ blkTailFactor_ = 0;
591+ return;
592+ }
593+ // simt every core elemets align to 128Byte
594+ int64_t blkFactor = totalElements / coreNum_;
595+ int64_t ceilAlignFactor =
596+ Ops::Base::CeilDiv(blkFactor * shapeInfo_.eleLenInBytes, SMALL_SHAPE_SPLIT_BYTES_ALIGN_SIZE) *
597+ SMALL_SHAPE_SPLIT_BYTES_ALIGN_SIZE / shapeInfo_.eleLenInBytes;
598+ int64_t floorAlignFactor =
599+ Ops::Base::FloorDiv(blkFactor * shapeInfo_.eleLenInBytes, SMALL_SHAPE_SPLIT_BYTES_ALIGN_SIZE) *
600+ SMALL_SHAPE_SPLIT_BYTES_ALIGN_SIZE / shapeInfo_.eleLenInBytes;
601+ if (totalElements - floorAlignFactor * (coreNum_ - 1) <= floorAlignFactor) {
602+ realCoreNum_ = coreNum_;
603+ blkFactor_ = floorAlignFactor;
604+ blkTailFactor_ = totalElements % floorAlignFactor;
605+ } else {
606+ realCoreNum_ = Ops::Base::CeilDiv(totalElements, ceilAlignFactor);
607+ blkFactor_ = ceilAlignFactor;
608+ blkTailFactor_ = totalElements % ceilAlignFactor;
609+ }
610+}
611+ 
612+void TransposeNddmaTiling::CalcBlockSplitInfoForNLastTranspose()
613+{
614+ OP_LOGD(tilingContext_->GetNodeName(), "Entering CalcBlockSplitInfoForNLastTranspose.");
615+ splitInfo_.inUbElement = splitInfo_.ubElement;
616+ int64_t remainingTotalElment = shapeInfo_.totalVolumeActual;
617+ int64_t currentSplitIndex;
618+ int64_t currentInShapeDim;
619+ for (int64_t i = 0; i < shapeInfo_.dim; i++) {
620+ currentSplitIndex = shapeInfo_.dim - 1 - i;
621+ currentInShapeDim = shapeInfo_.reducedInShape[currentSplitIndex];
622+ remainingTotalElment /= currentInShapeDim;
623+ int64_t coreNumTmp = remainingTotalElment * Ops::Base::CeilDiv(currentInShapeDim, splitInfo_.inUbElement);
624+ if (splitInfo_.inUbElement < currentInShapeDim) {
625+ if (coreNumTmp < coreNum_) { // use at least VEC_CORE_USED_THRES_HOLD * coreNum
626+ FindSplitFactorByRateNLast(currentSplitIndex, currentInShapeDim, remainingTotalElment);
627+ break;
628+ } else { // use full coreNum
629+ int64_t coreNumMultiples = Ops::Base::FloorDiv(coreNumTmp, coreNum_);
630+ FindSplitFactorByMultiplesNLast(
631+ currentSplitIndex, currentInShapeDim, remainingTotalElment, coreNumMultiples);
632+ break;
633+ }
634+ } else if (coreNumTmp < coreNum_) { // use at least VEC_CORE_USED_THRES_HOLD * coreNum
635+ FindSplitFactorByRateNLast(currentSplitIndex, currentInShapeDim, remainingTotalElment);
636+ break;
637+ } else {
638+ splitInfo_.inUbElement /= currentInShapeDim;
639+ }
640+ }
641+ int64_t coreNum = Ops::Base::CeilDiv(shapeInfo_.reducedInShape[splitInfo_.inCutIndex], splitInfo_.inUbFactor) *
642+ remainingTotalElment;
643+ SetRealCoreNumAndBlkFactor(coreNum);
644+}
645+ 
646+void TransposeNddmaTiling::SetRealCoreNumAndBlkFactor(int64_t coreNum)
647+{
648+ if (coreNum >= coreNum_) {
649+ realCoreNum_ = coreNum_;
650+ blkFactor_ = coreNum / coreNum_;
651+ blkTailFactor_ = coreNum % coreNum_;
652+ } else {
653+ realCoreNum_ = coreNum;
654+ blkFactor_ = 1;
655+ blkTailFactor_ = 0;
656+ }
657+}
658+ 
659+void TransposeNddmaTiling::CalcBlockSplitInfoForCutOnce()
660+{
661+ OP_LOGD(tilingContext_->GetNodeName(), "Entering CalcBlockSplitInfoForCutOnce.");
662+ // input and output split the same axis, the split factor is subject to the output
663+ if (splitInfo_.inCutIndex == shapeInfo_.reducedPerm[splitInfo_.outCutIndex]) {
664+ splitInfo_.outUbFactor *= splitInfo_.inUbFactor;
665+ splitInfo_.outTailFactor = shapeInfo_.reducedOutShape[splitInfo_.outCutIndex] % splitInfo_.outUbFactor;
666+ }
667+ // input and output split different axis, but output split factor is the whole axis
668+ if (splitInfo_.outUbFactor == shapeInfo_.reducedOutShape[splitInfo_.outCutIndex]) {
669+ splitInfo_.outCutIndex = FindOutIndex(splitInfo_.inCutIndex);
670+ splitInfo_.outUbFactor = splitInfo_.inUbFactor;
671+ splitInfo_.outTailFactor = shapeInfo_.reducedOutShape[splitInfo_.outCutIndex] % splitInfo_.outUbFactor;
672+ }
673+ int64_t outUbAxis = Ops::Base::CeilDiv(shapeInfo_.reducedOutShape[splitInfo_.outCutIndex], splitInfo_.outUbFactor);
674+ int64_t outUbAxisExceptSplitAxis = 1;
675+ for (int64_t i = 0; i < splitInfo_.outCutIndex; i++) {
676+ if (shapeInfo_.reducedPerm[i] < splitInfo_.inCutIndex) {
677+ outUbAxisExceptSplitAxis *= shapeInfo_.reducedOutShape[i];
678+ }
679+ }
680+ if (outUbAxis < coreNum_) {
681+ // use at least VEC_CORE_USED_THRES_HOLD * coreNum
682+ int64_t currentSplitIndex = splitInfo_.outCutIndex;
683+ int64_t currentShapeDim = shapeInfo_.reducedOutShape[currentSplitIndex];
684+ int64_t bestI = 1;
685+ double bestRate = 0.0;
686+ bool foundValidFactor = false;
687+ for (int64_t i = splitInfo_.outUbFactor; i >= 1; i--) {
688+ int64_t coreNumNew = Ops::Base::CeilDiv(currentShapeDim, i) * outUbAxisExceptSplitAxis;
689+ double rate = static_cast<double>(coreNumNew) / coreNum_;
690+ if ((rate >= VEC_CORE_USED_THRES_HOLD) && !UbOutOfBoundCheck(currentSplitIndex, i, false)) {
691+ splitInfo_.outUbFactor = i;
692+ splitInfo_.outTailFactor = currentShapeDim % i;
693+ foundValidFactor = true;
694+ break;
695+ }
696+ if (!UbOutOfBoundCheck(currentSplitIndex, i, false) && rate > bestRate) {
697+ bestRate = rate;
698+ bestI = i;
699+ }
700+ }
701+ if (!foundValidFactor) {
702+ splitInfo_.outUbFactor = bestI;
703+ splitInfo_.outTailFactor = currentShapeDim % bestI;
704+ }
705+ }
706+ outUbAxis = Ops::Base::CeilDiv(shapeInfo_.reducedOutShape[splitInfo_.outCutIndex], splitInfo_.outUbFactor) *
707+ outUbAxisExceptSplitAxis;
708+ SetRealCoreNumAndBlkFactor(outUbAxis);
709+}
710+ 
711+void TransposeNddmaTiling::CalcBlockSplitInfoForCutTwice()
712+{
713+ OP_LOGD(tilingContext_->GetNodeName(), "Entering CalcBlockSplitInfoForCutTwice.");
714+ int64_t outAxiseExceptSplitInAxis = 1;
715+ for (int64_t i = 0; i < splitInfo_.outCutIndex; i++) {
716+ if (shapeInfo_.reducedPerm[i] < splitInfo_.inCutIndex) {
717+ outAxiseExceptSplitInAxis *= shapeInfo_.reducedOutShape[i];
718+ }
719+ }
720+ outAxiseExceptSplitInAxis *=
721+ Ops::Base::CeilDiv(shapeInfo_.reducedOutShape[splitInfo_.outCutIndex], splitInfo_.outUbFactor);
722+ int64_t inUbAxis = Ops::Base::CeilDiv(shapeInfo_.reducedInShape[splitInfo_.inCutIndex], splitInfo_.inUbFactor);
723+ if (outAxiseExceptSplitInAxis * inUbAxis < coreNum_) {
724+ // use at least VEC_CORE_USED_THRES_HOLD * coreNum
725+ int64_t currentSplitIndex = splitInfo_.inCutIndex;
726+ int64_t currentShapeDim = shapeInfo_.reducedInShape[currentSplitIndex];
727+ int64_t bestI = 1;
728+ double bestRate = 0.0;
729+ bool foundValidFactor = false;
730+ for (int64_t i = splitInfo_.inUbFactor; i >= 1; i--) {
731+ int64_t coreNumNew = Ops::Base::CeilDiv(currentShapeDim, i) * outAxiseExceptSplitInAxis;
732+ double rate = static_cast<double>(coreNumNew) / coreNum_;
733+ if ((rate >= VEC_CORE_USED_THRES_HOLD) && !UbOutOfBoundCheck(currentSplitIndex, i, true)) {
734+ splitInfo_.inUbFactor = i;
735+ splitInfo_.inTailFactor = currentShapeDim % i;
736+ foundValidFactor = true;
737+ break;
738+ }
739+ if (rate > bestRate && !UbOutOfBoundCheck(currentSplitIndex, i, true)) {
740+ bestRate = rate;
741+ bestI = i;
742+ }
743+ }
744+ if (!foundValidFactor) {
745+ splitInfo_.inUbFactor = bestI;
746+ splitInfo_.inTailFactor = currentShapeDim % bestI;
747+ }
748+ }
749+ inUbAxis = Ops::Base::CeilDiv(shapeInfo_.reducedInShape[splitInfo_.inCutIndex], splitInfo_.inUbFactor) *
750+ outAxiseExceptSplitInAxis;
751+ SetRealCoreNumAndBlkFactor(inUbAxis);
752+}
753+ 
754+void TransposeNddmaTiling::CalcBlockSplitInfoForBigDim()
755+{
756+ OP_LOGD(tilingContext_->GetNodeName(), "Entering CalcBlockSplitInfoForBigDim.");
757+ int64_t outUbAxisExceptSplitAxis = 1;
758+ for (int64_t i = 0; i < splitInfo_.outCutIndex; i++) {
759+ outUbAxisExceptSplitAxis *= shapeInfo_.reducedOutShape[i];
760+ }
761+ int64_t coreNum = Ops::Base::CeilDiv(shapeInfo_.reducedOutShape[splitInfo_.outCutIndex], splitInfo_.outUbFactor) *
762+ outUbAxisExceptSplitAxis;
763+ int64_t currentShapeDim = shapeInfo_.reducedOutShape[splitInfo_.outCutIndex];
764+ if (coreNum < coreNum_) {
765+ // use at least VEC_CORE_USED_THRES_HOLD * coreNum
766+ int64_t bestI = 1;
767+ double bestRate = 0.0;
768+ bool foundValidFactor = false;
769+ for (int64_t i = splitInfo_.outUbFactor; i >= 1; i--) {
770+ int64_t coreNumNew = Ops::Base::CeilDiv(currentShapeDim, i) * outUbAxisExceptSplitAxis;
771+ double rate = static_cast<double>(coreNumNew) / coreNum_;
772+ if ((rate >= VEC_CORE_USED_THRES_HOLD)) {
773+ splitInfo_.outUbFactor = i;
774+ splitInfo_.outTailFactor = currentShapeDim % i;
775+ foundValidFactor = true;
776+ break;
777+ }
778+ if (rate > bestRate) {
779+ bestRate = rate;
780+ bestI = i;
781+ }
782+ }
783+ if (!foundValidFactor) {
784+ splitInfo_.outUbFactor = bestI;
785+ splitInfo_.outTailFactor = currentShapeDim % bestI;
786+ }
787+ } else {
788+ // use full coreNum
789+ int64_t coreNumMultiples = Ops::Base::FloorDiv(coreNum, coreNum_);
790+ for (int64_t i = 1; i <= splitInfo_.outUbFactor; i++) {
791+ int64_t coreNumNew = outUbAxisExceptSplitAxis * Ops::Base::CeilDiv(currentShapeDim, i);
792+ if ((Ops::Base::FloorDiv(coreNumNew, coreNum_) == coreNumMultiples)) {
793+ splitInfo_.outUbFactor = i;
794+ splitInfo_.outTailFactor = currentShapeDim % i;
795+ break;
796+ }
797+ }
798+ }
799+ FlushBaseNumForBigDim();
800+ coreNum = Ops::Base::CeilDiv(shapeInfo_.reducedOutShape[splitInfo_.outCutIndex], splitInfo_.outUbFactor) *
801+ outUbAxisExceptSplitAxis;
802+ SetRealCoreNumAndBlkFactor(coreNum);
803+}
804+ 
805+void TransposeNddmaTiling::CalcBlockSplitInfo()
806+{
807+ OP_LOGD(tilingContext_->GetNodeName(), "Entering CalcBlockSplitInfo.");
808+ switch (tilingKey_) {
809+ case static_cast<int64_t>(SplitMode::TENSOR_MOVE):
810+ CalcBlockSplitInfoForTensorMove();
811+ break;
812+ case static_cast<int64_t>(SplitMode::SMALL_SHAPE):
813+ CalcBlockSplitInfoForSmallShape();
814+ break;
815+ case static_cast<int64_t>(SplitMode::CUT_ONCE):
816+ CalcBlockSplitInfoForCutOnce();
817+ break;
818+ case static_cast<int64_t>(SplitMode::CUT_TWICE):
819+ CalcBlockSplitInfoForCutTwice();
820+ break;
821+ case static_cast<int64_t>(SplitMode::BIG_DIM):
822+ CalcBlockSplitInfoForBigDim();
823+ break;
824+ case static_cast<int64_t>(SplitMode::N_LAST_TRANSPOSE):
825+ CalcBlockSplitInfoForNLastTranspose();
826+ break;
827+ default:
828+ break;
829+ }
830+}
831+ 
832+void TransposeNddmaTiling::NDDMADimExpand()
833+{
834+ int64_t offset = (shapeInfo_.dim < NDDMA_MAX_DIM_NUM) ? (NDDMA_MAX_DIM_NUM - shapeInfo_.dim) : 0;
835+ 
836+ for (int64_t i = 0; i < shapeInfo_.dim; i++) {
837+ expandedPerm_[i + offset] = shapeInfo_.reducedPerm[i] + offset;
838+ expandedInputShape_[i + offset] = shapeInfo_.reducedInShape[i];
839+ expandedOutputShape_[i + offset] = shapeInfo_.reducedOutShape[i];
840+ }
841+}
842+ 
843+void TransposeNddmaTiling::GetInUbShapeInfo()
844+{
845+ switch (tilingKey_) {
846+ case static_cast<int64_t>(SplitMode::SMALL_SHAPE):
847+ CalcInUbShapeInfoForNoNeedCut();
848+ break;
849+ case static_cast<int64_t>(SplitMode::CUT_ONCE):
850+ CalcInUbShapeInfoForCutOnce();
851+ break;
852+ case static_cast<int64_t>(SplitMode::CUT_TWICE):
853+ CalcInUbShapeInfoForCutTwice();
854+ break;
855+ default:
856+ break;
857+ }
858+}
859+ 
860+void TransposeNddmaTiling::GetIntervalInfo()
861+{
862+ switch (tilingKey_) {
863+ case static_cast<int64_t>(SplitMode::CUT_TWICE):
864+ GetIntervalInfoForCutTwice();
865+ break;
866+ default:
867+ break;
868+ }
869+}
870+ 
871+void TransposeNddmaTiling::CalcInUbShapeInfoForNoNeedCut()
872+{
873+ int64_t outCutIndexExpand = splitInfo_.outCutIndex + NDDMA_MAX_DIM_NUM - shapeInfo_.dim;
874+ for (int64_t i = 0; i < NDDMA_MAX_DIM_NUM; i++) {
875+ if (i > outCutIndexExpand) {
876+ inUbMainDstShape_[i] = expandedOutputShape_[i];
877+ inUbTailDstShape_[i] = expandedOutputShape_[i];
878+ } else if (i == outCutIndexExpand) {
879+ inUbMainDstShape_[i] = splitInfo_.outUbFactor;
880+ inUbTailDstShape_[i] = splitInfo_.outTailFactor;
881+ } else {
882+ inUbMainDstShape_[i] = 1;
883+ inUbTailDstShape_[i] = 1;
884+ }
885+ }
886+ for (int64_t i = 0; i < NDDMA_MAX_DIM_NUM; i++) {
887+ inUbMainSrcShape_[expandedPerm_[i]] = inUbMainDstShape_[i];
888+ inUbTailSrcShape_[expandedPerm_[i]] = inUbTailDstShape_[i];
889+ }
890+}
891+ 
892+void TransposeNddmaTiling::CalcInUbShapeInfoForCutOnce()
893+{
894+ int64_t outCutIndexExpand = splitInfo_.outCutIndex + NDDMA_MAX_DIM_NUM - shapeInfo_.dim;
895+ int64_t inCutIndexExpand = splitInfo_.inCutIndex + NDDMA_MAX_DIM_NUM - shapeInfo_.dim;
896+ for (int64_t i = 0; i < NDDMA_MAX_DIM_NUM; i++) {
897+ inUbMainDstShape_[i] = expandedOutputShape_[i];
898+ inUbTailDstShape_[i] = expandedOutputShape_[i];
899+ if (i == outCutIndexExpand) {
900+ inUbMainDstShape_[i] = splitInfo_.outUbFactor;
901+ inUbTailDstShape_[i] = splitInfo_.outTailFactor;
902+ } else if (i < outCutIndexExpand && expandedPerm_[i] < inCutIndexExpand) {
903+ inUbMainDstShape_[i] = 1;
904+ inUbTailDstShape_[i] = 1;
905+ }
906+ }
907+ for (int64_t i = 0; i < NDDMA_MAX_DIM_NUM; i++) {
908+ inUbMainSrcShape_[expandedPerm_[i]] = inUbMainDstShape_[i];
909+ inUbTailSrcShape_[expandedPerm_[i]] = inUbTailDstShape_[i];
910+ }
911+}
912+ 
913+void TransposeNddmaTiling::CalcInUbShapeInfoForCutTwice()
914+{
915+ // 双切分场景下,对于输入,输入切分轴右侧为UB内的轴;对于输出,输出切分轴右侧非由输入确定的UB内的轴也都为UB内的轴
916+ for (int64_t idx = 0; idx < NDDMA_MAX_DIM_NUM; idx++) {
917+ inUbMainSrcShape_[idx] = expandedInputShape_[idx];
918+ inUbInputTailSrcShape_[idx] = expandedInputShape_[idx];
919+ inUbOutputTailSrcShape_[idx] = expandedInputShape_[idx];
920+ inUbTailSrcShape_[idx] = expandedInputShape_[idx];
921+ if (idx < splitInfo_.inCutIndex + NDDMA_MAX_DIM_NUM - shapeInfo_.dim) {
922+ inUbMainSrcShape_[idx] = 1;
923+ inUbInputTailSrcShape_[idx] = 1;
924+ inUbTailSrcShape_[idx] = 1;
925+ } else if (idx == splitInfo_.inCutIndex + NDDMA_MAX_DIM_NUM - shapeInfo_.dim) {
926+ inUbMainSrcShape_[idx] = splitInfo_.inUbFactor;
927+ inUbInputTailSrcShape_[idx] = splitInfo_.inTailFactor;
928+ inUbTailSrcShape_[idx] = splitInfo_.inTailFactor;
929+ }
930+ inUbOutputTailSrcShape_[idx] = inUbInputTailSrcShape_[idx];
931+ }
932+ inUbOutputTailSrcShape_[splitInfo_.inCutIndex + NDDMA_MAX_DIM_NUM - shapeInfo_.dim] = splitInfo_.inUbFactor;
933+ inUbOutputTailSrcShape_[expandedPerm_[splitInfo_.outCutIndex + NDDMA_MAX_DIM_NUM - shapeInfo_.dim]] =
934+ splitInfo_.outTailFactor;
935+ inUbMainSrcShape_[expandedPerm_[splitInfo_.outCutIndex + NDDMA_MAX_DIM_NUM - shapeInfo_.dim]] =
936+ splitInfo_.outUbFactor;
937+ inUbInputTailSrcShape_[expandedPerm_[splitInfo_.outCutIndex + NDDMA_MAX_DIM_NUM - shapeInfo_.dim]] =
938+ splitInfo_.outUbFactor;
939+ inUbTailSrcShape_[expandedPerm_[splitInfo_.outCutIndex + NDDMA_MAX_DIM_NUM - shapeInfo_.dim]] =
940+ splitInfo_.outTailFactor;
941+ for (int64_t idx = splitInfo_.outCutIndex + NDDMA_MAX_DIM_NUM - shapeInfo_.dim + 1; idx < NDDMA_MAX_DIM_NUM;
942+ idx++) {
943+ if (expandedPerm_[idx] == splitInfo_.inCutIndex + NDDMA_MAX_DIM_NUM - shapeInfo_.dim) {
944+ continue;
945+ } else {
946+ inUbMainSrcShape_[expandedPerm_[idx]] = expandedInputShape_[expandedPerm_[idx]];
947+ inUbInputTailSrcShape_[expandedPerm_[idx]] = expandedInputShape_[expandedPerm_[idx]];
948+ inUbOutputTailSrcShape_[expandedPerm_[idx]] = expandedInputShape_[expandedPerm_[idx]];
949+ inUbTailSrcShape_[expandedPerm_[idx]] = expandedInputShape_[expandedPerm_[idx]];
950+ }
951+ }
952+ for (int64_t idx = 0; idx < NDDMA_MAX_DIM_NUM; idx++) {
953+ inUbMainDstShape_[idx] = inUbMainSrcShape_[expandedPerm_[idx]];
954+ inUbInputTailDstShape_[idx] = inUbInputTailSrcShape_[expandedPerm_[idx]];
955+ inUbOutputTailDstShape_[idx] = inUbOutputTailSrcShape_[expandedPerm_[idx]];
956+ inUbTailDstShape_[idx] = inUbTailSrcShape_[expandedPerm_[idx]];
957+ }
958+}
959+ 
960+void TransposeNddmaTiling::GetIntervalInfoForCutTwice()
961+{
962+ int64_t expandedInputCutIndex = splitInfo_.inCutIndex + NDDMA_MAX_DIM_NUM - shapeInfo_.dim;
963+ int64_t inputOutputCutIndex = expandedPerm_[splitInfo_.outCutIndex + NDDMA_MAX_DIM_NUM - shapeInfo_.dim];
964+ 
965+ int64_t outUbLoop = 1;
966+ for (int64_t i = NDDMA_MAX_DIM_NUM - 1; i >= 0; i--) {
967+ if (i != expandedInputCutIndex && i != inputOutputCutIndex) {
968+ outUbLoop = outUbLoop * (expandedInputShape_[i] / inUbMainSrcShape_[i]);
969+ }
970+ }
971+ 
972+ offsetRangeMain_.end = (expandedInputShape_[expandedInputCutIndex] / inUbMainSrcShape_[expandedInputCutIndex]) *
973+ (expandedInputShape_[inputOutputCutIndex] / inUbMainSrcShape_[inputOutputCutIndex]) *
974+ outUbLoop -
975+ 1;
976+ 
977+ if (splitInfo_.inTailFactor != 0 && splitInfo_.outTailFactor != 0) {
978+ offsetRangeInputTail_.start = offsetRangeMain_.end + 1;
979+ offsetRangeInputTail_.end =
980+ offsetRangeInputTail_.start +
981+ (expandedInputShape_[inputOutputCutIndex] / inUbMainSrcShape_[inputOutputCutIndex]) * outUbLoop - 1;
982+ offsetRangeOutputTail_.start = offsetRangeInputTail_.end + 1;
983+ offsetRangeOutputTail_.end =
984+ offsetRangeOutputTail_.start +
985+ (expandedInputShape_[expandedInputCutIndex] / inUbMainSrcShape_[expandedInputCutIndex]) * outUbLoop - 1;
986+ offsetRangeTail_.start = offsetRangeOutputTail_.end + 1;
987+ offsetRangeTail_.end = offsetRangeTail_.start + outUbLoop - 1;
988+ }
989+ 
990+ if (splitInfo_.inTailFactor != 0 && splitInfo_.outTailFactor == 0) {
991+ offsetRangeInputTail_.start = offsetRangeMain_.end + 1;
992+ offsetRangeInputTail_.end =
993+ offsetRangeInputTail_.start +
994+ (expandedInputShape_[inputOutputCutIndex] / inUbMainSrcShape_[inputOutputCutIndex]) * outUbLoop - 1;
995+ }
996+ 
997+ if (splitInfo_.inTailFactor == 0 && splitInfo_.outTailFactor != 0) {
998+ offsetRangeOutputTail_.start = offsetRangeMain_.end + 1;
999+ offsetRangeOutputTail_.end =
1000+ offsetRangeOutputTail_.start +
1001+ (expandedInputShape_[expandedInputCutIndex] / inUbMainSrcShape_[expandedInputCutIndex]) * outUbLoop - 1;
1002+ }
1003+}
1004+ 
1005+void TransposeNddmaTiling::FillTilingData()
1006+{
1007+ OP_LOGD(tilingContext_->GetNodeName(), "Entering FillTilingData.");
1008+ tilingData_.transposeOpTiling.set_permSize(shapeInfo_.dim);
1009+ tilingData_.transposeOpTiling.set_inCutIndex(splitInfo_.inCutIndex);
1010+ tilingData_.transposeOpTiling.set_outCutIndex(splitInfo_.outCutIndex);
1011+ tilingData_.transposeOpTiling.set_inUbFactor(splitInfo_.inUbFactor);
1012+ tilingData_.transposeOpTiling.set_outUbFactor(splitInfo_.outUbFactor);
1013+ tilingData_.transposeOpTiling.set_inTailFactor(splitInfo_.inTailFactor);
1014+ tilingData_.transposeOpTiling.set_outTailFactor(splitInfo_.outTailFactor);
1015+ tilingData_.transposeOpTiling.set_realCoreNum(realCoreNum_);
1016+ tilingData_.transposeOpTiling.set_blkFactor(blkFactor_);
1017+ tilingData_.transposeOpTiling.set_blkTailFactor(blkTailFactor_);
1018+ tilingData_.transposeOpTiling.set_ubSize(ubSize_);
1019+ 
1020+ for (int64_t i = 0; i < shapeInfo_.dim; i++) {
1021+ inputShape_[i] = shapeInfo_.reducedInShape[i];
1022+ outputShape_[i] = shapeInfo_.reducedOutShape[i];
1023+ perm_[i] = shapeInfo_.reducedPerm[i];
1024+ }
1025+ tilingData_.transposeOpTiling.set_inputShape(inputShape_);
1026+ tilingData_.transposeOpTiling.set_outputShape(outputShape_);
1027+ tilingData_.transposeOpTiling.set_perm(perm_);
1028+ tilingData_.transposeOpTiling.set_baseInShape(baseInShape_);
1029+ tilingData_.transposeOpTiling.set_baseNddmaShape(baseNddmaShape_);
1030+ tilingData_.transposeOpTiling.set_nddmaIdx(nddmaIdx_);
1031+ tilingData_.transposeOpTiling.set_totalNddmaNum(totalNddmaNum_);
1032+ tilingData_.transposeOpTiling.set_rangeMainEnd(offsetRangeMain_.end);
1033+ tilingData_.transposeOpTiling.set_rangeInputTailStart(offsetRangeInputTail_.start);
1034+ tilingData_.transposeOpTiling.set_rangeInputTailEnd(offsetRangeInputTail_.end);
1035+ tilingData_.transposeOpTiling.set_rangeOutputTailStart(offsetRangeOutputTail_.start);
1036+ tilingData_.transposeOpTiling.set_rangeOutputTailEnd(offsetRangeOutputTail_.end);
1037+ tilingData_.transposeOpTiling.set_rangeTailStart(offsetRangeTail_.start);
1038+ tilingData_.transposeOpTiling.set_rangeTailEnd(offsetRangeTail_.end);
1039+ 
1040+ tilingData_.transposeOpTiling.set_expandedPerm(expandedPerm_);
1041+ tilingData_.transposeOpTiling.set_expandedInputShape(expandedInputShape_);
1042+ tilingData_.transposeOpTiling.set_expandedOutputShape(expandedOutputShape_);
1043+ 
1044+ tilingData_.transposeOpTiling.set_inUbMainSrcShape(inUbMainSrcShape_);
1045+ tilingData_.transposeOpTiling.set_inUbMainDstShape(inUbMainDstShape_);
1046+ tilingData_.transposeOpTiling.set_inUbInputTailSrcShape(inUbInputTailSrcShape_);
1047+ tilingData_.transposeOpTiling.set_inUbInputTailDstShape(inUbInputTailDstShape_);
1048+ tilingData_.transposeOpTiling.set_inUbOutputTailSrcShape(inUbOutputTailSrcShape_);
1049+ tilingData_.transposeOpTiling.set_inUbOutputTailDstShape(inUbOutputTailDstShape_);
1050+ tilingData_.transposeOpTiling.set_inUbTailSrcShape(inUbTailSrcShape_);
1051+ tilingData_.transposeOpTiling.set_inUbTailDstShape(inUbTailDstShape_);
1052+ 
1053+ if (!isReleatedTranspsoe_) {
1054+ tilingData_.SaveToBuffer(
1055+ tilingContext_->GetRawTilingData()->GetData(), tilingContext_->GetRawTilingData()->GetCapacity());
1056+ tilingContext_->GetRawTilingData()->SetDataSize(tilingData_.GetDataSize());
1057+ }
1058+}
1059+ 
1060+void TransposeNddmaTiling::PrintTilingData()
1061+{
1062+ OP_LOGI(tilingContext_->GetNodeName(), "Entering PrintTilingData.");
1063+ for (int64_t i = 0; i < shapeInfo_.dim; i++) {
1064+ OP_LOGI(
1065+ tilingContext_->GetNodeName(),
1066+ "reducedInShape[%ld] is:%ld, reducedOutShape[%ld]:%ld, reducedPerm[%ld]:%ld. \
1067+ baseInShape[%ld] is:%ld",
1068+ i, inputShape_[i], i, outputShape_[i], i, perm_[i], i, baseInShape_[i]);
1069+ }
1070+ for (int64_t i = 0; i < NDDMA_MAX_DIM_NUM; i++) {
1071+ OP_LOGI(
1072+ tilingContext_->GetNodeName(), "baseNddmaShape_[%ld] is:%ld, nddmaIdx_[%ld]:%ld", i, baseNddmaShape_[i], i,
1073+ nddmaIdx_[i]);
1074+ }
1075+ OP_LOGI(
1076+ tilingContext_->GetNodeName(),
1077+ "tilingData is permSize:%ld, inCutIndex:%ld, outCutIndex:%ld, inUbFactor:%ld, outUbFactor:%ld, \
1078+ inTailFactor:%ld, outTailFactor:%ld, realCoreNum:%ld, blkFactor:%ld, blkTailFactor:%ld, \
1079+ ubSize:%ld, totalNddmaNum:%ld, Tiling4Transpose ends. ",
1080+ tilingData_.transposeOpTiling.get_permSize(), tilingData_.transposeOpTiling.get_inCutIndex(),
1081+ tilingData_.transposeOpTiling.get_outCutIndex(), tilingData_.transposeOpTiling.get_inUbFactor(),
1082+ tilingData_.transposeOpTiling.get_outUbFactor(), tilingData_.transposeOpTiling.get_inTailFactor(),
1083+ tilingData_.transposeOpTiling.get_outTailFactor(), tilingData_.transposeOpTiling.get_realCoreNum(),
1084+ tilingData_.transposeOpTiling.get_blkFactor(), tilingData_.transposeOpTiling.get_blkTailFactor(),
1085+ tilingData_.transposeOpTiling.get_ubSize(), tilingData_.transposeOpTiling.get_totalNddmaNum());
1086+}
1087+ 
1088+static ge::graphStatus TransposeTilingForAscendC(gert::TilingContext* context)
1089+{
1090+ OP_LOGD(context->GetNodeName(), "begin to do TilingForTranspose");
1091+ auto compilerInfo = context->GetCompileInfo<TransposeCompilerInfo>();
1092+ OP_CHECK_NULL_WITH_CONTEXT(context, compilerInfo);
1093+ TransposeNddmaTiling tilingObject(context);
1094+ if (tilingObject.Init(compilerInfo->coreNum, compilerInfo->ubSize) != ge::GRAPH_SUCCESS) {
1095+ return ge::GRAPH_FAILED;
1096+ }
1097+ return tilingObject.RunTranposelTiling();
1098+}
1099+ 
1100+static ge::graphStatus TilingPrepareTransposeForAscendC(gert::TilingParseContext* context)
1101+{
1102+ OP_LOGD(context->GetNodeName(), "Start TilingPrepareTransposeForAscendC");
1103+ auto ci = context->GetCompiledInfo<TransposeCompilerInfo>();
1104+ OP_CHECK_NULL_WITH_CONTEXT(context, ci);
1105+ auto platformInfo = context->GetPlatformInfo();
1106+ OP_CHECK_NULL_WITH_CONTEXT(context, platformInfo);
1107+ auto ascendcPlatform = platform_ascendc::PlatformAscendC(platformInfo);
1108+ ci->coreNum = ascendcPlatform.GetCoreNumAiv();
1109+ OP_CHECK_IF(
1110+ (ci->coreNum <= 0),
1111+ OP_LOGE(context->GetNodeName(), "Transpose Op GetHardwareInfo Failed, coreNum:%ld.", ci->coreNum),
1112+ return ge::GRAPH_FAILED);
1113+ uint64_t ubSize;
1114+ ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::UB, ubSize);
1115+ ci->ubSize = static_cast<int64_t>(ubSize);
1116+ OP_CHECK_IF(
1117+ (ci->ubSize <= 0),
1118+ OP_LOGE(context->GetNodeName(), "Transpose Op GetHardwareInfo Failed, ubSize:%ld.", ci->ubSize),
1119+ return ge::GRAPH_FAILED);
1120+ 
1121+ OP_LOGD(context->GetNodeName(), "Transpose Op get coreNum:%ld, ubSize:%ld.", ci->coreNum, ci->ubSize);
1122+ return ge::GRAPH_SUCCESS;
1123+}
1124+ 
1125+IMPL_OP_OPTILING(Transpose)
1126+ .Tiling(TransposeTilingForAscendC)
1127+ .TilingParse<TransposeCompilerInfo>(TilingPrepareTransposeForAscendC);
1128+ 
1129+} // namespace optiling
@@ -0,0 +1,243 @@
1+/**
2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+/*!
12+ * \file transpose_tiling_arc35.h
CANN-robot
CANN-robotCANN-robot2025年12月27日

代码结构与可维护性: 第12行文件注释中的文件名 transpose_tiling_arc35.h 与实际的宏定义 AIR_CXX_RUNTIME_V2_OP_IMPL_TRANSPOSE_TILING_ARCH35_H 不一致('arc35' vs 'arch35')。虽然这可能只是注释错误,但会影响文档的准确性。

问题类型: 代码结构与可维护性 文件路径: conversion/transpose/op_host/arch35/transpose_tiling_arch35.h 行号: 12 问题代码:

 * \file transpose_tiling_arc35.h

修改建议:

将注释中的文件名更正为 `transpose_tiling_arch35.h`,以与实际文件名和宏定义保持一致。

此评论由代码审查工具自动生成

likedislike
13+ * \brief
14+ */
15+ 
16+#ifndef AIR_CXX_RUNTIME_V2_OP_IMPL_TRANSPOSE_TILING_ARCH35_H
17+#define AIR_CXX_RUNTIME_V2_OP_IMPL_TRANSPOSE_TILING_ARCH35_H
18+ 
19+#include <cstdlib>
20+#include <algorithm>
21+#include <iostream>
22+#include <cstdint>
23+#include <vector>
24+#include "log/log.h"
25+#include "util/math_util.h"
26+#include "util/platform_util.h"
27+#include "register/op_impl_registry.h"
28+#include "register/tilingdata_base.h"
29+#include "transpose_tiling_base.h"
30+ 
31+namespace optiling {
32+constexpr int64_t MAX_AXIS_NUM_FOR_TRANSPOSE = 8;
33+constexpr int64_t NDDMA_MAX_DIM_NUM = 5;
34+constexpr int64_t NDDMA_MAX_LOOP_NUM = 3;
35+constexpr uint64_t INPUT_IDX_X = 0;
36+constexpr uint64_t OUTPUT_IDX_Y = 0;
37+constexpr uint64_t INPUT_IDX_PERM = 1;
38+constexpr uint64_t B8_BYTES = 1;
39+constexpr uint64_t B16_BYTES = 2;
40+constexpr uint64_t B32_BYTES = 4;
41+constexpr uint64_t B64_BYTES = 8;
42+constexpr uint64_t bufferNum = 2;
43+constexpr uint64_t WORK_SPACE_SIZE = 16 * 1024 * 1024;
44+constexpr double VEC_CORE_USED_THRES_HOLD = 0.9;
45+constexpr int64_t SMALL_SHAPE_BYTES_THRES_HOLD = 8000000;
46+constexpr int64_t SMALL_SHAPE_SPLIT_BYTES_ALIGN_SIZE = 128;
47+constexpr int64_t INPUT_IDX = 0;
48+constexpr int64_t OUTPUT_IDX = 0;
49+constexpr int64_t ATTR_BLOCK_SIZE_IDX = 0;
50+constexpr int64_t ATTR_MODE_IDX = 1;
51+constexpr int64_t ATTR_DEPTH_DATA_FORMAT_IDX = 2;
52+constexpr int64_t ATTR_SPACE_DATA_FORMAT_IDX = 1;
53+constexpr int64_t DIM_NUM = 4;
54+constexpr int64_t DIM_ZERO = 0;
55+constexpr int64_t DIM_ONE = 1;
56+constexpr int64_t DIM_TWO = 2;
57+constexpr int64_t DIM_THREE = 3;
58+constexpr int64_t DIM_FOUR = 4;
59+constexpr int64_t DIM_FIVE = 5;
60+constexpr int64_t DIM_SIX = 6;
61+BEGIN_TILING_DATA_DEF(TransposeOpTilingData)
62+TILING_DATA_FIELD_DEF(int64_t, permSize);
63+TILING_DATA_FIELD_DEF(int64_t, inCutIndex);
64+TILING_DATA_FIELD_DEF(int64_t, outCutIndex);
65+TILING_DATA_FIELD_DEF(int64_t, inUbFactor);
66+TILING_DATA_FIELD_DEF(int64_t, outUbFactor);
67+TILING_DATA_FIELD_DEF(int64_t, inTailFactor);
68+TILING_DATA_FIELD_DEF(int64_t, outTailFactor);
69+TILING_DATA_FIELD_DEF(int64_t, realCoreNum);
70+TILING_DATA_FIELD_DEF(int64_t, blkFactor);
71+TILING_DATA_FIELD_DEF(int64_t, blkTailFactor);
72+TILING_DATA_FIELD_DEF(int64_t, ubSize);
73+TILING_DATA_FIELD_DEF(int64_t, totalNddmaNum);
74+TILING_DATA_FIELD_DEF(int64_t, rangeMainEnd);
75+TILING_DATA_FIELD_DEF(int64_t, rangeInputTailStart);
76+TILING_DATA_FIELD_DEF(int64_t, rangeInputTailEnd);
77+TILING_DATA_FIELD_DEF(int64_t, rangeOutputTailStart);
78+TILING_DATA_FIELD_DEF(int64_t, rangeOutputTailEnd);
79+TILING_DATA_FIELD_DEF(int64_t, rangeTailStart);
80+TILING_DATA_FIELD_DEF(int64_t, rangeTailEnd);
81+TILING_DATA_FIELD_DEF_ARR(int64_t, MAX_AXIS_NUM_FOR_TRANSPOSE, inputShape);
82+TILING_DATA_FIELD_DEF_ARR(int64_t, MAX_AXIS_NUM_FOR_TRANSPOSE, outputShape);
83+TILING_DATA_FIELD_DEF_ARR(int64_t, MAX_AXIS_NUM_FOR_TRANSPOSE, perm);
84+TILING_DATA_FIELD_DEF_ARR(int64_t, MAX_AXIS_NUM_FOR_TRANSPOSE, baseInShape);
85+TILING_DATA_FIELD_DEF_ARR(int64_t, NDDMA_MAX_DIM_NUM, baseNddmaShape);
86+TILING_DATA_FIELD_DEF_ARR(int64_t, NDDMA_MAX_DIM_NUM, nddmaIdx);
87+TILING_DATA_FIELD_DEF_ARR(int64_t, NDDMA_MAX_DIM_NUM, expandedPerm);
88+TILING_DATA_FIELD_DEF_ARR(int64_t, NDDMA_MAX_DIM_NUM, expandedInputShape);
89+TILING_DATA_FIELD_DEF_ARR(int64_t, NDDMA_MAX_DIM_NUM, expandedOutputShape);
90+TILING_DATA_FIELD_DEF_ARR(int64_t, NDDMA_MAX_DIM_NUM, inUbMainSrcShape);
91+TILING_DATA_FIELD_DEF_ARR(int64_t, NDDMA_MAX_DIM_NUM, inUbMainDstShape);
92+TILING_DATA_FIELD_DEF_ARR(int64_t, NDDMA_MAX_DIM_NUM, inUbInputTailSrcShape);
93+TILING_DATA_FIELD_DEF_ARR(int64_t, NDDMA_MAX_DIM_NUM, inUbInputTailDstShape);
94+TILING_DATA_FIELD_DEF_ARR(int64_t, NDDMA_MAX_DIM_NUM, inUbOutputTailSrcShape);
95+TILING_DATA_FIELD_DEF_ARR(int64_t, NDDMA_MAX_DIM_NUM, inUbOutputTailDstShape);
96+TILING_DATA_FIELD_DEF_ARR(int64_t, NDDMA_MAX_DIM_NUM, inUbTailSrcShape);
97+TILING_DATA_FIELD_DEF_ARR(int64_t, NDDMA_MAX_DIM_NUM, inUbTailDstShape);
98+END_TILING_DATA_DEF;
99+REGISTER_TILING_DATA_CLASS(TransposeOpTilingDataOp, TransposeOpTilingData)
100+ 
101+BEGIN_TILING_DATA_DEF(TransposeTilingData)
102+TILING_DATA_FIELD_DEF_STRUCT(TransposeOpTilingData, transposeOpTiling);
103+END_TILING_DATA_DEF;
104+REGISTER_TILING_DATA_CLASS(Transpose, TransposeTilingData);
105+ 
106+enum class SplitMode : int64_t
107+{
108+ TENSOR_MOVE = 10000, // only one axis after fuse
109+ SMALL_SHAPE = 10001, // UB is enough
110+ CUT_ONCE = 10002, // cut one axis and last transpose
111+ CUT_TWICE = 10003, // cut two axis and last transpose
112+ N_LAST_TRANSPOSE = 10004, // nLast transpose and last axis bigger than cacheLine
113+ BIG_DIM = 10005, // dim bigger than 5 and last transpose
114+ GATHER_TRANSPOSE = 10006 // transpose with gather
115+};
116+ 
117+struct SplitInfo {
118+ int64_t inUbAxisSize = 1;
119+ int64_t outUbAxisSize = 1;
120+ int64_t ubElement = 1;
121+ int64_t inUbElement = 1;
122+ int64_t outUbElement = 1;
123+ int64_t inUbActual = 1;
124+ int64_t outUbActual = 1;
125+ int64_t inCutIndex = 0;
126+ int64_t outCutIndex = 0;
127+ int64_t inUbFactor = 0;
128+ int64_t outUbFactor = 0;
129+ int64_t inTailFactor = 0;
130+ int64_t outTailFactor = 0;
131+ int64_t blkFactor = 0;
132+ int64_t blkTailFactor = 0;
133+ bool isAllLastAxisInUb = false;
134+};
135+ 
136+struct Interval {
137+ int64_t start = 0;
138+ int64_t end = 0;
139+};
140+ 
141+struct ParamInfo {
142+ gert::Shape xShape;
143+ ge::DataType xDtype;
144+ int64_t blockSize;
145+ const char* modePtr;
146+ const char* dataFormatPtr;
147+};
148+ 
149+ge::graphStatus TransposeTilingForAscendC(gert::TilingContext* context, const int64_t& coreNum, const int64_t& ubSize);
150+ 
151+class TransposeNddmaTiling {
152+public:
153+ explicit TransposeNddmaTiling(gert::TilingContext* context) : tilingContext_(context){};
154+ ge::graphStatus Init(const int64_t& coreNum, const int64_t& ubSize);
155+ ge::graphStatus RunTranposelTiling();
156+ ge::graphStatus TilingForReleatedTranspose(
CANN-robot
CANN-robotCANN-robot2025年12月27日

代码结构与可维护性: 第156行函数名 TilingForReleatedTranspose 存在拼写错误,应为 TilingForRelatedTranspose。函数名拼写错误会影响代码的可读性和调用时的准确性。

问题类型: 代码结构与可维护性 文件路径: conversion/transpose/op_host/arch35/transpose_tiling_arch35.h 行号: 156 问题代码:

    ge::graphStatus TilingForReleatedTranspose(
        gert::TilingContext* context, TransposeOpTilingData* tilingData, TransposeCompilerInfo* compilerInfo,
        ShapeInfo& opInput);

修改建议:

将函数名更正为 `TilingForRelatedTranspose`,并同步更新所有调用该函数的地方。

此评论由代码审查工具自动生成

likedislike
157+ gert::TilingContext* context, TransposeOpTilingData* tilingData, TransposeCompilerInfo* compilerInfo,
158+ ShapeInfo& opInput);
159+ 
160+private:
161+ template <typename T>
162+ bool GetPerm(const gert::Tensor* permTensor);
163+ void SetIsLastAxisTranspose();
164+ void CalcTotalVolumeActual();
165+ ge::graphStatus GetShapeInfo();
166+ ge::graphStatus CheckShapeInfo();
167+ ge::graphStatus CheckReducedShapeInfo();
168+ void FlushBaseNumForBigDim();
169+ void CalcSplitInfo();
170+ void CalcBlockSplitInfo();
171+ void CalcBlockSplitInfoForTensorMove();
172+ void CalcBlockSplitInfoForSmallShape();
173+ int64_t CalcBlockSplitInfoForNoCutForMultiCore(int64_t i, int64_t shapeSizeByte, int64_t& totalElment);
174+ void CalcBlockSplitInfoForNLastTranspose();
175+ void SetRealCoreNumAndBlkFactor(int64_t coreNum);
176+ void CalcBlockSplitInfoForCutOnce();
177+ void CalcBlockSplitInfoForCutTwice();
178+ void CalcBlockSplitInfoForBigDim();
179+ void FillTilingData();
180+ void PrintTilingData();
181+ void DoSplitUB();
182+ int64_t DoSplitUBInput();
183+ int64_t FindOutIndex(int64_t index);
184+ bool UbOutOfBoundCheck(int64_t currentSplitIndex, int64_t currentSplitValue, bool calcIn);
185+ bool UbOutOfBoundCheckNLast(int64_t currentSplitIndex, int64_t currentSplitValue);
186+ void FindSplitFactorByMultiplesLast(
187+ int64_t currentSplitIndex, int64_t currentInShapeDim, int64_t remainingTotalElment, int64_t coreNumMultiples);
188+ void FindSplitFactorByRateNLast(int64_t currentSplitIndex, int64_t currentInShapeDim, int64_t remainingTotalElment);
189+ void FindSplitFactorByMultiplesNLast(
190+ int64_t currentSplitIndex, int64_t currentInShapeDim, int64_t remainingTotalElment, int64_t coreNumMultiples);
191+ void DoSplitUBBigDim();
192+ void NDDMADimExpand();
193+ void GetInUbShapeInfo();
194+ void GetIntervalInfo();
195+ void CalcInUbShapeInfoForNoNeedCut();
196+ void CalcInUbShapeInfoForCutOnce();
197+ void CalcInUbShapeInfoForCutTwice();
198+ void GetIntervalInfoForCutTwice();
199+ 
200+private:
201+ TransposeTilingData tilingData_;
202+ gert::TilingContext* tilingContext_ = nullptr;
203+ 
204+ int64_t realCoreNum_ = 0;
205+ int64_t tilingKey_ = 0;
206+ int64_t blkFactor_ = 0;
207+ int64_t blkTailFactor_ = 0;
208+ int64_t totalNddmaNum_ = 1;
209+ int64_t isNddmaAxisContinue_ = 0;
210+ int64_t inputShape_[MAX_AXIS_NUM_FOR_TRANSPOSE] = {0};
211+ int64_t outputShape_[MAX_AXIS_NUM_FOR_TRANSPOSE] = {0};
212+ int64_t perm_[MAX_AXIS_NUM_FOR_TRANSPOSE] = {0};
213+ ShapeInfo shapeInfo_;
214+ SplitInfo splitInfo_;
215+ int64_t coreNum_ = 0;
216+ int64_t ubSize_ = 0;
217+ int64_t cacheLineSize_ = 0;
218+ int64_t ubBlockSize_ = 0;
219+ Interval offsetRangeMain_;
220+ Interval offsetRangeInputTail_;
221+ Interval offsetRangeOutputTail_;
222+ Interval offsetRangeTail_;
223+ int64_t baseInShape_[TRANSPOSE_MAX_AXIS_NUM] = {0};
224+ int64_t baseNddmaShape_[NDDMA_MAX_DIM_NUM] = {0};
225+ int64_t nddmaIdx_[NDDMA_MAX_DIM_NUM] = {-1};
CANN-robot
CANN-robotCANN-robot2025年12月27日

数组越界与内存安全: 第225行数组 nddmaIdx_ 初始化为 {-1},但数组大小为 NDDMA_MAX_DIM_NUM = 5。C++中初始化列表只提供第一个元素的值,其余元素将被零初始化。这可能导致逻辑错误,因为代码可能期望所有元素初始化为 -1。

问题类型: 数组越界与内存安全 文件路径: conversion/transpose/op_host/arch35/transpose_tiling_arch35.h 行号: 225 问题代码:

    int64_t nddmaIdx_[NDDMA_MAX_DIM_NUM] = {-1};

修改建议:

使用循环或 `std::fill` 将所有元素初始化为 -1,或者使用初始化列表 `{-1, -1, -1, -1, -1}` 以确保所有元素都被正确初始化。

此评论由代码审查工具自动生成

likedislike
226+ 
227+ int64_t expandedPerm_[NDDMA_MAX_DIM_NUM] = {0, 1, 2, 3, 4};
228+ int64_t expandedInputShape_[NDDMA_MAX_DIM_NUM] = {1, 1, 1, 1, 1};
229+ int64_t expandedOutputShape_[NDDMA_MAX_DIM_NUM] = {1, 1, 1, 1, 1};
230+ int64_t inUbMainSrcShape_[NDDMA_MAX_DIM_NUM] = {0};
231+ int64_t inUbMainDstShape_[NDDMA_MAX_DIM_NUM] = {0};
232+ int64_t inUbInputTailSrcShape_[NDDMA_MAX_DIM_NUM] = {0};
233+ int64_t inUbInputTailDstShape_[NDDMA_MAX_DIM_NUM] = {0};
234+ int64_t inUbOutputTailSrcShape_[NDDMA_MAX_DIM_NUM] = {0};
235+ int64_t inUbOutputTailDstShape_[NDDMA_MAX_DIM_NUM] = {0};
236+ int64_t inUbTailSrcShape_[NDDMA_MAX_DIM_NUM] = {0};
237+ int64_t inUbTailDstShape_[NDDMA_MAX_DIM_NUM] = {0};
238+ 
239+ bool isReleatedTranspsoe_ = false;
CANN-robot
CANN-robotCANN-robot2025年12月27日

代码结构与可维护性: 第239行成员变量名 isReleatedTranspsoe_ 存在拼写错误,应为 isRelatedTranspose_。拼写错误会影响代码的可读性和可维护性,可能导致其他开发者在引用该变量时产生混淆。

问题类型: 代码结构与可维护性 文件路径: conversion/transpose/op_host/arch35/transpose_tiling_arch35.h 行号: 239 问题代码:

    bool isReleatedTranspsoe_ = false;

修改建议:

将变量名更正为 `isRelatedTranspose_`,并确保所有使用该变量的地方同步更新。

此评论由代码审查工具自动生成

likedislike
240+};
241+} // namespace optiling
242+ 
243+#endif // AIR_CXX_RUNTIME_V2_OP_IMPL_TRANSPOSE_TILING_ARCH35_H
@@ -0,0 +1,207 @@
1+/**
2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+/*!
11+ * \file transpose_tiling_base.cpp
12+ * \brief transpose
13+ */
14+#include "transpose_tiling_arch35.h"
15+#include "transpose_tiling_base.h"
16+ 
17+#include <cstdio>
18+#include <cstdlib>
19+#include <string>
20+#include <vector>
21+#include <memory>
22+#include <algorithm>
23+#include <iostream>
24+#include <math.h>
CANN-robot
CANN-robotCANN-robot2025年12月27日

代码结构与可维护性: 包含了C风格的<math.h>头文件,而代码中使用了std::ceil。建议使用C++标准的头文件。

问题类型: 代码结构与可维护性 文件路径: conversion/transpose/op_host/arch35/transpose_tiling_base.cpp 行号: 24 问题代码:

#include <math.h>

修改建议:

将#include <math.h>改为#include <cmath>,并使用std::ceil

此评论由代码审查工具自动生成

likedislike
25+#include <climits>
26+ 
27+using namespace std;
CANN-robot
CANN-robotCANN-robot2025年12月27日

代码结构与可维护性: 使用了'using namespace std;'和'using namespace gert;',这可能导致命名冲突,特别是在大型项目中。头文件可能被其他文件包含,带来全局命名空间污染风险。

问题类型: 代码结构与可维护性 文件路径: conversion/transpose/op_host/arch35/transpose_tiling_base.cpp 行号: 27 问题代码:

using namespace std;
using namespace gert;

修改建议:

移除using namespace语句,改为在代码中使用std::和gert::前缀,或仅在函数内部使用using声明。

此评论由代码审查工具自动生成

likedislike
28+using namespace gert;
29+ 
30+namespace optiling {
31+ 
32+static void DuplicateArray(const int64_t* src, vector<int64_t>& dst, int64_t len)
33+{
34+ for (int64_t i = 0; i < len; i++) {
35+ dst[i] = src[i];
36+ }
37+}
38+ 
39+static void DuplicateArray(const vector<int64_t>& src, vector<int64_t>& dst, int64_t len)
40+{
41+ for (int64_t i = 0; i < len; i++) {
42+ dst[i] = src[i];
43+ }
44+}
45+ 
46+static void DuplicateArray(const vector<int64_t>& src, int64_t* dst, int64_t len)
47+{
48+ for (int64_t i = 0; i < len; i++) {
49+ dst[i] = src[i];
50+ }
51+}
52+ 
53+static bool IsAllOne(const ShapeInfo& shapeInfo)
54+{
55+ return std::all_of(shapeInfo.inShape.begin(), shapeInfo.inShape.begin() + shapeInfo.dim, [](const int64_t& item) {
56+ return item == 1;
57+ });
58+}
59+ 
60+static int DecreaseCompare(const void* a, const void* b)
61+{
62+ return (*(int64_t*)b - *(int64_t*)a);
63+}
64+ 
65+static void CalcOutShape(ShapeInfo& shapeInfo)
66+{
67+ const vector<int64_t>& inShape = shapeInfo.reducedInShape;
68+ const vector<int64_t>& perm = shapeInfo.reducedPerm;
69+ vector<int64_t>& outShape = shapeInfo.reducedOutShape;
70+ for (int64_t i = 0; i < shapeInfo.dim; i++) {
71+ outShape[i] = inShape[perm[i]];
72+ }
73+}
74+ 
75+void RemoveAxisV2(ShapeInfo& shapeInfo)
76+{
77+ int64_t dim = shapeInfo.dim;
78+ if (dim == 1) {
79+ DuplicateArray(shapeInfo.inShape, shapeInfo.reducedInShape, dim);
80+ DuplicateArray(shapeInfo.perm, shapeInfo.reducedPerm, dim);
81+ DuplicateArray(shapeInfo.outShape, shapeInfo.reducedOutShape, dim);
82+ return;
83+ }
84+ 
85+ if (IsAllOne(shapeInfo)) {
86+ shapeInfo.reducedInShape[0] = 1;
87+ shapeInfo.reducedPerm[0] = 0;
88+ shapeInfo.reducedOutShape[0] = 1;
89+ shapeInfo.dim = 1;
90+ return;
91+ }
92+ 
93+ vector<int64_t>& shape = shapeInfo.reducedInShape;
94+ int64_t delPerm[TRANSPOSE_MAX_AXIS_NUM];
95+ int64_t newPerm[TRANSPOSE_MAX_AXIS_NUM];
96+ int64_t shapeSize = 0;
97+ int64_t delPermSize = 0;
98+ int64_t newPermSize = 0;
99+ 
100+ for (int64_t i = 0; i < dim; i++) {
101+ if (shapeInfo.inShape[i] != 1) {
102+ shape[shapeSize++] = shapeInfo.inShape[i];
103+ } else {
104+ for (int64_t j = 0; j < dim; j++) {
105+ if (shapeInfo.perm[j] == i) {
106+ delPerm[delPermSize++] = shapeInfo.perm[j];
107+ }
108+ }
109+ }
110+ }
111+ 
112+ qsort(reinterpret_cast<void*>(&delPerm[0]), delPermSize, sizeof(int64_t), DecreaseCompare);
113+ 
114+ for (int64_t i = 0; i < dim; i++) {
115+ bool delFlag = false;
116+ for (int64_t j = 0; j < delPermSize; j++) {
117+ if (shapeInfo.perm[i] == delPerm[j]) {
118+ delFlag = true;
119+ }
120+ }
121+ if (!delFlag) {
122+ newPerm[newPermSize++] = shapeInfo.perm[i];
123+ }
124+ }
125+ 
126+ for (int64_t i = 0; i < delPermSize; i++) {
127+ for (int64_t j = 0; j < newPermSize; j++) {
128+ if (newPerm[j] > delPerm[i]) {
129+ newPerm[j] = newPerm[j] - 1;
130+ }
131+ }
132+ }
133+ 
134+ DuplicateArray(newPerm, shapeInfo.reducedPerm, newPermSize);
135+ shapeInfo.dim = newPermSize;
136+ CalcOutShape(shapeInfo);
137+}
138+ 
139+void MergeAxisV2(ShapeInfo& shapeInfo)
140+{
141+ int64_t dim = shapeInfo.dim;
142+ if (dim == 1) {
143+ return;
144+ }
145+ int64_t perm[TRANSPOSE_MAX_AXIS_NUM];
146+ int64_t shape[TRANSPOSE_MAX_AXIS_NUM];
147+ int64_t newPerm[TRANSPOSE_MAX_AXIS_NUM];
148+ int64_t newShape[TRANSPOSE_MAX_AXIS_NUM];
149+ int64_t newDimPosition[TRANSPOSE_MAX_AXIS_NUM];
150+ int64_t mergedShape[TRANSPOSE_MAX_AXIS_NUM] = {0};
151+ DuplicateArray(shapeInfo.reducedPerm, perm, dim);
152+ DuplicateArray(shapeInfo.reducedInShape, shape, dim);
153+ for (int i = 0; i < TRANSPOSE_MAX_AXIS_NUM; i++) {
154+ newDimPosition[i] = -1;
155+ }
156+ 
157+ int64_t curHead = shapeInfo.reducedPerm[0];
158+ newDimPosition[curHead] = 0;
159+ mergedShape[0] = shape[curHead];
160+ int dimIndex = 0;
161+ for (int permIndex = 1; permIndex < dim; ++permIndex) {
162+ // If two indices in permutation are consecutive numbers, combine their dimensions.
163+ if (curHead + 1 == perm[permIndex]) {
164+ curHead = perm[permIndex];
165+ mergedShape[dimIndex] *= shape[curHead];
166+ } else {
167+ // Else start a new dimension.
168+ curHead = perm[permIndex];
169+ dimIndex++;
170+ newDimPosition[curHead] = dimIndex;
171+ mergedShape[dimIndex] = shape[curHead];
172+ }
173+ }
174+ 
175+ shapeInfo.dim = dimIndex + 1;
176+ 
177+ dimIndex = 0;
178+ for (int i = 0; i < dim; i++) {
179+ if (newDimPosition[i] >= 0) {
180+ newDimPosition[dimIndex++] = newDimPosition[i];
181+ }
182+ }
183+ 
184+ // Compact the new permutations and dimension sizes.
185+ dimIndex = 0;
186+ for (int64_t i = 0; i < dim; ++i) {
187+ if (newDimPosition[i] >= 0) {
188+ int64_t newPermIndex = newDimPosition[i];
189+ for (int64_t j = 0; j < dim; j++) {
190+ if (newDimPosition[j] == i) {
191+ newPerm[dimIndex] = j;
192+ break;
193+ }
194+ }
195+ newShape[dimIndex] = mergedShape[newPermIndex];
196+ dimIndex++;
197+ }
198+ }
199+ 
200+ DuplicateArray(newShape, shapeInfo.reducedInShape, dimIndex);
201+ DuplicateArray(newPerm, shapeInfo.reducedPerm, dimIndex);
202+ shapeInfo.lastAxisLen = shapeInfo.reducedInShape[shapeInfo.dim - 1];
203+ shapeInfo.lastAxisBurstLen = static_cast<int64_t>(ceil(shapeInfo.lastAxisLen * 1.0 / shapeInfo.elePerBlock));
204+ CalcOutShape(shapeInfo);
205+}
206+ 
207+} // namespace optiling
@@ -0,0 +1,100 @@
1+/**
2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+/*!
12+ * \file transpose_tiling_base.h
13+ * \brief transpose
14+ */
15+#ifndef __TRANSPOSE_RT_V2_H__
16+#define __TRANSPOSE_RT_V2_H__
17+ 
18+#include <array>
19+#include <vector>
20+#include <string>
21+#include <map>
22+#include <queue>
23+#include <memory>
24+ 
25+namespace optiling {
26+#define TRANSPOSE_MAX_AXIS_NUM 8
27+ 
28+struct ShapeInfo {
29+ int64_t id;
30+ std::vector<int64_t> inShape;
31+ std::vector<int64_t> outShape;
32+ std::vector<int64_t> perm;
33+ std::vector<int64_t> reducedInShape;
34+ std::vector<int64_t> reducedOutShape;
35+ std::vector<int64_t> reducedPerm;
36+ 
37+ int64_t inShapeSize;
38+ int64_t outShapeSize;
39+ int64_t permSize;
40+ 
41+ int64_t origDim;
42+ int64_t dim;
43+ int64_t totalVolumeActual;
44+ int64_t identical;
45+ int64_t lastAxisLen;
46+ int64_t lastAxisBurstLen;
47+ int64_t elePerBlock;
48+ int64_t eleLenInBytes;
49+ int64_t alignElement; // unit: element number padding. eg. dtype=float, axis[0]= 11, alignElement=8-(11-8)%8=5
50+ bool isLastAxisTranspose;
51+ bool isLastAxisHuge;
52+ bool isLastTwoAlignedAndTrans;
53+ 
54+ ShapeInfo()
55+ {
56+ inShape.resize(TRANSPOSE_MAX_AXIS_NUM);
57+ outShape.resize(TRANSPOSE_MAX_AXIS_NUM);
58+ perm.resize(TRANSPOSE_MAX_AXIS_NUM);
59+ reducedInShape.resize(TRANSPOSE_MAX_AXIS_NUM);
60+ reducedOutShape.resize(TRANSPOSE_MAX_AXIS_NUM);
61+ reducedPerm.resize(TRANSPOSE_MAX_AXIS_NUM);
62+ Reset();
63+ }
64+ 
65+ void Reset()
66+ {
67+ id = 0;
68+ inShapeSize = 0;
69+ outShapeSize = 0;
70+ permSize = 0;
71+ origDim = 0;
72+ dim = 0;
73+ totalVolumeActual = 0;
74+ identical = 0;
75+ lastAxisLen = 0;
76+ lastAxisBurstLen = 0;
77+ elePerBlock = 8;
78+ eleLenInBytes = 0;
79+ alignElement = 0;
80+ isLastAxisTranspose = false;
81+ isLastAxisHuge = false;
82+ isLastTwoAlignedAndTrans = false;
83+ }
84+};
85+ 
86+struct TransposeCompilerInfo {
87+ int64_t coreNum;
88+ int64_t ubSize; // unit: block
89+ 
90+ TransposeCompilerInfo() : coreNum(0), ubSize(0)
91+ {}
92+};
93+ 
94+void RemoveAxisV2(ShapeInfo& shapeInfo);
95+ 
96+void MergeAxisV2(ShapeInfo& shapeInfo);
97+ 
98+} // namespace optiling
99+ 
100+#endif // __TRANSPOSE_RT_V2_H__
@@ -0,0 +1,627 @@
1+/**
2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+/*!
12+ * \file transpose_tiling_with_gather_arch35.cpp
13+ * \brief
14+ */
15+#include "transpose_tiling_with_gather_arch35.h"
16+ 
17+namespace optiling {
18+namespace TransWithGather {
19+static constexpr int8_t NUM_TWO = 2;
20+static constexpr int8_t NUM_THREE = 3;
21+static constexpr int64_t NUM_FOUR = 4;
22+static constexpr int64_t NUM_EIGHT = 8;
23+static constexpr size_t SYS_WORKSPACE_SIZE = static_cast<size_t>(16) * 1024 * 1024;
24+ 
25+void TransposeGatherTiling::CalcTensorSize()
26+{
27+ // ping pong, input and output
28+ if (shapeInfo_.eleLenInBytes == 1L) {
29+ dataTensorSize_ = static_cast<uint32_t>(
30+ platInfo_.ubSize / (NUM_TWO * NUM_TWO + NUM_TWO) / platInfo_.ubBlockSize * platInfo_.ubBlockSize);
31+ indexTensorSize_ = dataTensorSize_ * static_cast<uint32_t>(NUM_TWO);
32+ } else if (shapeInfo_.eleLenInBytes == NUM_EIGHT) {
33+ dataTensorSize_ = static_cast<uint32_t>(
34+ (platInfo_.ubSize / (NUM_TWO * NUM_TWO * NUM_EIGHT + NUM_FOUR) * NUM_EIGHT / platInfo_.ubBlockSize *
35+ platInfo_.ubBlockSize));
36+ indexTensorSize_ = dataTensorSize_ / static_cast<uint32_t>(NUM_TWO);
37+ } else {
38+ dataTensorSize_ = static_cast<uint32_t>(
39+ platInfo_.ubSize / (NUM_TWO * NUM_TWO + 1) / platInfo_.ubBlockSize * platInfo_.ubBlockSize);
40+ indexTensorSize_ = dataTensorSize_;
41+ }
42+}
43+ 
44+int64_t TransposeGatherTiling::CalcShapeSize(const std::vector<int64_t>& shape, int64_t beg, int64_t end)
45+{
46+ int64_t res = 1;
47+ for (auto idx = beg; idx < end; ++idx) {
48+ res *= shape[idx];
49+ }
50+ return res;
51+}
52+ 
53+void TransposeGatherTiling::CalcInUbPerm(int64_t sqrtedTensor)
54+{
55+ for (int64_t i = shapeInfo_.dim - 1; i >= 0; --i) {
56+ inUbPerm_.perm[inUbPerm_.cnt++] = i;
57+ inUbPermSet_.insert(i);
58+ allUbPerm_.insert(i);
59+ if (inUbPerm_.cnt >= UB_MAX_BRW_NUM ||
60+ CalcShapeSize(shapeInfo_.reducedInShape, i, shapeInfo_.dim) > sqrtedTensor) {
61+ break;
62+ }
63+ }
64+}
65+ 
66+void TransposeGatherTiling::CalcOutUbPerm(int64_t sqrtedTensor)
67+{
68+ for (int64_t i = shapeInfo_.dim - 1; i >= 0; --i) {
69+ outUbPerm_.perm[outUbPerm_.cnt++] = shapeInfo_.reducedPerm[i];
70+ allUbPerm_.insert(shapeInfo_.reducedPerm[i]);
71+ if (outUbPerm_.cnt >= UB_MAX_BRW_NUM ||
72+ CalcShapeSize(shapeInfo_.reducedOutShape, i, shapeInfo_.dim) > sqrtedTensor) {
73+ break;
74+ }
75+ }
76+}
77+ 
78+void TransposeGatherTiling::AdjustUbCutAxisFactor(int32_t& axisFactor, int8_t axisFlag, int64_t elemInTensor)
79+{
80+ int64_t srcInUbAxesSize = 1;
81+ int64_t srcOutUbAxesSize = 1;
82+ int64_t dstInUbAxesSize = 1;
83+ int64_t dstOutUbAxesSize = 1;
84+ 
85+ std::set<int8_t> viceUbPerm0(allUbPerm_);
86+ for (int8_t i = 0; i < outUbPerm_.cnt - 1; ++i) {
87+ dstOutUbAxesSize *= shapeInfo_.reducedInShape[outUbPerm_.perm[i]];
88+ viceUbPerm0.erase(outUbPerm_.perm[i]);
89+ }
90+ for (int8_t i = 0; i < inUbPerm_.cnt - 1; ++i) {
91+ if (viceUbPerm0.find(inUbPerm_.perm[i]) != viceUbPerm0.end()) {
92+ dstInUbAxesSize *= shapeInfo_.reducedInShape[inUbPerm_.perm[i]];
93+ }
94+ }
95+ std::set<int8_t> viceUbPerm1(allUbPerm_);
96+ for (int8_t i = 0; i < inUbPerm_.cnt - 1; ++i) {
97+ srcInUbAxesSize *= shapeInfo_.reducedInShape[inUbPerm_.perm[i]];
98+ viceUbPerm1.erase(inUbPerm_.perm[i]);
99+ }
100+ for (int8_t i = 0; i < outUbPerm_.cnt - 1; ++i) {
101+ if (viceUbPerm1.find(outUbPerm_.perm[i]) != viceUbPerm1.end()) {
102+ srcOutUbAxesSize *= shapeInfo_.reducedInShape[outUbPerm_.perm[i]];
103+ }
104+ }
105+ 
106+ int64_t elemPerBlock = platInfo_.ubBlockSize / shapeInfo_.eleLenInBytes;
107+ int64_t dstFactor = 0;
108+ int64_t srcFactor = 0;
109+ // in and out ub cut same axis
110+ if (axisFlag == 0) {
111+ bool isDstUbOverflow =
112+ (dstInUbAxesSize * Ops::Base::CeilAlign(dstOutUbAxesSize * axisFactor, elemPerBlock) > elemInTensor);
113+ bool isSrcUbOverflow =
114+ (srcOutUbAxesSize * Ops::Base::CeilAlign(srcInUbAxesSize * axisFactor, elemPerBlock) > elemInTensor);
115+ if (isDstUbOverflow || isSrcUbOverflow) {
116+ dstFactor = elemInTensor / dstInUbAxesSize / elemPerBlock * elemPerBlock / dstOutUbAxesSize;
117+ srcFactor = elemInTensor / srcOutUbAxesSize / elemPerBlock * elemPerBlock / srcInUbAxesSize;
118+ axisFactor = static_cast<int32_t>(std::min(dstFactor, srcFactor));
119+ }
120+ // out ub cut axis
121+ } else if (axisFlag == 1 || axisFlag == NUM_THREE) {
122+ if (axisFlag == NUM_THREE) {
123+ dstInUbAxesSize *= ubSplitInfo_.inUbCutAxisFactor;
124+ }
125+ if (axisFlag == 1) {
126+ srcOutUbAxesSize /= ubSplitInfo_.inUbCutAxisFactor;
127+ }
128+ bool isDstUbOverflow =
129+ (dstInUbAxesSize * Ops::Base::CeilAlign(dstOutUbAxesSize * axisFactor, elemPerBlock) > elemInTensor);
130+ bool isSrcUbOverflow =
131+ (axisFactor * srcOutUbAxesSize *
132+ Ops::Base::CeilAlign(srcInUbAxesSize * ubSplitInfo_.inUbCutAxisFactor, elemPerBlock) >
133+ elemInTensor);
134+ if (isDstUbOverflow || isSrcUbOverflow) {
135+ dstFactor = elemInTensor / dstInUbAxesSize / elemPerBlock * elemPerBlock / dstOutUbAxesSize;
136+ srcFactor =
137+ (elemInTensor / srcOutUbAxesSize /
138+ Ops::Base::CeilAlign(srcInUbAxesSize * ubSplitInfo_.inUbCutAxisFactor, elemPerBlock));
139+ axisFactor = static_cast<int32_t>(std::min(dstFactor, srcFactor));
140+ }
141+ // in ub cut axis
142+ } else if (axisFlag == NUM_TWO) {
143+ dstInUbAxesSize /= ubSplitInfo_.outUbCutAxisFactor;
144+ bool isDstUbOverflow =
145+ (axisFactor * dstInUbAxesSize *
146+ Ops::Base::CeilAlign(dstOutUbAxesSize * ubSplitInfo_.outUbCutAxisFactor, elemPerBlock) >
147+ elemInTensor);
148+ bool isSrcUbOverflow =
149+ (srcOutUbAxesSize * Ops::Base::CeilAlign(srcInUbAxesSize * axisFactor, elemPerBlock) > elemInTensor);
150+ if (isDstUbOverflow || isSrcUbOverflow) {
151+ dstFactor =
152+ (elemInTensor / dstInUbAxesSize /
153+ Ops::Base::CeilAlign(dstOutUbAxesSize * ubSplitInfo_.outUbCutAxisFactor, elemPerBlock));
154+ srcFactor = elemInTensor / srcOutUbAxesSize / elemPerBlock * elemPerBlock / srcInUbAxesSize;
155+ axisFactor = static_cast<int32_t>(std::min(dstFactor, srcFactor));
156+ }
157+ }
158+}
159+ 
160+void TransposeGatherTiling::CalcUbAxisCutFactor(
161+ int64_t elemInTensor, int64_t sqrtedTensor, bool isLastInPermLeft, bool isLastOutPermLeft,
162+ const std::set<int8_t>& viceAllUbPerm)
163+{
164+ int64_t allSavedElems = 1;
165+ for (int8_t idx : allUbPerm_) {
166+ if (viceAllUbPerm.find(idx) == viceAllUbPerm.end()) {
167+ allSavedElems *= shapeInfo_.reducedInShape[idx];
168+ }
169+ }
170+ auto dim = shapeInfo_.dim;
171+ int64_t outSavedElems = CalcShapeSize(shapeInfo_.reducedOutShape, dim - outUbPerm_.cnt + 1, dim);
172+ int64_t inSavedElems = CalcShapeSize(shapeInfo_.reducedInShape, dim - inUbPerm_.cnt + 1, dim);
173+ // to save ub for gather index
174+ int64_t elemPerBlock = platInfo_.ubBlockSize / shapeInfo_.eleLenInBytes;
175+ int64_t maxOutCutAxisSize =
176+ elemInTensor / NUM_FOUR / elemPerBlock * elemPerBlock / Ops::Base::CeilAlign(outSavedElems, elemPerBlock);
177+ int64_t maxCutAxisSize = elemInTensor / allSavedElems;
178+ 
179+ if (isLastInPermLeft && isLastOutPermLeft) {
180+ if (inUbPerm_.perm[inUbPerm_.cnt - 1] != outUbPerm_.perm[outUbPerm_.cnt - 1]) {
181+ if (outUbPerm_.cnt + inUbPerm_.cnt == ubSplitInfo_.ubAxesCnt) {
182+ ubSplitInfo_.inUbCutAxisFactor = std::min(ubSplitInfo_.inUbCutAxisSize, sqrtedTensor / inSavedElems);
183+ ubSplitInfo_.outUbCutAxisFactor = std::min(ubSplitInfo_.outUbCutAxisSize, sqrtedTensor / outSavedElems);
184+ } else {
185+ int64_t comSavedElems = 1;
186+ for (int8_t idx = 0; idx < outUbPerm_.cnt - 1; ++idx) {
187+ if (inUbPermSet_.find(outUbPerm_.perm[idx]) != inUbPermSet_.end()) {
188+ comSavedElems *= shapeInfo_.reducedInShape[outUbPerm_.perm[idx]];
189+ }
190+ }
191+ int64_t newSqrtedTensor =
192+ static_cast<int64_t>(std::sqrt(elemInTensor / comSavedElems / elemPerBlock * elemPerBlock));
193+ int64_t inLeft = inSavedElems / comSavedElems;
194+ int64_t outLeft = outSavedElems / comSavedElems;
195+ ubSplitInfo_.inUbCutAxisFactor = std::min(ubSplitInfo_.inUbCutAxisSize, newSqrtedTensor / inLeft);
196+ ubSplitInfo_.outUbCutAxisFactor = std::min(ubSplitInfo_.outUbCutAxisSize, newSqrtedTensor / outLeft);
197+ AdjustUbCutAxisFactor(ubSplitInfo_.outUbCutAxisFactor, NUM_THREE, elemInTensor);
198+ }
199+ } else {
200+ ubSplitInfo_.inUbCutAxisFactor =
201+ std::min(std::min(ubSplitInfo_.inUbCutAxisSize, maxCutAxisSize), maxOutCutAxisSize);
202+ AdjustUbCutAxisFactor(ubSplitInfo_.inUbCutAxisFactor, 0, elemInTensor);
203+ ubSplitInfo_.outUbCutAxisFactor = ubSplitInfo_.inUbCutAxisFactor;
204+ }
205+ } else if (!isLastInPermLeft && !isLastOutPermLeft) {
206+ ubSplitInfo_.inUbCutAxisFactor = ubSplitInfo_.inUbCutAxisSize;
207+ ubSplitInfo_.outUbCutAxisFactor = ubSplitInfo_.outUbCutAxisSize;
208+ } else {
209+ if (!isLastInPermLeft) {
210+ ubSplitInfo_.inUbCutAxisFactor = ubSplitInfo_.inUbCutAxisSize;
211+ ubSplitInfo_.outUbCutAxisFactor =
212+ std::min(std::min(ubSplitInfo_.outUbCutAxisSize, maxCutAxisSize), maxOutCutAxisSize);
213+ AdjustUbCutAxisFactor(ubSplitInfo_.outUbCutAxisFactor, 1, elemInTensor);
214+ } else {
215+ ubSplitInfo_.outUbCutAxisFactor = ubSplitInfo_.outUbCutAxisSize;
216+ ubSplitInfo_.inUbCutAxisFactor = std::min(ubSplitInfo_.inUbCutAxisSize, maxCutAxisSize);
217+ AdjustUbCutAxisFactor(ubSplitInfo_.inUbCutAxisFactor, NUM_TWO, elemInTensor);
218+ }
219+ }
220+}
221+ 
222+ge::graphStatus TransposeGatherTiling::CalcUbAxesInfo(
223+ const int64_t (&tmpInAxes)[MAX_TRANS_AXIS_NUM], const int64_t (&tmpOutAxes)[MAX_TRANS_AXIS_NUM],
224+ const int8_t (&tmpOutPerm)[MAX_TRANS_AXIS_NUM])
225+{
226+ int8_t inIdx = 0;
227+ int8_t outIdx = 0;
228+ for (int8_t j = 0; j < MAX_TRANS_AXIS_NUM; ++j) {
229+ if (tmpOutAxes[j] != 0) {
230+ ubSplitInfo_.outUbAxes[outIdx] = static_cast<int32_t>(tmpOutAxes[j]);
231+ // do like [5,2,3,0] -> [3,1,2,0]
232+ ubSplitInfo_.ubPerm[outIdx] =
233+ static_cast<int8_t>(std::distance(allUbPerm_.begin(), allUbPerm_.find(tmpOutPerm[j])));
234+ ++outIdx;
235+ }
236+ if (tmpInAxes[j] != 0) {
237+ ubSplitInfo_.inUbAxes[inIdx++] = static_cast<int32_t>(tmpInAxes[j]);
238+ }
239+ }
240+ 
241+ int32_t totalSizeInUb = static_cast<int32_t>(shapeInfo_.eleLenInBytes);
242+ for (int8_t i = 0; i < ubSplitInfo_.ubAxesCnt; ++i) {
243+ totalSizeInUb *= ubSplitInfo_.inUbAxes[i];
244+ }
245+ int32_t indexStep = 1;
246+ for (int8_t i = ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - 1] + 1; i < ubSplitInfo_.ubAxesCnt; ++i) {
247+ indexStep *= ubSplitInfo_.inUbAxes[i];
248+ }
249+ // MTE size must be >= gate
250+ if (totalSizeInUb < MTE_GATE || CheckBC(indexStep)) {
251+ return ge::GRAPH_FAILED;
252+ }
253+ 
254+ for (int8_t k = 0; k < static_cast<int8_t>(allUbPerm_.size()); ++k) {
255+ if (ubSplitInfo_.ubPerm[k] == ubSplitInfo_.inUbInCutPos) {
256+ ubSplitInfo_.outUbInCutPos = k;
257+ }
258+ if (ubSplitInfo_.ubPerm[k] == ubSplitInfo_.inUbOutCutPos) {
259+ ubSplitInfo_.outUbOutCutPos = k;
260+ }
261+ }
262+ return ge::GRAPH_SUCCESS;
263+}
264+ 
265+ge::graphStatus TransposeGatherTiling::CalcUbSplitInfo4Gather(int64_t elemInTensor, int64_t sqrtedTensor)
266+{
267+ int8_t tmpOutPerm[MAX_TRANS_AXIS_NUM] = {0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf};
268+ int64_t tmpInAxes[MAX_TRANS_AXIS_NUM] = {0, 0, 0, 0, 0, 0, 0, 0};
269+ int64_t tmpOutAxes[MAX_TRANS_AXIS_NUM] = {0, 0, 0, 0, 0, 0, 0, 0};
270+ std::set<int8_t> viceAllUbPerm(allUbPerm_);
271+ 
272+ ubSplitInfo_.ubAxesCnt = static_cast<int8_t>(allUbPerm_.size());
273+ ubSplitInfo_.inUbCutAxisSize = shapeInfo_.reducedInShape[inUbPerm_.perm[inUbPerm_.cnt - 1]];
274+ ubSplitInfo_.inUbInCutPos =
275+ static_cast<int8_t>(std::distance(allUbPerm_.begin(), allUbPerm_.find(inUbPerm_.perm[inUbPerm_.cnt - 1])));
276+ // all axes can be move in ub except last
277+ for (int8_t i = 0; i < inUbPerm_.cnt - 1; ++i) {
278+ auto iter = std::find(shapeInfo_.reducedPerm.begin(), shapeInfo_.reducedPerm.end(), inUbPerm_.perm[i]);
279+ auto idx = std::distance(shapeInfo_.reducedPerm.begin(), iter);
280+ tmpOutPerm[idx] = inUbPerm_.perm[i];
281+ tmpOutAxes[idx] = shapeInfo_.reducedInShape[inUbPerm_.perm[i]];
282+ tmpInAxes[inUbPerm_.perm[i]] = shapeInfo_.reducedInShape[inUbPerm_.perm[i]];
283+ viceAllUbPerm.erase(inUbPerm_.perm[i]);
284+ }
285+ ubSplitInfo_.outUbCutAxisSize = shapeInfo_.reducedInShape[outUbPerm_.perm[outUbPerm_.cnt - 1]];
286+ ubSplitInfo_.inUbOutCutPos =
287+ static_cast<int8_t>(std::distance(allUbPerm_.begin(), allUbPerm_.find(outUbPerm_.perm[outUbPerm_.cnt - 1])));
288+ for (int8_t i = 0; i < outUbPerm_.cnt - 1; ++i) {
289+ if (viceAllUbPerm.find(outUbPerm_.perm[i]) != viceAllUbPerm.end()) {
290+ auto iter = std::find(shapeInfo_.reducedPerm.begin(), shapeInfo_.reducedPerm.end(), outUbPerm_.perm[i]);
291+ auto idx = std::distance(shapeInfo_.reducedPerm.begin(), iter);
292+ // pattern like: [6, 5, 4, 0xf, 0, 2, 1, 0xf]
293+ tmpOutPerm[idx] = outUbPerm_.perm[i];
294+ // pattern like: [10, 20, 50, 0, 5, 7, 2, 0]
295+ tmpOutAxes[idx] = shapeInfo_.reducedInShape[outUbPerm_.perm[i]];
296+ // pattern like: [0, 10, 50, 20, 5, 0, 7, 2]
297+ tmpInAxes[outUbPerm_.perm[i]] = shapeInfo_.reducedInShape[outUbPerm_.perm[i]];
298+ viceAllUbPerm.erase(outUbPerm_.perm[i]);
299+ }
300+ }
301+ 
302+ bool isLastInPermLeft = viceAllUbPerm.find(inUbPerm_.perm[inUbPerm_.cnt - 1]) != viceAllUbPerm.end();
303+ bool isLastOutPermLeft = viceAllUbPerm.find(outUbPerm_.perm[outUbPerm_.cnt - 1]) != viceAllUbPerm.end();
304+ CalcUbAxisCutFactor(elemInTensor, sqrtedTensor, isLastInPermLeft, isLastOutPermLeft, viceAllUbPerm);
305+ 
306+ if (isLastInPermLeft) {
307+ auto iter =
308+ std::find(shapeInfo_.reducedPerm.begin(), shapeInfo_.reducedPerm.end(), inUbPerm_.perm[inUbPerm_.cnt - 1]);
309+ auto idx = std::distance(shapeInfo_.reducedPerm.begin(), iter);
310+ tmpOutPerm[idx] = inUbPerm_.perm[inUbPerm_.cnt - 1];
311+ tmpOutAxes[idx] = ubSplitInfo_.inUbCutAxisFactor;
312+ tmpInAxes[inUbPerm_.perm[inUbPerm_.cnt - 1]] = ubSplitInfo_.inUbCutAxisFactor;
313+ viceAllUbPerm.erase(inUbPerm_.perm[inUbPerm_.cnt - 1]);
314+ }
315+ if (isLastOutPermLeft) {
316+ auto iter = std::find(
317+ shapeInfo_.reducedPerm.begin(), shapeInfo_.reducedPerm.end(), outUbPerm_.perm[outUbPerm_.cnt - 1]);
318+ auto idx = std::distance(shapeInfo_.reducedPerm.begin(), iter);
319+ tmpOutPerm[idx] = outUbPerm_.perm[outUbPerm_.cnt - 1];
320+ tmpOutAxes[idx] = ubSplitInfo_.outUbCutAxisFactor;
321+ tmpInAxes[outUbPerm_.perm[outUbPerm_.cnt - 1]] = ubSplitInfo_.outUbCutAxisFactor;
322+ }
323+ 
324+ return CalcUbAxesInfo(tmpInAxes, tmpOutAxes, tmpOutPerm);
325+}
326+ 
327+void TransposeGatherTiling::CalcUbSplitInfo4MTE()
328+{
329+ auto dim = shapeInfo_.dim;
330+ int8_t axisIdx = 0;
331+ 
332+ if (outUbPerm_.perm[0] < inUbPerm_.perm[inUbPerm_.cnt - 1]) {
333+ // to make sure output last dim and move in cube are consecutive
334+ ubSplitInfo_.axis0InSrcStride = CalcShapeSize(shapeInfo_.reducedInShape, outUbPerm_.perm[0] + 1, dim);
335+ for (int8_t i = inUbPerm_.perm[inUbPerm_.cnt - 1] - 1; i >= 0; --i) {
336+ if (allUbPerm_.find(i) != allUbPerm_.end() && i != outUbPerm_.perm[0] && axisIdx == 0) {
337+ ubSplitInfo_.axis1InSrcStride = CalcShapeSize(shapeInfo_.reducedInShape, i + 1, dim);
338+ ++axisIdx;
339+ } else if (allUbPerm_.find(i) != allUbPerm_.end() && i != outUbPerm_.perm[0] && axisIdx == 1) {
340+ ubSplitInfo_.axis2InSrcStride = CalcShapeSize(shapeInfo_.reducedInShape, i + 1, dim);
341+ }
342+ }
343+ } else {
344+ for (int8_t i = inUbPerm_.perm[inUbPerm_.cnt - 1] - 1; i >= 0; --i) {
345+ if (allUbPerm_.find(i) != allUbPerm_.end() && axisIdx == 0) {
346+ ubSplitInfo_.axis0InSrcStride = CalcShapeSize(shapeInfo_.reducedInShape, i + 1, dim);
347+ ++axisIdx;
348+ } else if (allUbPerm_.find(i) != allUbPerm_.end() && axisIdx == 1) {
349+ ubSplitInfo_.axis1InSrcStride = CalcShapeSize(shapeInfo_.reducedInShape, i + 1, dim);
350+ }
351+ }
352+ }
353+ 
354+ axisIdx = 0;
355+ for (int8_t j = dim - outUbPerm_.cnt - 1; j >= 0; --j) {
356+ if (allUbPerm_.find(shapeInfo_.reducedPerm[j]) != allUbPerm_.end() && axisIdx == 0) {
357+ ubSplitInfo_.axis0OutDstStride = CalcShapeSize(shapeInfo_.reducedOutShape, j + 1, dim);
358+ ++axisIdx;
359+ } else if (allUbPerm_.find(shapeInfo_.reducedPerm[j]) != allUbPerm_.end() && axisIdx == 1) {
360+ ubSplitInfo_.axis1OutDstStride = CalcShapeSize(shapeInfo_.reducedOutShape, j + 1, dim);
361+ ++axisIdx;
362+ } else if (allUbPerm_.find(shapeInfo_.reducedPerm[j]) != allUbPerm_.end() && axisIdx > 1) {
363+ ubSplitInfo_.axis2OutDstStride = CalcShapeSize(shapeInfo_.reducedOutShape, j + 1, dim);
364+ }
365+ }
366+}
367+ 
368+void TransposeGatherTiling::AdjustInUbAxesPosition()
369+{
370+ int8_t outLastDimInPos = ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - 1];
371+ int8_t axis0Gap = ubSplitInfo_.inUbInCutPos - 1 - outLastDimInPos;
372+ // only for brorrow axis case, to make output last dim to be the axis0 when move data in
373+ if (axis0Gap > 0) {
374+ for (int8_t i = 0; i < axis0Gap; ++i) {
375+ ubSplitInfo_.inUbAxes[outLastDimInPos + i] = ubSplitInfo_.inUbAxes[outLastDimInPos + i + 1];
376+ }
377+ ubSplitInfo_.inUbAxes[outLastDimInPos + axis0Gap] = ubSplitInfo_.outUbAxes[ubSplitInfo_.ubAxesCnt - 1];
378+ if (outLastDimInPos < ubSplitInfo_.inUbOutCutPos && ubSplitInfo_.inUbOutCutPos < ubSplitInfo_.inUbInCutPos) {
379+ ubSplitInfo_.inUbOutCutPos -= 1;
380+ }
381+ 
382+ if (outUbPerm_.cnt == NUM_TWO) {
383+ ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - NUM_TWO] = 0;
384+ ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - 1] = 1;
385+ } else if (outUbPerm_.cnt == NUM_THREE) {
386+ /* no overlap: 2 1 0 -> 1 0 2
387+ * 2 0 1 -> 1 0 2
388+ * 0 2 1 -> 0 1 2
389+ * 1 2 0 -> 0 1 2
390+ * overlap: x 1 0 -> x 0 1
391+ * 1 x 0 -> 0 x 1
392+ */
393+ if (inUbPerm_.cnt + outUbPerm_.cnt == ubSplitInfo_.ubAxesCnt) {
394+ if (ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - NUM_THREE] == NUM_TWO) {
395+ ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - NUM_THREE] = 1;
396+ ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - NUM_TWO] = 0;
397+ ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - 1] = NUM_TWO;
398+ } else if (ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - NUM_TWO] == NUM_TWO) {
399+ ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - NUM_THREE] = 0;
400+ ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - NUM_TWO] = 1;
401+ ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - 1] = NUM_TWO;
402+ }
403+ } else {
404+ if (ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - NUM_THREE] >= NUM_TWO) {
405+ ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - NUM_TWO] = 0;
406+ ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - 1] = 1;
407+ } else if (ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - NUM_TWO] >= NUM_TWO) {
408+ ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - NUM_THREE] = 0;
409+ ubSplitInfo_.ubPerm[ubSplitInfo_.ubAxesCnt - 1] = 1;
410+ }
411+ }
412+ }
413+ }
414+}
415+ 
416+bool TransposeGatherTiling::CheckBC(int32_t steps)
417+{
418+ int32_t bytesPerSubBank = 8;
419+ int32_t bytesPerBank = 128;
420+ int32_t stepBytes = steps * shapeInfo_.eleLenInBytes;
421+ int32_t stepBytesAlign = Ops::Base::CeilAlign(stepBytes, bytesPerSubBank);
422+ return (stepBytesAlign % bytesPerBank / bytesPerSubBank % NUM_TWO == 0);
423+}
424+ 
425+int64_t TransposeGatherTiling::CalcSqrtedTensor(int64_t elemInTensor)
426+{
427+ int64_t elemPerBlock = platInfo_.ubBlockSize / shapeInfo_.eleLenInBytes;
428+ int64_t sqrtedTensor = static_cast<int64_t>(std::sqrt(elemInTensor)) / elemPerBlock * elemPerBlock;
429+ if (sqrtedTensor * shapeInfo_.eleLenInBytes > platInfo_.cacheLineSize) {
430+ sqrtedTensor =
431+ (sqrtedTensor * shapeInfo_.eleLenInBytes / platInfo_.cacheLineSize * platInfo_.cacheLineSize /
432+ shapeInfo_.eleLenInBytes);
433+ }
434+ int32_t bytesPerSubBank = 8;
435+ int64_t lastInDim = shapeInfo_.reducedInShape[shapeInfo_.dim - 1];
436+ if (lastInDim > sqrtedTensor && CheckBC(static_cast<int32_t>(sqrtedTensor))) {
437+ sqrtedTensor -= (bytesPerSubBank / shapeInfo_.eleLenInBytes);
438+ }
439+ return sqrtedTensor;
440+}
441+ 
442+ge::graphStatus TransposeGatherTiling::CalcUbSplitInfo()
443+{
444+ int64_t elemInTensor = static_cast<int64_t>(dataTensorSize_ / shapeInfo_.eleLenInBytes);
445+ int64_t sqrtedTensor = CalcSqrtedTensor(elemInTensor);
446+ CalcInUbPerm(sqrtedTensor);
447+ CalcOutUbPerm(sqrtedTensor);
448+ OP_CHECK_IF(
449+ CalcUbSplitInfo4Gather(elemInTensor, sqrtedTensor) != ge::GRAPH_SUCCESS,
450+ OP_LOGD(context_->GetNodeName(), "MTE size is too small!"), return ge::GRAPH_FAILED);
451+ CalcUbSplitInfo4MTE();
452+ AdjustInUbAxesPosition();
453+ OP_LOGD(context_->GetNodeName(), "UB tiling is done!");
454+ return ge::GRAPH_SUCCESS;
455+}
456+ 
457+ge::graphStatus TransposeGatherTiling::CalcBlockSplitInfo()
458+{
459+ int8_t dim = shapeInfo_.dim;
460+ int64_t axisFactor = 1;
461+ int64_t totalElems = 1;
462+ for (int8_t i = 0; i < dim; ++i) {
463+ if (allUbPerm_.find(i) == allUbPerm_.end()) {
464+ axisFactor = 1;
465+ } else if (
466+ i == inUbPerm_.perm[inUbPerm_.cnt - 1] && ubSplitInfo_.inUbCutAxisSize != ubSplitInfo_.inUbCutAxisFactor) {
467+ axisFactor = ubSplitInfo_.inUbCutAxisFactor;
468+ if (ubSplitInfo_.inUbCutAxisSize % ubSplitInfo_.inUbCutAxisFactor != 0) {
469+ blkSplitInfo_.blkInUbCutPos = blkSplitInfo_.blkAxesCnt;
470+ }
471+ } else if (
472+ i == outUbPerm_.perm[outUbPerm_.cnt - 1] &&
473+ ubSplitInfo_.outUbCutAxisSize != ubSplitInfo_.outUbCutAxisFactor) {
474+ axisFactor = ubSplitInfo_.outUbCutAxisFactor;
475+ if (ubSplitInfo_.outUbCutAxisSize % ubSplitInfo_.outUbCutAxisFactor != 0) {
476+ blkSplitInfo_.blkOutUbCutPos = blkSplitInfo_.blkAxesCnt;
477+ }
478+ } else {
479+ continue;
480+ }
481+ int64_t axisLpSize = Ops::Base::CeilDiv(shapeInfo_.reducedInShape[i], axisFactor);
482+ blkSplitInfo_.blkAxes[blkSplitInfo_.blkAxesCnt] = axisLpSize;
483+ blkSplitInfo_.blkAxesInAOffset[blkSplitInfo_.blkAxesCnt] =
484+ CalcShapeSize(shapeInfo_.reducedInShape, i + 1, dim) * axisFactor;
485+ auto iter = std::find(shapeInfo_.reducedPerm.begin(), shapeInfo_.reducedPerm.end(), i);
486+ int8_t gap = static_cast<int8_t>(std::distance(shapeInfo_.reducedPerm.begin(), iter));
487+ blkSplitInfo_.blkAxesOutAOffset[blkSplitInfo_.blkAxesCnt] =
488+ CalcShapeSize(shapeInfo_.reducedOutShape, gap + 1, dim) * axisFactor;
489+ ++blkSplitInfo_.blkAxesCnt;
490+ totalElems *= axisLpSize;
491+ }
492+ 
493+ blkSplitInfo_.usedCoreCnt = Ops::Base::CeilDiv(totalElems, Ops::Base::CeilDiv(totalElems, platInfo_.coreNum));
494+ if (blkSplitInfo_.usedCoreCnt < static_cast<uint32_t>(platInfo_.coreNum / NUM_TWO)) {
495+ return ge::GRAPH_FAILED;
496+ }
497+ blkSplitInfo_.blkFactor = Ops::Base::CeilDiv(totalElems, static_cast<int64_t>(blkSplitInfo_.usedCoreCnt));
498+ blkSplitInfo_.blkTailFactor = totalElems - (blkSplitInfo_.usedCoreCnt - 1) * blkSplitInfo_.blkFactor;
499+ OP_LOGD(context_->GetNodeName(), "Block tiling is done!");
500+ return ge::GRAPH_SUCCESS;
501+}
502+ 
503+ge::graphStatus TransposeGatherTiling::SetTilingKeyAndCore()
504+{
505+ OP_CHECK_IF(
506+ context_->SetTilingKey(tilingKey_) != ge::GRAPH_SUCCESS,
507+ OP_LOGE(context_->GetNodeName(), "Set tiling key is failed!"), return ge::GRAPH_FAILED);
508+ OP_CHECK_IF(
509+ context_->SetBlockDim(blkSplitInfo_.usedCoreCnt) != ge::GRAPH_SUCCESS,
510+ OP_LOGE(context_->GetNodeName(), "Set used core size is failed!"), return ge::GRAPH_FAILED);
511+ 
512+ size_t* workspaces = context_->GetWorkspaceSizes(1);
513+ OP_CHECK_NULL_WITH_CONTEXT(context_, workspaces);
514+ workspaces[0] = SYS_WORKSPACE_SIZE;
515+ 
516+ return ge::GRAPH_SUCCESS;
517+}
518+ 
519+void TransposeGatherTiling::WriteTilingData()
520+{
521+ tilingData_.set_tilingKey(tilingKey_);
522+ tilingData_.set_dataTensorSize(dataTensorSize_);
523+ tilingData_.set_indexTensorSize(indexTensorSize_);
524+ tilingData_.set_usedCoreCnt(blkSplitInfo_.usedCoreCnt);
525+ tilingData_.set_blkAxesCnt(blkSplitInfo_.blkAxesCnt);
526+ tilingData_.set_blkInUbCutPos(blkSplitInfo_.blkInUbCutPos);
527+ tilingData_.set_blkOutUbCutPos(blkSplitInfo_.blkOutUbCutPos);
528+ tilingData_.set_ubAxesCnt(ubSplitInfo_.ubAxesCnt);
529+ tilingData_.set_inUbInCutPos(ubSplitInfo_.inUbInCutPos);
530+ tilingData_.set_inUbOutCutPos(ubSplitInfo_.inUbOutCutPos);
531+ tilingData_.set_outUbInCutPos(ubSplitInfo_.outUbInCutPos);
532+ tilingData_.set_outUbOutCutPos(ubSplitInfo_.outUbOutCutPos);
533+ tilingData_.set_blkFactor(blkSplitInfo_.blkFactor);
534+ tilingData_.set_blkTailFactor(blkSplitInfo_.blkTailFactor);
535+ tilingData_.set_inUbCutAxisSize(ubSplitInfo_.inUbCutAxisSize);
536+ tilingData_.set_outUbCutAxisSize(ubSplitInfo_.outUbCutAxisSize);
537+ tilingData_.set_inUbCutAxisFactor(ubSplitInfo_.inUbCutAxisFactor);
538+ tilingData_.set_outUbCutAxisFactor(ubSplitInfo_.outUbCutAxisFactor);
539+ tilingData_.set_axis0InSrcStride(ubSplitInfo_.axis0InSrcStride);
540+ tilingData_.set_axis1InSrcStride(ubSplitInfo_.axis1InSrcStride);
541+ tilingData_.set_axis2InSrcStride(ubSplitInfo_.axis2InSrcStride);
542+ tilingData_.set_axis0OutDstStride(ubSplitInfo_.axis0OutDstStride);
543+ tilingData_.set_axis1OutDstStride(ubSplitInfo_.axis1OutDstStride);
544+ tilingData_.set_axis2OutDstStride(ubSplitInfo_.axis2OutDstStride);
545+ 
546+ tilingData_.set_blkAxes(blkSplitInfo_.blkAxes);
547+ tilingData_.set_blkAxesInAOffset(blkSplitInfo_.blkAxesInAOffset);
548+ tilingData_.set_blkAxesOutAOffset(blkSplitInfo_.blkAxesOutAOffset);
549+ tilingData_.set_inUbAxes(ubSplitInfo_.inUbAxes);
550+ tilingData_.set_outUbAxes(ubSplitInfo_.outUbAxes);
551+ tilingData_.set_ubPerm(ubSplitInfo_.ubPerm);
552+ 
553+ tilingData_.SaveToBuffer(context_->GetRawTilingData()->GetData(), context_->GetRawTilingData()->GetCapacity());
554+ context_->GetRawTilingData()->SetDataSize(tilingData_.GetDataSize());
555+}
556+ 
557+std::string TransposeGatherTiling::PrintTilingData()
558+{
559+ std::string tdStr;
560+ tdStr += std::to_string(static_cast<int64_t>(tilingKey_)) + ",";
561+ tdStr += std::to_string(static_cast<int32_t>(dataTensorSize_)) + ",";
562+ tdStr += std::to_string(static_cast<int32_t>(indexTensorSize_)) + ",";
563+ tdStr += std::to_string(static_cast<int32_t>(blkSplitInfo_.usedCoreCnt)) + ",";
564+ tdStr += std::to_string(blkSplitInfo_.blkAxesCnt) + ",";
565+ tdStr += std::to_string(blkSplitInfo_.blkInUbCutPos) + ",";
566+ tdStr += std::to_string(blkSplitInfo_.blkOutUbCutPos) + ",";
567+ tdStr += std::to_string(ubSplitInfo_.ubAxesCnt) + ",";
568+ tdStr += std::to_string(ubSplitInfo_.inUbInCutPos) + ",";
569+ tdStr += std::to_string(ubSplitInfo_.inUbOutCutPos) + ",";
570+ tdStr += std::to_string(ubSplitInfo_.outUbInCutPos) + ",";
571+ tdStr += std::to_string(ubSplitInfo_.outUbOutCutPos) + ",";
572+ tdStr += std::to_string(blkSplitInfo_.blkFactor) + ",";
573+ tdStr += std::to_string(blkSplitInfo_.blkTailFactor) + ",";
574+ tdStr += std::to_string(ubSplitInfo_.inUbCutAxisSize) + ",";
575+ tdStr += std::to_string(ubSplitInfo_.outUbCutAxisSize) + ",";
576+ tdStr += std::to_string(ubSplitInfo_.inUbCutAxisFactor) + ",";
577+ tdStr += std::to_string(ubSplitInfo_.outUbCutAxisFactor) + ",";
578+ tdStr += std::to_string(ubSplitInfo_.axis0InSrcStride) + ",";
579+ tdStr += std::to_string(ubSplitInfo_.axis1InSrcStride) + ",";
580+ tdStr += std::to_string(ubSplitInfo_.axis2InSrcStride) + ",";
581+ tdStr += std::to_string(ubSplitInfo_.axis0OutDstStride) + ",";
582+ tdStr += std::to_string(ubSplitInfo_.axis1OutDstStride) + ",";
583+ tdStr += std::to_string(ubSplitInfo_.axis2OutDstStride) + ",";
584+ tdStr += "block axes:";
585+ for (int8_t i = 0; i < MAX_TRANS_AXIS_NUM; ++i) {
586+ tdStr += std::to_string(blkSplitInfo_.blkAxes[i]) + " ";
587+ }
588+ tdStr += ",block axes in offset:";
589+ for (int8_t i = 0; i < MAX_TRANS_AXIS_NUM; ++i) {
590+ tdStr += std::to_string(blkSplitInfo_.blkAxesInAOffset[i]) + " ";
591+ }
592+ tdStr += ",block axes out offset:";
593+ for (int8_t i = 0; i < MAX_TRANS_AXIS_NUM; ++i) {
594+ tdStr += std::to_string(blkSplitInfo_.blkAxesOutAOffset[i]) + " ";
595+ }
596+ tdStr += ",ub in axes:";
597+ for (int8_t i = 0; i < UB_MAX_DIM_NUM; ++i) {
598+ tdStr += std::to_string(ubSplitInfo_.inUbAxes[i]) + " ";
599+ }
600+ tdStr += ",ub out axes:";
601+ for (int8_t i = 0; i < UB_MAX_DIM_NUM; ++i) {
602+ tdStr += std::to_string(ubSplitInfo_.outUbAxes[i]) + " ";
603+ }
604+ tdStr += ",ub perm:";
605+ for (int8_t i = 0; i < UB_MAX_DIM_NUM; ++i) {
606+ tdStr += std::to_string(ubSplitInfo_.ubPerm[i]) + " ";
607+ }
608+ return tdStr;
609+}
610+ 
611+ge::graphStatus TransposeGatherTiling::DoTiling()
612+{
613+ CalcTensorSize();
614+ OP_CHECK_IF(
615+ CalcUbSplitInfo() != ge::GRAPH_SUCCESS,
616+ OP_LOGD(context_->GetNodeName(), "Stop to run gather tiling, mte size is too small!"), return ge::GRAPH_FAILED);
617+ OP_CHECK_IF(
618+ CalcBlockSplitInfo() != ge::GRAPH_SUCCESS,
619+ OP_LOGD(context_->GetNodeName(), "Stop to run gather tiling, block count is too small!"),
620+ return ge::GRAPH_FAILED);
621+ WriteTilingData();
622+ OP_LOGI(context_->GetNodeName(), "The tiling data is: %s", PrintTilingData().c_str());
623+ return SetTilingKeyAndCore();
624+}
625+ 
626+} // namespace TransWithGather
627+} // namespace optiling
Rconversion/transpose/examples/test_aclnn_transpose.cpprandom/drop_out_v3/examples/test_aclnn_drop_out_v3.cpp+39-30
Rrandom/drop_out_v3/op_host/op_api/aclnn_dropout_v3.cpprandom/drop_out_v3/op_api/aclnn_dropout_v3.cpp+8-8
Rrandom/drop_out_v3/op_host/op_api/aclnn_dropout_v3.hrandom/drop_out_v3/op_api/aclnn_dropout_v3.h+8-8
Rrandom/drop_out_v3/op_host/op_api/dropout_v3.cpprandom/drop_out_v3/op_api/dropout_v3.cpp+8-8
Rrandom/drop_out_v3/op_host/op_api/dropout_v3.hrandom/drop_out_v3/op_api/dropout_v3.h+8-8
Rconversion/transpose/op_kernel/.gitkeeprandom/drop_out_v3/op_graph/fusion_pass/.gitkeep+0-0
Rrandom/drop_out_v3/tests/ut/op_host/op_api/test_aclnn_drop_out_v3.cpprandom/drop_out_v3/tests/ut/op_api/test_aclnn_drop_out_v3.cpp+9-9