已合并
A5 support transpose drop_out_v3 #539
TangPC创建于 2025年12月27日
A5 support transpose drop_out_v3 #539
已合并
从已删除 :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/common | 177 | ${OPS_MATH_DIR}/common/inc/common |
| 177 | ) | 178 | ) |
| 178 | 179 | ||
| @@ -16,8 +16,8 @@ | |||
| 16 | 16 | ||
| 17 | 17 | ||
| 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 | ||
| 22 | namespace ops { | 22 | namespace 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, INCLUDING | 6 | +# 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 | # Transpose | 1 | # 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 | # aclnnChannelShuffle | 1 | # 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、BFLOAT16。 | 33 | + - <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、BFLOAT16。 | 39 | + - <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 | # aclnnPermute | 1 | # 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、BFLOAT16。 | 33 | + - <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、BFLOAT16。 | 40 | + - <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 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + do { \ | ||
| 18 | + if (!(cond)) { \ | ||
| 19 | + return_expr; \ | ||
| 20 | + } \ | ||
| 21 | + } while (0) | ||
| 22 | + | ||
| 23 | + | ||
| 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 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + do { \ | ||
| 18 | + if (!(cond)) { \ | ||
| 19 | + return_expr; \ | ||
| 20 | + } \ | ||
| 21 | + } while (0) | ||
| 22 | + | ||
| 23 | + | ||
| 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.cpp→conversion/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 of | 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"). | 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 | ||
| 12 | 12 | ||
Rconversion/transpose/op_host/op_api/aclnn_channel_shuffle.h→conversion/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 of | 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"). | 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 | ||
| 12 | 12 | ||
Rconversion/transpose/op_host/op_api/aclnn_permute.cpp→conversion/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 of | 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"). | 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 | ||
| 12 | 12 | ||
Rconversion/transpose/op_host/op_api/aclnn_permute.h→conversion/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 of | 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"). | 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 | ||
| 12 | 12 | ||
| @@ -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 of | 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"). | 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 | ||
| 12 | 12 | ||
| @@ -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 of | 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"). | 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.h | 12 | * \file transpose_proto.h |
| 12 | * \brief | 13 | * \brief |
| @@ -16,8 +17,7 @@ | |||
| 16 | 17 | ||
| 17 | 18 | ||
| 18 | 19 | ||
| 19 | -namespace ge | 20 | +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 | */ |
| 41 | REG_OP(Transpose) | 41 | REG_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 ge | 53 | } // 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 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,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 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +namespace optiling { | ||
| 26 | + | ||
| 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 | + | ||
| @@ -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 | + | ||
| 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.cpp→random/drop_out_v3/examples/test_aclnn_drop_out_v3.cpp+39-30
Rrandom/drop_out_v3/op_host/op_api/aclnn_dropout_v3.cpp→random/drop_out_v3/op_api/aclnn_dropout_v3.cpp+8-8
Rrandom/drop_out_v3/op_host/op_api/aclnn_dropout_v3.h→random/drop_out_v3/op_api/aclnn_dropout_v3.h+8-8
Rrandom/drop_out_v3/tests/ut/op_host/op_api/test_aclnn_drop_out_v3.cpp→random/drop_out_v3/tests/ut/op_api/test_aclnn_drop_out_v3.cpp+9-9


代码结构与可维护性: 第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 问题代码:修改建议:
此评论由代码审查工具自动生成