已合并
下一代math支持tanh_grad #589
Sun创建于 2025年12月30日
下一代math支持tanh_grad #589
已合并
共 47 个文件变更+4937-393
| @@ -1557,12 +1557,12 @@ | |||
| 1557 | <tr> | 1557 | <tr> |
| 1558 | <td>math</td> | 1558 | <td>math</td> |
| 1559 | <td><a href="../../math/tanh_grad">tanh_grad</a></td> | 1559 | <td><a href="../../math/tanh_grad">tanh_grad</a></td> |
| 1560 | - <td>×</td> | 1560 | + <td>√</td> |
| 1561 | - <td>×</td> | 1561 | + <td>√</td> |
| 1562 | - <td>×</td> | 1562 | + <td>√</td> |
| 1563 | - <td>×</td> | 1563 | + <td>√</td> |
| 1564 | <td>AI Core</td> | 1564 | <td>AI Core</td> |
| 1565 | - <td>该算子暂无Ascend C代码实现,欢迎开发者补充贡献,贡献方式参考<a href="../../CONTRIBUTING.md">贡献指南</a>。</td> | 1565 | + <td>Tanh的反向计算。</td> |
| 1566 | </tr> | 1566 | </tr> |
| 1567 | <tr> | 1567 | <tr> |
| 1568 | <td>math</td> | 1568 | <td>math</td> |
| @@ -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 "ascend910_95") |
| 14 | - list(REMOVE_ITEM CURRENT_DIRS tests) | 13 | +# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译 |
| 15 | -endif() | 14 | +set(SUPPORT_TILING_DIR "arch35") |
| 16 | -foreach(SUB_DIR ${CURRENT_DIRS}) | 15 | +add_all_modules_sources(OPTYPE tanh_grad 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,73 @@ | |||
| 1 | # TanhGrad | 1 | # TanhGrad |
| 2 | 2 | ||
| 3 | -本目录仅包含TanhGrad算子对应的aclnn接口;如您想要贡献该算子的AscendC实现,请参考[贡献流程](../../CONTRIBUTING.md)。 | 3 | +## 产品支持情况 |
| 4 | + | ||
| 5 | +| 产品 | 是否支持 | | ||
| 6 | +| ---- | :----:| | ||
| 7 | +|Ascend 950PR/Ascend 950DT|√| | ||
| 8 | +|Atlas A3 训练系列产品/Atlas A3 推理系列产品|√| | ||
| 9 | +|Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件|√| | ||
| 10 | + | ||
| 11 | +## 功能说明 | ||
| 12 | + | ||
| 13 | +- 算子功能:Tanh的反向实现。 | ||
| 14 | + | ||
| 15 | +- 计算公式: | ||
| 16 | + | ||
| 17 | +$$ | ||
| 18 | +d = tanh(x)= (\frac{e^{x} - {e^{-x}}}{e^{x} + {e^{-x}}}) \tag{1} | ||
| 19 | +$$ | ||
| 20 | +$$ | ||
| 21 | +dy = 1 -tanh(x)^2 \tag{2} | ||
| 22 | +$$ | ||
| 23 | + | ||
| 24 | +## 参数说明 | ||
| 25 | + | ||
| 26 | +<table style="undefined;table-layout: fixed; width: 980px"><colgroup> | ||
| 27 | + <col style="width: 100px"> | ||
| 28 | + <col style="width: 150px"> | ||
| 29 | + <col style="width: 280px"> | ||
| 30 | + <col style="width: 330px"> | ||
| 31 | + <col style="width: 120px"> | ||
| 32 | + </colgroup> | ||
| 33 | + <thead> | ||
| 34 | + <tr> | ||
| 35 | + <th>参数名</th> | ||
| 36 | + <th>输入/输出/属性</th> | ||
| 37 | + <th>描述</th> | ||
| 38 | + <th>数据类型</th> | ||
| 39 | + <th>数据格式</th> | ||
| 40 | + </tr></thead> | ||
| 41 | + <tbody> | ||
| 42 | + <tr> | ||
| 43 | + <td>y</td> | ||
| 44 | + <td>输入</td> | ||
| 45 | + <td>正向的输出。</td> | ||
| 46 | + <td>FLOAT16、FLOAT、BFLOAT16</td> | ||
| 47 | + <td>ND</td> | ||
| 48 | + </tr> | ||
| 49 | + <tr> | ||
| 50 | + <td>dy</td> | ||
| 51 | + <td>输入</td> | ||
| 52 | + <td>反向上一个算子的梯度。</td> | ||
| 53 | + <td>FLOAT16、FLOAT、BFLOAT16</td> | ||
| 54 | + <td>ND</td> | ||
| 55 | + </tr> | ||
| 56 | + <tr> | ||
| 57 | + <td>z</td> | ||
| 58 | + <td>输出</td> | ||
| 59 | + <td>反向的输出。</td> | ||
| 60 | + <td>FLOAT16、FLOAT、BFLOAT16</td> | ||
| 61 | + <td>ND</td> | ||
| 62 | + </tr> | ||
| 63 | + </tbody></table> | ||
| 64 | + | ||
| 65 | +## 约束说明 | ||
| 66 | + | ||
| 67 | +无 | ||
| 68 | + | ||
| 69 | +## 调用说明 | ||
| 70 | + | ||
| 71 | +| 调用方式 | 调用样例 | 说明 | | ||
| 72 | +|--------------|------------------------------------------------------------------------|--------------------------------------------------------------| | ||
| 73 | +| aclnn调用 | [test_aclnn_tanh_backward](./examples/test_aclnn_tanh_grad.cpp) | 通过[aclnnTanhBackward](./docs/aclnnTanhBackward.md)接口方式调用tanh_grad算子。 | | ||
| @@ -3,6 +3,7 @@ | |||
| 3 | ## 产品支持情况 | 3 | ## 产品支持情况 |
| 4 | | 产品 | 是否支持 | | 4 | | 产品 | 是否支持 | |
| 5 | | :----------------------------------------------------------- | :------: | | 5 | | :----------------------------------------------------------- | :------: | |
| 6 | +|Ascend 950PR/Ascend 950DT|√| | ||
| 6 | | <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ | | 7 | | <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ | |
| 7 | | <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term> | √ | | 8 | | <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term> | √ | |
| 8 | 9 | ||
| @@ -0,0 +1,154 @@ | |||
| 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 shape_size = 1; | ||
| 31 | + for (auto i : shape) { | ||
| 32 | + shape_size *= i; | ||
| 33 | + } | ||
| 34 | + return shape_size; | ||
| 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 | + | ||
| 59 | + // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上 | ||
| 60 | + ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); | ||
| 61 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret); | ||
| 62 | + | ||
| 63 | + // 计算连续tensor的strides | ||
| 64 | + std::vector<int64_t> strides(shape.size(), 1); | ||
| 65 | + for (int64_t i = shape.size() - 2; i >= 0; i--) { | ||
| 66 | + strides[i] = shape[i + 1] * strides[i + 1]; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + // 调用aclCreateTensor接口创建aclTensor | ||
| 70 | + *tensor = aclCreateTensor( | ||
| 71 | + shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), | ||
| 72 | + *deviceAddr); | ||
| 73 | + return 0; | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | +int main() | ||
| 77 | +{ | ||
| 78 | + // 1. (固定写法)device/stream初始化, 参考acl API手册 | ||
| 79 | + // 根据自己的实际device填写deviceId | ||
| 80 | + int32_t deviceId = 0; | ||
| 81 | + aclrtStream stream; | ||
| 82 | + auto ret = Init(deviceId, &stream); | ||
| 83 | + // check根据自己的需要处理 | ||
| 84 | + CHECK_RET(ret == 0, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); | ||
| 85 | + // 2. 构造输入与输出,需要根据API的接口自定义构造 | ||
| 86 | + std::vector<int64_t> gradOutputShape = {4, 2}; | ||
| 87 | + std::vector<int64_t> outputShape = {4, 2}; | ||
| 88 | + std::vector<int64_t> gradInputShape = {4, 2}; | ||
| 89 | + void* gradOutputDeviceAddr = nullptr; | ||
| 90 | + void* outputDeviceAddr = nullptr; | ||
| 91 | + void* gradInputDeviceAddr = nullptr; | ||
| 92 | + aclTensor* gradOutput = nullptr; | ||
| 93 | + aclTensor* output = nullptr; | ||
| 94 | + aclTensor* gradInput = nullptr; | ||
| 95 | + std::vector<float> gradOutputHostData = {0, 1, 2, 3, 4, 5, 6, 7.0}; | ||
| 96 | + std::vector<float> outputHostData = {1, 1, 1, 2, 2, 2, 3, 3.0}; | ||
| 97 | + std::vector<float> gradInputHostData = {0, 0, 0, 0, 0, 0, 0, 0.0}; | ||
| 98 | + // 创建gradOutput aclTensor | ||
| 99 | + ret = CreateAclTensor( | ||
| 100 | + gradOutputHostData, gradOutputShape, &gradOutputDeviceAddr, aclDataType::ACL_FLOAT, &gradOutput); | ||
| 101 | + CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 102 | + // 创建output aclTensor | ||
| 103 | + ret = CreateAclTensor(outputHostData, outputShape, &outputDeviceAddr, aclDataType::ACL_FLOAT, &output); | ||
| 104 | + CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 105 | + // 创建gradInput aclTensor | ||
| 106 | + ret = CreateAclTensor(gradInputHostData, gradInputShape, &gradInputDeviceAddr, aclDataType::ACL_FLOAT, &gradInput); | ||
| 107 | + CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 108 | + | ||
| 109 | + // 3. 调用CANN算子库API,需要修改为具体的API | ||
| 110 | + uint64_t workspaceSize = 0; | ||
| 111 | + aclOpExecutor* executor; | ||
| 112 | + // 调用aclnnTanhBackward第一段接口 | ||
| 113 | + ret = aclnnTanhBackwardGetWorkspaceSize(gradOutput, output, gradInput, &workspaceSize, &executor); | ||
| 114 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnTanhBackwardGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); | ||
| 115 | + // 根据第一段接口计算出的workspaceSize申请device内存 | ||
| 116 | + void* workspaceAddr = nullptr; | ||
| 117 | + if (workspaceSize > 0) { | ||
| 118 | + ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| 119 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret;); | ||
| 120 | + } | ||
| 121 | + // 调用aclnnTanhBackward第二段接口 | ||
| 122 | + ret = aclnnTanhBackward(workspaceAddr, workspaceSize, executor, stream); | ||
| 123 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnTanhBackward failed. ERROR: %d\n", ret); return ret); | ||
| 124 | + // 4. (固定写法)同步等待任务执行结束 | ||
| 125 | + ret = aclrtSynchronizeStream(stream); | ||
| 126 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); | ||
| 127 | + // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 | ||
| 128 | + auto size = GetShapeSize(gradInputShape); | ||
| 129 | + std::vector<float> resultData(size, 0); | ||
| 130 | + ret = aclrtMemcpy( | ||
| 131 | + resultData.data(), resultData.size() * sizeof(resultData[0]), gradInputDeviceAddr, size * sizeof(float), | ||
| 132 | + ACL_MEMCPY_DEVICE_TO_HOST); | ||
| 133 | + CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret); | ||
| 134 | + for (int64_t i = 0; i < size; i++) { | ||
| 135 | + LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]); | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改 | ||
| 139 | + aclDestroyTensor(gradOutput); | ||
| 140 | + aclDestroyTensor(output); | ||
| 141 | + aclDestroyTensor(gradInput); | ||
| 142 | + | ||
| 143 | + // 7. 释放device资源,需要根据具体API的接口定义修改 | ||
| 144 | + aclrtFree(gradOutputDeviceAddr); | ||
| 145 | + aclrtFree(outputDeviceAddr); | ||
| 146 | + aclrtFree(gradInputDeviceAddr); | ||
| 147 | + if (workspaceSize > 0) { | ||
| 148 | + aclrtFree(workspaceAddr); | ||
| 149 | + } | ||
| 150 | + aclrtDestroyStream(stream); | ||
| 151 | + aclrtResetDevice(deviceId); | ||
| 152 | + aclFinalize(); | ||
| 153 | + return 0; | ||
| 154 | +} | ||
Rmath/tanh_grad/op_host/op_api/aclnn_tanh_backward.cpp→math/tanh_grad/op_api/aclnn_tanh_backward.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 | ||
Rmath/tanh_grad/op_host/op_api/aclnn_tanh_backward.h→math/tanh_grad/op_api/aclnn_tanh_backward.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,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 | * \file tanh_grad_proto.h | 12 | * \file tanh_grad_proto.h |
| @@ -47,4 +47,3 @@ REG_OP(TanhGrad) | |||
| 47 | } // namespace ge | 47 | } // namespace ge |
| 48 | 48 | ||
| 49 | 49 | ||
| 50 | - | ||
Dmath/tanh_grad/op_host/CMakeLists.txt+0-12
| @@ -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(OPTYPE tanh_grad ACLNNTYPE aclnn_exclude) | ||
| @@ -0,0 +1,338 @@ | |||
| 1 | +{ | ||
| 2 | + "op_type": "TanhGrad", | ||
| 3 | + "op_list": [ | ||
| 4 | + { | ||
| 5 | + "bin_filename": "TanhGrad_FP16_FP16", | ||
| 6 | + "inputs": [ | ||
| 7 | + { | ||
| 8 | + "name": "y", | ||
| 9 | + "index": 0, | ||
| 10 | + "dtype": "float16", | ||
| 11 | + "format": "ND", | ||
| 12 | + "paramType": "required", | ||
| 13 | + "shape": [ | ||
| 14 | + -2 | ||
| 15 | + ] | ||
| 16 | + }, | ||
| 17 | + { | ||
| 18 | + "name": "dy", | ||
| 19 | + "index": 1, | ||
| 20 | + "dtype": "float16", | ||
| 21 | + "format": "ND", | ||
| 22 | + "paramType": "required", | ||
| 23 | + "shape": [ | ||
| 24 | + -2 | ||
| 25 | + ] | ||
| 26 | + } | ||
| 27 | + ], | ||
| 28 | + "outputs": [ | ||
| 29 | + { | ||
| 30 | + "name": "z", | ||
| 31 | + "index": 0, | ||
| 32 | + "dtype": "float16", | ||
| 33 | + "format": "ND", | ||
| 34 | + "paramType": "required", | ||
| 35 | + "shape": [ | ||
| 36 | + -2 | ||
| 37 | + ] | ||
| 38 | + } | ||
| 39 | + ] | ||
| 40 | + }, | ||
| 41 | + { | ||
| 42 | + "bin_filename": "TanhGrad_FP32_FP32", | ||
| 43 | + "inputs": [ | ||
| 44 | + { | ||
| 45 | + "name": "y", | ||
| 46 | + "index": 0, | ||
| 47 | + "dtype": "float32", | ||
| 48 | + "format": "ND", | ||
| 49 | + "paramType": "required", | ||
| 50 | + "shape": [ | ||
| 51 | + -2 | ||
| 52 | + ] | ||
| 53 | + }, | ||
| 54 | + { | ||
| 55 | + "name": "dy", | ||
| 56 | + "index": 1, | ||
| 57 | + "dtype": "float32", | ||
| 58 | + "format": "ND", | ||
| 59 | + "paramType": "required", | ||
| 60 | + "shape": [ | ||
| 61 | + -2 | ||
| 62 | + ] | ||
| 63 | + } | ||
| 64 | + ], | ||
| 65 | + "outputs": [ | ||
| 66 | + { | ||
| 67 | + "name": "z", | ||
| 68 | + "index": 0, | ||
| 69 | + "dtype": "float32", | ||
| 70 | + "format": "ND", | ||
| 71 | + "paramType": "required", | ||
| 72 | + "shape": [ | ||
| 73 | + -2 | ||
| 74 | + ] | ||
| 75 | + } | ||
| 76 | + ] | ||
| 77 | + }, | ||
| 78 | + { | ||
| 79 | + "bin_filename": "TanhGrad_BF16_BF16", | ||
| 80 | + "inputs": [ | ||
| 81 | + { | ||
| 82 | + "name": "y", | ||
| 83 | + "index": 0, | ||
| 84 | + "dtype": "bfloat16", | ||
| 85 | + "format": "ND", | ||
| 86 | + "paramType": "required", | ||
| 87 | + "shape": [ | ||
| 88 | + -2 | ||
| 89 | + ] | ||
| 90 | + }, | ||
| 91 | + { | ||
| 92 | + "name": "dy", | ||
| 93 | + "index": 1, | ||
| 94 | + "dtype": "bfloat16", | ||
| 95 | + "format": "ND", | ||
| 96 | + "paramType": "required", | ||
| 97 | + "shape": [ | ||
| 98 | + -2 | ||
| 99 | + ] | ||
| 100 | + } | ||
| 101 | + ], | ||
| 102 | + "outputs": [ | ||
| 103 | + { | ||
| 104 | + "name": "z", | ||
| 105 | + "index": 0, | ||
| 106 | + "dtype": "bfloat16", | ||
| 107 | + "format": "ND", | ||
| 108 | + "paramType": "required", | ||
| 109 | + "shape": [ | ||
| 110 | + -2 | ||
| 111 | + ] | ||
| 112 | + } | ||
| 113 | + ] | ||
| 114 | + }, | ||
| 115 | + { | ||
| 116 | + "bin_filename": "TanhGrad_FP16_FP32", | ||
| 117 | + "inputs": [ | ||
| 118 | + { | ||
| 119 | + "name": "y", | ||
| 120 | + "index": 0, | ||
| 121 | + "dtype": "float16", | ||
| 122 | + "format": "ND", | ||
| 123 | + "paramType": "required", | ||
| 124 | + "shape": [ | ||
| 125 | + -2 | ||
| 126 | + ] | ||
| 127 | + }, | ||
| 128 | + { | ||
| 129 | + "name": "dy", | ||
| 130 | + "index": 1, | ||
| 131 | + "dtype": "float32", | ||
| 132 | + "format": "ND", | ||
| 133 | + "paramType": "required", | ||
| 134 | + "shape": [ | ||
| 135 | + -2 | ||
| 136 | + ] | ||
| 137 | + } | ||
| 138 | + ], | ||
| 139 | + "outputs": [ | ||
| 140 | + { | ||
| 141 | + "name": "z", | ||
| 142 | + "index": 0, | ||
| 143 | + "dtype": "float32", | ||
| 144 | + "format": "ND", | ||
| 145 | + "paramType": "required", | ||
| 146 | + "shape": [ | ||
| 147 | + -2 | ||
| 148 | + ] | ||
| 149 | + } | ||
| 150 | + ] | ||
| 151 | + }, | ||
| 152 | + { | ||
| 153 | + "bin_filename": "TanhGrad_FP16_BF16", | ||
| 154 | + "inputs": [ | ||
| 155 | + { | ||
| 156 | + "name": "y", | ||
| 157 | + "index": 0, | ||
| 158 | + "dtype": "float16", | ||
| 159 | + "format": "ND", | ||
| 160 | + "paramType": "required", | ||
| 161 | + "shape": [ | ||
| 162 | + -2 | ||
| 163 | + ] | ||
| 164 | + }, | ||
| 165 | + { | ||
| 166 | + "name": "dy", | ||
| 167 | + "index": 1, | ||
| 168 | + "dtype": "bfloat16", | ||
| 169 | + "format": "ND", | ||
| 170 | + "paramType": "required", | ||
| 171 | + "shape": [ | ||
| 172 | + -2 | ||
| 173 | + ] | ||
| 174 | + } | ||
| 175 | + ], | ||
| 176 | + "outputs": [ | ||
| 177 | + { | ||
| 178 | + "name": "z", | ||
| 179 | + "index": 0, | ||
| 180 | + "dtype": "float32", | ||
| 181 | + "format": "ND", | ||
| 182 | + "paramType": "required", | ||
| 183 | + "shape": [ | ||
| 184 | + -2 | ||
| 185 | + ] | ||
| 186 | + } | ||
| 187 | + ] | ||
| 188 | + }, | ||
| 189 | + { | ||
| 190 | + "bin_filename": "TanhGrad_FP32_FP16", | ||
| 191 | + "inputs": [ | ||
| 192 | + { | ||
| 193 | + "name": "y", | ||
| 194 | + "index": 0, | ||
| 195 | + "dtype": "float32", | ||
| 196 | + "format": "ND", | ||
| 197 | + "paramType": "required", | ||
| 198 | + "shape": [ | ||
| 199 | + -2 | ||
| 200 | + ] | ||
| 201 | + }, | ||
| 202 | + { | ||
| 203 | + "name": "dy", | ||
| 204 | + "index": 1, | ||
| 205 | + "dtype": "float16", | ||
| 206 | + "format": "ND", | ||
| 207 | + "paramType": "required", | ||
| 208 | + "shape": [ | ||
| 209 | + -2 | ||
| 210 | + ] | ||
| 211 | + } | ||
| 212 | + ], | ||
| 213 | + "outputs": [ | ||
| 214 | + { | ||
| 215 | + "name": "z", | ||
| 216 | + "index": 0, | ||
| 217 | + "dtype": "float32", | ||
| 218 | + "format": "ND", | ||
| 219 | + "paramType": "required", | ||
| 220 | + "shape": [ | ||
| 221 | + -2 | ||
| 222 | + ] | ||
| 223 | + } | ||
| 224 | + ] | ||
| 225 | + }, | ||
| 226 | + { | ||
| 227 | + "bin_filename": "TanhGrad_FP32_BF16", | ||
| 228 | + "inputs": [ | ||
| 229 | + { | ||
| 230 | + "name": "y", | ||
| 231 | + "index": 0, | ||
| 232 | + "dtype": "float32", | ||
| 233 | + "format": "ND", | ||
| 234 | + "paramType": "required", | ||
| 235 | + "shape": [ | ||
| 236 | + -2 | ||
| 237 | + ] | ||
| 238 | + }, | ||
| 239 | + { | ||
| 240 | + "name": "dy", | ||
| 241 | + "index": 1, | ||
| 242 | + "dtype": "bfloat16", | ||
| 243 | + "format": "ND", | ||
| 244 | + "paramType": "required", | ||
| 245 | + "shape": [ | ||
| 246 | + -2 | ||
| 247 | + ] | ||
| 248 | + } | ||
| 249 | + ], | ||
| 250 | + "outputs": [ | ||
| 251 | + { | ||
| 252 | + "name": "z", | ||
| 253 | + "index": 0, | ||
| 254 | + "dtype": "float32", | ||
| 255 | + "format": "ND", | ||
| 256 | + "paramType": "required", | ||
| 257 | + "shape": [ | ||
| 258 | + -2 | ||
| 259 | + ] | ||
| 260 | + } | ||
| 261 | + ] | ||
| 262 | + }, | ||
| 263 | + { | ||
| 264 | + "bin_filename": "TanhGrad_BF16_FP32", | ||
| 265 | + "inputs": [ | ||
| 266 | + { | ||
| 267 | + "name": "y", | ||
| 268 | + "index": 0, | ||
| 269 | + "dtype": "bfloat16", | ||
| 270 | + "format": "ND", | ||
| 271 | + "paramType": "required", | ||
| 272 | + "shape": [ | ||
| 273 | + -2 | ||
| 274 | + ] | ||
| 275 | + }, | ||
| 276 | + { | ||
| 277 | + "name": "dy", | ||
| 278 | + "index": 1, | ||
| 279 | + "dtype": "float32", | ||
| 280 | + "format": "ND", | ||
| 281 | + "paramType": "required", | ||
| 282 | + "shape": [ | ||
| 283 | + -2 | ||
| 284 | + ] | ||
| 285 | + } | ||
| 286 | + ], | ||
| 287 | + "outputs": [ | ||
| 288 | + { | ||
| 289 | + "name": "z", | ||
| 290 | + "index": 0, | ||
| 291 | + "dtype": "float32", | ||
| 292 | + "format": "ND", | ||
| 293 | + "paramType": "required", | ||
| 294 | + "shape": [ | ||
| 295 | + -2 | ||
| 296 | + ] | ||
| 297 | + } | ||
| 298 | + ] | ||
| 299 | + }, | ||
| 300 | + { | ||
| 301 | + "bin_filename": "TanhGrad_BF16_FP16", | ||
| 302 | + "inputs": [ | ||
| 303 | + { | ||
| 304 | + "name": "y", | ||
| 305 | + "index": 0, | ||
| 306 | + "dtype": "bfloat16", | ||
| 307 | + "format": "ND", | ||
| 308 | + "paramType": "required", | ||
| 309 | + "shape": [ | ||
| 310 | + -2 | ||
| 311 | + ] | ||
| 312 | + }, | ||
| 313 | + { | ||
| 314 | + "name": "dy", | ||
| 315 | + "index": 1, | ||
| 316 | + "dtype": "float16", | ||
| 317 | + "format": "ND", | ||
| 318 | + "paramType": "required", | ||
| 319 | + "shape": [ | ||
| 320 | + -2 | ||
| 321 | + ] | ||
| 322 | + } | ||
| 323 | + ], | ||
| 324 | + "outputs": [ | ||
| 325 | + { | ||
| 326 | + "name": "z", | ||
| 327 | + "index": 0, | ||
| 328 | + "dtype": "float32", | ||
| 329 | + "format": "ND", | ||
| 330 | + "paramType": "required", | ||
| 331 | + "shape": [ | ||
| 332 | + -2 | ||
| 333 | + ] | ||
| 334 | + } | ||
| 335 | + ] | ||
| 336 | + } | ||
| 337 | + ] | ||
| 338 | + } | ||
| @@ -0,0 +1,13 @@ | |||
| 1 | +; 该文件主要影响 opc 工具 编译二进制kernel时, --simplified_key_mode 选项中填写的值,格式如下所示: | ||
| 2 | +; [某算子] | ||
| 3 | +; default=xx | ||
| 4 | +; ascendxx=xx | ||
| 5 | +; 其中,default为默认mode,ascnedxx为可选mode,如果不同芯片有差异化要求时,需要配置; | ||
| 6 | +; 1)如果没有配置:非ascendC算子继续按空处理,即opc编译命令中不添加 --simplified_key_mode 选项,AscendC算子按照 simplified_key_mode=0 处理 | ||
| 7 | +; 2)如果仅有default配置:各个版本按default配置 | ||
| 8 | +; 3)如果仅有某些平台的配置,没有default配置:对应平台的按照配置的值传递,非对应平台的:非AscendC算子继续按空处理,AscendC算子按照 simplified_key_mode=0 处理 | ||
| 9 | +; 4)如果default配置和平台配置都有:对应平台的使用平台的配置,非对应的平台的以default值配置。 | ||
| 10 | +; 5)对于自定义simplified key的情况,需要在binary_simplified_key_mode.ini 文件中显式配置为None,不传入 --simplified_key_mode 选项,由opc工具和FE框架自行判断使用何种模式 | ||
| 11 | +; 6)是否是AscendC算子,由 ops/build-in/tbe/op_info_cfg/parser/ascendc_config.json 中配置的算子名字和对于的平台决定 | ||
| 12 | +[TanhGrad] | ||
| 13 | +default=0 | ||
| @@ -0,0 +1,24 @@ | |||
| 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 | +using namespace ge; | ||
| 16 | +namespace ops { | ||
| 17 | + | ||
| 18 | +static ge::graphStatus InferShape4GreaterEqual(gert::InferShapeContext* context) | ||
| 19 | +{ | ||
| 20 | + OP_LOGI("Begin InferShape4GreaterEqual"); | ||
| 21 | + return Ops::Base::InferShape4Broadcast(context); | ||
| 22 | +} | ||
| 23 | +IMPL_OP_INFERSHAPE(TanhGrad).InferShape(InferShape4GreaterEqual); | ||
| 24 | +} // namespace ops | ||
| @@ -0,0 +1,187 @@ | |||
| 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 tanh_grad_bf16_nddma_with_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is bfloat16, dy is bfloat16, z is bfloat16, max dims in ub is 8 and nddma needs loops | ||
| 31 | +class TanhGradBf16NddmaWithLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradBf16NddmaWithLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ bfloat16_t*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ bfloat16_t*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ bfloat16_t*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(bfloat16_t); | ||
| 44 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 45 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 46 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + __aicore__ inline void Process() | ||
| 50 | + { | ||
| 51 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 52 | + tilingDataPtr_->blockFormer; | ||
| 53 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 54 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 55 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 56 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 57 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 58 | + if (ubLoopIdx != 0) { | ||
| 59 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 60 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 61 | + } | ||
| 62 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 63 | + tilingDataPtr_->ubTail : | ||
| 64 | + tilingDataPtr_->ubFormer; | ||
| 65 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 66 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 67 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | +private: | ||
| 73 | + __aicore__ inline void CopyIn0( | ||
| 74 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 75 | + { | ||
| 76 | + bufferIn0_ = queIn0_.AllocTensor<bfloat16_t>(); | ||
| 77 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 78 | + (ubLoopIdx <= 1 || | ||
| 79 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 80 | + Ops::Base::BroadcastNddmaWithLoop( | ||
| 81 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 82 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 83 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 84 | + } | ||
| 85 | + queIn0_.EnQue<bfloat16_t>(bufferIn0_); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + __aicore__ inline void CopyIn1( | ||
| 89 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 90 | + { | ||
| 91 | + bufferIn1_ = queIn1_.AllocTensor<bfloat16_t>(); | ||
| 92 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 93 | + (ubLoopIdx <= 1 || | ||
| 94 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 95 | + Ops::Base::BroadcastNddmaWithLoop( | ||
| 96 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 97 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 98 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 99 | + } | ||
| 100 | + queIn1_.EnQue<bfloat16_t>(bufferIn1_); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + __aicore__ inline void Compute2( | ||
| 104 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 105 | + { | ||
| 106 | + bufferIn0_ = queIn0_.DeQue<bfloat16_t>(); | ||
| 107 | + bufferIn1_ = queIn1_.DeQue<bfloat16_t>(); | ||
| 108 | + bufferOut0_ = queOut0_.AllocTensor<bfloat16_t>(); | ||
| 109 | + __VEC_SCOPE__ | ||
| 110 | + { | ||
| 111 | + RegTensor<bfloat16_t> vreg0; | ||
| 112 | + RegTensor<float> vreg1; | ||
| 113 | + RegTensor<float> vreg2; | ||
| 114 | + RegTensor<float> vreg3; | ||
| 115 | + RegTensor<float> vreg4; | ||
| 116 | + RegTensor<bfloat16_t> vreg5; | ||
| 117 | + RegTensor<float> vreg6; | ||
| 118 | + RegTensor<float> vreg7; | ||
| 119 | + RegTensor<bfloat16_t> vreg8; | ||
| 120 | + MaskReg preg0; | ||
| 121 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 122 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 123 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 124 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 125 | + __local_mem__ bfloat16_t* bufferIn0Addr = (__local_mem__ bfloat16_t*)bufferIn0_.GetPhyAddr(); | ||
| 126 | + __local_mem__ bfloat16_t* bufferIn1Addr = (__local_mem__ bfloat16_t*)bufferIn1_.GetPhyAddr(); | ||
| 127 | + __local_mem__ bfloat16_t* bufferOut0Addr = (__local_mem__ bfloat16_t*)bufferOut0_.GetPhyAddr(); | ||
| 128 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 129 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 130 | + AscendC::MicroAPI::DataCopy<bfloat16_t, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 131 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 132 | + AscendC::MicroAPI::Cast<float, bfloat16_t, castTrait0>(vreg1, vreg0, preg0); | ||
| 133 | + AscendC::MicroAPI::Duplicate<float, float>(vreg4, 1.0); | ||
| 134 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 135 | + vreg2, vreg1, static_cast<float>(-1), preg0); | ||
| 136 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 137 | + vreg4, vreg2, vreg1, preg0); | ||
| 138 | + AscendC::MicroAPI::DataCopy<bfloat16_t, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 139 | + vreg5, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 140 | + AscendC::MicroAPI::Cast<float, bfloat16_t, castTrait0>(vreg6, vreg5, preg0); | ||
| 141 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg7, vreg4, vreg6, preg0); | ||
| 142 | + AscendC::MicroAPI::Cast<bfloat16_t, float, castTrait1>(vreg8, vreg7, preg0); | ||
| 143 | + AscendC::MicroAPI::DataCopy<bfloat16_t, AscendC::MicroAPI::StoreDist::DIST_PACK_B32>( | ||
| 144 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg8, preg0); | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 148 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 149 | + queOut0_.EnQue<bfloat16_t>(bufferOut0_); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + __aicore__ inline void CopyOut3( | ||
| 153 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 154 | + { | ||
| 155 | + bufferOut0_ = queOut0_.DeQue<bfloat16_t>(); | ||
| 156 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 157 | + dataCopyExtParams.blockCount = 1; | ||
| 158 | + dataCopyExtParams.blockLen = | ||
| 159 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(bfloat16_t); | ||
| 160 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 161 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 162 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 163 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | +private: | ||
| 167 | + TPipe* pipePtr_; | ||
| 168 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 169 | + GlobalTensor<bfloat16_t> inputGmY_; | ||
| 170 | + GlobalTensor<bfloat16_t> inputGmDy_; | ||
| 171 | + GlobalTensor<bfloat16_t> outputGmZ_; | ||
| 172 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 173 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 174 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 175 | + LocalTensor<bfloat16_t> bufferIn0_; | ||
| 176 | + LocalTensor<bfloat16_t> bufferIn1_; | ||
| 177 | + LocalTensor<bfloat16_t> bufferOut0_; | ||
| 178 | + constexpr static AscendC::MicroAPI::CastTrait castTrait0 = { | ||
| 179 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::UNKNOWN, | ||
| 180 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::UNKNOWN}; | ||
| 181 | + constexpr static AscendC::MicroAPI::CastTrait castTrait1 = { | ||
| 182 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::NO_SAT, | ||
| 183 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::CAST_RINT}; | ||
| 184 | +}; | ||
| 185 | + | ||
| 186 | +} // namespace TanhGrad | ||
| 187 | + | ||
| @@ -0,0 +1,187 @@ | |||
| 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 tanh_grad_bf16_nddma_without_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is bfloat16, dy is bfloat16, z is bfloat16, max dims in ub is 5 and nddma does not need loops | ||
| 31 | +class TanhGradBf16NddmaWithoutLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradBf16NddmaWithoutLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ bfloat16_t*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ bfloat16_t*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ bfloat16_t*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(bfloat16_t); | ||
| 44 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 45 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 46 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + __aicore__ inline void Process() | ||
| 50 | + { | ||
| 51 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 52 | + tilingDataPtr_->blockFormer; | ||
| 53 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 54 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 55 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 56 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 57 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 58 | + if (ubLoopIdx != 0) { | ||
| 59 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 60 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 61 | + } | ||
| 62 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 63 | + tilingDataPtr_->ubTail : | ||
| 64 | + tilingDataPtr_->ubFormer; | ||
| 65 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 66 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 67 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | +private: | ||
| 73 | + __aicore__ inline void CopyIn0( | ||
| 74 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 75 | + { | ||
| 76 | + bufferIn0_ = queIn0_.AllocTensor<bfloat16_t>(); | ||
| 77 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 78 | + (ubLoopIdx <= 1 || | ||
| 79 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 80 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 81 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 82 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 83 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 84 | + } | ||
| 85 | + queIn0_.EnQue<bfloat16_t>(bufferIn0_); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + __aicore__ inline void CopyIn1( | ||
| 89 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 90 | + { | ||
| 91 | + bufferIn1_ = queIn1_.AllocTensor<bfloat16_t>(); | ||
| 92 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 93 | + (ubLoopIdx <= 1 || | ||
| 94 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 95 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 96 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 97 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 98 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 99 | + } | ||
| 100 | + queIn1_.EnQue<bfloat16_t>(bufferIn1_); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + __aicore__ inline void Compute2( | ||
| 104 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 105 | + { | ||
| 106 | + bufferIn0_ = queIn0_.DeQue<bfloat16_t>(); | ||
| 107 | + bufferIn1_ = queIn1_.DeQue<bfloat16_t>(); | ||
| 108 | + bufferOut0_ = queOut0_.AllocTensor<bfloat16_t>(); | ||
| 109 | + __VEC_SCOPE__ | ||
| 110 | + { | ||
| 111 | + RegTensor<bfloat16_t> vreg0; | ||
| 112 | + RegTensor<float> vreg1; | ||
| 113 | + RegTensor<float> vreg2; | ||
| 114 | + RegTensor<float> vreg3; | ||
| 115 | + RegTensor<float> vreg4; | ||
| 116 | + RegTensor<bfloat16_t> vreg5; | ||
| 117 | + RegTensor<float> vreg6; | ||
| 118 | + RegTensor<float> vreg7; | ||
| 119 | + RegTensor<bfloat16_t> vreg8; | ||
| 120 | + MaskReg preg0; | ||
| 121 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 122 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 123 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 124 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 125 | + __local_mem__ bfloat16_t* bufferIn0Addr = (__local_mem__ bfloat16_t*)bufferIn0_.GetPhyAddr(); | ||
| 126 | + __local_mem__ bfloat16_t* bufferIn1Addr = (__local_mem__ bfloat16_t*)bufferIn1_.GetPhyAddr(); | ||
| 127 | + __local_mem__ bfloat16_t* bufferOut0Addr = (__local_mem__ bfloat16_t*)bufferOut0_.GetPhyAddr(); | ||
| 128 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 129 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 130 | + AscendC::MicroAPI::DataCopy<bfloat16_t, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 131 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 132 | + AscendC::MicroAPI::Cast<float, bfloat16_t, castTrait0>(vreg1, vreg0, preg0); | ||
| 133 | + AscendC::MicroAPI::Duplicate<float, float>(vreg4, 1.0); | ||
| 134 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 135 | + vreg2, vreg1, static_cast<float>(-1), preg0); | ||
| 136 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 137 | + vreg4, vreg2, vreg1, preg0); | ||
| 138 | + AscendC::MicroAPI::DataCopy<bfloat16_t, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 139 | + vreg5, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 140 | + AscendC::MicroAPI::Cast<float, bfloat16_t, castTrait0>(vreg6, vreg5, preg0); | ||
| 141 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg7, vreg4, vreg6, preg0); | ||
| 142 | + AscendC::MicroAPI::Cast<bfloat16_t, float, castTrait1>(vreg8, vreg7, preg0); | ||
| 143 | + AscendC::MicroAPI::DataCopy<bfloat16_t, AscendC::MicroAPI::StoreDist::DIST_PACK_B32>( | ||
| 144 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg8, preg0); | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 148 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 149 | + queOut0_.EnQue<bfloat16_t>(bufferOut0_); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + __aicore__ inline void CopyOut3( | ||
| 153 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 154 | + { | ||
| 155 | + bufferOut0_ = queOut0_.DeQue<bfloat16_t>(); | ||
| 156 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 157 | + dataCopyExtParams.blockCount = 1; | ||
| 158 | + dataCopyExtParams.blockLen = | ||
| 159 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(bfloat16_t); | ||
| 160 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 161 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 162 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 163 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | +private: | ||
| 167 | + TPipe* pipePtr_; | ||
| 168 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 169 | + GlobalTensor<bfloat16_t> inputGmY_; | ||
| 170 | + GlobalTensor<bfloat16_t> inputGmDy_; | ||
| 171 | + GlobalTensor<bfloat16_t> outputGmZ_; | ||
| 172 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 173 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 174 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 175 | + LocalTensor<bfloat16_t> bufferIn0_; | ||
| 176 | + LocalTensor<bfloat16_t> bufferIn1_; | ||
| 177 | + LocalTensor<bfloat16_t> bufferOut0_; | ||
| 178 | + constexpr static AscendC::MicroAPI::CastTrait castTrait0 = { | ||
| 179 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::UNKNOWN, | ||
| 180 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::UNKNOWN}; | ||
| 181 | + constexpr static AscendC::MicroAPI::CastTrait castTrait1 = { | ||
| 182 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::NO_SAT, | ||
| 183 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::CAST_RINT}; | ||
| 184 | +}; | ||
| 185 | + | ||
| 186 | +} // namespace TanhGrad | ||
| 187 | + | ||
| @@ -0,0 +1,181 @@ | |||
| 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 tanh_grad_dtype_comb_0_nddma_with_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is float16, dy is float32, z is float32, max dims in ub is 8 and nddma needs loops | ||
| 31 | +class TanhGradDtypeComb0NddmaWithLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradDtypeComb0NddmaWithLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ half*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ float*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ float*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(half); | ||
| 44 | + int64_t BUFFER_SIZE_1 = tilingDataPtr_->elemNum * sizeof(float); | ||
| 45 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 46 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 47 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + __aicore__ inline void Process() | ||
| 51 | + { | ||
| 52 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 53 | + tilingDataPtr_->blockFormer; | ||
| 54 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 55 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 56 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 57 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 58 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 59 | + if (ubLoopIdx != 0) { | ||
| 60 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 61 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 62 | + } | ||
| 63 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 64 | + tilingDataPtr_->ubTail : | ||
| 65 | + tilingDataPtr_->ubFormer; | ||
| 66 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 67 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | +private: | ||
| 74 | + __aicore__ inline void CopyIn0( | ||
| 75 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 76 | + { | ||
| 77 | + bufferIn0_ = queIn0_.AllocTensor<half>(); | ||
| 78 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 79 | + (ubLoopIdx <= 1 || | ||
| 80 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 81 | + Ops::Base::BroadcastNddmaWithLoop( | ||
| 82 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 83 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 84 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 85 | + } | ||
| 86 | + queIn0_.EnQue<half>(bufferIn0_); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + __aicore__ inline void CopyIn1( | ||
| 90 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 91 | + { | ||
| 92 | + bufferIn1_ = queIn1_.AllocTensor<float>(); | ||
| 93 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 94 | + (ubLoopIdx <= 1 || | ||
| 95 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 96 | + Ops::Base::BroadcastNddmaWithLoop( | ||
| 97 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 98 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 99 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 100 | + } | ||
| 101 | + queIn1_.EnQue<float>(bufferIn1_); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + __aicore__ inline void Compute2( | ||
| 105 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 106 | + { | ||
| 107 | + bufferIn0_ = queIn0_.DeQue<half>(); | ||
| 108 | + bufferIn1_ = queIn1_.DeQue<float>(); | ||
| 109 | + bufferOut0_ = queOut0_.AllocTensor<float>(); | ||
| 110 | + __VEC_SCOPE__ | ||
| 111 | + { | ||
| 112 | + RegTensor<half> vreg0; | ||
| 113 | + RegTensor<float> vreg1; | ||
| 114 | + RegTensor<float> vreg2; | ||
| 115 | + RegTensor<float> vreg3; | ||
| 116 | + RegTensor<float> vreg4; | ||
| 117 | + RegTensor<float> vreg5; | ||
| 118 | + RegTensor<float> vreg6; | ||
| 119 | + MaskReg preg0; | ||
| 120 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 121 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 122 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 123 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 124 | + __local_mem__ float* bufferIn1Addr = (__local_mem__ float*)bufferIn1_.GetPhyAddr(); | ||
| 125 | + __local_mem__ float* bufferOut0Addr = (__local_mem__ float*)bufferOut0_.GetPhyAddr(); | ||
| 126 | + __local_mem__ half* bufferIn0Addr = (__local_mem__ half*)bufferIn0_.GetPhyAddr(); | ||
| 127 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 128 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 129 | + AscendC::MicroAPI::DataCopy<half, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 130 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 131 | + AscendC::MicroAPI::Cast<float, half, castTrait0>(vreg1, vreg0, preg0); | ||
| 132 | + AscendC::MicroAPI::Duplicate<float, float>(vreg4, 1.0); | ||
| 133 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 134 | + vreg2, vreg1, static_cast<float>(-1), preg0); | ||
| 135 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 136 | + vreg4, vreg2, vreg1, preg0); | ||
| 137 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::LoadDist::DIST_NORM>( | ||
| 138 | + vreg5, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 139 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg6, vreg4, vreg5, preg0); | ||
| 140 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::StoreDist::DIST_NORM_B32>( | ||
| 141 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg6, preg0); | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 145 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 146 | + queOut0_.EnQue<float>(bufferOut0_); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + __aicore__ inline void CopyOut3( | ||
| 150 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 151 | + { | ||
| 152 | + bufferOut0_ = queOut0_.DeQue<float>(); | ||
| 153 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 154 | + dataCopyExtParams.blockCount = 1; | ||
| 155 | + dataCopyExtParams.blockLen = | ||
| 156 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(float); | ||
| 157 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 158 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 159 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 160 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | +private: | ||
| 164 | + TPipe* pipePtr_; | ||
| 165 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 166 | + GlobalTensor<half> inputGmY_; | ||
| 167 | + GlobalTensor<float> inputGmDy_; | ||
| 168 | + GlobalTensor<float> outputGmZ_; | ||
| 169 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 170 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 171 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 172 | + LocalTensor<half> bufferIn0_; | ||
| 173 | + LocalTensor<float> bufferIn1_; | ||
| 174 | + LocalTensor<float> bufferOut0_; | ||
| 175 | + constexpr static AscendC::MicroAPI::CastTrait castTrait0 = { | ||
| 176 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::UNKNOWN, | ||
| 177 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::UNKNOWN}; | ||
| 178 | +}; | ||
| 179 | + | ||
| 180 | +} // namespace TanhGrad | ||
| 181 | + | ||
| @@ -0,0 +1,181 @@ | |||
| 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 tanh_grad_dtype_comb_0_nddma_without_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is float16, dy is float32, z is float32, max dims in ub is 5 and nddma does not need loops | ||
| 31 | +class TanhGradDtypeComb0NddmaWithoutLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradDtypeComb0NddmaWithoutLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ half*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ float*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ float*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(half); | ||
| 44 | + int64_t BUFFER_SIZE_1 = tilingDataPtr_->elemNum * sizeof(float); | ||
| 45 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 46 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 47 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + __aicore__ inline void Process() | ||
| 51 | + { | ||
| 52 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 53 | + tilingDataPtr_->blockFormer; | ||
| 54 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 55 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 56 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 57 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 58 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 59 | + if (ubLoopIdx != 0) { | ||
| 60 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 61 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 62 | + } | ||
| 63 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 64 | + tilingDataPtr_->ubTail : | ||
| 65 | + tilingDataPtr_->ubFormer; | ||
| 66 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 67 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | +private: | ||
| 74 | + __aicore__ inline void CopyIn0( | ||
| 75 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 76 | + { | ||
| 77 | + bufferIn0_ = queIn0_.AllocTensor<half>(); | ||
| 78 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 79 | + (ubLoopIdx <= 1 || | ||
| 80 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 81 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 82 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 83 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 84 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 85 | + } | ||
| 86 | + queIn0_.EnQue<half>(bufferIn0_); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + __aicore__ inline void CopyIn1( | ||
| 90 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 91 | + { | ||
| 92 | + bufferIn1_ = queIn1_.AllocTensor<float>(); | ||
| 93 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 94 | + (ubLoopIdx <= 1 || | ||
| 95 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 96 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 97 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 98 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 99 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 100 | + } | ||
| 101 | + queIn1_.EnQue<float>(bufferIn1_); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + __aicore__ inline void Compute2( | ||
| 105 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 106 | + { | ||
| 107 | + bufferIn0_ = queIn0_.DeQue<half>(); | ||
| 108 | + bufferIn1_ = queIn1_.DeQue<float>(); | ||
| 109 | + bufferOut0_ = queOut0_.AllocTensor<float>(); | ||
| 110 | + __VEC_SCOPE__ | ||
| 111 | + { | ||
| 112 | + RegTensor<half> vreg0; | ||
| 113 | + RegTensor<float> vreg1; | ||
| 114 | + RegTensor<float> vreg2; | ||
| 115 | + RegTensor<float> vreg3; | ||
| 116 | + RegTensor<float> vreg4; | ||
| 117 | + RegTensor<float> vreg5; | ||
| 118 | + RegTensor<float> vreg6; | ||
| 119 | + MaskReg preg0; | ||
| 120 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 121 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 122 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 123 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 124 | + __local_mem__ float* bufferIn1Addr = (__local_mem__ float*)bufferIn1_.GetPhyAddr(); | ||
| 125 | + __local_mem__ float* bufferOut0Addr = (__local_mem__ float*)bufferOut0_.GetPhyAddr(); | ||
| 126 | + __local_mem__ half* bufferIn0Addr = (__local_mem__ half*)bufferIn0_.GetPhyAddr(); | ||
| 127 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 128 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 129 | + AscendC::MicroAPI::DataCopy<half, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 130 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 131 | + AscendC::MicroAPI::Cast<float, half, castTrait0>(vreg1, vreg0, preg0); | ||
| 132 | + AscendC::MicroAPI::Duplicate<float, float>(vreg4, 1.0); | ||
| 133 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 134 | + vreg2, vreg1, static_cast<float>(-1), preg0); | ||
| 135 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 136 | + vreg4, vreg2, vreg1, preg0); | ||
| 137 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::LoadDist::DIST_NORM>( | ||
| 138 | + vreg5, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 139 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg6, vreg4, vreg5, preg0); | ||
| 140 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::StoreDist::DIST_NORM_B32>( | ||
| 141 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg6, preg0); | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 145 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 146 | + queOut0_.EnQue<float>(bufferOut0_); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + __aicore__ inline void CopyOut3( | ||
| 150 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 151 | + { | ||
| 152 | + bufferOut0_ = queOut0_.DeQue<float>(); | ||
| 153 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 154 | + dataCopyExtParams.blockCount = 1; | ||
| 155 | + dataCopyExtParams.blockLen = | ||
| 156 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(float); | ||
| 157 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 158 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 159 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 160 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | +private: | ||
| 164 | + TPipe* pipePtr_; | ||
| 165 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 166 | + GlobalTensor<half> inputGmY_; | ||
| 167 | + GlobalTensor<float> inputGmDy_; | ||
| 168 | + GlobalTensor<float> outputGmZ_; | ||
| 169 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 170 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 171 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 172 | + LocalTensor<half> bufferIn0_; | ||
| 173 | + LocalTensor<float> bufferIn1_; | ||
| 174 | + LocalTensor<float> bufferOut0_; | ||
| 175 | + constexpr static AscendC::MicroAPI::CastTrait castTrait0 = { | ||
| 176 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::UNKNOWN, | ||
| 177 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::UNKNOWN}; | ||
| 178 | +}; | ||
| 179 | + | ||
| 180 | +} // namespace TanhGrad | ||
| 181 | + | ||
| @@ -0,0 +1,184 @@ | |||
| 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 tanh_grad_dtype_comb_1_nddma_with_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is float16, dy is bfloat16, z is float32, max dims in ub is 8 and nddma needs loops | ||
| 31 | +class TanhGradDtypeComb1NddmaWithLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradDtypeComb1NddmaWithLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ half*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ bfloat16_t*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ float*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(half); | ||
| 44 | + int64_t BUFFER_SIZE_1 = tilingDataPtr_->elemNum * sizeof(bfloat16_t); | ||
| 45 | + int64_t BUFFER_SIZE_2 = tilingDataPtr_->elemNum * sizeof(float); | ||
| 46 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 47 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 48 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_2); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + __aicore__ inline void Process() | ||
| 52 | + { | ||
| 53 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 54 | + tilingDataPtr_->blockFormer; | ||
| 55 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 56 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 57 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 58 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 59 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 60 | + if (ubLoopIdx != 0) { | ||
| 61 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 62 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 63 | + } | ||
| 64 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 65 | + tilingDataPtr_->ubTail : | ||
| 66 | + tilingDataPtr_->ubFormer; | ||
| 67 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 70 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 71 | + } | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | +private: | ||
| 75 | + __aicore__ inline void CopyIn0( | ||
| 76 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 77 | + { | ||
| 78 | + bufferIn0_ = queIn0_.AllocTensor<half>(); | ||
| 79 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 80 | + (ubLoopIdx <= 1 || | ||
| 81 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 82 | + Ops::Base::BroadcastNddmaWithLoop( | ||
| 83 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 84 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 85 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 86 | + } | ||
| 87 | + queIn0_.EnQue<half>(bufferIn0_); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + __aicore__ inline void CopyIn1( | ||
| 91 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 92 | + { | ||
| 93 | + bufferIn1_ = queIn1_.AllocTensor<bfloat16_t>(); | ||
| 94 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 95 | + (ubLoopIdx <= 1 || | ||
| 96 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 97 | + Ops::Base::BroadcastNddmaWithLoop( | ||
| 98 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 99 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 100 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 101 | + } | ||
| 102 | + queIn1_.EnQue<bfloat16_t>(bufferIn1_); | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + __aicore__ inline void Compute2( | ||
| 106 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 107 | + { | ||
| 108 | + bufferIn0_ = queIn0_.DeQue<half>(); | ||
| 109 | + bufferIn1_ = queIn1_.DeQue<bfloat16_t>(); | ||
| 110 | + bufferOut0_ = queOut0_.AllocTensor<float>(); | ||
| 111 | + __VEC_SCOPE__ | ||
| 112 | + { | ||
| 113 | + RegTensor<half> vreg0; | ||
| 114 | + RegTensor<float> vreg1; | ||
| 115 | + RegTensor<float> vreg2; | ||
| 116 | + RegTensor<float> vreg3; | ||
| 117 | + RegTensor<float> vreg4; | ||
| 118 | + RegTensor<bfloat16_t> vreg5; | ||
| 119 | + RegTensor<float> vreg6; | ||
| 120 | + RegTensor<float> vreg7; | ||
| 121 | + MaskReg preg0; | ||
| 122 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 123 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 124 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 125 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 126 | + __local_mem__ bfloat16_t* bufferIn1Addr = (__local_mem__ bfloat16_t*)bufferIn1_.GetPhyAddr(); | ||
| 127 | + __local_mem__ float* bufferOut0Addr = (__local_mem__ float*)bufferOut0_.GetPhyAddr(); | ||
| 128 | + __local_mem__ half* bufferIn0Addr = (__local_mem__ half*)bufferIn0_.GetPhyAddr(); | ||
| 129 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 130 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 131 | + AscendC::MicroAPI::DataCopy<half, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 132 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 133 | + AscendC::MicroAPI::Cast<float, half, castTrait0>(vreg1, vreg0, preg0); | ||
| 134 | + AscendC::MicroAPI::Duplicate<float, float>(vreg4, 1.0); | ||
| 135 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 136 | + vreg2, vreg1, static_cast<float>(-1), preg0); | ||
| 137 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 138 | + vreg4, vreg2, vreg1, preg0); | ||
| 139 | + AscendC::MicroAPI::DataCopy<bfloat16_t, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 140 | + vreg5, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 141 | + AscendC::MicroAPI::Cast<float, bfloat16_t, castTrait0>(vreg6, vreg5, preg0); | ||
| 142 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg7, vreg4, vreg6, preg0); | ||
| 143 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::StoreDist::DIST_NORM_B32>( | ||
| 144 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg7, preg0); | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 148 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 149 | + queOut0_.EnQue<float>(bufferOut0_); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + __aicore__ inline void CopyOut3( | ||
| 153 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 154 | + { | ||
| 155 | + bufferOut0_ = queOut0_.DeQue<float>(); | ||
| 156 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 157 | + dataCopyExtParams.blockCount = 1; | ||
| 158 | + dataCopyExtParams.blockLen = | ||
| 159 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(float); | ||
| 160 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 161 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 162 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 163 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | +private: | ||
| 167 | + TPipe* pipePtr_; | ||
| 168 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 169 | + GlobalTensor<half> inputGmY_; | ||
| 170 | + GlobalTensor<bfloat16_t> inputGmDy_; | ||
| 171 | + GlobalTensor<float> outputGmZ_; | ||
| 172 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 173 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 174 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 175 | + LocalTensor<half> bufferIn0_; | ||
| 176 | + LocalTensor<bfloat16_t> bufferIn1_; | ||
| 177 | + LocalTensor<float> bufferOut0_; | ||
| 178 | + constexpr static AscendC::MicroAPI::CastTrait castTrait0 = { | ||
| 179 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::UNKNOWN, | ||
| 180 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::UNKNOWN}; | ||
| 181 | +}; | ||
| 182 | + | ||
| 183 | +} // namespace TanhGrad | ||
| 184 | + | ||
| @@ -0,0 +1,184 @@ | |||
| 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 tanh_grad_dtype_comb_1_nddma_without_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is float16, dy is bfloat16, z is float32, max dims in ub is 5 and nddma does not need loops | ||
| 31 | +class TanhGradDtypeComb1NddmaWithoutLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradDtypeComb1NddmaWithoutLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ half*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ bfloat16_t*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ float*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(half); | ||
| 44 | + int64_t BUFFER_SIZE_1 = tilingDataPtr_->elemNum * sizeof(bfloat16_t); | ||
| 45 | + int64_t BUFFER_SIZE_2 = tilingDataPtr_->elemNum * sizeof(float); | ||
| 46 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 47 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 48 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_2); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + __aicore__ inline void Process() | ||
| 52 | + { | ||
| 53 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 54 | + tilingDataPtr_->blockFormer; | ||
| 55 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 56 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 57 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 58 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 59 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 60 | + if (ubLoopIdx != 0) { | ||
| 61 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 62 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 63 | + } | ||
| 64 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 65 | + tilingDataPtr_->ubTail : | ||
| 66 | + tilingDataPtr_->ubFormer; | ||
| 67 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 70 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 71 | + } | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | +private: | ||
| 75 | + __aicore__ inline void CopyIn0( | ||
| 76 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 77 | + { | ||
| 78 | + bufferIn0_ = queIn0_.AllocTensor<half>(); | ||
| 79 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 80 | + (ubLoopIdx <= 1 || | ||
| 81 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 82 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 83 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 84 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 85 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 86 | + } | ||
| 87 | + queIn0_.EnQue<half>(bufferIn0_); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + __aicore__ inline void CopyIn1( | ||
| 91 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 92 | + { | ||
| 93 | + bufferIn1_ = queIn1_.AllocTensor<bfloat16_t>(); | ||
| 94 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 95 | + (ubLoopIdx <= 1 || | ||
| 96 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 97 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 98 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 99 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 100 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 101 | + } | ||
| 102 | + queIn1_.EnQue<bfloat16_t>(bufferIn1_); | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + __aicore__ inline void Compute2( | ||
| 106 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 107 | + { | ||
| 108 | + bufferIn0_ = queIn0_.DeQue<half>(); | ||
| 109 | + bufferIn1_ = queIn1_.DeQue<bfloat16_t>(); | ||
| 110 | + bufferOut0_ = queOut0_.AllocTensor<float>(); | ||
| 111 | + __VEC_SCOPE__ | ||
| 112 | + { | ||
| 113 | + RegTensor<half> vreg0; | ||
| 114 | + RegTensor<float> vreg1; | ||
| 115 | + RegTensor<float> vreg2; | ||
| 116 | + RegTensor<float> vreg3; | ||
| 117 | + RegTensor<float> vreg4; | ||
| 118 | + RegTensor<bfloat16_t> vreg5; | ||
| 119 | + RegTensor<float> vreg6; | ||
| 120 | + RegTensor<float> vreg7; | ||
| 121 | + MaskReg preg0; | ||
| 122 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 123 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 124 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 125 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 126 | + __local_mem__ bfloat16_t* bufferIn1Addr = (__local_mem__ bfloat16_t*)bufferIn1_.GetPhyAddr(); | ||
| 127 | + __local_mem__ float* bufferOut0Addr = (__local_mem__ float*)bufferOut0_.GetPhyAddr(); | ||
| 128 | + __local_mem__ half* bufferIn0Addr = (__local_mem__ half*)bufferIn0_.GetPhyAddr(); | ||
| 129 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 130 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 131 | + AscendC::MicroAPI::DataCopy<half, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 132 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 133 | + AscendC::MicroAPI::Cast<float, half, castTrait0>(vreg1, vreg0, preg0); | ||
| 134 | + AscendC::MicroAPI::Duplicate<float, float>(vreg4, 1.0); | ||
| 135 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 136 | + vreg2, vreg1, static_cast<float>(-1), preg0); | ||
| 137 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 138 | + vreg4, vreg2, vreg1, preg0); | ||
| 139 | + AscendC::MicroAPI::DataCopy<bfloat16_t, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 140 | + vreg5, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 141 | + AscendC::MicroAPI::Cast<float, bfloat16_t, castTrait0>(vreg6, vreg5, preg0); | ||
| 142 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg7, vreg4, vreg6, preg0); | ||
| 143 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::StoreDist::DIST_NORM_B32>( | ||
| 144 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg7, preg0); | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 148 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 149 | + queOut0_.EnQue<float>(bufferOut0_); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + __aicore__ inline void CopyOut3( | ||
| 153 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 154 | + { | ||
| 155 | + bufferOut0_ = queOut0_.DeQue<float>(); | ||
| 156 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 157 | + dataCopyExtParams.blockCount = 1; | ||
| 158 | + dataCopyExtParams.blockLen = | ||
| 159 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(float); | ||
| 160 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 161 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 162 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 163 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | +private: | ||
| 167 | + TPipe* pipePtr_; | ||
| 168 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 169 | + GlobalTensor<half> inputGmY_; | ||
| 170 | + GlobalTensor<bfloat16_t> inputGmDy_; | ||
| 171 | + GlobalTensor<float> outputGmZ_; | ||
| 172 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 173 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 174 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 175 | + LocalTensor<half> bufferIn0_; | ||
| 176 | + LocalTensor<bfloat16_t> bufferIn1_; | ||
| 177 | + LocalTensor<float> bufferOut0_; | ||
| 178 | + constexpr static AscendC::MicroAPI::CastTrait castTrait0 = { | ||
| 179 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::UNKNOWN, | ||
| 180 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::UNKNOWN}; | ||
| 181 | +}; | ||
| 182 | + | ||
| 183 | +} // namespace TanhGrad | ||
| 184 | + | ||
| @@ -0,0 +1,181 @@ | |||
| 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 tanh_grad_dtype_comb_2_nddma_with_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is float32, dy is float16, z is float32, max dims in ub is 8 and nddma needs loops | ||
| 31 | +class TanhGradDtypeComb2NddmaWithLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradDtypeComb2NddmaWithLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ float*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ half*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ float*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(float); | ||
| 44 | + int64_t BUFFER_SIZE_1 = tilingDataPtr_->elemNum * sizeof(half); | ||
| 45 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 46 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 47 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + __aicore__ inline void Process() | ||
| 51 | + { | ||
| 52 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 53 | + tilingDataPtr_->blockFormer; | ||
| 54 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 55 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 56 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 57 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 58 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 59 | + if (ubLoopIdx != 0) { | ||
| 60 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 61 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 62 | + } | ||
| 63 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 64 | + tilingDataPtr_->ubTail : | ||
| 65 | + tilingDataPtr_->ubFormer; | ||
| 66 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 67 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | +private: | ||
| 74 | + __aicore__ inline void CopyIn0( | ||
| 75 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 76 | + { | ||
| 77 | + bufferIn0_ = queIn0_.AllocTensor<float>(); | ||
| 78 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 79 | + (ubLoopIdx <= 1 || | ||
| 80 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 81 | + Ops::Base::BroadcastNddmaWithLoop( | ||
| 82 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 83 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 84 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 85 | + } | ||
| 86 | + queIn0_.EnQue<float>(bufferIn0_); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + __aicore__ inline void CopyIn1( | ||
| 90 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 91 | + { | ||
| 92 | + bufferIn1_ = queIn1_.AllocTensor<half>(); | ||
| 93 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 94 | + (ubLoopIdx <= 1 || | ||
| 95 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 96 | + Ops::Base::BroadcastNddmaWithLoop( | ||
| 97 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 98 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 99 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 100 | + } | ||
| 101 | + queIn1_.EnQue<half>(bufferIn1_); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + __aicore__ inline void Compute2( | ||
| 105 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 106 | + { | ||
| 107 | + bufferIn0_ = queIn0_.DeQue<float>(); | ||
| 108 | + bufferIn1_ = queIn1_.DeQue<half>(); | ||
| 109 | + bufferOut0_ = queOut0_.AllocTensor<float>(); | ||
| 110 | + __VEC_SCOPE__ | ||
| 111 | + { | ||
| 112 | + RegTensor<float> vreg0; | ||
| 113 | + RegTensor<float> vreg1; | ||
| 114 | + RegTensor<float> vreg2; | ||
| 115 | + RegTensor<float> vreg3; | ||
| 116 | + RegTensor<half> vreg4; | ||
| 117 | + RegTensor<float> vreg5; | ||
| 118 | + RegTensor<float> vreg6; | ||
| 119 | + MaskReg preg0; | ||
| 120 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 121 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 122 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 123 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 124 | + __local_mem__ float* bufferIn0Addr = (__local_mem__ float*)bufferIn0_.GetPhyAddr(); | ||
| 125 | + __local_mem__ float* bufferOut0Addr = (__local_mem__ float*)bufferOut0_.GetPhyAddr(); | ||
| 126 | + __local_mem__ half* bufferIn1Addr = (__local_mem__ half*)bufferIn1_.GetPhyAddr(); | ||
| 127 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 128 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 129 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::LoadDist::DIST_NORM>( | ||
| 130 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 131 | + AscendC::MicroAPI::Duplicate<float, float>(vreg3, 1.0); | ||
| 132 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 133 | + vreg2, vreg0, static_cast<float>(-1), preg0); | ||
| 134 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 135 | + vreg3, vreg2, vreg0, preg0); | ||
| 136 | + AscendC::MicroAPI::DataCopy<half, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 137 | + vreg4, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 138 | + AscendC::MicroAPI::Cast<float, half, castTrait0>(vreg5, vreg4, preg0); | ||
| 139 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg6, vreg3, vreg5, preg0); | ||
| 140 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::StoreDist::DIST_NORM_B32>( | ||
| 141 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg6, preg0); | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 145 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 146 | + queOut0_.EnQue<float>(bufferOut0_); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + __aicore__ inline void CopyOut3( | ||
| 150 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 151 | + { | ||
| 152 | + bufferOut0_ = queOut0_.DeQue<float>(); | ||
| 153 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 154 | + dataCopyExtParams.blockCount = 1; | ||
| 155 | + dataCopyExtParams.blockLen = | ||
| 156 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(float); | ||
| 157 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 158 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 159 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 160 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | +private: | ||
| 164 | + TPipe* pipePtr_; | ||
| 165 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 166 | + GlobalTensor<float> inputGmY_; | ||
| 167 | + GlobalTensor<half> inputGmDy_; | ||
| 168 | + GlobalTensor<float> outputGmZ_; | ||
| 169 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 170 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 171 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 172 | + LocalTensor<float> bufferIn0_; | ||
| 173 | + LocalTensor<half> bufferIn1_; | ||
| 174 | + LocalTensor<float> bufferOut0_; | ||
| 175 | + constexpr static AscendC::MicroAPI::CastTrait castTrait0 = { | ||
| 176 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::UNKNOWN, | ||
| 177 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::UNKNOWN}; | ||
| 178 | +}; | ||
| 179 | + | ||
| 180 | +} // namespace TanhGrad | ||
| 181 | + | ||
| @@ -0,0 +1,181 @@ | |||
| 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 tanh_grad_dtype_comb_2_nddma_without_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is float32, dy is float16, z is float32, max dims in ub is 5 and nddma does not need loops | ||
| 31 | +class TanhGradDtypeComb2NddmaWithoutLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradDtypeComb2NddmaWithoutLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ float*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ half*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ float*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(float); | ||
| 44 | + int64_t BUFFER_SIZE_1 = tilingDataPtr_->elemNum * sizeof(half); | ||
| 45 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 46 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 47 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + __aicore__ inline void Process() | ||
| 51 | + { | ||
| 52 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 53 | + tilingDataPtr_->blockFormer; | ||
| 54 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 55 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 56 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 57 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 58 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 59 | + if (ubLoopIdx != 0) { | ||
| 60 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 61 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 62 | + } | ||
| 63 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 64 | + tilingDataPtr_->ubTail : | ||
| 65 | + tilingDataPtr_->ubFormer; | ||
| 66 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 67 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | +private: | ||
| 74 | + __aicore__ inline void CopyIn0( | ||
| 75 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 76 | + { | ||
| 77 | + bufferIn0_ = queIn0_.AllocTensor<float>(); | ||
| 78 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 79 | + (ubLoopIdx <= 1 || | ||
| 80 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 81 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 82 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 83 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 84 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 85 | + } | ||
| 86 | + queIn0_.EnQue<float>(bufferIn0_); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + __aicore__ inline void CopyIn1( | ||
| 90 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 91 | + { | ||
| 92 | + bufferIn1_ = queIn1_.AllocTensor<half>(); | ||
| 93 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 94 | + (ubLoopIdx <= 1 || | ||
| 95 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 96 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 97 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 98 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 99 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 100 | + } | ||
| 101 | + queIn1_.EnQue<half>(bufferIn1_); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + __aicore__ inline void Compute2( | ||
| 105 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 106 | + { | ||
| 107 | + bufferIn0_ = queIn0_.DeQue<float>(); | ||
| 108 | + bufferIn1_ = queIn1_.DeQue<half>(); | ||
| 109 | + bufferOut0_ = queOut0_.AllocTensor<float>(); | ||
| 110 | + __VEC_SCOPE__ | ||
| 111 | + { | ||
| 112 | + RegTensor<float> vreg0; | ||
| 113 | + RegTensor<float> vreg1; | ||
| 114 | + RegTensor<float> vreg2; | ||
| 115 | + RegTensor<float> vreg3; | ||
| 116 | + RegTensor<half> vreg4; | ||
| 117 | + RegTensor<float> vreg5; | ||
| 118 | + RegTensor<float> vreg6; | ||
| 119 | + MaskReg preg0; | ||
| 120 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 121 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 122 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 123 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 124 | + __local_mem__ float* bufferIn0Addr = (__local_mem__ float*)bufferIn0_.GetPhyAddr(); | ||
| 125 | + __local_mem__ float* bufferOut0Addr = (__local_mem__ float*)bufferOut0_.GetPhyAddr(); | ||
| 126 | + __local_mem__ half* bufferIn1Addr = (__local_mem__ half*)bufferIn1_.GetPhyAddr(); | ||
| 127 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 128 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 129 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::LoadDist::DIST_NORM>( | ||
| 130 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 131 | + AscendC::MicroAPI::Duplicate<float, float>(vreg3, 1.0); | ||
| 132 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 133 | + vreg2, vreg0, static_cast<float>(-1), preg0); | ||
| 134 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 135 | + vreg3, vreg2, vreg0, preg0); | ||
| 136 | + AscendC::MicroAPI::DataCopy<half, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 137 | + vreg4, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 138 | + AscendC::MicroAPI::Cast<float, half, castTrait0>(vreg5, vreg4, preg0); | ||
| 139 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg6, vreg3, vreg5, preg0); | ||
| 140 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::StoreDist::DIST_NORM_B32>( | ||
| 141 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg6, preg0); | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 145 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 146 | + queOut0_.EnQue<float>(bufferOut0_); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + __aicore__ inline void CopyOut3( | ||
| 150 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 151 | + { | ||
| 152 | + bufferOut0_ = queOut0_.DeQue<float>(); | ||
| 153 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 154 | + dataCopyExtParams.blockCount = 1; | ||
| 155 | + dataCopyExtParams.blockLen = | ||
| 156 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(float); | ||
| 157 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 158 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 159 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 160 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | +private: | ||
| 164 | + TPipe* pipePtr_; | ||
| 165 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 166 | + GlobalTensor<float> inputGmY_; | ||
| 167 | + GlobalTensor<half> inputGmDy_; | ||
| 168 | + GlobalTensor<float> outputGmZ_; | ||
| 169 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 170 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 171 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 172 | + LocalTensor<float> bufferIn0_; | ||
| 173 | + LocalTensor<half> bufferIn1_; | ||
| 174 | + LocalTensor<float> bufferOut0_; | ||
| 175 | + constexpr static AscendC::MicroAPI::CastTrait castTrait0 = { | ||
| 176 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::UNKNOWN, | ||
| 177 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::UNKNOWN}; | ||
| 178 | +}; | ||
| 179 | + | ||
| 180 | +} // namespace TanhGrad | ||
| 181 | + | ||
| @@ -0,0 +1,181 @@ | |||
| 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 tanh_grad_dtype_comb_3_nddma_without_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is float32, dy is bfloat16, z is float32, max dims in ub is 5 and nddma does not need loops | ||
| 31 | +class TanhGradDtypeComb3NddmaWithoutLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradDtypeComb3NddmaWithoutLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ float*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ bfloat16_t*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ float*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(float); | ||
| 44 | + int64_t BUFFER_SIZE_1 = tilingDataPtr_->elemNum * sizeof(bfloat16_t); | ||
| 45 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 46 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 47 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + __aicore__ inline void Process() | ||
| 51 | + { | ||
| 52 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 53 | + tilingDataPtr_->blockFormer; | ||
| 54 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 55 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 56 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 57 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 58 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 59 | + if (ubLoopIdx != 0) { | ||
| 60 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 61 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 62 | + } | ||
| 63 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 64 | + tilingDataPtr_->ubTail : | ||
| 65 | + tilingDataPtr_->ubFormer; | ||
| 66 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 67 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | +private: | ||
| 74 | + __aicore__ inline void CopyIn0( | ||
| 75 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 76 | + { | ||
| 77 | + bufferIn0_ = queIn0_.AllocTensor<float>(); | ||
| 78 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 79 | + (ubLoopIdx <= 1 || | ||
| 80 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 81 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 82 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 83 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 84 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 85 | + } | ||
| 86 | + queIn0_.EnQue<float>(bufferIn0_); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + __aicore__ inline void CopyIn1( | ||
| 90 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 91 | + { | ||
| 92 | + bufferIn1_ = queIn1_.AllocTensor<bfloat16_t>(); | ||
| 93 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 94 | + (ubLoopIdx <= 1 || | ||
| 95 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 96 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 97 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 98 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 99 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 100 | + } | ||
| 101 | + queIn1_.EnQue<bfloat16_t>(bufferIn1_); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + __aicore__ inline void Compute2( | ||
| 105 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 106 | + { | ||
| 107 | + bufferIn0_ = queIn0_.DeQue<float>(); | ||
| 108 | + bufferIn1_ = queIn1_.DeQue<bfloat16_t>(); | ||
| 109 | + bufferOut0_ = queOut0_.AllocTensor<float>(); | ||
| 110 | + __VEC_SCOPE__ | ||
| 111 | + { | ||
| 112 | + RegTensor<float> vreg0; | ||
| 113 | + RegTensor<float> vreg1; | ||
| 114 | + RegTensor<float> vreg2; | ||
| 115 | + RegTensor<float> vreg3; | ||
| 116 | + RegTensor<bfloat16_t> vreg4; | ||
| 117 | + RegTensor<float> vreg5; | ||
| 118 | + RegTensor<float> vreg6; | ||
| 119 | + MaskReg preg0; | ||
| 120 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 121 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 122 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 123 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 124 | + __local_mem__ bfloat16_t* bufferIn1Addr = (__local_mem__ bfloat16_t*)bufferIn1_.GetPhyAddr(); | ||
| 125 | + __local_mem__ float* bufferIn0Addr = (__local_mem__ float*)bufferIn0_.GetPhyAddr(); | ||
| 126 | + __local_mem__ float* bufferOut0Addr = (__local_mem__ float*)bufferOut0_.GetPhyAddr(); | ||
| 127 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 128 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 129 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::LoadDist::DIST_NORM>( | ||
| 130 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 131 | + AscendC::MicroAPI::Duplicate<float, float>(vreg3, 1.0); | ||
| 132 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 133 | + vreg2, vreg0, static_cast<float>(-1), preg0); | ||
| 134 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 135 | + vreg3, vreg2, vreg0, preg0); | ||
| 136 | + AscendC::MicroAPI::DataCopy<bfloat16_t, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 137 | + vreg4, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 138 | + AscendC::MicroAPI::Cast<float, bfloat16_t, castTrait0>(vreg5, vreg4, preg0); | ||
| 139 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg6, vreg3, vreg5, preg0); | ||
| 140 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::StoreDist::DIST_NORM_B32>( | ||
| 141 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg6, preg0); | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 145 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 146 | + queOut0_.EnQue<float>(bufferOut0_); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + __aicore__ inline void CopyOut3( | ||
| 150 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 151 | + { | ||
| 152 | + bufferOut0_ = queOut0_.DeQue<float>(); | ||
| 153 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 154 | + dataCopyExtParams.blockCount = 1; | ||
| 155 | + dataCopyExtParams.blockLen = | ||
| 156 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(float); | ||
| 157 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 158 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 159 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 160 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | +private: | ||
| 164 | + TPipe* pipePtr_; | ||
| 165 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 166 | + GlobalTensor<float> inputGmY_; | ||
| 167 | + GlobalTensor<bfloat16_t> inputGmDy_; | ||
| 168 | + GlobalTensor<float> outputGmZ_; | ||
| 169 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 170 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 171 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 172 | + LocalTensor<float> bufferIn0_; | ||
| 173 | + LocalTensor<bfloat16_t> bufferIn1_; | ||
| 174 | + LocalTensor<float> bufferOut0_; | ||
| 175 | + constexpr static AscendC::MicroAPI::CastTrait castTrait0 = { | ||
| 176 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::UNKNOWN, | ||
| 177 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::UNKNOWN}; | ||
| 178 | +}; | ||
| 179 | + | ||
| 180 | +} // namespace TanhGrad | ||
| 181 | + | ||
| @@ -0,0 +1,184 @@ | |||
| 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 tanh_grad_dtype_comb_4_nddma_with_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is bfloat16, dy is float16, z is float32, max dims in ub is 8 and nddma needs loops | ||
| 31 | +class TanhGradDtypeComb4NddmaWithLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradDtypeComb4NddmaWithLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ bfloat16_t*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ half*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ float*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(bfloat16_t); | ||
| 44 | + int64_t BUFFER_SIZE_1 = tilingDataPtr_->elemNum * sizeof(half); | ||
| 45 | + int64_t BUFFER_SIZE_2 = tilingDataPtr_->elemNum * sizeof(float); | ||
| 46 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 47 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 48 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_2); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + __aicore__ inline void Process() | ||
| 52 | + { | ||
| 53 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 54 | + tilingDataPtr_->blockFormer; | ||
| 55 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 56 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 57 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 58 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 59 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 60 | + if (ubLoopIdx != 0) { | ||
| 61 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 62 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 63 | + } | ||
| 64 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 65 | + tilingDataPtr_->ubTail : | ||
| 66 | + tilingDataPtr_->ubFormer; | ||
| 67 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 70 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 71 | + } | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | +private: | ||
| 75 | + __aicore__ inline void CopyIn0( | ||
| 76 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 77 | + { | ||
| 78 | + bufferIn0_ = queIn0_.AllocTensor<bfloat16_t>(); | ||
| 79 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 80 | + (ubLoopIdx <= 1 || | ||
| 81 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 82 | + Ops::Base::BroadcastNddmaWithLoop( | ||
| 83 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 84 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 85 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 86 | + } | ||
| 87 | + queIn0_.EnQue<bfloat16_t>(bufferIn0_); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + __aicore__ inline void CopyIn1( | ||
| 91 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 92 | + { | ||
| 93 | + bufferIn1_ = queIn1_.AllocTensor<half>(); | ||
| 94 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 95 | + (ubLoopIdx <= 1 || | ||
| 96 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 97 | + Ops::Base::BroadcastNddmaWithLoop( | ||
| 98 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 99 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 100 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 101 | + } | ||
| 102 | + queIn1_.EnQue<half>(bufferIn1_); | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + __aicore__ inline void Compute2( | ||
| 106 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 107 | + { | ||
| 108 | + bufferIn0_ = queIn0_.DeQue<bfloat16_t>(); | ||
| 109 | + bufferIn1_ = queIn1_.DeQue<half>(); | ||
| 110 | + bufferOut0_ = queOut0_.AllocTensor<float>(); | ||
| 111 | + __VEC_SCOPE__ | ||
| 112 | + { | ||
| 113 | + RegTensor<bfloat16_t> vreg0; | ||
| 114 | + RegTensor<float> vreg1; | ||
| 115 | + RegTensor<float> vreg2; | ||
| 116 | + RegTensor<float> vreg3; | ||
| 117 | + RegTensor<float> vreg4; | ||
| 118 | + RegTensor<half> vreg5; | ||
| 119 | + RegTensor<float> vreg6; | ||
| 120 | + RegTensor<float> vreg7; | ||
| 121 | + MaskReg preg0; | ||
| 122 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 123 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 124 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 125 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 126 | + __local_mem__ bfloat16_t* bufferIn0Addr = (__local_mem__ bfloat16_t*)bufferIn0_.GetPhyAddr(); | ||
| 127 | + __local_mem__ float* bufferOut0Addr = (__local_mem__ float*)bufferOut0_.GetPhyAddr(); | ||
| 128 | + __local_mem__ half* bufferIn1Addr = (__local_mem__ half*)bufferIn1_.GetPhyAddr(); | ||
| 129 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 130 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 131 | + AscendC::MicroAPI::DataCopy<bfloat16_t, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 132 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 133 | + AscendC::MicroAPI::Cast<float, bfloat16_t, castTrait0>(vreg1, vreg0, preg0); | ||
| 134 | + AscendC::MicroAPI::Duplicate<float, float>(vreg4, 1.0); | ||
| 135 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 136 | + vreg2, vreg1, static_cast<float>(-1), preg0); | ||
| 137 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 138 | + vreg4, vreg2, vreg1, preg0); | ||
| 139 | + AscendC::MicroAPI::DataCopy<half, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 140 | + vreg5, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 141 | + AscendC::MicroAPI::Cast<float, half, castTrait0>(vreg6, vreg5, preg0); | ||
| 142 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg7, vreg4, vreg6, preg0); | ||
| 143 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::StoreDist::DIST_NORM_B32>( | ||
| 144 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg7, preg0); | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 148 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 149 | + queOut0_.EnQue<float>(bufferOut0_); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + __aicore__ inline void CopyOut3( | ||
| 153 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 154 | + { | ||
| 155 | + bufferOut0_ = queOut0_.DeQue<float>(); | ||
| 156 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 157 | + dataCopyExtParams.blockCount = 1; | ||
| 158 | + dataCopyExtParams.blockLen = | ||
| 159 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(float); | ||
| 160 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 161 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 162 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 163 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | +private: | ||
| 167 | + TPipe* pipePtr_; | ||
| 168 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 169 | + GlobalTensor<bfloat16_t> inputGmY_; | ||
| 170 | + GlobalTensor<half> inputGmDy_; | ||
| 171 | + GlobalTensor<float> outputGmZ_; | ||
| 172 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 173 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 174 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 175 | + LocalTensor<bfloat16_t> bufferIn0_; | ||
| 176 | + LocalTensor<half> bufferIn1_; | ||
| 177 | + LocalTensor<float> bufferOut0_; | ||
| 178 | + constexpr static AscendC::MicroAPI::CastTrait castTrait0 = { | ||
| 179 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::UNKNOWN, | ||
| 180 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::UNKNOWN}; | ||
| 181 | +}; | ||
| 182 | + | ||
| 183 | +} // namespace TanhGrad | ||
| 184 | + | ||
| @@ -0,0 +1,184 @@ | |||
| 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 tanh_grad_dtype_comb_4_nddma_without_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is bfloat16, dy is float16, z is float32, max dims in ub is 5 and nddma does not need loops | ||
| 31 | +class TanhGradDtypeComb4NddmaWithoutLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradDtypeComb4NddmaWithoutLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ bfloat16_t*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ half*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ float*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(bfloat16_t); | ||
| 44 | + int64_t BUFFER_SIZE_1 = tilingDataPtr_->elemNum * sizeof(half); | ||
| 45 | + int64_t BUFFER_SIZE_2 = tilingDataPtr_->elemNum * sizeof(float); | ||
| 46 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 47 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 48 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_2); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + __aicore__ inline void Process() | ||
| 52 | + { | ||
| 53 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 54 | + tilingDataPtr_->blockFormer; | ||
| 55 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 56 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 57 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 58 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 59 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 60 | + if (ubLoopIdx != 0) { | ||
| 61 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 62 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 63 | + } | ||
| 64 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 65 | + tilingDataPtr_->ubTail : | ||
| 66 | + tilingDataPtr_->ubFormer; | ||
| 67 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 70 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 71 | + } | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | +private: | ||
| 75 | + __aicore__ inline void CopyIn0( | ||
| 76 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 77 | + { | ||
| 78 | + bufferIn0_ = queIn0_.AllocTensor<bfloat16_t>(); | ||
| 79 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 80 | + (ubLoopIdx <= 1 || | ||
| 81 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 82 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 83 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 84 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 85 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 86 | + } | ||
| 87 | + queIn0_.EnQue<bfloat16_t>(bufferIn0_); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + __aicore__ inline void CopyIn1( | ||
| 91 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 92 | + { | ||
| 93 | + bufferIn1_ = queIn1_.AllocTensor<half>(); | ||
| 94 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 95 | + (ubLoopIdx <= 1 || | ||
| 96 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 97 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 98 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 99 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 100 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 101 | + } | ||
| 102 | + queIn1_.EnQue<half>(bufferIn1_); | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + __aicore__ inline void Compute2( | ||
| 106 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 107 | + { | ||
| 108 | + bufferIn0_ = queIn0_.DeQue<bfloat16_t>(); | ||
| 109 | + bufferIn1_ = queIn1_.DeQue<half>(); | ||
| 110 | + bufferOut0_ = queOut0_.AllocTensor<float>(); | ||
| 111 | + __VEC_SCOPE__ | ||
| 112 | + { | ||
| 113 | + RegTensor<bfloat16_t> vreg0; | ||
| 114 | + RegTensor<float> vreg1; | ||
| 115 | + RegTensor<float> vreg2; | ||
| 116 | + RegTensor<float> vreg3; | ||
| 117 | + RegTensor<float> vreg4; | ||
| 118 | + RegTensor<half> vreg5; | ||
| 119 | + RegTensor<float> vreg6; | ||
| 120 | + RegTensor<float> vreg7; | ||
| 121 | + MaskReg preg0; | ||
| 122 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 123 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 124 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 125 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 126 | + __local_mem__ bfloat16_t* bufferIn0Addr = (__local_mem__ bfloat16_t*)bufferIn0_.GetPhyAddr(); | ||
| 127 | + __local_mem__ float* bufferOut0Addr = (__local_mem__ float*)bufferOut0_.GetPhyAddr(); | ||
| 128 | + __local_mem__ half* bufferIn1Addr = (__local_mem__ half*)bufferIn1_.GetPhyAddr(); | ||
| 129 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 130 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 131 | + AscendC::MicroAPI::DataCopy<bfloat16_t, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 132 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 133 | + AscendC::MicroAPI::Cast<float, bfloat16_t, castTrait0>(vreg1, vreg0, preg0); | ||
| 134 | + AscendC::MicroAPI::Duplicate<float, float>(vreg4, 1.0); | ||
| 135 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 136 | + vreg2, vreg1, static_cast<float>(-1), preg0); | ||
| 137 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 138 | + vreg4, vreg2, vreg1, preg0); | ||
| 139 | + AscendC::MicroAPI::DataCopy<half, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 140 | + vreg5, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 141 | + AscendC::MicroAPI::Cast<float, half, castTrait0>(vreg6, vreg5, preg0); | ||
| 142 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg7, vreg4, vreg6, preg0); | ||
| 143 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::StoreDist::DIST_NORM_B32>( | ||
| 144 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg7, preg0); | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 148 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 149 | + queOut0_.EnQue<float>(bufferOut0_); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + __aicore__ inline void CopyOut3( | ||
| 153 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 154 | + { | ||
| 155 | + bufferOut0_ = queOut0_.DeQue<float>(); | ||
| 156 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 157 | + dataCopyExtParams.blockCount = 1; | ||
| 158 | + dataCopyExtParams.blockLen = | ||
| 159 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(float); | ||
| 160 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 161 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 162 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 163 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | +private: | ||
| 167 | + TPipe* pipePtr_; | ||
| 168 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 169 | + GlobalTensor<bfloat16_t> inputGmY_; | ||
| 170 | + GlobalTensor<half> inputGmDy_; | ||
| 171 | + GlobalTensor<float> outputGmZ_; | ||
| 172 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 173 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 174 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 175 | + LocalTensor<bfloat16_t> bufferIn0_; | ||
| 176 | + LocalTensor<half> bufferIn1_; | ||
| 177 | + LocalTensor<float> bufferOut0_; | ||
| 178 | + constexpr static AscendC::MicroAPI::CastTrait castTrait0 = { | ||
| 179 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::UNKNOWN, | ||
| 180 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::UNKNOWN}; | ||
| 181 | +}; | ||
| 182 | + | ||
| 183 | +} // namespace TanhGrad | ||
| 184 | + | ||
| @@ -0,0 +1,181 @@ | |||
| 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 tanh_grad_dtype_comb_5_nddma_with_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is bfloat16, dy is float32, z is float32, max dims in ub is 8 and nddma needs loops | ||
| 31 | +class TanhGradDtypeComb5NddmaWithLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradDtypeComb5NddmaWithLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ bfloat16_t*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ float*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ float*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(bfloat16_t); | ||
| 44 | + int64_t BUFFER_SIZE_1 = tilingDataPtr_->elemNum * sizeof(float); | ||
| 45 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 46 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 47 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + __aicore__ inline void Process() | ||
| 51 | + { | ||
| 52 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 53 | + tilingDataPtr_->blockFormer; | ||
| 54 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 55 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 56 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 57 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 58 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 59 | + if (ubLoopIdx != 0) { | ||
| 60 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 61 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 62 | + } | ||
| 63 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 64 | + tilingDataPtr_->ubTail : | ||
| 65 | + tilingDataPtr_->ubFormer; | ||
| 66 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 67 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | +private: | ||
| 74 | + __aicore__ inline void CopyIn0( | ||
| 75 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 76 | + { | ||
| 77 | + bufferIn0_ = queIn0_.AllocTensor<bfloat16_t>(); | ||
| 78 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 79 | + (ubLoopIdx <= 1 || | ||
| 80 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 81 | + Ops::Base::BroadcastNddmaWithLoop( | ||
| 82 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 83 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 84 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 85 | + } | ||
| 86 | + queIn0_.EnQue<bfloat16_t>(bufferIn0_); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + __aicore__ inline void CopyIn1( | ||
| 90 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 91 | + { | ||
| 92 | + bufferIn1_ = queIn1_.AllocTensor<float>(); | ||
| 93 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 94 | + (ubLoopIdx <= 1 || | ||
| 95 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 96 | + Ops::Base::BroadcastNddmaWithLoop( | ||
| 97 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 98 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 99 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 100 | + } | ||
| 101 | + queIn1_.EnQue<float>(bufferIn1_); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + __aicore__ inline void Compute2( | ||
| 105 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 106 | + { | ||
| 107 | + bufferIn0_ = queIn0_.DeQue<bfloat16_t>(); | ||
| 108 | + bufferIn1_ = queIn1_.DeQue<float>(); | ||
| 109 | + bufferOut0_ = queOut0_.AllocTensor<float>(); | ||
| 110 | + __VEC_SCOPE__ | ||
| 111 | + { | ||
| 112 | + RegTensor<bfloat16_t> vreg0; | ||
| 113 | + RegTensor<float> vreg1; | ||
| 114 | + RegTensor<float> vreg2; | ||
| 115 | + RegTensor<float> vreg3; | ||
| 116 | + RegTensor<float> vreg4; | ||
| 117 | + RegTensor<float> vreg5; | ||
| 118 | + RegTensor<float> vreg6; | ||
| 119 | + MaskReg preg0; | ||
| 120 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 121 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 122 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 123 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 124 | + __local_mem__ bfloat16_t* bufferIn0Addr = (__local_mem__ bfloat16_t*)bufferIn0_.GetPhyAddr(); | ||
| 125 | + __local_mem__ float* bufferIn1Addr = (__local_mem__ float*)bufferIn1_.GetPhyAddr(); | ||
| 126 | + __local_mem__ float* bufferOut0Addr = (__local_mem__ float*)bufferOut0_.GetPhyAddr(); | ||
| 127 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 128 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 129 | + AscendC::MicroAPI::DataCopy<bfloat16_t, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 130 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 131 | + AscendC::MicroAPI::Cast<float, bfloat16_t, castTrait0>(vreg1, vreg0, preg0); | ||
| 132 | + AscendC::MicroAPI::Duplicate<float, float>(vreg4, 1.0); | ||
| 133 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 134 | + vreg2, vreg1, static_cast<float>(-1), preg0); | ||
| 135 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 136 | + vreg4, vreg2, vreg1, preg0); | ||
| 137 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::LoadDist::DIST_NORM>( | ||
| 138 | + vreg5, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 139 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg6, vreg4, vreg5, preg0); | ||
| 140 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::StoreDist::DIST_NORM_B32>( | ||
| 141 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg6, preg0); | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 145 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 146 | + queOut0_.EnQue<float>(bufferOut0_); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + __aicore__ inline void CopyOut3( | ||
| 150 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 151 | + { | ||
| 152 | + bufferOut0_ = queOut0_.DeQue<float>(); | ||
| 153 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 154 | + dataCopyExtParams.blockCount = 1; | ||
| 155 | + dataCopyExtParams.blockLen = | ||
| 156 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(float); | ||
| 157 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 158 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 159 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 160 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | +private: | ||
| 164 | + TPipe* pipePtr_; | ||
| 165 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 166 | + GlobalTensor<bfloat16_t> inputGmY_; | ||
| 167 | + GlobalTensor<float> inputGmDy_; | ||
| 168 | + GlobalTensor<float> outputGmZ_; | ||
| 169 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 170 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 171 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 172 | + LocalTensor<bfloat16_t> bufferIn0_; | ||
| 173 | + LocalTensor<float> bufferIn1_; | ||
| 174 | + LocalTensor<float> bufferOut0_; | ||
| 175 | + constexpr static AscendC::MicroAPI::CastTrait castTrait0 = { | ||
| 176 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::UNKNOWN, | ||
| 177 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::UNKNOWN}; | ||
| 178 | +}; | ||
| 179 | + | ||
| 180 | +} // namespace TanhGrad | ||
| 181 | + | ||
| @@ -0,0 +1,181 @@ | |||
| 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 tanh_grad_dtype_comb_5_nddma_without_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is bfloat16, dy is float32, z is float32, max dims in ub is 5 and nddma does not need loops | ||
| 31 | +class TanhGradDtypeComb5NddmaWithoutLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradDtypeComb5NddmaWithoutLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ bfloat16_t*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ float*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ float*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(bfloat16_t); | ||
| 44 | + int64_t BUFFER_SIZE_1 = tilingDataPtr_->elemNum * sizeof(float); | ||
| 45 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 46 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 47 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_1); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + __aicore__ inline void Process() | ||
| 51 | + { | ||
| 52 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 53 | + tilingDataPtr_->blockFormer; | ||
| 54 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 55 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 56 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 57 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 58 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 59 | + if (ubLoopIdx != 0) { | ||
| 60 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 61 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 62 | + } | ||
| 63 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 64 | + tilingDataPtr_->ubTail : | ||
| 65 | + tilingDataPtr_->ubFormer; | ||
| 66 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 67 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | +private: | ||
| 74 | + __aicore__ inline void CopyIn0( | ||
| 75 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 76 | + { | ||
| 77 | + bufferIn0_ = queIn0_.AllocTensor<bfloat16_t>(); | ||
| 78 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 79 | + (ubLoopIdx <= 1 || | ||
| 80 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 81 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 82 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 83 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 84 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 85 | + } | ||
| 86 | + queIn0_.EnQue<bfloat16_t>(bufferIn0_); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + __aicore__ inline void CopyIn1( | ||
| 90 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 91 | + { | ||
| 92 | + bufferIn1_ = queIn1_.AllocTensor<float>(); | ||
| 93 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 94 | + (ubLoopIdx <= 1 || | ||
| 95 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 96 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 97 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 98 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 99 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 100 | + } | ||
| 101 | + queIn1_.EnQue<float>(bufferIn1_); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + __aicore__ inline void Compute2( | ||
| 105 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 106 | + { | ||
| 107 | + bufferIn0_ = queIn0_.DeQue<bfloat16_t>(); | ||
| 108 | + bufferIn1_ = queIn1_.DeQue<float>(); | ||
| 109 | + bufferOut0_ = queOut0_.AllocTensor<float>(); | ||
| 110 | + __VEC_SCOPE__ | ||
| 111 | + { | ||
| 112 | + RegTensor<bfloat16_t> vreg0; | ||
| 113 | + RegTensor<float> vreg1; | ||
| 114 | + RegTensor<float> vreg2; | ||
| 115 | + RegTensor<float> vreg3; | ||
| 116 | + RegTensor<float> vreg4; | ||
| 117 | + RegTensor<float> vreg5; | ||
| 118 | + RegTensor<float> vreg6; | ||
| 119 | + MaskReg preg0; | ||
| 120 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 121 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 122 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 123 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 124 | + __local_mem__ bfloat16_t* bufferIn0Addr = (__local_mem__ bfloat16_t*)bufferIn0_.GetPhyAddr(); | ||
| 125 | + __local_mem__ float* bufferIn1Addr = (__local_mem__ float*)bufferIn1_.GetPhyAddr(); | ||
| 126 | + __local_mem__ float* bufferOut0Addr = (__local_mem__ float*)bufferOut0_.GetPhyAddr(); | ||
| 127 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 128 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 129 | + AscendC::MicroAPI::DataCopy<bfloat16_t, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 130 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 131 | + AscendC::MicroAPI::Cast<float, bfloat16_t, castTrait0>(vreg1, vreg0, preg0); | ||
| 132 | + AscendC::MicroAPI::Duplicate<float, float>(vreg4, 1.0); | ||
| 133 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 134 | + vreg2, vreg1, static_cast<float>(-1), preg0); | ||
| 135 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 136 | + vreg4, vreg2, vreg1, preg0); | ||
| 137 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::LoadDist::DIST_NORM>( | ||
| 138 | + vreg5, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 139 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg6, vreg4, vreg5, preg0); | ||
| 140 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::StoreDist::DIST_NORM_B32>( | ||
| 141 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg6, preg0); | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 145 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 146 | + queOut0_.EnQue<float>(bufferOut0_); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + __aicore__ inline void CopyOut3( | ||
| 150 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 151 | + { | ||
| 152 | + bufferOut0_ = queOut0_.DeQue<float>(); | ||
| 153 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 154 | + dataCopyExtParams.blockCount = 1; | ||
| 155 | + dataCopyExtParams.blockLen = | ||
| 156 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(float); | ||
| 157 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 158 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 159 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 160 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | +private: | ||
| 164 | + TPipe* pipePtr_; | ||
| 165 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 166 | + GlobalTensor<bfloat16_t> inputGmY_; | ||
| 167 | + GlobalTensor<float> inputGmDy_; | ||
| 168 | + GlobalTensor<float> outputGmZ_; | ||
| 169 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 170 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 171 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 172 | + LocalTensor<bfloat16_t> bufferIn0_; | ||
| 173 | + LocalTensor<float> bufferIn1_; | ||
| 174 | + LocalTensor<float> bufferOut0_; | ||
| 175 | + constexpr static AscendC::MicroAPI::CastTrait castTrait0 = { | ||
| 176 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::UNKNOWN, | ||
| 177 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::UNKNOWN}; | ||
| 178 | +}; | ||
| 179 | + | ||
| 180 | +} // namespace TanhGrad | ||
| 181 | + | ||
| @@ -0,0 +1,187 @@ | |||
| 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 tanh_grad_f16_nddma_without_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is float16, dy is float16, z is float16, max dims in ub is 5 and nddma does not need loops | ||
| 31 | +class TanhGradF16NddmaWithoutLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradF16NddmaWithoutLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ half*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ half*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ half*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(half); | ||
| 44 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 45 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 46 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + __aicore__ inline void Process() | ||
| 50 | + { | ||
| 51 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 52 | + tilingDataPtr_->blockFormer; | ||
| 53 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 54 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 55 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 56 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 57 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 58 | + if (ubLoopIdx != 0) { | ||
| 59 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 60 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 61 | + } | ||
| 62 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 63 | + tilingDataPtr_->ubTail : | ||
| 64 | + tilingDataPtr_->ubFormer; | ||
| 65 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 66 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 67 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | +private: | ||
| 73 | + __aicore__ inline void CopyIn0( | ||
| 74 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 75 | + { | ||
| 76 | + bufferIn0_ = queIn0_.AllocTensor<half>(); | ||
| 77 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 78 | + (ubLoopIdx <= 1 || | ||
| 79 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 80 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 81 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 82 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 83 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 84 | + } | ||
| 85 | + queIn0_.EnQue<half>(bufferIn0_); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + __aicore__ inline void CopyIn1( | ||
| 89 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 90 | + { | ||
| 91 | + bufferIn1_ = queIn1_.AllocTensor<half>(); | ||
| 92 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 93 | + (ubLoopIdx <= 1 || | ||
| 94 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 95 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 96 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 97 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 98 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 99 | + } | ||
| 100 | + queIn1_.EnQue<half>(bufferIn1_); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + __aicore__ inline void Compute2( | ||
| 104 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 105 | + { | ||
| 106 | + bufferIn0_ = queIn0_.DeQue<half>(); | ||
| 107 | + bufferIn1_ = queIn1_.DeQue<half>(); | ||
| 108 | + bufferOut0_ = queOut0_.AllocTensor<half>(); | ||
| 109 | + __VEC_SCOPE__ | ||
| 110 | + { | ||
| 111 | + RegTensor<half> vreg0; | ||
| 112 | + RegTensor<float> vreg1; | ||
| 113 | + RegTensor<float> vreg2; | ||
| 114 | + RegTensor<float> vreg3; | ||
| 115 | + RegTensor<float> vreg4; | ||
| 116 | + RegTensor<half> vreg5; | ||
| 117 | + RegTensor<float> vreg6; | ||
| 118 | + RegTensor<float> vreg7; | ||
| 119 | + RegTensor<half> vreg8; | ||
| 120 | + MaskReg preg0; | ||
| 121 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 122 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 123 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 124 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 125 | + __local_mem__ half* bufferIn0Addr = (__local_mem__ half*)bufferIn0_.GetPhyAddr(); | ||
| 126 | + __local_mem__ half* bufferIn1Addr = (__local_mem__ half*)bufferIn1_.GetPhyAddr(); | ||
| 127 | + __local_mem__ half* bufferOut0Addr = (__local_mem__ half*)bufferOut0_.GetPhyAddr(); | ||
| 128 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 129 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 130 | + AscendC::MicroAPI::DataCopy<half, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 131 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 132 | + AscendC::MicroAPI::Cast<float, half, castTrait0>(vreg1, vreg0, preg0); | ||
| 133 | + AscendC::MicroAPI::Duplicate<float, float>(vreg4, 1.0); | ||
| 134 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 135 | + vreg2, vreg1, static_cast<float>(-1), preg0); | ||
| 136 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 137 | + vreg4, vreg2, vreg1, preg0); | ||
| 138 | + AscendC::MicroAPI::DataCopy<half, AscendC::MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 139 | + vreg5, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 140 | + AscendC::MicroAPI::Cast<float, half, castTrait0>(vreg6, vreg5, preg0); | ||
| 141 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg7, vreg4, vreg6, preg0); | ||
| 142 | + AscendC::MicroAPI::Cast<half, float, castTrait1>(vreg8, vreg7, preg0); | ||
| 143 | + AscendC::MicroAPI::DataCopy<half, AscendC::MicroAPI::StoreDist::DIST_PACK_B32>( | ||
| 144 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg8, preg0); | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 148 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 149 | + queOut0_.EnQue<half>(bufferOut0_); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + __aicore__ inline void CopyOut3( | ||
| 153 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 154 | + { | ||
| 155 | + bufferOut0_ = queOut0_.DeQue<half>(); | ||
| 156 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 157 | + dataCopyExtParams.blockCount = 1; | ||
| 158 | + dataCopyExtParams.blockLen = | ||
| 159 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(half); | ||
| 160 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 161 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 162 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 163 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | +private: | ||
| 167 | + TPipe* pipePtr_; | ||
| 168 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 169 | + GlobalTensor<half> inputGmY_; | ||
| 170 | + GlobalTensor<half> inputGmDy_; | ||
| 171 | + GlobalTensor<half> outputGmZ_; | ||
| 172 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 173 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 174 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 175 | + LocalTensor<half> bufferIn0_; | ||
| 176 | + LocalTensor<half> bufferIn1_; | ||
| 177 | + LocalTensor<half> bufferOut0_; | ||
| 178 | + constexpr static AscendC::MicroAPI::CastTrait castTrait0 = { | ||
| 179 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::UNKNOWN, | ||
| 180 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::UNKNOWN}; | ||
| 181 | + constexpr static AscendC::MicroAPI::CastTrait castTrait1 = { | ||
| 182 | + AscendC::MicroAPI::RegLayout::ZERO, AscendC::MicroAPI::SatMode::NO_SAT, | ||
| 183 | + AscendC::MicroAPI::MaskMergeMode::ZEROING, AscendC::RoundMode::CAST_RINT}; | ||
| 184 | +}; | ||
| 185 | + | ||
| 186 | +} // namespace TanhGrad | ||
| 187 | + | ||
| @@ -0,0 +1,175 @@ | |||
| 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 tanh_grad_f32_nddma_with_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is float32, dy is float32, z is float32, max dims in ub is 8 and nddma needs loops | ||
| 31 | +class TanhGradF32NddmaWithLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradF32NddmaWithLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ float*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ float*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ float*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(float); | ||
| 44 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 45 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 46 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + __aicore__ inline void Process() | ||
| 50 | + { | ||
| 51 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 52 | + tilingDataPtr_->blockFormer; | ||
| 53 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 54 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 55 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 56 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 57 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 58 | + if (ubLoopIdx != 0) { | ||
| 59 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 60 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 61 | + } | ||
| 62 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 63 | + tilingDataPtr_->ubTail : | ||
| 64 | + tilingDataPtr_->ubFormer; | ||
| 65 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 66 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 67 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | +private: | ||
| 73 | + __aicore__ inline void CopyIn0( | ||
| 74 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 75 | + { | ||
| 76 | + bufferIn0_ = queIn0_.AllocTensor<float>(); | ||
| 77 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 78 | + (ubLoopIdx <= 1 || | ||
| 79 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 80 | + Ops::Base::BroadcastNddmaWithLoop( | ||
| 81 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 82 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 83 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 84 | + } | ||
| 85 | + queIn0_.EnQue<float>(bufferIn0_); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + __aicore__ inline void CopyIn1( | ||
| 89 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 90 | + { | ||
| 91 | + bufferIn1_ = queIn1_.AllocTensor<float>(); | ||
| 92 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 93 | + (ubLoopIdx <= 1 || | ||
| 94 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 95 | + Ops::Base::BroadcastNddmaWithLoop( | ||
| 96 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 97 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 98 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 99 | + } | ||
| 100 | + queIn1_.EnQue<float>(bufferIn1_); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + __aicore__ inline void Compute2( | ||
| 104 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 105 | + { | ||
| 106 | + bufferIn0_ = queIn0_.DeQue<float>(); | ||
| 107 | + bufferIn1_ = queIn1_.DeQue<float>(); | ||
| 108 | + bufferOut0_ = queOut0_.AllocTensor<float>(); | ||
| 109 | + __VEC_SCOPE__ | ||
| 110 | + { | ||
| 111 | + RegTensor<float> vreg0; | ||
| 112 | + RegTensor<float> vreg1; | ||
| 113 | + RegTensor<float> vreg2; | ||
| 114 | + RegTensor<float> vreg3; | ||
| 115 | + RegTensor<float> vreg4; | ||
| 116 | + RegTensor<float> vreg5; | ||
| 117 | + MaskReg preg0; | ||
| 118 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 119 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 120 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 121 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 122 | + __local_mem__ float* bufferIn0Addr = (__local_mem__ float*)bufferIn0_.GetPhyAddr(); | ||
| 123 | + __local_mem__ float* bufferIn1Addr = (__local_mem__ float*)bufferIn1_.GetPhyAddr(); | ||
| 124 | + __local_mem__ float* bufferOut0Addr = (__local_mem__ float*)bufferOut0_.GetPhyAddr(); | ||
| 125 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 126 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 127 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::LoadDist::DIST_NORM>( | ||
| 128 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 129 | + AscendC::MicroAPI::Duplicate<float, float>(vreg3, 1.0); | ||
| 130 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 131 | + vreg2, vreg0, static_cast<float>(-1), preg0); | ||
| 132 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 133 | + vreg3, vreg2, vreg0, preg0); | ||
| 134 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::LoadDist::DIST_NORM>( | ||
| 135 | + vreg4, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 136 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg5, vreg3, vreg4, preg0); | ||
| 137 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::StoreDist::DIST_NORM_B32>( | ||
| 138 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg5, preg0); | ||
| 139 | + } | ||
| 140 | + } | ||
| 141 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 142 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 143 | + queOut0_.EnQue<float>(bufferOut0_); | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + __aicore__ inline void CopyOut3( | ||
| 147 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 148 | + { | ||
| 149 | + bufferOut0_ = queOut0_.DeQue<float>(); | ||
| 150 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 151 | + dataCopyExtParams.blockCount = 1; | ||
| 152 | + dataCopyExtParams.blockLen = | ||
| 153 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(float); | ||
| 154 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 155 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 156 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 157 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | +private: | ||
| 161 | + TPipe* pipePtr_; | ||
| 162 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 163 | + GlobalTensor<float> inputGmY_; | ||
| 164 | + GlobalTensor<float> inputGmDy_; | ||
| 165 | + GlobalTensor<float> outputGmZ_; | ||
| 166 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 167 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 168 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 169 | + LocalTensor<float> bufferIn0_; | ||
| 170 | + LocalTensor<float> bufferIn1_; | ||
| 171 | + LocalTensor<float> bufferOut0_; | ||
| 172 | +}; | ||
| 173 | + | ||
| 174 | +} // namespace TanhGrad | ||
| 175 | + | ||
| @@ -0,0 +1,175 @@ | |||
| 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 tanh_grad_f32_nddma_without_loops.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace TanhGrad { | ||
| 22 | +using AscendC::GlobalTensor; | ||
| 23 | +using AscendC::LocalTensor; | ||
| 24 | +using AscendC::TBuf; | ||
| 25 | +using AscendC::TPipe; | ||
| 26 | +using AscendC::TQue; | ||
| 27 | +using AscendC::MicroAPI::MaskReg; | ||
| 28 | +using AscendC::MicroAPI::RegTensor; | ||
| 29 | + | ||
| 30 | +// y is float32, dy is float32, z is float32, max dims in ub is 5 and nddma does not need loops | ||
| 31 | +class TanhGradF32NddmaWithoutLoops { | ||
| 32 | +public: | ||
| 33 | + __aicore__ inline TanhGradF32NddmaWithoutLoops(){}; | ||
| 34 | + __aicore__ inline void Init( | ||
| 35 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, const TanhGradTilingData* tilingDataPtr, TPipe* pipePtr) | ||
| 36 | + { | ||
| 37 | + pipePtr_ = pipePtr; | ||
| 38 | + tilingDataPtr_ = tilingDataPtr; | ||
| 39 | + inputGmY_.SetGlobalBuffer((__gm__ float*)y); | ||
| 40 | + inputGmDy_.SetGlobalBuffer((__gm__ float*)dy); | ||
| 41 | + outputGmZ_.SetGlobalBuffer((__gm__ float*)z); | ||
| 42 | + constexpr int64_t DOUBLE_BUFFER = 2; | ||
| 43 | + int64_t BUFFER_SIZE_0 = tilingDataPtr_->elemNum * sizeof(float); | ||
| 44 | + pipePtr_->InitBuffer(queIn0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 45 | + pipePtr_->InitBuffer(queIn1_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 46 | + pipePtr_->InitBuffer(queOut0_, DOUBLE_BUFFER, BUFFER_SIZE_0); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + __aicore__ inline void Process() | ||
| 50 | + { | ||
| 51 | + int64_t ubLoopNum = AscendC::GetBlockIdx() == AscendC::GetBlockNum() - 1 ? tilingDataPtr_->blockTail : | ||
| 52 | + tilingDataPtr_->blockFormer; | ||
| 53 | + int64_t axesIndices[Ops::Base::BROADCAST_MAX_DIMS] = {0}; | ||
| 54 | + Ops::Base::BroadcastGetAxesIndices( | ||
| 55 | + axesIndices, tilingDataPtr_->blockFormer * AscendC::GetBlockIdx(), tilingDataPtr_->outputDims, | ||
| 56 | + tilingDataPtr_->ubSplitAxis, tilingDataPtr_->dimProductBeforeUbInner); | ||
| 57 | + for (int64_t ubLoopIdx = 0; ubLoopIdx < ubLoopNum; ubLoopIdx += 1) { | ||
| 58 | + if (ubLoopIdx != 0) { | ||
| 59 | + Ops::Base::BroadcastUpdateAxesIndices( | ||
| 60 | + axesIndices, tilingDataPtr_->outputDims, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubOuter); | ||
| 61 | + } | ||
| 62 | + int64_t ubSplitSize = axesIndices[tilingDataPtr_->ubSplitAxis] == tilingDataPtr_->ubOuter - 1 ? | ||
| 63 | + tilingDataPtr_->ubTail : | ||
| 64 | + tilingDataPtr_->ubFormer; | ||
| 65 | + CopyIn0(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 66 | + CopyIn1(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 67 | + Compute2(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 68 | + CopyOut3(ubSplitSize, axesIndices, ubLoopIdx); | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | +private: | ||
| 73 | + __aicore__ inline void CopyIn0( | ||
| 74 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 75 | + { | ||
| 76 | + bufferIn0_ = queIn0_.AllocTensor<float>(); | ||
| 77 | + if ((tilingDataPtr_->input0Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 78 | + (ubLoopIdx <= 1 || | ||
| 79 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 80 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 81 | + inputGmY_, bufferIn0_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 82 | + tilingDataPtr_->input0Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 83 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 84 | + } | ||
| 85 | + queIn0_.EnQue<float>(bufferIn0_); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + __aicore__ inline void CopyIn1( | ||
| 89 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 90 | + { | ||
| 91 | + bufferIn1_ = queIn1_.AllocTensor<float>(); | ||
| 92 | + if ((tilingDataPtr_->input1Strides[tilingDataPtr_->ubSplitAxis] != 0) || | ||
| 93 | + (ubLoopIdx <= 1 || | ||
| 94 | + (AscendC::GetBlockIdx() * tilingDataPtr_->blockFormer + ubLoopIdx) % tilingDataPtr_->ubOuter <= 1)) { | ||
| 95 | + Ops::Base::BroadcastNddmaWithoutLoop( | ||
| 96 | + inputGmDy_, bufferIn1_, tilingDataPtr_->outputDims, tilingDataPtr_->outputStrides, | ||
| 97 | + tilingDataPtr_->input1Strides, axesIndices, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->shapeLen, | ||
| 98 | + ubSplitSize, tilingDataPtr_->ubFormer); | ||
| 99 | + } | ||
| 100 | + queIn1_.EnQue<float>(bufferIn1_); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + __aicore__ inline void Compute2( | ||
| 104 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 105 | + { | ||
| 106 | + bufferIn0_ = queIn0_.DeQue<float>(); | ||
| 107 | + bufferIn1_ = queIn1_.DeQue<float>(); | ||
| 108 | + bufferOut0_ = queOut0_.AllocTensor<float>(); | ||
| 109 | + __VEC_SCOPE__ | ||
| 110 | + { | ||
| 111 | + RegTensor<float> vreg0; | ||
| 112 | + RegTensor<float> vreg1; | ||
| 113 | + RegTensor<float> vreg2; | ||
| 114 | + RegTensor<float> vreg3; | ||
| 115 | + RegTensor<float> vreg4; | ||
| 116 | + RegTensor<float> vreg5; | ||
| 117 | + MaskReg preg0; | ||
| 118 | + uint32_t size = ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis]; | ||
| 119 | + uint16_t vfLoopNum = (ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] + | ||
| 120 | + (AscendC::VECTOR_REG_WIDTH / 4) - 1) / | ||
| 121 | + (AscendC::VECTOR_REG_WIDTH / 4); | ||
| 122 | + __local_mem__ float* bufferIn0Addr = (__local_mem__ float*)bufferIn0_.GetPhyAddr(); | ||
| 123 | + __local_mem__ float* bufferIn1Addr = (__local_mem__ float*)bufferIn1_.GetPhyAddr(); | ||
| 124 | + __local_mem__ float* bufferOut0Addr = (__local_mem__ float*)bufferOut0_.GetPhyAddr(); | ||
| 125 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 126 | + preg0 = AscendC::MicroAPI::UpdateMask<float>(size); | ||
| 127 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::LoadDist::DIST_NORM>( | ||
| 128 | + vreg0, bufferIn0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 129 | + AscendC::MicroAPI::Duplicate<float, float>(vreg3, 1.0); | ||
| 130 | + AscendC::MicroAPI::Muls<float, float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 131 | + vreg2, vreg0, static_cast<float>(-1), preg0); | ||
| 132 | + AscendC::MicroAPI::MulAddDst<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>( | ||
| 133 | + vreg3, vreg2, vreg0, preg0); | ||
| 134 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::LoadDist::DIST_NORM>( | ||
| 135 | + vreg4, bufferIn1Addr + i * (AscendC::VECTOR_REG_WIDTH / 4)); | ||
| 136 | + AscendC::MicroAPI::Mul<float, AscendC::MicroAPI::MaskMergeMode::ZEROING>(vreg5, vreg3, vreg4, preg0); | ||
| 137 | + AscendC::MicroAPI::DataCopy<float, AscendC::MicroAPI::StoreDist::DIST_NORM_B32>( | ||
| 138 | + bufferOut0Addr + i * (AscendC::VECTOR_REG_WIDTH / 4), vreg5, preg0); | ||
| 139 | + } | ||
| 140 | + } | ||
| 141 | + queIn0_.FreeTensor(bufferIn0_); | ||
| 142 | + queIn1_.FreeTensor(bufferIn1_); | ||
| 143 | + queOut0_.EnQue<float>(bufferOut0_); | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + __aicore__ inline void CopyOut3( | ||
| 147 | + int64_t ubSplitSize, const int64_t (&axesIndices)[Ops::Base::BROADCAST_MAX_DIMS], int64_t ubLoopIdx) | ||
| 148 | + { | ||
| 149 | + bufferOut0_ = queOut0_.DeQue<float>(); | ||
| 150 | + AscendC::DataCopyExtParams dataCopyExtParams; | ||
| 151 | + dataCopyExtParams.blockCount = 1; | ||
| 152 | + dataCopyExtParams.blockLen = | ||
| 153 | + ubSplitSize * tilingDataPtr_->outputStrides[tilingDataPtr_->ubSplitAxis] * sizeof(float); | ||
| 154 | + int64_t gmOffset = Ops::Base::BroadcastGetGmOffset( | ||
| 155 | + axesIndices, tilingDataPtr_->outputStrides, tilingDataPtr_->ubSplitAxis, tilingDataPtr_->ubFormer); | ||
| 156 | + AscendC::DataCopyPad(outputGmZ_[gmOffset], bufferOut0_[0], dataCopyExtParams); | ||
| 157 | + queOut0_.FreeTensor(bufferOut0_); | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | +private: | ||
| 161 | + TPipe* pipePtr_; | ||
| 162 | + const TanhGradTilingData* tilingDataPtr_; | ||
| 163 | + GlobalTensor<float> inputGmY_; | ||
| 164 | + GlobalTensor<float> inputGmDy_; | ||
| 165 | + GlobalTensor<float> outputGmZ_; | ||
| 166 | + TQue<AscendC::QuePosition::VECIN, 1> queIn0_; | ||
| 167 | + TQue<AscendC::QuePosition::VECIN, 1> queIn1_; | ||
| 168 | + TQue<AscendC::QuePosition::VECOUT, 1> queOut0_; | ||
| 169 | + LocalTensor<float> bufferIn0_; | ||
| 170 | + LocalTensor<float> bufferIn1_; | ||
| 171 | + LocalTensor<float> bufferOut0_; | ||
| 172 | +}; | ||
| 173 | + | ||
| 174 | +} // namespace TanhGrad | ||
| 175 | + | ||
| @@ -0,0 +1,173 @@ | |||
| 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 tanh_grad_apt.cpp | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + | ||
| 34 | +using namespace TanhGrad; | ||
| 35 | + | ||
| 36 | +// y is float16, dy is float16, z is float16, max dims in ub is 5 and nddma does not need loops | ||
| 37 | + | ||
| 38 | +// y is float16, dy is float16, z is float16, max dims in ub is 8 and nddma needs loops | ||
| 39 | + | ||
| 40 | +// y is float32, dy is float32, z is float32, max dims in ub is 5 and nddma does not need loops | ||
| 41 | + | ||
| 42 | +// y is float32, dy is float32, z is float32, max dims in ub is 8 and nddma needs loops | ||
| 43 | + | ||
| 44 | +// y is bfloat16, dy is bfloat16, z is bfloat16, max dims in ub is 5 and nddma does not need loops | ||
| 45 | + | ||
| 46 | +// y is bfloat16, dy is bfloat16, z is bfloat16, max dims in ub is 8 and nddma needs loops | ||
| 47 | + | ||
| 48 | +// y is float16, dy is float32, z is float32, max dims in ub is 5 and nddma does not need loops | ||
| 49 | + | ||
| 50 | +// y is float16, dy is float32, z is float32, max dims in ub is 8 and nddma needs loops | ||
| 51 | + | ||
| 52 | +// y is float16, dy is bfloat16, z is float32, max dims in ub is 5 and nddma does not need loops | ||
| 53 | + | ||
| 54 | +// y is float16, dy is bfloat16, z is float32, max dims in ub is 8 and nddma needs loops | ||
| 55 | + | ||
| 56 | +// y is float32, dy is float16, z is float32, max dims in ub is 5 and nddma does not need loops | ||
| 57 | + | ||
| 58 | +// y is float32, dy is float16, z is float32, max dims in ub is 8 and nddma needs loops | ||
| 59 | + | ||
| 60 | +// y is float32, dy is bfloat16, z is float32, max dims in ub is 5 and nddma does not need loops | ||
| 61 | + | ||
| 62 | +// y is float32, dy is bfloat16, z is float32, max dims in ub is 8 and nddma needs loops | ||
| 63 | + | ||
| 64 | +// y is bfloat16, dy is float16, z is float32, max dims in ub is 5 and nddma does not need loops | ||
| 65 | + | ||
| 66 | +// y is bfloat16, dy is float16, z is float32, max dims in ub is 8 and nddma needs loops | ||
| 67 | + | ||
| 68 | +// y is bfloat16, dy is float32, z is float32, max dims in ub is 5 and nddma does not need loops | ||
| 69 | + | ||
| 70 | +// y is bfloat16, dy is float32, z is float32, max dims in ub is 8 and nddma needs loops | ||
| 71 | + | ||
| 72 | + | ||
| 73 | +extern "C" __global__ __aicore__ void tanh_grad(GM_ADDR y, GM_ADDR dy, GM_ADDR z, GM_ADDR workspace, GM_ADDR tiling) | ||
| 74 | +{ | ||
| 75 | + if (g_coreType == AscendC::AIC) { | ||
| 76 | + return; | ||
| 77 | + } | ||
| 78 | + KERNEL_TASK_TYPE_DEFAULT(KERNEL_TYPE_AIV_ONLY); | ||
| 79 | + GET_TILING_DATA(tilingData, tiling); | ||
| 80 | + TPipe tPipe; | ||
| 81 | + if (TILING_KEY_IS(TANH_GRAD_F16_NDDMA_WITHOUT_LOOPS_TILING_KEY)) { | ||
| 82 | + TanhGradF16NddmaWithoutLoops op; | ||
| 83 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 84 | + op.Process(); | ||
| 85 | + return; | ||
| 86 | + } else if (TILING_KEY_IS(TANH_GRAD_F16_NDDMA_WITH_LOOPS_TILING_KEY)) { | ||
| 87 | + TanhGradF16NddmaWithLoops op; | ||
| 88 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 89 | + op.Process(); | ||
| 90 | + return; | ||
| 91 | + } else if (TILING_KEY_IS(TANH_GRAD_F32_NDDMA_WITHOUT_LOOPS_TILING_KEY)) { | ||
| 92 | + TanhGradF32NddmaWithoutLoops op; | ||
| 93 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 94 | + op.Process(); | ||
| 95 | + return; | ||
| 96 | + } else if (TILING_KEY_IS(TANH_GRAD_F32_NDDMA_WITH_LOOPS_TILING_KEY)) { | ||
| 97 | + TanhGradF32NddmaWithLoops op; | ||
| 98 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 99 | + op.Process(); | ||
| 100 | + return; | ||
| 101 | + } else if (TILING_KEY_IS(TANH_GRAD_BF16_NDDMA_WITHOUT_LOOPS_TILING_KEY)) { | ||
| 102 | + TanhGradBf16NddmaWithoutLoops op; | ||
| 103 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 104 | + op.Process(); | ||
| 105 | + return; | ||
| 106 | + } else if (TILING_KEY_IS(TANH_GRAD_BF16_NDDMA_WITH_LOOPS_TILING_KEY)) { | ||
| 107 | + TanhGradBf16NddmaWithLoops op; | ||
| 108 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 109 | + op.Process(); | ||
| 110 | + return; | ||
| 111 | + } else if (TILING_KEY_IS(TANH_GRAD_DTYPE_COMB_0_NDDMA_WITHOUT_LOOPS_TILING_KEY)) { | ||
| 112 | + TanhGradDtypeComb0NddmaWithoutLoops op; | ||
| 113 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 114 | + op.Process(); | ||
| 115 | + return; | ||
| 116 | + } else if (TILING_KEY_IS(TANH_GRAD_DTYPE_COMB_0_NDDMA_WITH_LOOPS_TILING_KEY)) { | ||
| 117 | + TanhGradDtypeComb0NddmaWithLoops op; | ||
| 118 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 119 | + op.Process(); | ||
| 120 | + return; | ||
| 121 | + } else if (TILING_KEY_IS(TANH_GRAD_DTYPE_COMB_1_NDDMA_WITHOUT_LOOPS_TILING_KEY)) { | ||
| 122 | + TanhGradDtypeComb1NddmaWithoutLoops op; | ||
| 123 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 124 | + op.Process(); | ||
| 125 | + return; | ||
| 126 | + } else if (TILING_KEY_IS(TANH_GRAD_DTYPE_COMB_1_NDDMA_WITH_LOOPS_TILING_KEY)) { | ||
| 127 | + TanhGradDtypeComb1NddmaWithLoops op; | ||
| 128 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 129 | + op.Process(); | ||
| 130 | + return; | ||
| 131 | + } else if (TILING_KEY_IS(TANH_GRAD_DTYPE_COMB_2_NDDMA_WITHOUT_LOOPS_TILING_KEY)) { | ||
| 132 | + TanhGradDtypeComb2NddmaWithoutLoops op; | ||
| 133 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 134 | + op.Process(); | ||
| 135 | + return; | ||
| 136 | + } else if (TILING_KEY_IS(TANH_GRAD_DTYPE_COMB_2_NDDMA_WITH_LOOPS_TILING_KEY)) { | ||
| 137 | + TanhGradDtypeComb2NddmaWithLoops op; | ||
| 138 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 139 | + op.Process(); | ||
| 140 | + return; | ||
| 141 | + } else if (TILING_KEY_IS(TANH_GRAD_DTYPE_COMB_3_NDDMA_WITHOUT_LOOPS_TILING_KEY)) { | ||
| 142 | + TanhGradDtypeComb3NddmaWithoutLoops op; | ||
| 143 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 144 | + op.Process(); | ||
| 145 | + return; | ||
| 146 | + } else if (TILING_KEY_IS(TANH_GRAD_DTYPE_COMB_3_NDDMA_WITH_LOOPS_TILING_KEY)) { | ||
| 147 | + TanhGradDtypeComb3NddmaWithLoops op; | ||
| 148 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 149 | + op.Process(); | ||
| 150 | + return; | ||
| 151 | + } else if (TILING_KEY_IS(TANH_GRAD_DTYPE_COMB_4_NDDMA_WITHOUT_LOOPS_TILING_KEY)) { | ||
| 152 | + TanhGradDtypeComb4NddmaWithoutLoops op; | ||
| 153 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 154 | + op.Process(); | ||
| 155 | + return; | ||
| 156 | + } else if (TILING_KEY_IS(TANH_GRAD_DTYPE_COMB_4_NDDMA_WITH_LOOPS_TILING_KEY)) { | ||
| 157 | + TanhGradDtypeComb4NddmaWithLoops op; | ||
| 158 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 159 | + op.Process(); | ||
| 160 | + return; | ||
| 161 | + } else if (TILING_KEY_IS(TANH_GRAD_DTYPE_COMB_5_NDDMA_WITHOUT_LOOPS_TILING_KEY)) { | ||
| 162 | + TanhGradDtypeComb5NddmaWithoutLoops op; | ||
| 163 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 164 | + op.Process(); | ||
| 165 | + return; | ||
| 166 | + } else if (TILING_KEY_IS(TANH_GRAD_DTYPE_COMB_5_NDDMA_WITH_LOOPS_TILING_KEY)) { | ||
| 167 | + TanhGradDtypeComb5NddmaWithLoops op; | ||
| 168 | + op.Init(y, dy, z, workspace, &tilingData, &tPipe); | ||
| 169 | + op.Process(); | ||
| 170 | + return; | ||
| 171 | + } | ||
| 172 | + return; | ||
| 173 | +} | ||
| @@ -1,13 +1,13 @@ | |||
| 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 | # ---------------------------------------------------------------------------- |
| 10 | + | ||
| 11 | file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | 11 | file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) |
| 12 | foreach(SUB_DIR ${CURRENT_DIRS}) | 12 | foreach(SUB_DIR ${CURRENT_DIRS}) |
| 13 | if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | 13 | if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") |
| @@ -1,11 +1,10 @@ | |||
| 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 | ||
Dmath/tanh_grad/tests/ut/graph_plugin/CMakeLists.txt+0-10
| @@ -1,10 +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 | -# ---------------------------------------------------------------------------- | ||
Dmath/tanh_grad/tests/ut/graph_plugin/fusion_pass/CMakeLists.txt+0-10
| @@ -1,10 +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 | -# ---------------------------------------------------------------------------- | ||
| @@ -1,11 +1,10 @@ | |||
| 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 | ||
| @@ -16,7 +15,6 @@ foreach(SUB_DIR ${CURRENT_DIRS}) | |||
| 16 | endif() | 15 | endif() |
| 17 | endforeach() | 16 | endforeach() |
| 18 | 17 | ||
| 19 | -if(UT_TEST_ALL OR OP_HOST_UT) | 18 | +if(TILING_UT OR PROTO_UT OR OP_API_UT OR (UT_TEST_ALL AND NOT AICPU_ONLY)) |
| 20 | - # add_modules_ut_sources(UT_NAME ${OP_TILING_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}) | 19 | + add_modules_llt_sources(HOSTNAME ${OPTEST_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}) |
| 21 | - # add_modules_ut_sources(UT_NAME ${OP_INFERSHAPE_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}) | ||
| 22 | endif() | 20 | endif() |
| @@ -0,0 +1,49 @@ | |||
| 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 | +using namespace std; | ||
| 18 | +using namespace ge; | ||
| 19 | +using namespace optiling; | ||
| 20 | + | ||
| 21 | +class TanhGradTilingTest : public testing::Test { | ||
| 22 | +protected: | ||
| 23 | + static void SetUpTestCase() | ||
| 24 | + { | ||
| 25 | + std::cout << "TanhGradTilingTest SetUp" << std::endl; | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + static void TearDownTestCase() | ||
| 29 | + { | ||
| 30 | + std::cout << "TanhGradTilingTest TearDown" << std::endl; | ||
| 31 | + } | ||
| 32 | +}; | ||
| 33 | + | ||
| 34 | +TEST_F(TanhGradTilingTest, tanh_grad_tiling_test_001) | ||
| 35 | +{ | ||
| 36 | + gert::StorageShape shape = {{32, 32}, {32, 32}}; | ||
| 37 | + | ||
| 38 | + TanhGradCompileInfo compileInfo = {64, 253952}; | ||
| 39 | + | ||
| 40 | + gert::TilingContextPara tilingContextPara( | ||
| 41 | + "TanhGrad", | ||
| 42 | + {{shape, ge::DT_FLOAT16, ge::FORMAT_ND}, {shape, ge::DT_FLOAT16, ge::FORMAT_ND}}, | ||
| 43 | + {{shape, ge::DT_FLOAT16, ge::FORMAT_ND},}, | ||
| 44 | + &compileInfo); | ||
| 45 | + uint64_t expectTilingKey = 100000001000100; | ||
| 46 | + string expectTilingData = "1 21760 1 1024 1 1 0 1 21760 1024 0 0 0 0 0 0 0 1024 0 0 0 0 0 0 0 1024 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 "; | ||
| 47 | + std::vector<size_t> expectWorkspaces = {32}; | ||
| 48 | + ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces); | ||
| 49 | +} | ||
| @@ -1,14 +1,13 @@ | |||
| 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 | if(UT_TEST_ALL OR OP_API_UT) | 11 | if(UT_TEST_ALL OR OP_API_UT) |
| 13 | - # add_modules_ut_sources(UT_NAME ${OP_API_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}) | 12 | + add_modules_ut_sources(UT_NAME ${OP_API_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}) |
| 14 | endif() | 13 | endif() |
Dmath/tanh_grad/tests/ut/op_host/op_api/test_aclnn_tanh_backward_l0.cpp+0-9
| @@ -1,9 +0,0 @@ | |||
| 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 | - */ | ||
| @@ -1,399 +1,418 @@ | |||
| 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 | -#include "aclnn_tanh_backward.h" | 11 | +#include "../../../op_api/aclnn_tanh_backward.h" |
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | class l2_tanh_backward_test : public testing::Test { | 16 | class l2_tanh_backward_test : public testing::Test { |
| 17 | protected: | 17 | protected: |
| 18 | - static void SetUpTestCase() { | 18 | + static void SetUpTestCase() |
| 19 | - std::cout << "l2_tanh_backward_test SetUp" << std::endl; | 19 | + { |
| 20 | - } | 20 | + std::cout << "l2_tanh_backward_test SetUp" << std::endl; |
| 21 | + } | ||
| 21 | 22 | ||
| 22 | - static void TearDownTestCase() { std::cout << "l2_tanh_backward_test TearDown" << std::endl; } | 23 | + static void TearDownTestCase() |
| 24 | + { | ||
| 25 | + std::cout << "l2_tanh_backward_test TearDown" << std::endl; | ||
| 26 | + } | ||
| 23 | }; | 27 | }; |
| 24 | 28 | ||
| 25 | // 正常场景_float32_nd | 29 | // 正常场景_float32_nd |
| 26 | -TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_nd) { | 30 | +TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_nd) |
| 27 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 31 | +{ |
| 28 | - auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 32 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); |
| 29 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND).Precision(0.0001, 0.0001); | 33 | + auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); |
| 34 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND).Precision(0.0001, 0.0001); | ||
| 30 | 35 | ||
| 31 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 36 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 32 | 37 | ||
| 33 | - uint64_t workspaceSize = 0; | 38 | + uint64_t workspaceSize = 0; |
| 34 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 39 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 35 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | 40 | + EXPECT_EQ(aclRet, ACL_SUCCESS); |
| 36 | } | 41 | } |
| 37 | 42 | ||
| 38 | // 正常场景_float16_nd | 43 | // 正常场景_float16_nd |
| 39 | -TEST_F(l2_tanh_backward_test, normal_dtype_float16_format_nd) { | 44 | +TEST_F(l2_tanh_backward_test, normal_dtype_float16_format_nd) |
| 40 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT16, ACL_FORMAT_ND); | 45 | +{ |
| 41 | - auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT16, ACL_FORMAT_ND); | 46 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT16, ACL_FORMAT_ND); |
| 42 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT16, ACL_FORMAT_ND).Precision(0.0001, 0.0001); | 47 | + auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT16, ACL_FORMAT_ND); |
| 48 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT16, ACL_FORMAT_ND).Precision(0.0001, 0.0001); | ||
| 43 | 49 | ||
| 44 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 50 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 45 | 51 | ||
| 46 | - uint64_t workspaceSize = 0; | 52 | + uint64_t workspaceSize = 0; |
| 47 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 53 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 48 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | 54 | + EXPECT_EQ(aclRet, ACL_SUCCESS); |
| 49 | -} | ||
| 50 | - | ||
| 51 | -// 正常场景_double_nd | ||
| 52 | -TEST_F(l2_tanh_backward_test, normal_dtype_double_format_nd) { | ||
| 53 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_DOUBLE, ACL_FORMAT_ND); | ||
| 54 | - auto outputDesc = TensorDesc({2, 3}, ACL_DOUBLE, ACL_FORMAT_ND); | ||
| 55 | - auto outDesc = TensorDesc({2, 3}, ACL_DOUBLE, ACL_FORMAT_ND).Precision(0.0001, 0.0001); | ||
| 56 | - | ||
| 57 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | ||
| 58 | - | ||
| 59 | - uint64_t workspaceSize = 0; | ||
| 60 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | ||
| 61 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 62 | } | 55 | } |
| 63 | 56 | ||
| 64 | // 不支持场景_complex64_nd | 57 | // 不支持场景_complex64_nd |
| 65 | -TEST_F(l2_tanh_backward_test, normal_dtype_complex64_format_nd) { | 58 | +TEST_F(l2_tanh_backward_test, normal_dtype_complex64_format_nd) |
| 66 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_COMPLEX64, ACL_FORMAT_ND); | 59 | +{ |
| 67 | - auto outputDesc = TensorDesc({2, 3}, ACL_COMPLEX64, ACL_FORMAT_ND); | 60 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_COMPLEX64, ACL_FORMAT_ND); |
| 68 | - auto outDesc = TensorDesc({2, 3}, ACL_COMPLEX64, ACL_FORMAT_ND); | 61 | + auto outputDesc = TensorDesc({2, 3}, ACL_COMPLEX64, ACL_FORMAT_ND); |
| 62 | + auto outDesc = TensorDesc({2, 3}, ACL_COMPLEX64, ACL_FORMAT_ND); | ||
| 69 | 63 | ||
| 70 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 64 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 71 | 65 | ||
| 72 | - uint64_t workspaceSize = 0; | 66 | + uint64_t workspaceSize = 0; |
| 73 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 67 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 74 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 68 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 75 | } | 69 | } |
| 76 | 70 | ||
| 77 | // 不支持场景_complex128_nd | 71 | // 不支持场景_complex128_nd |
| 78 | -TEST_F(l2_tanh_backward_test, normal_dtype_complex128_format_nd) { | 72 | +TEST_F(l2_tanh_backward_test, normal_dtype_complex128_format_nd) |
| 79 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_COMPLEX128, ACL_FORMAT_ND); | 73 | +{ |
| 80 | - auto outputDesc = TensorDesc({2, 3}, ACL_COMPLEX128, ACL_FORMAT_ND); | 74 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_COMPLEX128, ACL_FORMAT_ND); |
| 81 | - auto outDesc = TensorDesc({2, 3}, ACL_COMPLEX128, ACL_FORMAT_ND); | 75 | + auto outputDesc = TensorDesc({2, 3}, ACL_COMPLEX128, ACL_FORMAT_ND); |
| 76 | + auto outDesc = TensorDesc({2, 3}, ACL_COMPLEX128, ACL_FORMAT_ND); | ||
| 82 | 77 | ||
| 83 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 78 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 84 | 79 | ||
| 85 | - uint64_t workspaceSize = 0; | 80 | + uint64_t workspaceSize = 0; |
| 86 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 81 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 87 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 82 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 88 | } | 83 | } |
| 89 | 84 | ||
| 90 | // 不支持场景_uint8_nd | 85 | // 不支持场景_uint8_nd |
| 91 | -TEST_F(l2_tanh_backward_test, abnormal_dtype_uint8_format_nd) { | 86 | +TEST_F(l2_tanh_backward_test, abnormal_dtype_uint8_format_nd) |
| 92 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_UINT8, ACL_FORMAT_ND); | 87 | +{ |
| 93 | - auto outputDesc = TensorDesc({2, 3}, ACL_UINT8, ACL_FORMAT_ND); | 88 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_UINT8, ACL_FORMAT_ND); |
| 94 | - auto outDesc = TensorDesc({2, 3}, ACL_UINT8, ACL_FORMAT_ND); | 89 | + auto outputDesc = TensorDesc({2, 3}, ACL_UINT8, ACL_FORMAT_ND); |
| 90 | + auto outDesc = TensorDesc({2, 3}, ACL_UINT8, ACL_FORMAT_ND); | ||
| 95 | 91 | ||
| 96 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 92 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 97 | 93 | ||
| 98 | - uint64_t workspaceSize = 0; | 94 | + uint64_t workspaceSize = 0; |
| 99 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 95 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 100 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 96 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 101 | } | 97 | } |
| 102 | 98 | ||
| 103 | // 不支持场景_int8_nd | 99 | // 不支持场景_int8_nd |
| 104 | -TEST_F(l2_tanh_backward_test, abnormal_dtype_int8_format_nd) { | 100 | +TEST_F(l2_tanh_backward_test, abnormal_dtype_int8_format_nd) |
| 105 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_INT8, ACL_FORMAT_ND); | 101 | +{ |
| 106 | - auto outputDesc = TensorDesc({2, 3}, ACL_INT8, ACL_FORMAT_ND); | 102 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_INT8, ACL_FORMAT_ND); |
| 107 | - auto outDesc = TensorDesc({2, 3}, ACL_INT8, ACL_FORMAT_ND); | 103 | + auto outputDesc = TensorDesc({2, 3}, ACL_INT8, ACL_FORMAT_ND); |
| 104 | + auto outDesc = TensorDesc({2, 3}, ACL_INT8, ACL_FORMAT_ND); | ||
| 108 | 105 | ||
| 109 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 106 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 110 | 107 | ||
| 111 | - uint64_t workspaceSize = 0; | 108 | + uint64_t workspaceSize = 0; |
| 112 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 109 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 113 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 110 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 114 | } | 111 | } |
| 115 | 112 | ||
| 116 | // 不支持场景_int16_nd | 113 | // 不支持场景_int16_nd |
| 117 | -TEST_F(l2_tanh_backward_test, abnormal_dtype_int16_format_nd) { | 114 | +TEST_F(l2_tanh_backward_test, abnormal_dtype_int16_format_nd) |
| 118 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_INT16, ACL_FORMAT_ND); | 115 | +{ |
| 119 | - auto outputDesc = TensorDesc({2, 3}, ACL_INT16, ACL_FORMAT_ND); | 116 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_INT16, ACL_FORMAT_ND); |
| 120 | - auto outDesc = TensorDesc({2, 3}, ACL_INT16, ACL_FORMAT_ND); | 117 | + auto outputDesc = TensorDesc({2, 3}, ACL_INT16, ACL_FORMAT_ND); |
| 118 | + auto outDesc = TensorDesc({2, 3}, ACL_INT16, ACL_FORMAT_ND); | ||
| 121 | 119 | ||
| 122 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 120 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 123 | 121 | ||
| 124 | - uint64_t workspaceSize = 0; | 122 | + uint64_t workspaceSize = 0; |
| 125 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 123 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 126 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 124 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 127 | } | 125 | } |
| 128 | 126 | ||
| 129 | // 不支持场景_int32_nd | 127 | // 不支持场景_int32_nd |
| 130 | -TEST_F(l2_tanh_backward_test, abnormal_dtype_int32_format_nd) { | 128 | +TEST_F(l2_tanh_backward_test, abnormal_dtype_int32_format_nd) |
| 131 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_INT32, ACL_FORMAT_ND); | 129 | +{ |
| 132 | - auto outputDesc = TensorDesc({2, 3}, ACL_INT32, ACL_FORMAT_ND); | 130 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_INT32, ACL_FORMAT_ND); |
| 133 | - auto outDesc = TensorDesc({2, 3}, ACL_INT32, ACL_FORMAT_ND); | 131 | + auto outputDesc = TensorDesc({2, 3}, ACL_INT32, ACL_FORMAT_ND); |
| 132 | + auto outDesc = TensorDesc({2, 3}, ACL_INT32, ACL_FORMAT_ND); | ||
| 134 | 133 | ||
| 135 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 134 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 136 | 135 | ||
| 137 | - uint64_t workspaceSize = 0; | 136 | + uint64_t workspaceSize = 0; |
| 138 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 137 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 139 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 138 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 140 | } | 139 | } |
| 141 | 140 | ||
| 142 | // 不支持场景_int64_nd | 141 | // 不支持场景_int64_nd |
| 143 | -TEST_F(l2_tanh_backward_test, abnormal_dtype_int64_format_nd) { | 142 | +TEST_F(l2_tanh_backward_test, abnormal_dtype_int64_format_nd) |
| 144 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_INT64, ACL_FORMAT_ND); | 143 | +{ |
| 145 | - auto outputDesc = TensorDesc({2, 3}, ACL_INT64, ACL_FORMAT_ND); | 144 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_INT64, ACL_FORMAT_ND); |
| 146 | - auto outDesc = TensorDesc({2, 3}, ACL_INT64, ACL_FORMAT_ND); | 145 | + auto outputDesc = TensorDesc({2, 3}, ACL_INT64, ACL_FORMAT_ND); |
| 146 | + auto outDesc = TensorDesc({2, 3}, ACL_INT64, ACL_FORMAT_ND); | ||
| 147 | 147 | ||
| 148 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 148 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 149 | 149 | ||
| 150 | - uint64_t workspaceSize = 0; | 150 | + uint64_t workspaceSize = 0; |
| 151 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 151 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 152 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 152 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | // 不支持场景_bool_nd | 155 | // 不支持场景_bool_nd |
| 156 | -TEST_F(l2_tanh_backward_test, abnormal_dtype_bool_format_nd) { | 156 | +TEST_F(l2_tanh_backward_test, abnormal_dtype_bool_format_nd) |
| 157 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_BOOL, ACL_FORMAT_ND); | 157 | +{ |
| 158 | - auto outputDesc = TensorDesc({2, 3}, ACL_BOOL, ACL_FORMAT_ND); | 158 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_BOOL, ACL_FORMAT_ND); |
| 159 | - auto outDesc = TensorDesc({2, 3}, ACL_BOOL, ACL_FORMAT_ND); | 159 | + auto outputDesc = TensorDesc({2, 3}, ACL_BOOL, ACL_FORMAT_ND); |
| 160 | + auto outDesc = TensorDesc({2, 3}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 160 | 161 | ||
| 161 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 162 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 162 | 163 | ||
| 163 | - uint64_t workspaceSize = 0; | 164 | + uint64_t workspaceSize = 0; |
| 164 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 165 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 165 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 166 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | // 正常场景_bfloat16_nd | 169 | // 正常场景_bfloat16_nd |
| 169 | -TEST_F(l2_tanh_backward_test, ascend910B2_normal_dtype_bfloat16_format_nd) { | 170 | +TEST_F(l2_tanh_backward_test, ascend910B2_normal_dtype_bfloat16_format_nd) |
| 170 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_BF16, ACL_FORMAT_ND); | 171 | +{ |
| 171 | - auto outputDesc = TensorDesc({2, 3}, ACL_BF16, ACL_FORMAT_ND); | 172 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_BF16, ACL_FORMAT_ND); |
| 172 | - auto outDesc = TensorDesc({2, 3}, ACL_BF16, ACL_FORMAT_ND); | 173 | + auto outputDesc = TensorDesc({2, 3}, ACL_BF16, ACL_FORMAT_ND); |
| 174 | + auto outDesc = TensorDesc({2, 3}, ACL_BF16, ACL_FORMAT_ND); | ||
| 173 | 175 | ||
| 174 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 176 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 175 | 177 | ||
| 176 | - uint64_t workspaceSize = 0; | 178 | + uint64_t workspaceSize = 0; |
| 177 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 179 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 178 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | 180 | + EXPECT_EQ(aclRet, ACL_SUCCESS); |
| 179 | } | 181 | } |
| 180 | 182 | ||
| 181 | // 正常场景_float32_fractal_nz | 183 | // 正常场景_float32_fractal_nz |
| 182 | -TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_fractal_nz) { | 184 | +TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_fractal_nz) |
| 183 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_FRACTAL_NZ).ValueRange(-2, 2); | 185 | +{ |
| 184 | - auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_FRACTAL_NZ).ValueRange(-2, 2); | 186 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_FRACTAL_NZ).ValueRange(-2, 2); |
| 185 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_FRACTAL_NZ).Precision(0.0001, 0.0001); | 187 | + auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_FRACTAL_NZ).ValueRange(-2, 2); |
| 188 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_FRACTAL_NZ).Precision(0.0001, 0.0001); | ||
| 186 | 189 | ||
| 187 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 190 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 188 | 191 | ||
| 189 | - uint64_t workspaceSize = 0; | 192 | + uint64_t workspaceSize = 0; |
| 190 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 193 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 191 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | 194 | + EXPECT_EQ(aclRet, ACL_SUCCESS); |
| 192 | } | 195 | } |
| 193 | 196 | ||
| 194 | // 正常场景_float32_nc1hwc0 | 197 | // 正常场景_float32_nc1hwc0 |
| 195 | -TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_nc1hwc0) { | 198 | +TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_nc1hwc0) |
| 196 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NC1HWC0).ValueRange(-2, 2); | 199 | +{ |
| 197 | - auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NC1HWC0).ValueRange(-2, 2); | 200 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NC1HWC0).ValueRange(-2, 2); |
| 198 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NC1HWC0).Precision(0.0001, 0.0001); | 201 | + auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NC1HWC0).ValueRange(-2, 2); |
| 202 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NC1HWC0).Precision(0.0001, 0.0001); | ||
| 199 | 203 | ||
| 200 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 204 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 201 | 205 | ||
| 202 | - uint64_t workspaceSize = 0; | 206 | + uint64_t workspaceSize = 0; |
| 203 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 207 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 204 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | 208 | + EXPECT_EQ(aclRet, ACL_SUCCESS); |
| 205 | } | 209 | } |
| 206 | 210 | ||
| 207 | // 正常场景_float32_nhwc | 211 | // 正常场景_float32_nhwc |
| 208 | -TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_nhwc) { | 212 | +TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_nhwc) |
| 209 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NHWC).ValueRange(-2, 2); | 213 | +{ |
| 210 | - auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NHWC).ValueRange(-2, 2); | 214 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NHWC).ValueRange(-2, 2); |
| 211 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NHWC).Precision(0.0001, 0.0001); | 215 | + auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NHWC).ValueRange(-2, 2); |
| 216 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NHWC).Precision(0.0001, 0.0001); | ||
| 212 | 217 | ||
| 213 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 218 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 214 | 219 | ||
| 215 | - uint64_t workspaceSize = 0; | 220 | + uint64_t workspaceSize = 0; |
| 216 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 221 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 217 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | 222 | + EXPECT_EQ(aclRet, ACL_SUCCESS); |
| 218 | } | 223 | } |
| 219 | 224 | ||
| 220 | // 正常场景_float32_nchw | 225 | // 正常场景_float32_nchw |
| 221 | -TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_nchw) { | 226 | +TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_nchw) |
| 222 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NCHW).ValueRange(-2, 2); | 227 | +{ |
| 223 | - auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NCHW).ValueRange(-2, 2); | 228 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NCHW).ValueRange(-2, 2); |
| 224 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NCHW).Precision(0.0001, 0.0001); | 229 | + auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NCHW).ValueRange(-2, 2); |
| 230 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NCHW).Precision(0.0001, 0.0001); | ||
| 225 | 231 | ||
| 226 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 232 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 227 | 233 | ||
| 228 | - uint64_t workspaceSize = 0; | 234 | + uint64_t workspaceSize = 0; |
| 229 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 235 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 230 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | 236 | + EXPECT_EQ(aclRet, ACL_SUCCESS); |
| 231 | } | 237 | } |
| 232 | 238 | ||
| 233 | // 正常场景_float32_hwcn | 239 | // 正常场景_float32_hwcn |
| 234 | -TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_hwcn) { | 240 | +TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_hwcn) |
| 235 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_HWCN).ValueRange(-2, 2); | 241 | +{ |
| 236 | - auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_HWCN).ValueRange(-2, 2); | 242 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_HWCN).ValueRange(-2, 2); |
| 237 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_HWCN).Precision(0.0001, 0.0001); | 243 | + auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_HWCN).ValueRange(-2, 2); |
| 244 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_HWCN).Precision(0.0001, 0.0001); | ||
| 238 | 245 | ||
| 239 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 246 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 240 | 247 | ||
| 241 | - uint64_t workspaceSize = 0; | 248 | + uint64_t workspaceSize = 0; |
| 242 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 249 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 243 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | 250 | + EXPECT_EQ(aclRet, ACL_SUCCESS); |
| 244 | } | 251 | } |
| 245 | 252 | ||
| 246 | // 正常场景_float32_ncdhw | 253 | // 正常场景_float32_ncdhw |
| 247 | -TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_ncdhw) { | 254 | +TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_ncdhw) |
| 248 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NCDHW).ValueRange(-2, 2); | 255 | +{ |
| 249 | - auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NCDHW).ValueRange(-2, 2); | 256 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NCDHW).ValueRange(-2, 2); |
| 250 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NCDHW).Precision(0.0001, 0.0001); | 257 | + auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NCDHW).ValueRange(-2, 2); |
| 258 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NCDHW).Precision(0.0001, 0.0001); | ||
| 251 | 259 | ||
| 252 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 260 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 253 | 261 | ||
| 254 | - uint64_t workspaceSize = 0; | 262 | + uint64_t workspaceSize = 0; |
| 255 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 263 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 256 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | 264 | + EXPECT_EQ(aclRet, ACL_SUCCESS); |
| 257 | } | 265 | } |
| 258 | 266 | ||
| 259 | // 正常场景_float32_ndhwc | 267 | // 正常场景_float32_ndhwc |
| 260 | -TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_ndhwc) { | 268 | +TEST_F(l2_tanh_backward_test, normal_dtype_float32_format_ndhwc) |
| 261 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NDHWC).ValueRange(-2, 2); | 269 | +{ |
| 262 | - auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NDHWC).ValueRange(-2, 2); | 270 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NDHWC).ValueRange(-2, 2); |
| 263 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NDHWC).Precision(0.0001, 0.0001); | 271 | + auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NDHWC).ValueRange(-2, 2); |
| 272 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NDHWC).Precision(0.0001, 0.0001); | ||
| 264 | 273 | ||
| 265 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 274 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 266 | 275 | ||
| 267 | - uint64_t workspaceSize = 0; | 276 | + uint64_t workspaceSize = 0; |
| 268 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 277 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 269 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | 278 | + EXPECT_EQ(aclRet, ACL_SUCCESS); |
| 270 | } | 279 | } |
| 271 | 280 | ||
| 272 | // 空tensor场景 | 281 | // 空tensor场景 |
| 273 | -TEST_F(l2_tanh_backward_test, normal_empty_tensor) { | 282 | +TEST_F(l2_tanh_backward_test, normal_empty_tensor) |
| 274 | - auto gradOutputDesc = TensorDesc({0, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 283 | +{ |
| 275 | - auto outputDesc = TensorDesc({0, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 284 | + auto gradOutputDesc = TensorDesc({0, 3}, ACL_FLOAT, ACL_FORMAT_ND); |
| 276 | - auto outDesc = TensorDesc({0, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 285 | + auto outputDesc = TensorDesc({0, 3}, ACL_FLOAT, ACL_FORMAT_ND); |
| 286 | + auto outDesc = TensorDesc({0, 3}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 277 | 287 | ||
| 278 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 288 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 279 | 289 | ||
| 280 | - uint64_t workspaceSize = 0; | 290 | + uint64_t workspaceSize = 0; |
| 281 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 291 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 282 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | 292 | + EXPECT_EQ(aclRet, ACL_SUCCESS); |
| 283 | } | 293 | } |
| 284 | 294 | ||
| 285 | // CheckNotNull_1 | 295 | // CheckNotNull_1 |
| 286 | -TEST_F(l2_tanh_backward_test, abnormal_grad_output_nullptr) { | 296 | +TEST_F(l2_tanh_backward_test, abnormal_grad_output_nullptr) |
| 287 | - auto gradOutputDesc = nullptr; | 297 | +{ |
| 288 | - auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 298 | + auto gradOutputDesc = nullptr; |
| 289 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 299 | + auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); |
| 300 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 290 | 301 | ||
| 291 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 302 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 292 | 303 | ||
| 293 | - uint64_t workspaceSize = 0; | 304 | + uint64_t workspaceSize = 0; |
| 294 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 305 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 295 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_NULLPTR); | 306 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_NULLPTR); |
| 296 | } | 307 | } |
| 297 | 308 | ||
| 298 | // CheckNotNull_2 | 309 | // CheckNotNull_2 |
| 299 | -TEST_F(l2_tanh_backward_test, abnormal_output_nullptr) { | 310 | +TEST_F(l2_tanh_backward_test, abnormal_output_nullptr) |
| 300 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 311 | +{ |
| 301 | - auto outputDesc = nullptr; | 312 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); |
| 302 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 313 | + auto outputDesc = nullptr; |
| 314 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 303 | 315 | ||
| 304 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 316 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 305 | 317 | ||
| 306 | - uint64_t workspaceSize = 0; | 318 | + uint64_t workspaceSize = 0; |
| 307 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 319 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 308 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_NULLPTR); | 320 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_NULLPTR); |
| 309 | } | 321 | } |
| 310 | 322 | ||
| 311 | // CheckNotNull_3 | 323 | // CheckNotNull_3 |
| 312 | -TEST_F(l2_tanh_backward_test, abnormal_grad_input_nullptr) { | 324 | +TEST_F(l2_tanh_backward_test, abnormal_grad_input_nullptr) |
| 313 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 325 | +{ |
| 314 | - auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 326 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); |
| 315 | - auto outDesc = nullptr; | 327 | + auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); |
| 328 | + auto outDesc = nullptr; | ||
| 316 | 329 | ||
| 317 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 330 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 318 | 331 | ||
| 319 | - uint64_t workspaceSize = 0; | 332 | + uint64_t workspaceSize = 0; |
| 320 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 333 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 321 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_NULLPTR); | 334 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_NULLPTR); |
| 322 | } | 335 | } |
| 323 | 336 | ||
| 324 | // CheckDtypeValid_1 | 337 | // CheckDtypeValid_1 |
| 325 | -TEST_F(l2_tanh_backward_test, abnormal_dtype_grad_output_int64) { | 338 | +TEST_F(l2_tanh_backward_test, abnormal_dtype_grad_output_int64) |
| 326 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_INT64, ACL_FORMAT_ND); | 339 | +{ |
| 327 | - auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 340 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_INT64, ACL_FORMAT_ND); |
| 328 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 341 | + auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); |
| 342 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 329 | 343 | ||
| 330 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 344 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 331 | 345 | ||
| 332 | - uint64_t workspaceSize = 0; | 346 | + uint64_t workspaceSize = 0; |
| 333 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 347 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 334 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 348 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 335 | } | 349 | } |
| 336 | 350 | ||
| 337 | // CheckDtypeValid_2 | 351 | // CheckDtypeValid_2 |
| 338 | -TEST_F(l2_tanh_backward_test, abnormal_dtype_output_int64) { | 352 | +TEST_F(l2_tanh_backward_test, abnormal_dtype_output_int64) |
| 339 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 353 | +{ |
| 340 | - auto outputDesc = TensorDesc({2, 3}, ACL_INT64, ACL_FORMAT_ND); | 354 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); |
| 341 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 355 | + auto outputDesc = TensorDesc({2, 3}, ACL_INT64, ACL_FORMAT_ND); |
| 356 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 342 | 357 | ||
| 343 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 358 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 344 | 359 | ||
| 345 | - uint64_t workspaceSize = 0; | 360 | + uint64_t workspaceSize = 0; |
| 346 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 361 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 347 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 362 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 348 | } | 363 | } |
| 349 | 364 | ||
| 350 | // CheckDtypeValid_3 | 365 | // CheckDtypeValid_3 |
| 351 | -TEST_F(l2_tanh_backward_test, abnormal_dtype_grad_output_output_unequal) { | 366 | +TEST_F(l2_tanh_backward_test, abnormal_dtype_grad_output_output_unequal) |
| 352 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 367 | +{ |
| 353 | - auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT16, ACL_FORMAT_ND); | 368 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); |
| 354 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 369 | + auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT16, ACL_FORMAT_ND); |
| 370 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 355 | 371 | ||
| 356 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 372 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 357 | 373 | ||
| 358 | - uint64_t workspaceSize = 0; | 374 | + uint64_t workspaceSize = 0; |
| 359 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 375 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 360 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 376 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 361 | } | 377 | } |
| 362 | 378 | ||
| 363 | // CheckShape_1 | 379 | // CheckShape_1 |
| 364 | -TEST_F(l2_tanh_backward_test, abnormal_shape_grad_output_output_unequal) { | 380 | +TEST_F(l2_tanh_backward_test, abnormal_shape_grad_output_output_unequal) |
| 365 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 381 | +{ |
| 366 | - auto outputDesc = TensorDesc({1, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 382 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); |
| 367 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | 383 | + auto outputDesc = TensorDesc({1, 3}, ACL_FLOAT, ACL_FORMAT_ND); |
| 384 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 368 | 385 | ||
| 369 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 386 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 370 | 387 | ||
| 371 | - uint64_t workspaceSize = 0; | 388 | + uint64_t workspaceSize = 0; |
| 372 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 389 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 373 | - // EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 390 | + // EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 374 | } | 391 | } |
| 375 | 392 | ||
| 376 | // CheckShape_2 | 393 | // CheckShape_2 |
| 377 | -TEST_F(l2_tanh_backward_test, abnormal_shape_dim_greater_than_threshold) { | 394 | +TEST_F(l2_tanh_backward_test, abnormal_shape_dim_greater_than_threshold) |
| 378 | - auto gradOutputDesc = TensorDesc({7, 9, 11, 3, 4, 6, 9, 2, 2}, ACL_FLOAT, ACL_FORMAT_ND); | 395 | +{ |
| 379 | - auto outputDesc = TensorDesc({7, 9, 11, 3, 4, 6, 9, 2, 2}, ACL_FLOAT, ACL_FORMAT_ND); | 396 | + auto gradOutputDesc = TensorDesc({7, 9, 11, 3, 4, 6, 9, 2, 2}, ACL_FLOAT, ACL_FORMAT_ND); |
| 380 | - auto outDesc = TensorDesc({7, 9, 11, 3, 4, 6, 9, 2, 2}, ACL_FLOAT, ACL_FORMAT_ND); | 397 | + auto outputDesc = TensorDesc({7, 9, 11, 3, 4, 6, 9, 2, 2}, ACL_FLOAT, ACL_FORMAT_ND); |
| 398 | + auto outDesc = TensorDesc({7, 9, 11, 3, 4, 6, 9, 2, 2}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 381 | 399 | ||
| 382 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 400 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 383 | 401 | ||
| 384 | - uint64_t workspaceSize = 0; | 402 | + uint64_t workspaceSize = 0; |
| 385 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 403 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 386 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 404 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 387 | } | 405 | } |
| 388 | 406 | ||
| 389 | -TEST_F(l2_tanh_backward_test, Ascend910_9589_normal_dtype_float32_format_ndhwc) { | 407 | +TEST_F(l2_tanh_backward_test, Ascend910_9589_normal_dtype_float32_format_ndhwc) |
| 390 | - auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NDHWC).ValueRange(-2, 2); | 408 | +{ |
| 391 | - auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NDHWC).ValueRange(-2, 2); | 409 | + auto gradOutputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NDHWC).ValueRange(-2, 2); |
| 392 | - auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NDHWC).Precision(0.0001, 0.0001); | 410 | + auto outputDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NDHWC).ValueRange(-2, 2); |
| 411 | + auto outDesc = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_NDHWC).Precision(0.0001, 0.0001); | ||
| 393 | 412 | ||
| 394 | - auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); | 413 | + auto ut = OP_API_UT(aclnnTanhBackward, INPUT(gradOutputDesc, outputDesc), OUTPUT(outDesc)); |
| 395 | 414 | ||
| 396 | - uint64_t workspaceSize = 0; | 415 | + uint64_t workspaceSize = 0; |
| 397 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); | 416 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize); |
| 398 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | 417 | + EXPECT_EQ(aclRet, ACL_SUCCESS); |
| 399 | } | 418 | } |
| @@ -0,0 +1,39 @@ | |||
| 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 | +class TanhGradInfershapeTest : public testing::Test { | ||
| 18 | + protected: | ||
| 19 | + static void SetUpTestCase() { | ||
| 20 | + std::cout << "TanhGradInfershapeTest SetUp" << std::endl; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + static void TearDownTestCase() { | ||
| 24 | + std::cout << "TanhGradInfershapeTest TearDown" << std::endl; | ||
| 25 | + } | ||
| 26 | +}; | ||
| 27 | + | ||
| 28 | +TEST_F(TanhGradInfershapeTest, tanh_grad_infershape_test_01) | ||
| 29 | +{ | ||
| 30 | + gert::StorageShape shape = {{32, 32}, {32, 32}}; | ||
| 31 | + | ||
| 32 | + gert::InfershapeContextPara infershapeContextPara( | ||
| 33 | + "TanhGrad", | ||
| 34 | + {{shape, ge::DT_FLOAT, ge::FORMAT_ND}, {shape, ge::DT_FLOAT, ge::FORMAT_ND}}, | ||
| 35 | + {{{{-2}, {-2}}, ge::DT_FLOAT, ge::FORMAT_ND}}); | ||
| 36 | + | ||
| 37 | + std::vector<std::vector<int64_t>> expectOutputShape = {{32, 32}}; | ||
| 38 | + ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape); | ||
| 39 | +} | ||
Dmath/tanh_grad/tests/ut/op_kernel/CMakeLists.txt+0-17
| @@ -1,17 +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 | -file(GLOB CURRENT_SOURCE_DIRS LIST_DIRECTORIES true ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 13 | -foreach(SUB_DIR ${CURRENT_SOURCE_DIRS}) | ||
| 14 | - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 15 | - add_subdirectory(${SUB_DIR}) | ||
| 16 | - endif() | ||
| 17 | -endforeach() | ||


代码结构与可维护性: GetOpKey函数使用了大量重复的模式化代码来判断数据类型组合,代码冗长且难以维护。当需要新增数据类型组合时,需要添加新的条件判断,容易出错。
问题类型: 代码结构与可维护性 文件路径:
math/tanh_grad/op_host/arch35/tanh_grad_tiling_arch35.cpp行号: 55 问题代码:bool opKey1Flag = yDtype == DT_FLOAT16 && dyDtype == DT_FLOAT16 && zDtype == DT_FLOAT16; if (opKey1Flag) { return OP_KEY_1; }修改建议:
此评论由代码审查工具自动生成