已合并
[CANNBOT]ascosh_grad适配Ascend950 Ascendc开发 #3254
wangweidong创建于 6月10日
[CANNBOT]ascosh_grad适配Ascend950 Ascendc开发 #3254
已合并
共 20 个文件变更+1967-0
| @@ -65,6 +65,16 @@ | |||
| 65 | <td>×</td> | 65 | <td>×</td> |
| 66 | <td>AI CORE/AI CPU</td> | 66 | <td>AI CORE/AI CPU</td> |
| 67 | <td>该算子暂无Ascend C代码实现,欢迎开发者补充贡献,贡献方式参考<a href="../../CONTRIBUTING.md">贡献指南</a>。</td> | 67 | <td>该算子暂无Ascend C代码实现,欢迎开发者补充贡献,贡献方式参考<a href="../../CONTRIBUTING.md">贡献指南</a>。</td> |
| 68 | + </tr> | ||
| 69 | + <tr> | ||
| 70 | + <td>math</td> | ||
| 71 | + <td><a href="../../math/acosh_grad/README.md">acosh_grad</a></td> | ||
| 72 | + <td>√</td> | ||
| 73 | + <td>√</td> | ||
| 74 | + <td>×</td> | ||
陈 | |||
| 75 | + <td>√</td> | ||
| 76 | + <td>AI CORE</td> | ||
| 77 | + <td>计算Acosh算子的反向梯度,公式 z = dy / sqrt(y² - 1)。</td> | ||
| 68 | </tr> | 78 | </tr> |
| 69 | <tr> | 79 | <tr> |
| 70 | <td>math</td> | 80 | <td>math</td> |
| @@ -0,0 +1,16 @@ | |||
| 1 | +# ---------------------------------------------------------------------------- | ||
| 2 | +# Copyright (c) 2026 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 | +# Generated By CANNBot | ||
| 11 | + | ||
| 12 | +# 设置算子定义时支持的芯片类型 | ||
| 13 | +set(SUPPORT_COMPUTE_UNIT "ascend950") | ||
| 14 | +# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译 | ||
| 15 | +set(SUPPORT_TILING_DIR "arch35") | ||
| 16 | +add_all_modules_sources(OPTYPE acosh_grad ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE) | ||
| @@ -0,0 +1,78 @@ | |||
| 1 | +# AcoshGrad | ||
| 2 | + | ||
| 3 | +## 产品支持情况 | ||
| 4 | + | ||
| 5 | +| 产品 | 是否支持 | | ||
| 6 | +| :----------------------------------------------------------- | :------: | | ||
| 7 | +| <term>Ascend 950PR/Ascend 950DT</term> | √ | | ||
| 8 | +| <term>Atlas A3训练系列产品/Atlas A3推理系列产品</term> | √ | | ||
| 9 | +| <term>Atlas A2训练系列产品/Atlas A2推理系列产品</term> | √ | | ||
| 10 | +| <term>Atlas 200I/500 A2推理产品</term> | × | | ||
| 11 | +| <term>Atlas推理系列产品</term> | √ | | ||
| 12 | +| <term>Atlas训练系列产品</term> | √ | | ||
| 13 | + | ||
| 14 | +## 功能说明 | ||
| 15 | + | ||
| 16 | +- 算子功能:计算Acosh(反双曲余弦)算子的反向梯度。 | ||
| 17 | +- 算子公式:$$ | ||
| 18 | + z_i = dy_i \cdot \dfrac{1}{\sqrt{y_i^2 - 1}} | ||
| 19 | + $$其中: | ||
| 20 | + - $y_i$为前向Acosh算子的输入张量,值域期望$\geq 1$; | ||
| 21 | + - $dy_i$为上游传入的梯度; | ||
| 22 | + - $z_i$为对原始输入张量的梯度,等于上游梯度乘以$1/\sqrt{y_i^2 - 1}$。 | ||
| 23 | + | ||
| 24 | +- 边界($y_i \leq 1$):$y_i = 1$时$\sqrt{0}=0$,除零结果为$+\text{Inf}$;$y_i < 1$时$\sqrt{负数}$结果为NaN,按IEEE 754自然传播。建议输入$y$的值域落在$[1, +\infty)$,以避免产生Inf或NaN结果。 | ||
| 25 | + | ||
| 26 | +## 参数说明 | ||
| 27 | + | ||
| 28 | +<table style="undefined;table-layout: fixed; width: 1576px"><colgroup> | ||
| 29 | + <col style="width: 170px"> | ||
| 30 | + <col style="width: 170px"> | ||
| 31 | + <col style="width: 310px"> | ||
| 32 | + <col style="width: 212px"> | ||
| 33 | + <col style="width: 100px"> | ||
| 34 | + </colgroup> | ||
| 35 | + <thead> | ||
| 36 | + <tr> | ||
| 37 | + <th>参数名</th> | ||
| 38 | + <th>输入/输出/属性</th> | ||
| 39 | + <th>描述</th> | ||
| 40 | + <th>数据类型</th> | ||
| 41 | + <th>数据格式</th> | ||
| 42 | + </tr></thead> | ||
| 43 | + <tbody> | ||
| 44 | + <tr> | ||
| 45 | + <td>y</td> | ||
| 46 | + <td>输入</td> | ||
| 47 | + <td>前向Acosh算子的输入张量。值域期望落在[1, +∞)。</td> | ||
| 48 | + <td>FLOAT16, FLOAT32, BFLOAT16</td> | ||
| 49 | + <td>ND</td> | ||
| 50 | + </tr> | ||
| 51 | + <tr> | ||
| 52 | + <td>dy</td> | ||
| 53 | + <td>输入</td> | ||
| 54 | + <td>上游传入的梯度张量,shape与dtype与y一致。</td> | ||
| 55 | + <td>FLOAT16, FLOAT32, BFLOAT16</td> | ||
| 56 | + <td>ND</td> | ||
| 57 | + </tr> | ||
| 58 | + <tr> | ||
| 59 | + <td>z</td> | ||
| 60 | + <td>输出</td> | ||
| 61 | + <td>对原始输入张量的梯度,shape与dtype与y一致。</td> | ||
| 62 | + <td>FLOAT16, FLOAT32, BFLOAT16</td> | ||
| 63 | + <td>ND</td> | ||
| 64 | + </tr> | ||
| 65 | + </tbody></table> | ||
| 66 | + | ||
| 67 | +## 约束说明 | ||
| 68 | + | ||
| 69 | +- y与dy的shape必须完全一致。 | ||
| 70 | +- y与dy的dtype必须完全一致。 | ||
| 71 | +- 仅支持ND格式。 | ||
| 72 | +- 支持[非连续的Tensor](../../docs/zh/context/非连续的Tensor.md),非连续的Tensor维度不大于8。 | ||
| 73 | + | ||
| 74 | +## 调用说明 | ||
| 75 | + | ||
| 76 | +| 调用方式 | 调用样例 | 说明 | | ||
| 77 | +| -------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | | ||
| 78 | +| 图模式调用 | [test_geir_acosh_grad](./examples/test_geir_acosh_grad.cpp) | 通过[算子IR](./op_graph/acosh_grad_proto.h) 构图方式调用AcoshGrad算子。 | | ||
| @@ -0,0 +1,327 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | + * Generated By CANNBot | ||
| 11 | + */ | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + | ||
| 34 | + | ||
| 35 | + | ||
| 36 | + | ||
| 37 | +using namespace ge; | ||
| 38 | +using std::map; | ||
| 39 | +using std::string; | ||
| 40 | +using std::vector; | ||
| 41 | + | ||
| 42 | + vector<int64_t> placeholder##intputIndex##_shape = inputShape; \ | ||
| 43 | + auto placeholder##intputIndex = op::Data("placeholder" + intputIndex).set_attr_index(0); \ | ||
| 44 | + TensorDesc placeholder##intputIndex##_desc = \ | ||
| 45 | + TensorDesc(ge::Shape(placeholder##intputIndex##_shape), FORMAT_ND, intputDtype); \ | ||
| 46 | + placeholder##intputIndex##_desc.SetPlacement(ge::kPlacementHost); \ | ||
| 47 | + placeholder##intputIndex##_desc.SetFormat(FORMAT_ND); \ | ||
| 48 | + Tensor tensor_placeholder##intputIndex; \ | ||
| 49 | + ret = GenOnesData(placeholder##intputIndex##_shape, \ | ||
| 50 | + tensor_placeholder##intputIndex, \ | ||
| 51 | + placeholder##intputIndex##_desc, \ | ||
| 52 | + intputDtype, \ | ||
| 53 | + 2); \ | ||
| 54 | + if (ret != SUCCESS) { \ | ||
| 55 | + printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \ | ||
| 56 | + return FAILED; \ | ||
| 57 | + } \ | ||
| 58 | + placeholder##intputIndex.update_input_desc_x(placeholder##intputIndex##_desc); \ | ||
| 59 | + input.push_back(tensor_placeholder##intputIndex); \ | ||
| 60 | + graph.AddOp(placeholder##intputIndex); \ | ||
| 61 | + acoshGrad.set_input_##intputName(placeholder##intputIndex); \ | ||
| 62 | + inputs.push_back(placeholder##intputIndex) | ||
| 63 | + | ||
| 64 | + | ||
| 65 | + vector<int64_t> placeholder##intputIndex##_shape = inputShape; \ | ||
| 66 | + auto placeholder##intputIndex = op::Const("placeholder" + intputIndex); \ | ||
| 67 | + TensorDesc placeholder##intputIndex##_desc = \ | ||
| 68 | + TensorDesc(ge::Shape(placeholder##intputIndex##_shape), FORMAT_ND, intputDtype); \ | ||
| 69 | + placeholder##intputIndex##_desc.SetPlacement(ge::kPlacementHost); \ | ||
| 70 | + placeholder##intputIndex##_desc.SetFormat(FORMAT_ND); \ | ||
| 71 | + Tensor tensor_placeholder##intputIndex; \ | ||
| 72 | + ret = GenOnesData(placeholder##intputIndex##_shape, \ | ||
| 73 | + tensor_placeholder##intputIndex, \ | ||
| 74 | + placeholder##intputIndex##_desc, \ | ||
| 75 | + intputDtype, \ | ||
| 76 | + 2); \ | ||
| 77 | + if (ret != SUCCESS) { \ | ||
| 78 | + printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \ | ||
| 79 | + return FAILED; \ | ||
| 80 | + } \ | ||
| 81 | + placeholder##intputIndex.SetAttr("value", tensor_placeholder##intputIndex); \ | ||
| 82 | + placeholder##intputIndex.update_output_desc_y(placeholder##intputIndex##_desc); \ | ||
| 83 | + graph.AddOp(placeholder##intputIndex); \ | ||
| 84 | + acoshGrad.set_input_##intputName(placeholder##intputIndex); \ | ||
| 85 | + acoshGrad.update_input_desc_##intputName(placeholder##intputIndex##_desc); \ | ||
| 86 | + inputs.push_back(placeholder##intputIndex) | ||
| 87 | + | ||
| 88 | + | ||
| 89 | + TensorDesc outputName##outputIndex##_desc = \ | ||
| 90 | + TensorDesc(ge::Shape(outputShape), FORMAT_ND, outputDtype); \ | ||
| 91 | + acoshGrad.update_output_desc_##outputName(outputName##outputIndex##_desc) | ||
| 92 | + | ||
| 93 | + | ||
| 94 | + | ||
| 95 | +string GetTime() | ||
| 96 | +{ | ||
| 97 | + time_t timep; | ||
| 98 | + time(&timep); | ||
| 99 | + char tmp[64]; | ||
| 100 | + strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S,000", localtime(&timep)); | ||
| 101 | + return tmp; | ||
| 102 | +} | ||
| 103 | + | ||
| 104 | +uint32_t GetDataTypeSize(DataType dt) | ||
| 105 | +{ | ||
| 106 | + uint32_t dilation = 1; | ||
| 107 | + uint32_t oneByte = 1; | ||
| 108 | + uint32_t twoByte = 2; | ||
| 109 | + uint32_t fourByte = 4; | ||
| 110 | + uint32_t eightByte = 8; | ||
| 111 | + | ||
| 112 | + if (dt == ge::DT_FLOAT) { | ||
| 113 | + dilation = fourByte; | ||
| 114 | + } else if (dt == ge::DT_FLOAT16) { | ||
| 115 | + dilation = twoByte; | ||
| 116 | + } else if (dt == ge::DT_BF16) { | ||
| 117 | + dilation = twoByte; | ||
| 118 | + } else if (dt == ge::DT_INT16) { | ||
| 119 | + dilation = twoByte; | ||
| 120 | + } else if (dt == ge::DT_UINT16) { | ||
| 121 | + dilation = twoByte; | ||
| 122 | + } else if (dt == ge::DT_INT32) { | ||
| 123 | + dilation = fourByte; | ||
| 124 | + } else if (dt == ge::DT_UINT32) { | ||
| 125 | + dilation = fourByte; | ||
| 126 | + } else if (dt == ge::DT_INT64) { | ||
| 127 | + dilation = eightByte; | ||
| 128 | + } else if (dt == ge::DT_UINT64) { | ||
| 129 | + dilation = eightByte; | ||
| 130 | + } else if (dt == ge::DT_INT8) { | ||
| 131 | + dilation = oneByte; | ||
| 132 | + } | ||
| 133 | + return dilation; | ||
| 134 | +} | ||
| 135 | + | ||
| 136 | +int32_t GenOnesData( | ||
| 137 | + vector<int64_t> shapes, Tensor &input_tensor, TensorDesc &input_tensor_desc, DataType data_type, int value) | ||
| 138 | +{ | ||
| 139 | + input_tensor_desc.SetRealDimCnt(shapes.size()); | ||
| 140 | + size_t size = 1; | ||
| 141 | + for (uint32_t i = 0; i < shapes.size(); i++) { | ||
| 142 | + size *= shapes[i]; | ||
| 143 | + } | ||
| 144 | + uint32_t data_len = size * GetDataTypeSize(data_type); | ||
| 145 | + if (data_type == ge::DT_FLOAT) { | ||
| 146 | + float *pData = new (std::nothrow) float[size]; | ||
| 147 | + for (uint32_t i = 0; i < size; ++i) { | ||
| 148 | + *(pData + i) = static_cast<float>(value); | ||
| 149 | + } | ||
| 150 | + input_tensor = Tensor(input_tensor_desc, reinterpret_cast<uint8_t *>(pData), data_len); | ||
| 151 | + return SUCCESS; | ||
| 152 | + } | ||
| 153 | + int32_t *pData = new (std::nothrow) int32_t[size]; | ||
| 154 | + for (uint32_t i = 0; i < size; ++i) { | ||
| 155 | + *(pData + i) = value; | ||
| 156 | + } | ||
| 157 | + input_tensor = Tensor(input_tensor_desc, reinterpret_cast<uint8_t *>(pData), data_len); | ||
| 158 | + return SUCCESS; | ||
| 159 | +} | ||
| 160 | + | ||
| 161 | +int32_t WriteDataToFile(string bin_file, uint64_t data_size, uint8_t *inputData) | ||
| 162 | +{ | ||
| 163 | + FILE *fp = fopen(bin_file.c_str(), "wb"); | ||
| 164 | + fwrite(inputData, sizeof(uint8_t), data_size, fp); | ||
| 165 | + fclose(fp); | ||
| 166 | + return SUCCESS; | ||
| 167 | +} | ||
| 168 | + | ||
| 169 | +int CreateOppInGraph(DataType inDtype, std::vector<ge::Tensor> &input, std::vector<Operator> &inputs, | ||
| 170 | + std::vector<Operator> &outputs, Graph &graph) | ||
| 171 | +{ | ||
| 172 | + Status ret = SUCCESS; | ||
| 173 | + // 自定义代码:添加单算子定义到图中 | ||
| 174 | + auto acoshGrad = op::AcoshGrad("acosh_grad"); | ||
| 175 | + | ||
| 176 | + std::vector<int64_t> yShape = {4, 2}; | ||
| 177 | + ADD_INPUT(1, y, inDtype, yShape); | ||
| 178 | + ADD_INPUT(2, dy, inDtype, yShape); | ||
| 179 | + | ||
| 180 | + ADD_OUTPUT(1, z, inDtype, yShape); | ||
| 181 | + | ||
| 182 | + outputs.push_back(acoshGrad); | ||
| 183 | + // 添加完毕 | ||
| 184 | + return SUCCESS; | ||
| 185 | +} | ||
| 186 | + | ||
| 187 | + | ||
| 188 | +int InitializeAndSetupGraph(Graph& graph, std::vector<ge::Tensor>& input, DataType inDtype) { | ||
| 189 | + printf("%s - INFO - [XIR]: Start to initialize ge using ge global options\n", GetTime().c_str()); | ||
| 190 | + std::map<AscendString, AscendString> global_options = {{"ge.exec.deviceId", "0"}, {"ge.graphRunMode", "1"}}; | ||
| 191 | + Status ret = ge::GEInitialize(global_options); | ||
| 192 | + if (ret != SUCCESS) { | ||
| 193 | + printf("%s - INFO - [XIR]: Initialize ge using ge global options failed\n", GetTime().c_str()); | ||
| 194 | + return FAILED; | ||
| 195 | + } | ||
| 196 | + printf("%s - INFO - [XIR]: Initialize ge using ge global options success\n", GetTime().c_str()); | ||
| 197 | + | ||
| 198 | + std::vector<Operator> inputs{}; | ||
| 199 | + std::vector<Operator> outputs{}; | ||
| 200 | + | ||
| 201 | + ret = CreateOppInGraph(inDtype, input, inputs, outputs, graph); | ||
| 202 | + if (ret != SUCCESS) { | ||
| 203 | + printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str()); | ||
| 204 | + return FAILED; | ||
| 205 | + } | ||
| 206 | + | ||
| 207 | + if (!inputs.empty() && !outputs.empty()) { | ||
| 208 | + graph.SetInputs(inputs).SetOutputs(outputs); | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + return SUCCESS; | ||
| 212 | +} | ||
| 213 | + | ||
| 214 | + | ||
| 215 | +int ExecuteGraph(Graph& graph, std::vector<ge::Tensor>& input, std::vector<ge::Tensor>& output) { | ||
| 216 | + std::map<AscendString, AscendString> build_options = {}; | ||
| 217 | + printf("%s - INFO - [XIR]: Start to create ir session using build options\n", GetTime().c_str()); | ||
| 218 | + ge::Session *session = new Session(build_options); | ||
| 219 | + | ||
| 220 | + if (session == nullptr) { | ||
| 221 | + printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str()); | ||
| 222 | + return FAILED; | ||
| 223 | + } | ||
| 224 | + printf("%s - INFO - [XIR]: Create ir session using build options success\n", GetTime().c_str()); | ||
| 225 | + printf("%s - INFO - [XIR]: Start to add compute graph to ir session\n", GetTime().c_str()); | ||
| 226 | + | ||
| 227 | + std::map<AscendString, AscendString> graph_options = {}; | ||
| 228 | + uint32_t graph_id = 0; | ||
| 229 | + Status ret = session->AddGraph(graph_id, graph, graph_options); | ||
| 230 | + | ||
| 231 | + printf("%s - INFO - [XIR]: Session add ir compute graph to ir session success\n", GetTime().c_str()); | ||
| 232 | + printf("%s - INFO - [XIR]: dump graph to txt\n", GetTime().c_str()); | ||
| 233 | + std::string file_path = "./dump"; | ||
| 234 | + aclgrphDumpGraph(graph, file_path.c_str(), file_path.length()); | ||
| 235 | + printf("%s - INFO - [XIR]: Start to run ir compute graph\n", GetTime().c_str()); | ||
| 236 | + | ||
| 237 | + ret = session->RunGraph(graph_id, input, output); | ||
| 238 | + if (ret != SUCCESS) { | ||
| 239 | + printf("%s - INFO - [XIR]: Run graph failed\n", GetTime().c_str()); | ||
| 240 | + delete session; | ||
| 241 | + GEFinalize(); | ||
| 242 | + return FAILED; | ||
| 243 | + } | ||
| 244 | + printf("%s - INFO - [XIR]: Session run ir compute graph success\n", GetTime().c_str()); | ||
| 245 | + | ||
| 246 | + delete session; | ||
| 247 | + return SUCCESS; | ||
| 248 | +} | ||
| 249 | + | ||
| 250 | +void ProcessIOData(std::vector<ge::Tensor>& input, std::vector<ge::Tensor>& output) { | ||
| 251 | + int input_num = input.size(); | ||
| 252 | + for (int i = 0; i < input_num; i++) { | ||
| 253 | + std::cout << "input " << i << " dtype : " << input[i].GetTensorDesc().GetDataType() << std::endl; | ||
| 254 | + string input_file = "./tc_ge_irrun_test_0009_npu_input_" + std::to_string(i) + ".bin"; | ||
| 255 | + uint8_t *input_data_i = input[i].GetData(); | ||
| 256 | + int64_t input_shape = input[i].GetTensorDesc().GetShape().GetShapeSize(); | ||
| 257 | + std::cout << "this is " << i << "th input, input shape size =" << input_shape << std::endl; | ||
| 258 | + uint32_t data_size = input_shape * GetDataTypeSize(input[i].GetTensorDesc().GetDataType()); | ||
| 259 | + WriteDataToFile((const char *)input_file.c_str(), data_size, input_data_i); | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + int output_num = output.size(); | ||
| 263 | + for (int i = 0; i < output_num; i++) { | ||
| 264 | + std::cout << "output " << i << " dtype : " << output[i].GetTensorDesc().GetDataType() << std::endl; | ||
| 265 | + string output_file = "./tc_ge_irrun_test_0009_npu_output_" + std::to_string(i) + ".bin"; | ||
| 266 | + uint8_t *output_data_i = output[i].GetData(); | ||
| 267 | + int64_t output_shape = output[i].GetTensorDesc().GetShape().GetShapeSize(); | ||
| 268 | + std::cout << "this is " << i << "th output, output shape size =" << output_shape << std::endl; | ||
| 269 | + uint32_t data_size = output_shape * GetDataTypeSize(output[i].GetTensorDesc().GetDataType()); | ||
| 270 | + WriteDataToFile((const char *)output_file.c_str(), data_size, output_data_i); | ||
| 271 | + float* resultData = (float*)output_data_i; | ||
| 272 | + float expected = 2.0f / 1.7320508f; // dy/sqrt(y*y-1) = 2/sqrt(3) | ||
| 273 | + bool allok = true; | ||
| 274 | + for (int64_t j = 0; j < output_shape; j++) { | ||
| 275 | + LOG_PRINT("result[%ld] is: %f (expected %f)\n", j, resultData[j], expected); | ||
| 276 | + if (resultData[j] < expected - 0.01f || resultData[j] > expected + 0.01f) { | ||
| 277 | + allok = false; | ||
| 278 | + } | ||
| 279 | + } | ||
| 280 | + LOG_PRINT("%s - INFO - [XIR]: AcoshGrad precision %s\n", GetTime().c_str(), allok ? "PASS" : "FAIL"); | ||
| 281 | + } | ||
| 282 | +} | ||
| 283 | + | ||
| 284 | + | ||
| 285 | +int main(int argc, char *argv[]) | ||
| 286 | +{ | ||
| 287 | + // 1、创建图对象 | ||
| 288 | + const char *graph_name = "tc_ge_irrun_acosh_grad_test"; | ||
| 289 | + Graph graph(graph_name); | ||
| 290 | + std::vector<ge::Tensor> input; | ||
| 291 | + | ||
| 292 | + std::cout << argv[1] << std::endl; | ||
| 293 | + | ||
| 294 | + DataType inDtype = DT_FLOAT; | ||
| 295 | + | ||
| 296 | + std::cout << inDtype << std::endl; | ||
| 297 | + | ||
| 298 | + // 初始化和设置图 | ||
| 299 | + if (InitializeAndSetupGraph(graph, input, inDtype) != SUCCESS) { | ||
| 300 | + return FAILED; | ||
| 301 | + } | ||
| 302 | + | ||
| 303 | + // 执行图计算 | ||
| 304 | + std::vector<ge::Tensor> output; | ||
| 305 | + if (ExecuteGraph(graph, input, output) != SUCCESS) { | ||
| 306 | + return FAILED; | ||
| 307 | + } | ||
| 308 | + | ||
| 309 | + // 处理输入输出数据 | ||
| 310 | + ProcessIOData(input, output); | ||
| 311 | + | ||
| 312 | + ge::AscendString error_msg = ge::GEGetErrorMsgV2(); | ||
| 313 | + std::string error_str(error_msg.GetString()); | ||
| 314 | + std::cout << "Error message: " << error_str << std::endl; | ||
| 315 | + ge::AscendString warning_msg = ge::GEGetWarningMsgV2(); | ||
| 316 | + std::string warning_str(warning_msg.GetString()); | ||
| 317 | + std::cout << "Warning message: " << warning_str << std::endl; | ||
| 318 | + printf("%s - INFO - [XIR]: Precision is ok\n", GetTime().c_str()); | ||
| 319 | + printf("%s - INFO - [XIR]: Start to finalize ir graph session\n", GetTime().c_str()); | ||
| 320 | + Status ret = ge::GEFinalize(); | ||
| 321 | + if (ret != SUCCESS) { | ||
| 322 | + printf("%s - INFO - [XIR]: Finalize ir graph session failed\n", GetTime().c_str()); | ||
| 323 | + return FAILED; | ||
| 324 | + } | ||
| 325 | + printf("%s - INFO - [XIR]: Finalize ir graph session success\n", GetTime().c_str()); | ||
| 326 | + return SUCCESS; | ||
| 327 | +} | ||
| @@ -0,0 +1,327 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | + * Generated By CANNBot | ||
| 11 | + */ | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + | ||
| 34 | + | ||
| 35 | + | ||
| 36 | + | ||
| 37 | +using namespace ge; | ||
| 38 | +using std::map; | ||
| 39 | +using std::string; | ||
| 40 | +using std::vector; | ||
| 41 | + | ||
| 42 | + vector<int64_t> placeholder##intputIndex##_shape = inputShape; \ | ||
| 43 | + auto placeholder##intputIndex = op::Data("placeholder" + intputIndex).set_attr_index(0); \ | ||
| 44 | + TensorDesc placeholder##intputIndex##_desc = \ | ||
| 45 | + TensorDesc(ge::Shape(placeholder##intputIndex##_shape), FORMAT_ND, intputDtype); \ | ||
| 46 | + placeholder##intputIndex##_desc.SetPlacement(ge::kPlacementHost); \ | ||
| 47 | + placeholder##intputIndex##_desc.SetFormat(FORMAT_ND); \ | ||
| 48 | + Tensor tensor_placeholder##intputIndex; \ | ||
| 49 | + ret = GenOnesData(placeholder##intputIndex##_shape, \ | ||
| 50 | + tensor_placeholder##intputIndex, \ | ||
| 51 | + placeholder##intputIndex##_desc, \ | ||
| 52 | + intputDtype, \ | ||
| 53 | + 2); \ | ||
| 54 | + if (ret != SUCCESS) { \ | ||
| 55 | + printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \ | ||
| 56 | + return FAILED; \ | ||
| 57 | + } \ | ||
| 58 | + placeholder##intputIndex.update_input_desc_x(placeholder##intputIndex##_desc); \ | ||
| 59 | + input.push_back(tensor_placeholder##intputIndex); \ | ||
| 60 | + graph.AddOp(placeholder##intputIndex); \ | ||
| 61 | + acoshGrad.set_input_##intputName(placeholder##intputIndex); \ | ||
| 62 | + inputs.push_back(placeholder##intputIndex) | ||
| 63 | + | ||
| 64 | + | ||
| 65 | + vector<int64_t> placeholder##intputIndex##_shape = inputShape; \ | ||
| 66 | + auto placeholder##intputIndex = op::Const("placeholder" + intputIndex); \ | ||
| 67 | + TensorDesc placeholder##intputIndex##_desc = \ | ||
| 68 | + TensorDesc(ge::Shape(placeholder##intputIndex##_shape), FORMAT_ND, intputDtype); \ | ||
| 69 | + placeholder##intputIndex##_desc.SetPlacement(ge::kPlacementHost); \ | ||
| 70 | + placeholder##intputIndex##_desc.SetFormat(FORMAT_ND); \ | ||
| 71 | + Tensor tensor_placeholder##intputIndex; \ | ||
| 72 | + ret = GenOnesData(placeholder##intputIndex##_shape, \ | ||
| 73 | + tensor_placeholder##intputIndex, \ | ||
| 74 | + placeholder##intputIndex##_desc, \ | ||
| 75 | + intputDtype, \ | ||
| 76 | + 2); \ | ||
| 77 | + if (ret != SUCCESS) { \ | ||
| 78 | + printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \ | ||
| 79 | + return FAILED; \ | ||
| 80 | + } \ | ||
| 81 | + placeholder##intputIndex.SetAttr("value", tensor_placeholder##intputIndex); \ | ||
| 82 | + placeholder##intputIndex.update_output_desc_y(placeholder##intputIndex##_desc); \ | ||
| 83 | + graph.AddOp(placeholder##intputIndex); \ | ||
| 84 | + acoshGrad.set_input_##intputName(placeholder##intputIndex); \ | ||
| 85 | + acoshGrad.update_input_desc_##intputName(placeholder##intputIndex##_desc); \ | ||
| 86 | + inputs.push_back(placeholder##intputIndex) | ||
| 87 | + | ||
| 88 | + | ||
| 89 | + TensorDesc outputName##outputIndex##_desc = \ | ||
| 90 | + TensorDesc(ge::Shape(outputShape), FORMAT_ND, outputDtype); \ | ||
| 91 | + acoshGrad.update_output_desc_##outputName(outputName##outputIndex##_desc) | ||
| 92 | + | ||
| 93 | + | ||
| 94 | + | ||
| 95 | +string GetTime() | ||
| 96 | +{ | ||
| 97 | + time_t timep; | ||
| 98 | + time(&timep); | ||
| 99 | + char tmp[64]; | ||
| 100 | + strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S,000", localtime(&timep)); | ||
| 101 | + return tmp; | ||
| 102 | +} | ||
| 103 | + | ||
| 104 | +uint32_t GetDataTypeSize(DataType dt) | ||
| 105 | +{ | ||
| 106 | + uint32_t dilation = 1; | ||
| 107 | + uint32_t oneByte = 1; | ||
| 108 | + uint32_t twoByte = 2; | ||
| 109 | + uint32_t fourByte = 4; | ||
| 110 | + uint32_t eightByte = 8; | ||
| 111 | + | ||
| 112 | + if (dt == ge::DT_FLOAT) { | ||
| 113 | + dilation = fourByte; | ||
| 114 | + } else if (dt == ge::DT_FLOAT16) { | ||
| 115 | + dilation = twoByte; | ||
| 116 | + } else if (dt == ge::DT_BF16) { | ||
| 117 | + dilation = twoByte; | ||
| 118 | + } else if (dt == ge::DT_INT16) { | ||
| 119 | + dilation = twoByte; | ||
| 120 | + } else if (dt == ge::DT_UINT16) { | ||
| 121 | + dilation = twoByte; | ||
| 122 | + } else if (dt == ge::DT_INT32) { | ||
| 123 | + dilation = fourByte; | ||
| 124 | + } else if (dt == ge::DT_UINT32) { | ||
| 125 | + dilation = fourByte; | ||
| 126 | + } else if (dt == ge::DT_INT64) { | ||
| 127 | + dilation = eightByte; | ||
| 128 | + } else if (dt == ge::DT_UINT64) { | ||
| 129 | + dilation = eightByte; | ||
| 130 | + } else if (dt == ge::DT_INT8) { | ||
| 131 | + dilation = oneByte; | ||
| 132 | + } | ||
| 133 | + return dilation; | ||
| 134 | +} | ||
| 135 | + | ||
| 136 | +int32_t GenOnesData( | ||
| 137 | + vector<int64_t> shapes, Tensor &input_tensor, TensorDesc &input_tensor_desc, DataType data_type, int value) | ||
| 138 | +{ | ||
| 139 | + input_tensor_desc.SetRealDimCnt(shapes.size()); | ||
| 140 | + size_t size = 1; | ||
| 141 | + for (uint32_t i = 0; i < shapes.size(); i++) { | ||
| 142 | + size *= shapes[i]; | ||
| 143 | + } | ||
| 144 | + uint32_t data_len = size * GetDataTypeSize(data_type); | ||
| 145 | + if (data_type == ge::DT_FLOAT) { | ||
| 146 | + float *pData = new (std::nothrow) float[size]; | ||
| 147 | + for (uint32_t i = 0; i < size; ++i) { | ||
| 148 | + *(pData + i) = static_cast<float>(value); | ||
| 149 | + } | ||
| 150 | + input_tensor = Tensor(input_tensor_desc, reinterpret_cast<uint8_t *>(pData), data_len); | ||
| 151 | + return SUCCESS; | ||
| 152 | + } | ||
| 153 | + int32_t *pData = new (std::nothrow) int32_t[size]; | ||
| 154 | + for (uint32_t i = 0; i < size; ++i) { | ||
| 155 | + *(pData + i) = value; | ||
| 156 | + } | ||
| 157 | + input_tensor = Tensor(input_tensor_desc, reinterpret_cast<uint8_t *>(pData), data_len); | ||
| 158 | + return SUCCESS; | ||
| 159 | +} | ||
| 160 | + | ||
| 161 | +int32_t WriteDataToFile(string bin_file, uint64_t data_size, uint8_t *inputData) | ||
| 162 | +{ | ||
| 163 | + FILE *fp = fopen(bin_file.c_str(), "wb"); | ||
| 164 | + fwrite(inputData, sizeof(uint8_t), data_size, fp); | ||
| 165 | + fclose(fp); | ||
| 166 | + return SUCCESS; | ||
| 167 | +} | ||
| 168 | + | ||
| 169 | +int CreateOppInGraph(DataType inDtype, std::vector<ge::Tensor> &input, std::vector<Operator> &inputs, | ||
| 170 | + std::vector<Operator> &outputs, Graph &graph) | ||
| 171 | +{ | ||
| 172 | + Status ret = SUCCESS; | ||
| 173 | + // 自定义代码:添加单算子定义到图中 | ||
| 174 | + auto acoshGrad = op::AcoshGrad("acosh_grad"); | ||
| 175 | + | ||
| 176 | + std::vector<int64_t> yShape = {4, 2}; | ||
| 177 | + ADD_INPUT(1, y, inDtype, yShape); | ||
| 178 | + ADD_INPUT(2, dy, inDtype, yShape); | ||
| 179 | + | ||
| 180 | + ADD_OUTPUT(1, z, inDtype, yShape); | ||
| 181 | + | ||
| 182 | + outputs.push_back(acoshGrad); | ||
| 183 | + // 添加完毕 | ||
| 184 | + return SUCCESS; | ||
| 185 | +} | ||
| 186 | + | ||
| 187 | + | ||
| 188 | +int InitializeAndSetupGraph(Graph& graph, std::vector<ge::Tensor>& input, DataType inDtype) { | ||
| 189 | + printf("%s - INFO - [XIR]: Start to initialize ge using ge global options\n", GetTime().c_str()); | ||
| 190 | + std::map<AscendString, AscendString> global_options = {{"ge.exec.deviceId", "0"}, {"ge.graphRunMode", "1"}}; | ||
| 191 | + Status ret = ge::GEInitialize(global_options); | ||
| 192 | + if (ret != SUCCESS) { | ||
| 193 | + printf("%s - INFO - [XIR]: Initialize ge using ge global options failed\n", GetTime().c_str()); | ||
| 194 | + return FAILED; | ||
| 195 | + } | ||
| 196 | + printf("%s - INFO - [XIR]: Initialize ge using ge global options success\n", GetTime().c_str()); | ||
| 197 | + | ||
| 198 | + std::vector<Operator> inputs{}; | ||
| 199 | + std::vector<Operator> outputs{}; | ||
| 200 | + | ||
| 201 | + ret = CreateOppInGraph(inDtype, input, inputs, outputs, graph); | ||
| 202 | + if (ret != SUCCESS) { | ||
| 203 | + printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str()); | ||
| 204 | + return FAILED; | ||
| 205 | + } | ||
| 206 | + | ||
| 207 | + if (!inputs.empty() && !outputs.empty()) { | ||
| 208 | + graph.SetInputs(inputs).SetOutputs(outputs); | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + return SUCCESS; | ||
| 212 | +} | ||
| 213 | + | ||
| 214 | + | ||
| 215 | +int ExecuteGraph(Graph& graph, std::vector<ge::Tensor>& input, std::vector<ge::Tensor>& output) { | ||
| 216 | + std::map<AscendString, AscendString> build_options = {}; | ||
| 217 | + printf("%s - INFO - [XIR]: Start to create ir session using build options\n", GetTime().c_str()); | ||
| 218 | + ge::Session *session = new Session(build_options); | ||
| 219 | + | ||
| 220 | + if (session == nullptr) { | ||
| 221 | + printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str()); | ||
| 222 | + return FAILED; | ||
| 223 | + } | ||
| 224 | + printf("%s - INFO - [XIR]: Create ir session using build options success\n", GetTime().c_str()); | ||
| 225 | + printf("%s - INFO - [XIR]: Start to add compute graph to ir session\n", GetTime().c_str()); | ||
| 226 | + | ||
| 227 | + std::map<AscendString, AscendString> graph_options = {}; | ||
| 228 | + uint32_t graph_id = 0; | ||
| 229 | + Status ret = session->AddGraph(graph_id, graph, graph_options); | ||
| 230 | + | ||
| 231 | + printf("%s - INFO - [XIR]: Session add ir compute graph to ir session success\n", GetTime().c_str()); | ||
| 232 | + printf("%s - INFO - [XIR]: dump graph to txt\n", GetTime().c_str()); | ||
| 233 | + std::string file_path = "./dump"; | ||
| 234 | + aclgrphDumpGraph(graph, file_path.c_str(), file_path.length()); | ||
| 235 | + printf("%s - INFO - [XIR]: Start to run ir compute graph\n", GetTime().c_str()); | ||
| 236 | + | ||
| 237 | + ret = session->RunGraph(graph_id, input, output); | ||
| 238 | + if (ret != SUCCESS) { | ||
| 239 | + printf("%s - INFO - [XIR]: Run graph failed\n", GetTime().c_str()); | ||
| 240 | + delete session; | ||
| 241 | + GEFinalize(); | ||
| 242 | + return FAILED; | ||
| 243 | + } | ||
| 244 | + printf("%s - INFO - [XIR]: Session run ir compute graph success\n", GetTime().c_str()); | ||
| 245 | + | ||
| 246 | + delete session; | ||
| 247 | + return SUCCESS; | ||
| 248 | +} | ||
| 249 | + | ||
| 250 | +void ProcessIOData(std::vector<ge::Tensor>& input, std::vector<ge::Tensor>& output) { | ||
| 251 | + int input_num = input.size(); | ||
| 252 | + for (int i = 0; i < input_num; i++) { | ||
| 253 | + std::cout << "input " << i << " dtype : " << input[i].GetTensorDesc().GetDataType() << std::endl; | ||
| 254 | + string input_file = "./tc_ge_irrun_test_0009_npu_input_" + std::to_string(i) + ".bin"; | ||
| 255 | + uint8_t *input_data_i = input[i].GetData(); | ||
| 256 | + int64_t input_shape = input[i].GetTensorDesc().GetShape().GetShapeSize(); | ||
| 257 | + std::cout << "this is " << i << "th input, input shape size =" << input_shape << std::endl; | ||
| 258 | + uint32_t data_size = input_shape * GetDataTypeSize(input[i].GetTensorDesc().GetDataType()); | ||
| 259 | + WriteDataToFile((const char *)input_file.c_str(), data_size, input_data_i); | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + int output_num = output.size(); | ||
| 263 | + for (int i = 0; i < output_num; i++) { | ||
| 264 | + std::cout << "output " << i << " dtype : " << output[i].GetTensorDesc().GetDataType() << std::endl; | ||
| 265 | + string output_file = "./tc_ge_irrun_test_0009_npu_output_" + std::to_string(i) + ".bin"; | ||
| 266 | + uint8_t *output_data_i = output[i].GetData(); | ||
| 267 | + int64_t output_shape = output[i].GetTensorDesc().GetShape().GetShapeSize(); | ||
| 268 | + std::cout << "this is " << i << "th output, output shape size =" << output_shape << std::endl; | ||
| 269 | + uint32_t data_size = output_shape * GetDataTypeSize(output[i].GetTensorDesc().GetDataType()); | ||
| 270 | + WriteDataToFile((const char *)output_file.c_str(), data_size, output_data_i); | ||
| 271 | + float* resultData = (float*)output_data_i; | ||
| 272 | + float expected = 2.0f / 1.7320508f; // dy/sqrt(y*y-1) = 2/sqrt(3) | ||
| 273 | + bool allok = true; | ||
| 274 | + for (int64_t j = 0; j < output_shape; j++) { | ||
| 275 | + LOG_PRINT("result[%ld] is: %f (expected %f)\n", j, resultData[j], expected); | ||
| 276 | + if (resultData[j] < expected - 0.01f || resultData[j] > expected + 0.01f) { | ||
| 277 | + allok = false; | ||
| 278 | + } | ||
| 279 | + } | ||
| 280 | + LOG_PRINT("%s - INFO - [XIR]: AcoshGrad precision %s\n", GetTime().c_str(), allok ? "PASS" : "FAIL"); | ||
| 281 | + } | ||
| 282 | +} | ||
| 283 | + | ||
| 284 | + | ||
| 285 | +int main(int argc, char *argv[]) | ||
| 286 | +{ | ||
| 287 | + // 1、创建图对象 | ||
| 288 | + const char *graph_name = "tc_ge_irrun_acosh_grad_test"; | ||
| 289 | + Graph graph(graph_name); | ||
| 290 | + std::vector<ge::Tensor> input; | ||
| 291 | + | ||
| 292 | + std::cout << argv[1] << std::endl; | ||
| 293 | + | ||
| 294 | + DataType inDtype = DT_FLOAT; | ||
| 295 | + | ||
| 296 | + std::cout << inDtype << std::endl; | ||
| 297 | + | ||
| 298 | + // 初始化和设置图 | ||
| 299 | + if (InitializeAndSetupGraph(graph, input, inDtype) != SUCCESS) { | ||
| 300 | + return FAILED; | ||
| 301 | + } | ||
| 302 | + | ||
| 303 | + // 执行图计算 | ||
| 304 | + std::vector<ge::Tensor> output; | ||
| 305 | + if (ExecuteGraph(graph, input, output) != SUCCESS) { | ||
| 306 | + return FAILED; | ||
| 307 | + } | ||
| 308 | + | ||
| 309 | + // 处理输入输出数据 | ||
| 310 | + ProcessIOData(input, output); | ||
| 311 | + | ||
| 312 | + ge::AscendString error_msg = ge::GEGetErrorMsgV2(); | ||
| 313 | + std::string error_str(error_msg.GetString()); | ||
| 314 | + std::cout << "Error message: " << error_str << std::endl; | ||
| 315 | + ge::AscendString warning_msg = ge::GEGetWarningMsgV2(); | ||
| 316 | + std::string warning_str(warning_msg.GetString()); | ||
| 317 | + std::cout << "Warning message: " << warning_str << std::endl; | ||
| 318 | + printf("%s - INFO - [XIR]: Precision is ok\n", GetTime().c_str()); | ||
| 319 | + printf("%s - INFO - [XIR]: Start to finalize ir graph session\n", GetTime().c_str()); | ||
| 320 | + Status ret = ge::GEFinalize(); | ||
| 321 | + if (ret != SUCCESS) { | ||
| 322 | + printf("%s - INFO - [XIR]: Finalize ir graph session failed\n", GetTime().c_str()); | ||
| 323 | + return FAILED; | ||
| 324 | + } | ||
| 325 | + printf("%s - INFO - [XIR]: Finalize ir graph session success\n", GetTime().c_str()); | ||
| 326 | + return SUCCESS; | ||
| 327 | +} | ||
| @@ -0,0 +1,46 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | +/* Generated By CANNBot */ | ||
| 12 | + | ||
| 13 | +/*! | ||
| 14 | + * \file acosh_grad_proto.h | ||
| 15 | + * \brief AcoshGrad GE IR 图模式注册 | ||
| 16 | + */ | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | +namespace ge { | ||
| 24 | + | ||
| 25 | +/** | ||
| 26 | + *@brief AcoshGrad: z = dy / sqrt(y² - 1), reverse gradient of acosh. | ||
| 27 | + *@par Inputs: | ||
| 28 | + *Two inputs: | ||
| 29 | + * @li y: A Tensor. Must be float16, bfloat16, or float32. Original input of forward acosh, domain ≥ 1. | ||
| 30 | + * @li dy: A Tensor. Must be float16, bfloat16, or float32. Upstream gradient, same shape/dtype as y. | ||
| 31 | + * | ||
| 32 | + *@par Outputs: | ||
| 33 | + *z: A Tensor. Must be float16, bfloat16, or float32. Reverse gradient, same shape/dtype as y. | ||
| 34 | + * | ||
| 35 | + *@par Third-party framework compatibility: | ||
| 36 | + *Compatible with TensorFlow AcoshGrad. | ||
| 37 | + */ | ||
| 38 | +REG_OP(AcoshGrad) | ||
| 39 | + .INPUT(y, TensorType({DT_FLOAT16, DT_BF16, DT_FLOAT})) | ||
| 40 | + .INPUT(dy, TensorType({DT_FLOAT16, DT_BF16, DT_FLOAT})) | ||
| 41 | + .OUTPUT(z, TensorType({DT_FLOAT16, DT_BF16, DT_FLOAT})) | ||
| 42 | + .OP_END_FACTORY_REG(AcoshGrad) | ||
| 43 | + | ||
| 44 | +} // namespace ge | ||
| 45 | + | ||
| 46 | + | ||
| @@ -0,0 +1,57 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | +/* Generated By CANNBot */ | ||
| 12 | + | ||
| 13 | +/*! | ||
| 14 | + * \file acosh_grad_def.cpp | ||
| 15 | + * \brief AcoshGrad 算子定义 | ||
| 16 | + * | ||
| 17 | + * 迭代二:FP16 + BF16 + FP32 全 dtype 注册。 | ||
| 18 | + */ | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace ops { | ||
| 22 | +class AcoshGrad : public OpDef { | ||
| 23 | +public: | ||
| 24 | + explicit AcoshGrad(const char* name) : OpDef(name) | ||
| 25 | + { | ||
| 26 | + this->Input("y") | ||
| 27 | + .ParamType(REQUIRED) | ||
| 28 | + .DataType({ge::DT_FLOAT16, ge::DT_BF16, ge::DT_FLOAT}) | ||
| 29 | + .Format({ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND}) | ||
| 30 | + .UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND}) | ||
| 31 | + .AutoContiguous(); | ||
| 32 | + this->Input("dy") | ||
| 33 | + .ParamType(REQUIRED) | ||
| 34 | + .DataType({ge::DT_FLOAT16, ge::DT_BF16, ge::DT_FLOAT}) | ||
| 35 | + .Format({ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND}) | ||
| 36 | + .UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND}) | ||
| 37 | + .AutoContiguous(); | ||
| 38 | + this->Output("z") | ||
| 39 | + .ParamType(REQUIRED) | ||
| 40 | + .DataType({ge::DT_FLOAT16, ge::DT_BF16, ge::DT_FLOAT}) | ||
| 41 | + .Format({ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND}) | ||
| 42 | + .UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND}) | ||
| 43 | + .AutoContiguous(); | ||
| 44 | + | ||
| 45 | + OpAICoreConfig aiCoreConfig; | ||
| 46 | + aiCoreConfig.DynamicCompileStaticFlag(true) | ||
| 47 | + .DynamicFormatFlag(false) | ||
| 48 | + .DynamicRankSupportFlag(true) | ||
| 49 | + .DynamicShapeSupportFlag(true) | ||
| 50 | + .NeedCheckSupportFlag(false) | ||
| 51 | + .PrecisionReduceFlag(true) | ||
| 52 | + .ExtendCfgInfo("opFile.value", "acosh_grad_apt"); | ||
| 53 | + this->AICore().AddConfig("ascend950", aiCoreConfig); | ||
| 54 | + } | ||
| 55 | +}; | ||
| 56 | +OP_ADD(AcoshGrad); | ||
| 57 | +} // namespace ops | ||
| @@ -0,0 +1,44 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | +/* Generated By CANNBot */ | ||
| 12 | + | ||
| 13 | +/*! | ||
| 14 | + * \file acosh_grad_infershape.cpp | ||
| 15 | + * \brief AcoshGrad 算子形状推导 | ||
| 16 | + * | ||
| 17 | + * z.shape = y.shape(element-wise,无广播) | ||
| 18 | + */ | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | +using namespace ge; | ||
| 25 | + | ||
| 26 | +namespace ops { | ||
| 27 | + | ||
| 28 | +static ge::graphStatus InferShape4AcoshGrad(gert::InferShapeContext* context) | ||
| 29 | +{ | ||
| 30 | + const gert::Shape* input_shape = context->GetInputShape(0); | ||
| 31 | + OP_CHECK_NULL_WITH_CONTEXT(context, input_shape); | ||
| 32 | + | ||
| 33 | + gert::Shape* output_shape = context->GetOutputShape(0); | ||
| 34 | + OP_CHECK_NULL_WITH_CONTEXT(context, output_shape); | ||
| 35 | + | ||
| 36 | + // z.shape = y.shape | ||
| 37 | + *output_shape = *input_shape; | ||
| 38 | + | ||
| 39 | + return ge::GRAPH_SUCCESS; | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +IMPL_OP_INFERSHAPE(AcoshGrad).InferShape(InferShape4AcoshGrad); | ||
| 43 | + | ||
| 44 | +} // namespace ops | ||
| @@ -0,0 +1,182 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | +/* Generated By CANNBot */ | ||
| 12 | + | ||
| 13 | +/*! | ||
| 14 | + * \file acosh_grad_tiling_arch35.cpp | ||
| 15 | + * \brief AcoshGrad Host 侧 Tiling 计算(arch35 / DAV_3510) | ||
| 16 | + * | ||
| 17 | + * 迭代二:FP16 + BF16 + FP32, Double Buffer, workspace = 0 | ||
| 18 | + */ | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | +namespace optiling { | ||
| 28 | + | ||
| 29 | +using Ops::Base::CeilDiv; | ||
| 30 | +using Ops::Base::CeilAlign; | ||
| 31 | +using Ops::Base::FloorDiv; | ||
| 32 | +using Ops::Base::FloorAlign; | ||
| 33 | +using Ops::Base::GetUbBlockSize; | ||
| 34 | + | ||
| 35 | +constexpr uint32_t WS_SYS_SIZE = 0U; | ||
| 36 | +constexpr size_t WORKSPACE_NUM = 1; | ||
| 37 | +constexpr int64_t DOUBLE_BUF_TENSOR_COUNT = 6; // 3 queues × 2 slots | ||
| 38 | +constexpr int64_t WORK_BUF_COUNT = 3; // 3 份 FP32 中间 buffer | ||
| 39 | +constexpr int64_t MIN_SPLIT_THRESHOLD = 1024; // 双缓冲阈值 | ||
| 40 | +constexpr int64_t TYPE_SIZE_FP16 = 2; | ||
| 41 | +constexpr int64_t TYPE_SIZE_FP32 = 4; | ||
| 42 | + | ||
| 43 | +static const gert::Shape g_vec_1_shape = {1}; | ||
| 44 | + | ||
| 45 | +static inline const gert::Shape EnsureNotScalar(const gert::Shape& in_shape) { | ||
| 46 | + if (in_shape.GetDimNum() == 0) { | ||
| 47 | + return g_vec_1_shape; | ||
| 48 | + } | ||
| 49 | + return in_shape; | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +static ge::graphStatus GetPlatformInfo(gert::TilingContext* context, uint64_t* ubSize, int64_t* coreNum) | ||
| 53 | +{ | ||
| 54 | + fe::PlatFormInfos* platformInfoPtr = context->GetPlatformInfo(); | ||
| 55 | + OP_CHECK_NULL_WITH_CONTEXT(context, platformInfoPtr); | ||
| 56 | + auto ascendcPlatform = platform_ascendc::PlatformAscendC(platformInfoPtr); | ||
| 57 | + *coreNum = ascendcPlatform.GetCoreNumAiv(); | ||
| 58 | + OP_CHECK_IF(*coreNum == 0, OP_LOGE(context, "coreNum is 0"), return ge::GRAPH_FAILED); | ||
| 59 | + ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::UB, *ubSize); | ||
| 60 | + OP_CHECK_IF(*ubSize == 0, OP_LOGE(context, "ubSize is 0"), return ge::GRAPH_FAILED); | ||
| 61 | + return ge::GRAPH_SUCCESS; | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | +static ge::graphStatus GetShapeAttrsInfo(gert::TilingContext* context, int64_t* totalIdx, ge::DataType* dataType) | ||
| 65 | +{ | ||
| 66 | + auto inputY = context->GetInputShape(0); | ||
| 67 | + OP_CHECK_NULL_WITH_CONTEXT(context, inputY); | ||
| 68 | + auto inputShapeY = EnsureNotScalar(inputY->GetStorageShape()); | ||
| 69 | + | ||
| 70 | + auto inputDy = context->GetInputShape(1); | ||
| 71 | + OP_CHECK_NULL_WITH_CONTEXT(context, inputDy); | ||
| 72 | + auto inputShapeDy = EnsureNotScalar(inputDy->GetStorageShape()); | ||
| 73 | + | ||
| 74 | + auto outZ = context->GetOutputShape(0); | ||
| 75 | + OP_CHECK_NULL_WITH_CONTEXT(context, outZ); | ||
| 76 | + auto outShapeZ = EnsureNotScalar(outZ->GetStorageShape()); | ||
| 77 | + | ||
| 78 | + // shape 校验:y.shape == dy.shape == z.shape | ||
| 79 | + OP_CHECK_IF( | ||
| 80 | + inputShapeY.GetShapeSize() != inputShapeDy.GetShapeSize() || | ||
| 81 | + inputShapeY.GetShapeSize() != outShapeZ.GetShapeSize(), | ||
| 82 | + OP_LOGE(context, "AcoshGrad: shape mismatch: y=%ld, dy=%ld, z=%ld", | ||
| 83 | + inputShapeY.GetShapeSize(), inputShapeDy.GetShapeSize(), outShapeZ.GetShapeSize()), | ||
| 84 | + return ge::GRAPH_FAILED); | ||
| 85 | + | ||
| 86 | + *totalIdx = inputShapeY.GetShapeSize(); | ||
| 87 | + | ||
| 88 | + auto inputDesc = context->GetInputDesc(0); | ||
| 89 | + OP_CHECK_NULL_WITH_CONTEXT(context, inputDesc); | ||
| 90 | + *dataType = inputDesc->GetDataType(); | ||
| 91 | + | ||
| 92 | + // 迭代二:支持 FP16、BF16、FP32 | ||
| 93 | + const std::set<ge::DataType> supportedDtype = {ge::DT_FLOAT16, ge::DT_BF16, ge::DT_FLOAT}; | ||
| 94 | + OP_CHECK_IF(supportedDtype.count(*dataType) == 0, | ||
| 95 | + OP_LOGE(context, "AcoshGrad: unsupported dtype %d", static_cast<int>(*dataType)), | ||
| 96 | + return ge::GRAPH_FAILED); | ||
| 97 | + | ||
| 98 | + return ge::GRAPH_SUCCESS; | ||
| 99 | +} | ||
| 100 | + | ||
| 101 | +static ge::graphStatus GetWorkspaceSize(gert::TilingContext* context) | ||
| 102 | +{ | ||
| 103 | + size_t* currentWorkspace = context->GetWorkspaceSizes(WORKSPACE_NUM); | ||
| 104 | + OP_CHECK_NULL_WITH_CONTEXT(context, currentWorkspace); | ||
| 105 | + currentWorkspace[0] = WS_SYS_SIZE; | ||
| 106 | + return ge::GRAPH_SUCCESS; | ||
| 107 | +} | ||
| 108 | + | ||
| 109 | +static ge::graphStatus AcoshGradTilingFunc(gert::TilingContext* context) | ||
| 110 | +{ | ||
| 111 | + // 1. 获取平台信息 | ||
| 112 | + uint64_t ubSize; | ||
| 113 | + int64_t coreNum; | ||
| 114 | + OP_CHECK_IF( | ||
| 115 | + GetPlatformInfo(context, &ubSize, &coreNum) != ge::GRAPH_SUCCESS, | ||
| 116 | + OP_LOGE(context, "GetPlatformInfo error"), return ge::GRAPH_FAILED); | ||
| 117 | + | ||
| 118 | + // 2. 获取 shape/属性 | ||
| 119 | + int64_t totalIdx; | ||
| 120 | + ge::DataType dataType; | ||
| 121 | + OP_CHECK_IF( | ||
| 122 | + GetShapeAttrsInfo(context, &totalIdx, &dataType) != ge::GRAPH_SUCCESS, | ||
| 123 | + OP_LOGE(context, "GetShapeAttrsInfo error"), return ge::GRAPH_FAILED); | ||
| 124 | + | ||
| 125 | + // 3. Workspace | ||
| 126 | + OP_CHECK_IF( | ||
| 127 | + GetWorkspaceSize(context) != ge::GRAPH_SUCCESS, | ||
| 128 | + OP_LOGE(context, "GetWorkspaceSize error"), return ge::GRAPH_FAILED); | ||
| 129 | + | ||
| 130 | + // 4. 设置 TilingData | ||
| 131 | + AcoshGradTilingData* tiling = context->GetTilingData<AcoshGradTilingData>(); | ||
| 132 | + OP_CHECK_NULL_WITH_CONTEXT(context, tiling); | ||
| 133 | + OP_CHECK_IF( | ||
| 134 | + memset_s(tiling, sizeof(AcoshGradTilingData), 0, sizeof(AcoshGradTilingData)) != EOK, | ||
| 135 | + OP_LOGE(context, "set tiling data error"), return ge::GRAPH_FAILED); | ||
| 136 | + | ||
| 137 | + // 空 Tensor 检查 | ||
| 138 | + if (totalIdx == 0) { | ||
| 139 | + context->SetBlockDim(1); | ||
| 140 | + context->SetTilingKey(GET_TPL_TILING_KEY(ACOSH_GRAD_TPL_SCH_MODE_0)); | ||
| 141 | + return ge::GRAPH_SUCCESS; | ||
| 142 | + } | ||
| 143 | + | ||
| 144 | + // 5. 多核切分 | ||
| 145 | + int64_t ubBlockSize = Ops::Base::GetUbBlockSize(context); | ||
| 146 | + tiling->totalNum = totalIdx; | ||
| 147 | + tiling->blockFactor = CeilAlign(CeilDiv(totalIdx, coreNum), ubBlockSize); | ||
| 148 | + int64_t usedCoreNum = Ops::Base::CeilDiv(totalIdx, tiling->blockFactor); | ||
| 149 | + | ||
| 150 | + // 6. UB 切分 | ||
| 151 | + // FP16/BF16 + Double Buffer: | ||
| 152 | + // Queue 内存: 3 queues × 2 slots × ubFactor × 2 = 12 × ubFactor | ||
| 153 | + // Work 内存: 3 bufs × ubFactor × sizeof(float) = 12 × ubFactor | ||
| 154 | + // 总计: 24 × ubFactor bytes | ||
| 155 | + // FP32 + Double Buffer: | ||
| 156 | + // Queue 内存: 3 queues × 2 slots × ubFactor × 4 = 24 × ubFactor | ||
| 157 | + // Work 内存: 3 bufs × ubFactor × sizeof(float) = 12 × ubFactor | ||
| 158 | + // 总计: 36 × ubFactor bytes | ||
| 159 | + int64_t elemBytes = (dataType == ge::DT_FLOAT) ? TYPE_SIZE_FP32 : TYPE_SIZE_FP16; | ||
| 160 | + int64_t queueBufCount = DOUBLE_BUF_TENSOR_COUNT; | ||
| 161 | + int64_t totalBytesPerElem = queueBufCount * elemBytes + WORK_BUF_COUNT * static_cast<int64_t>(sizeof(float)); | ||
| 162 | + tiling->ubFactor = FloorAlign(FloorDiv(static_cast<int64_t>(ubSize), totalBytesPerElem), ubBlockSize); | ||
| 163 | + | ||
| 164 | + context->SetBlockDim(usedCoreNum); | ||
| 165 | + | ||
| 166 | + // 7. 设置 TilingKey(使用 GET_TPL_TILING_KEY,与 relu6_grad 模式一致) | ||
| 167 | + context->SetTilingKey(GET_TPL_TILING_KEY(ACOSH_GRAD_TPL_SCH_MODE_0)); | ||
| 168 | + return ge::GRAPH_SUCCESS; | ||
| 169 | +} | ||
| 170 | + | ||
| 171 | +static ge::graphStatus TilingParseForAcoshGrad([[maybe_unused]] gert::TilingParseContext* context) | ||
| 172 | +{ | ||
| 173 | + return ge::GRAPH_SUCCESS; | ||
| 174 | +} | ||
| 175 | + | ||
| 176 | +struct AcoshGradCompileInfo {}; | ||
| 177 | + | ||
| 178 | +IMPL_OP_OPTILING(AcoshGrad) | ||
| 179 | + .Tiling(AcoshGradTilingFunc) | ||
| 180 | + .TilingParse<AcoshGradCompileInfo>(TilingParseForAcoshGrad); | ||
| 181 | + | ||
| 182 | +} // namespace optiling | ||
| @@ -0,0 +1,35 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | +/* Generated By CANNBot */ | ||
| 12 | + | ||
| 13 | +/*! | ||
| 14 | + * \file acosh_grad_apt.cpp | ||
| 15 | + * \brief AcoshGrad 算子 Kernel 入口(arch35 / DAV_3510) | ||
| 16 | + * | ||
| 17 | + * 模板参数(对应 acosh_grad_tiling_key.h 中 ASCENDC_TPL_ARGS_DECL): | ||
| 18 | + * - schMode: 调度模式(0 = 逐元素) | ||
| 19 | + * | ||
| 20 | + * dtype 通过 DTYPE_Y 宏指定(CANN 编译系统根据 op_def 输入名 "y" 自动生成)。 | ||
| 21 | + * 每个 dtype 变体由编译系统独立编译,DTYPE_Y 自动替换为对应类型。 | ||
| 22 | + */ | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | +template <uint32_t schMode> | ||
| 27 | +__global__ __aicore__ void acosh_grad(GM_ADDR y, GM_ADDR dy, GM_ADDR z, | ||
| 28 | + GM_ADDR workspace, GM_ADDR tiling) | ||
| 29 | +{ | ||
| 30 | + REGISTER_TILING_DEFAULT(AcoshGradTilingData); | ||
| 31 | + GET_TILING_DATA_WITH_STRUCT(AcoshGradTilingData, tilingData, tiling); | ||
| 32 | + NsAcoshGrad::AcoshGradKernel<DTYPE_Y> op; | ||
| 33 | + op.Init(y, dy, z, &tilingData); | ||
| 34 | + op.Process(); | ||
| 35 | +} | ||
| @@ -0,0 +1,227 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | +/* Generated By CANNBot */ | ||
| 12 | + | ||
| 13 | +/*! | ||
| 14 | + * \file acosh_grad_kernel.h | ||
| 15 | + * \brief AcoshGrad 算子 Kernel 类定义(arch35 / DAV_3510) | ||
| 16 | + * | ||
| 17 | + * 公式: z = dy / sqrt(y² - 1) | ||
| 18 | + * 计算路径 (FP16/BF16): Cast→FP32 → Mul → Adds(-1) → Sqrt → Div → Cast→原dtype | ||
| 19 | + * 计算路径 (FP32): Mul → Adds(-1) → Sqrt → Div | ||
| 20 | + * Double Buffer 流水线并行 | ||
| 21 | + * | ||
| 22 | + * 关键设计约束(来自迭代二穿刺验证): | ||
| 23 | + * 1. GlobalTensor 多 tile 不自动推进:每次 tile 循环前必须显式调用 | ||
| 24 | + * SetGlobalBuffer(base + offset, remain) 更新 GM 指针偏移 | ||
| 25 | + * 2. TBuf 必须用独立实例:3 个独立 TBuf<VECCALC>(bufSlot0_/1_/2_), | ||
| 26 | + * 禁止单 TBuf + GetWithOffset(totalNum=1 时仅 12 字节导致 +Inf) | ||
| 27 | + * | ||
| 28 | + * dtype 通过 DTYPE_Y 宏指定(由 CANN 编译系统根据 op_def 输入名 "y" 自动生成) | ||
| 29 | + */ | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + | ||
| 34 | + | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + | ||
| 38 | +namespace NsAcoshGrad { | ||
| 39 | + | ||
| 40 | +using namespace AscendC; | ||
| 41 | + | ||
| 42 | +template <typename T> | ||
| 43 | +class AcoshGradKernel { | ||
| 44 | + static constexpr int32_t BUFFER_NUM = 2; // Double Buffer | ||
| 45 | + | ||
| 46 | +public: | ||
| 47 | + __aicore__ inline AcoshGradKernel() {}; | ||
| 48 | + | ||
| 49 | + __aicore__ inline void Init(GM_ADDR y, GM_ADDR dy, GM_ADDR z, | ||
| 50 | + const AcoshGradTilingData* tilingData); | ||
| 51 | + __aicore__ inline void Process(); | ||
| 52 | + | ||
| 53 | +private: | ||
| 54 | + __aicore__ inline void CopyIn(int64_t currentNum); | ||
| 55 | + __aicore__ inline void Compute(int64_t currentNum); | ||
| 56 | + __aicore__ inline void CopyOut(int64_t currentNum); | ||
| 57 | + | ||
| 58 | +private: | ||
| 59 | + TPipe pipe; | ||
| 60 | + TQue<TPosition::VECIN, BUFFER_NUM> inQueueY; | ||
| 61 | + TQue<TPosition::VECIN, BUFFER_NUM> inQueueDy; | ||
| 62 | + TQue<TPosition::VECOUT, BUFFER_NUM> outQueueZ; | ||
| 63 | + | ||
| 64 | + // 3 个独立 FP32 中间计算 buffer(禁止合并为单 TBuf + GetWithOffset) | ||
| 65 | + // 穿刺 probe_fp16_overflow 验证:单 TBuf 在 totalNum=1 时仅分配 12 字节, | ||
| 66 | + // 导致 slot 地址重叠,输出 +Inf | ||
| 67 | + TBuf<TPosition::VECCALC> bufSlot0_; // yFp32 → dyFp32 → result | ||
| 68 | + TBuf<TPosition::VECCALC> bufSlot1_; // ySq → ySqM1 | ||
| 69 | + TBuf<TPosition::VECCALC> bufSlot2_; // sqrtVal | ||
| 70 | + | ||
| 71 | + GlobalTensor<T> yGM; | ||
| 72 | + GlobalTensor<T> dyGM; | ||
| 73 | + GlobalTensor<T> zGM; | ||
| 74 | + | ||
| 75 | + // Base GM 地址(用于 tile 偏移计算,穿刺 probe_large_shape 验证必须保存) | ||
| 76 | + __gm__ T* yBase_ = nullptr; | ||
| 77 | + __gm__ T* dyBase_ = nullptr; | ||
| 78 | + __gm__ T* zBase_ = nullptr; | ||
| 79 | + | ||
| 80 | + int64_t blockLength_ = 0; | ||
| 81 | + int64_t ubLength_ = 0; | ||
| 82 | +}; | ||
| 83 | + | ||
| 84 | +template <typename T> | ||
| 85 | +__aicore__ inline void AcoshGradKernel<T>::Init( | ||
| 86 | + GM_ADDR y, GM_ADDR dy, GM_ADDR z, const AcoshGradTilingData* tilingData) | ||
| 87 | +{ | ||
| 88 | + int64_t remainderLength = tilingData->totalNum - tilingData->blockFactor * AscendC::GetBlockIdx(); | ||
| 89 | + blockLength_ = (remainderLength > tilingData->blockFactor) ? tilingData->blockFactor : remainderLength; | ||
| 90 | + // blockIdx 过大时 remainderLength 可能为负,钳为 0 避免后续计算出错(参考 ndtri_kernel.h:152-154) | ||
| 91 | + if (blockLength_ < 0) { | ||
| 92 | + blockLength_ = 0; | ||
| 93 | + } | ||
| 94 | + ubLength_ = tilingData->ubFactor; | ||
| 95 | + | ||
| 96 | + // 保存 base GM 地址,Process 中按 tile 偏移调用 SetGlobalBuffer | ||
| 97 | + // (穿刺 probe_large_shape 验证:DataCopyPad 不自动推进 GlobalTensor 地址) | ||
| 98 | + yBase_ = (__gm__ T*)y + tilingData->blockFactor * AscendC::GetBlockIdx(); | ||
| 99 | + dyBase_ = (__gm__ T*)dy + tilingData->blockFactor * AscendC::GetBlockIdx(); | ||
| 100 | + zBase_ = (__gm__ T*)z + tilingData->blockFactor * AscendC::GetBlockIdx(); | ||
| 101 | + | ||
| 102 | + // GlobalTensor 初始设置:指向第一个 tile | ||
| 103 | + yGM.SetGlobalBuffer(yBase_, blockLength_); | ||
| 104 | + dyGM.SetGlobalBuffer(dyBase_, blockLength_); | ||
| 105 | + zGM.SetGlobalBuffer(zBase_, blockLength_); | ||
| 106 | + | ||
| 107 | + pipe.InitBuffer(inQueueY, BUFFER_NUM, ubLength_ * sizeof(T)); | ||
| 108 | + pipe.InitBuffer(inQueueDy, BUFFER_NUM, ubLength_ * sizeof(T)); | ||
| 109 | + pipe.InitBuffer(outQueueZ, BUFFER_NUM, ubLength_ * sizeof(T)); | ||
| 110 | + | ||
| 111 | + // FP32 中间 buffer:3 个独立 TBuf 实例(禁止合并为单 TBuf) | ||
| 112 | + // 穿刺 probe_fp16_overflow 验证:单 TBuf + GetWithOffset 在 totalNum=1 时 | ||
| 113 | + // 仅分配 12 字节(3*sizeof(float)),slot 地址重叠导致输出 +Inf | ||
| 114 | + pipe.InitBuffer(bufSlot0_, ubLength_ * sizeof(float)); | ||
| 115 | + pipe.InitBuffer(bufSlot1_, ubLength_ * sizeof(float)); | ||
| 116 | + pipe.InitBuffer(bufSlot2_, ubLength_ * sizeof(float)); | ||
| 117 | +} | ||
| 118 | + | ||
| 119 | +template <typename T> | ||
| 120 | +__aicore__ inline void AcoshGradKernel<T>::CopyIn(int64_t currentNum) | ||
| 121 | +{ | ||
| 122 | + LocalTensor<T> yLocal = inQueueY.template AllocTensor<T>(); | ||
| 123 | + LocalTensor<T> dyLocal = inQueueDy.template AllocTensor<T>(); | ||
| 124 | + | ||
| 125 | + // DataCopyPad 直接从 GlobalTensor 当前地址读取(Process 中已推进到正确 tile) | ||
| 126 | + DataCopyParams copyParams; | ||
| 127 | + copyParams.blockCount = 1; | ||
| 128 | + copyParams.blockLen = currentNum * sizeof(T); | ||
| 129 | + copyParams.srcStride = 0; | ||
| 130 | + copyParams.dstStride = 0; | ||
| 131 | + | ||
| 132 | + DataCopyPad(yLocal, yGM, copyParams, {false, 0, 0, 0}); | ||
| 133 | + DataCopyPad(dyLocal, dyGM, copyParams, {false, 0, 0, 0}); | ||
| 134 | + | ||
| 135 | + inQueueY.EnQue(yLocal); | ||
| 136 | + inQueueDy.EnQue(dyLocal); | ||
| 137 | +} | ||
| 138 | + | ||
| 139 | +template <typename T> | ||
| 140 | +__aicore__ inline void AcoshGradKernel<T>::Compute(int64_t currentNum) | ||
| 141 | +{ | ||
| 142 | + LocalTensor<T> yLocal = inQueueY.template DeQue<T>(); | ||
| 143 | + LocalTensor<T> dyLocal = inQueueDy.template DeQue<T>(); | ||
| 144 | + LocalTensor<T> zLocal = outQueueZ.template AllocTensor<T>(); | ||
| 145 | + | ||
| 146 | + // 从 3 个独立 TBuf 获取 FP32 中间 Buffer(无地址冲突) | ||
| 147 | + // 穿刺 probe_fp16_overflow 验证:独立 TBuf 实例保证地址不重叠 | ||
| 148 | + LocalTensor<float> slot0 = bufSlot0_.Get<float>(); // yFp32 → dyFp32 → result | ||
| 149 | + LocalTensor<float> slot1 = bufSlot1_.Get<float>(); // ySq → ySqM1 | ||
| 150 | + LocalTensor<float> slot2 = bufSlot2_.Get<float>(); // sqrtVal | ||
| 151 | + | ||
| 152 | + if constexpr (std::is_same_v<T, float>) { | ||
| 153 | + // FP32 路径:直接计算,无需 Cast | ||
| 154 | + // slot0 = y² (临时) | ||
| 155 | + AscendC::Mul<float>(slot0, yLocal, yLocal, currentNum); | ||
| 156 | + // slot1 = y² - 1 | ||
| 157 | + AscendC::Adds<float>(slot1, slot0, -1.0f, currentNum); | ||
| 158 | + // slot2 = sqrt(y² - 1) | ||
| 159 | + AscendC::Sqrt<float>(slot2, slot1, currentNum); | ||
| 160 | + // zLocal = dy / sqrt(y² - 1) | ||
| 161 | + AscendC::Div<float>(zLocal, dyLocal, slot2, currentNum); | ||
| 162 | + } else { | ||
| 163 | + // FP16/BF16 路径:Cast→FP32→计算→Cast | ||
| 164 | + // Step 1: Cast y → FP32 (slot0) | ||
| 165 | + AscendC::Cast<float, T>(slot0, yLocal, AscendC::RoundMode::CAST_NONE, currentNum); | ||
| 166 | + // Step 2: y² (slot1) | ||
| 167 | + AscendC::Mul<float>(slot1, slot0, slot0, currentNum); | ||
| 168 | + // Step 3: y² - 1 (slot1, in-place) | ||
| 169 | + AscendC::Adds<float>(slot1, slot1, -1.0f, currentNum); | ||
| 170 | + // Step 4: sqrt(y² - 1) (slot2) | ||
| 171 | + AscendC::Sqrt<float>(slot2, slot1, currentNum); | ||
| 172 | + // Step 5: Cast dy → FP32 (slot0, 复用) | ||
| 173 | + AscendC::Cast<float, T>(slot0, dyLocal, AscendC::RoundMode::CAST_NONE, currentNum); | ||
| 174 | + // Step 6: dy / sqrt (slot0, 复用) | ||
| 175 | + AscendC::Div<float>(slot0, slot0, slot2, currentNum); | ||
| 176 | + // Step 7: Cast result → 原 dtype (zLocal) | ||
| 177 | + AscendC::Cast<T, float>(zLocal, slot0, AscendC::RoundMode::CAST_ROUND, currentNum); | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + outQueueZ.template EnQue<T>(zLocal); | ||
| 181 | + inQueueY.FreeTensor(yLocal); | ||
| 182 | + inQueueDy.FreeTensor(dyLocal); | ||
| 183 | +} | ||
| 184 | + | ||
| 185 | +template <typename T> | ||
| 186 | +__aicore__ inline void AcoshGradKernel<T>::CopyOut(int64_t currentNum) | ||
| 187 | +{ | ||
| 188 | + LocalTensor<T> zLocal = outQueueZ.template DeQue<T>(); | ||
| 189 | + | ||
| 190 | + // DataCopyPad 直接写入 GlobalTensor 当前地址(Process 中已推进到正确 tile) | ||
| 191 | + DataCopyParams copyParams; | ||
| 192 | + copyParams.blockCount = 1; | ||
| 193 | + copyParams.blockLen = currentNum * sizeof(T); | ||
| 194 | + copyParams.srcStride = 0; | ||
| 195 | + copyParams.dstStride = 0; | ||
| 196 | + | ||
| 197 | + DataCopyPad(zGM, zLocal, copyParams); | ||
| 198 | + outQueueZ.FreeTensor(zLocal); | ||
| 199 | +} | ||
| 200 | + | ||
| 201 | +template <typename T> | ||
| 202 | +__aicore__ inline void AcoshGradKernel<T>::Process() | ||
| 203 | +{ | ||
| 204 | + if (blockLength_ == 0) return; | ||
| 205 | + | ||
| 206 | + int64_t loopCount = (blockLength_ + ubLength_ - 1) / ubLength_; | ||
| 207 | + for (int64_t i = 0; i < loopCount; i++) { | ||
| 208 | + int64_t currentNum = (i == (loopCount - 1)) ? (blockLength_ - ubLength_ * i) : ubLength_; | ||
| 209 | + | ||
| 210 | + // 显式推进 GlobalTensor 到当前 tile 偏移 | ||
| 211 | + // (穿刺 probe_large_shape 验证:DataCopyPad 不自动推进 GlobalTensor 地址, | ||
| 212 | + // 多 tile 循环必须在每次迭代前重新调用 SetGlobalBuffer) | ||
| 213 | + int64_t offset = i * ubLength_; | ||
| 214 | + int64_t remain = blockLength_ - offset; | ||
| 215 | + yGM.SetGlobalBuffer(yBase_ + offset, remain); | ||
| 216 | + dyGM.SetGlobalBuffer(dyBase_ + offset, remain); | ||
| 217 | + zGM.SetGlobalBuffer(zBase_ + offset, remain); | ||
| 218 | + | ||
| 219 | + CopyIn(currentNum); | ||
| 220 | + Compute(currentNum); | ||
| 221 | + CopyOut(currentNum); | ||
| 222 | + } | ||
| 223 | +} | ||
| 224 | + | ||
| 225 | +} // namespace NsAcoshGrad | ||
| 226 | + | ||
| 227 | + | ||
| @@ -0,0 +1,31 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | +/* Generated By CANNBot */ | ||
| 12 | + | ||
| 13 | +/*! | ||
| 14 | + * \file acosh_grad_tiling_data.h | ||
| 15 | + * \brief TilingData 结构体定义(acosh_grad, arch35) | ||
| 16 | + * | ||
| 17 | + * 使用标准 C++ struct,禁止 BEGIN_TILING_DATA_DEF 宏 | ||
| 18 | + */ | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +struct AcoshGradTilingData { | ||
| 26 | + int64_t totalNum = 0; // 总元素数量 | ||
| 27 | + int64_t blockFactor = 0; // 每个核处理的元素数量(对齐后) | ||
| 28 | + int64_t ubFactor = 0; // 每次 UB tile 处理的元素数量(对齐后) | ||
| 29 | +}; | ||
| 30 | + | ||
| 31 | + | ||
| @@ -0,0 +1,39 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | +/* Generated By CANNBot */ | ||
| 12 | + | ||
| 13 | +/*! | ||
| 14 | + * \file acosh_grad_tiling_key.h | ||
| 15 | + * \brief TilingKey 模板参数定义(acosh_grad, arch35) | ||
| 16 | + * | ||
| 17 | + * 迭代一:单 schMode(0 = 逐元素),dtype 由 DTYPE_Y 自动宏处理。 | ||
| 18 | + * 使用 ASCENDC_TPL_ARGS_DECL 模板编程。 | ||
| 19 | + * | ||
| 20 | + * 注意:不使用 ASCENDC_TPL_DATATYPE_DECL —— CANN 9.0 beta.2 的 compile_op | ||
| 21 | + * 生成的 wrapper 代码无法正确推导 typename 模板参数。dtype 通过 op_def 中 | ||
| 22 | + * 输入名 "y" 自动生成的 DTYPE_Y 宏在 kernel entry 中指定。 | ||
| 23 | + */ | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + | ||
| 32 | +ASCENDC_TPL_ARGS_DECL( | ||
| 33 | + AcoshGrad, | ||
| 34 | + ASCENDC_TPL_UINT_DECL(schMode, 1, ASCENDC_TPL_UI_LIST, ACOSH_GRAD_TPL_SCH_MODE_0)); | ||
| 35 | + | ||
| 36 | +ASCENDC_TPL_SEL(ASCENDC_TPL_ARGS_SEL( | ||
| 37 | + ASCENDC_TPL_UINT_SEL(schMode, ASCENDC_TPL_UI_LIST, ACOSH_GRAD_TPL_SCH_MODE_0))); | ||
| 38 | + | ||
| 39 | + | ||
| @@ -0,0 +1,17 @@ | |||
| 1 | +# ---------------------------------------------------------------------------- | ||
| 2 | +# This program is free software, you can redistribute it and/or modify it. | ||
| 3 | +# Copyright (c) 2025-2026 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_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 13 | +foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 14 | + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 15 | + add_subdirectory(${SUB_DIR}) | ||
| 16 | + endif() | ||
| 17 | +endforeach() | ||
| @@ -0,0 +1,17 @@ | |||
| 1 | +# ---------------------------------------------------------------------------- | ||
| 2 | +# This program is free software, you can redistribute it and/or modify it. | ||
| 3 | +# Copyright (c) 2025-2026 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_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 13 | +foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 14 | + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 15 | + add_subdirectory(${SUB_DIR}) | ||
| 16 | + endif() | ||
| 17 | +endforeach() | ||
| @@ -0,0 +1,21 @@ | |||
| 1 | +# ---------------------------------------------------------------------------- | ||
| 2 | +# This program is free software, you can redistribute it and/or modify it. | ||
| 3 | +# Copyright (c) 2025-2026 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 | +if(UT_TEST_ALL OR OP_HOST_UT) | ||
| 13 | + add_modules_ut_sources(UT_NAME ${OP_INFERSHAPE_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}) | ||
| 14 | +endif() | ||
| 15 | + | ||
| 16 | +file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 17 | +foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 18 | + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 19 | + add_subdirectory(${SUB_DIR}) | ||
| 20 | + endif() | ||
| 21 | +endforeach() | ||
| @@ -0,0 +1,14 @@ | |||
| 1 | +# ---------------------------------------------------------------------------- | ||
| 2 | +# This program is free software, you can redistribute it and/or modify it. | ||
| 3 | +# Copyright (c) 2025-2026 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 | +if(UT_TEST_ALL OR OP_HOST_UT) | ||
| 13 | + add_modules_ut_sources(UT_NAME ${OP_TILING_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}) | ||
| 14 | +endif() | ||
| @@ -0,0 +1,311 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | + * Generated By CANNBot | ||
| 11 | + */ | ||
| 12 | + | ||
| 13 | +/*! | ||
| 14 | + * \file test_acosh_grad_tiling_arch35.cpp | ||
| 15 | + * \brief AcoshGrad Tiling UT (arch35 / Ascend950) | ||
| 16 | + * | ||
| 17 | + * Covers paths in op_host/arch35/acosh_grad_tiling_arch35.cpp: | ||
| 18 | + * 1) Dtype paths: FP16 / BF16 / FP32 all map to the SAME TilingKey | ||
| 19 | + * (GET_TPL_TILING_KEY(ACOSH_GRAD_TPL_SCH_MODE_0)=0). dtype only changes | ||
| 20 | + * bytesPerElem in UB-split (fp32=36, fp16/bf16=24) → different ubFactor. | ||
| 21 | + * 2) Multi-core path (large shape) vs single-core path (small shape, tail). | ||
| 22 | + * 3) Non-aligned tail. | ||
| 23 | + * 4) Empty tensor (totalNum==0) → early-return, all fields zero. | ||
| 24 | + * 5) Failure paths: | ||
| 25 | + * - shape mismatch (different sizes) → GRAPH_FAILED | ||
| 26 | + * - unsupported dtype (DT_DOUBLE) → GRAPH_FAILED | ||
| 27 | + * | ||
| 28 | + * Platform constants (UT faker): coreNum=64, ubSize=262144, ubBlockSize=32. | ||
| 29 | + * | ||
| 30 | + * TilingData struct (acosh_grad_tiling_data.h): | ||
| 31 | + * int64_t totalNum; int64_t blockFactor; int64_t ubFactor; | ||
| 32 | + * Serialized as 3× int64 → "totalNum blockFactor ubFactor ". | ||
| 33 | + * | ||
| 34 | + * Formulas: | ||
| 35 | + * blockFactor = CeilAlign(CeilDiv(total, 64), 32) | ||
| 36 | + * perElem = 6*elemBytes + 3*4 (fp32: 36, fp16/bf16: 24) | ||
| 37 | + * ubFactor = FloorAlign(262144 / perElem, 32) (fp32: 7264, fp16/bf16: 10912) | ||
| 38 | + */ | ||
| 39 | + | ||
| 40 | + | ||
| 41 | + | ||
| 42 | + | ||
| 43 | + | ||
| 44 | + | ||
| 45 | + | ||
| 46 | +namespace optiling { | ||
| 47 | +struct AcoshGradCompileInfo {}; | ||
| 48 | +} // namespace optiling | ||
| 49 | + | ||
| 50 | +using namespace std; | ||
| 51 | + | ||
| 52 | +class AcoshGradTilingTest : public testing::Test { | ||
| 53 | +protected: | ||
| 54 | + static void SetUpTestCase() | ||
| 55 | + { | ||
| 56 | + std::cout << "AcoshGradTilingTest SetUp" << std::endl; | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + static void TearDownTestCase() | ||
| 60 | + { | ||
| 61 | + std::cout << "AcoshGradTilingTest TearDown" << std::endl; | ||
| 62 | + } | ||
| 63 | +}; | ||
| 64 | + | ||
| 65 | +// =========================================================================== | ||
| 66 | +// 1) FP32 multi-core aligned — 8192 elem {1,64,2,64} | ||
| 67 | +// blockFactor=CeilAlign(CeilDiv(8192,64)=128,32)=128, ubFactor=7264 | ||
| 68 | +// TilingKey 0 | ||
| 69 | +// =========================================================================== | ||
| 70 | +TEST_F(AcoshGradTilingTest, test_tiling_fp32_multi_core_001) | ||
| 71 | +{ | ||
| 72 | + optiling::AcoshGradCompileInfo compileInfo; | ||
| 73 | + gert::TilingContextPara tilingContextPara( | ||
| 74 | + "AcoshGrad", | ||
| 75 | + { | ||
| 76 | + {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND}, // y | ||
| 77 | + {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND}, // dy | ||
| 78 | + }, | ||
| 79 | + { | ||
| 80 | + {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND}, // z | ||
| 81 | + }, | ||
| 82 | + &compileInfo); | ||
| 83 | + uint64_t expectTilingKey = 0; | ||
| 84 | + string expectTilingData = "8192 128 7264 "; | ||
| 85 | + std::vector<size_t> expectWorkspaces = {0}; | ||
| 86 | + ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces); | ||
| 87 | +} | ||
| 88 | + | ||
| 89 | +// =========================================================================== | ||
| 90 | +// 2) FP16 multi-core aligned — same shape; ubFactor=10912 | ||
| 91 | +// =========================================================================== | ||
| 92 | +TEST_F(AcoshGradTilingTest, test_tiling_fp16_multi_core_002) | ||
| 93 | +{ | ||
| 94 | + optiling::AcoshGradCompileInfo compileInfo; | ||
| 95 | + gert::TilingContextPara tilingContextPara( | ||
| 96 | + "AcoshGrad", | ||
| 97 | + { | ||
| 98 | + {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 99 | + {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 100 | + }, | ||
| 101 | + { | ||
| 102 | + {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 103 | + }, | ||
| 104 | + &compileInfo); | ||
| 105 | + uint64_t expectTilingKey = 0; | ||
| 106 | + string expectTilingData = "8192 128 10912 "; | ||
| 107 | + std::vector<size_t> expectWorkspaces = {0}; | ||
| 108 | + ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces); | ||
| 109 | +} | ||
| 110 | + | ||
| 111 | +// =========================================================================== | ||
| 112 | +// 3) BF16 multi-core aligned — same shape; ubFactor=10912 | ||
| 113 | +// =========================================================================== | ||
| 114 | +TEST_F(AcoshGradTilingTest, test_tiling_bf16_multi_core_003) | ||
| 115 | +{ | ||
| 116 | + optiling::AcoshGradCompileInfo compileInfo; | ||
| 117 | + gert::TilingContextPara tilingContextPara( | ||
| 118 | + "AcoshGrad", | ||
| 119 | + { | ||
| 120 | + {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_BF16, ge::FORMAT_ND}, | ||
| 121 | + {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_BF16, ge::FORMAT_ND}, | ||
| 122 | + }, | ||
| 123 | + { | ||
| 124 | + {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_BF16, ge::FORMAT_ND}, | ||
| 125 | + }, | ||
| 126 | + &compileInfo); | ||
| 127 | + uint64_t expectTilingKey = 0; | ||
| 128 | + string expectTilingData = "8192 128 10912 "; | ||
| 129 | + std::vector<size_t> expectWorkspaces = {0}; | ||
| 130 | + ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces); | ||
| 131 | +} | ||
| 132 | + | ||
| 133 | +// =========================================================================== | ||
| 134 | +// 4) FP32 small + single-core + tail — {7} elem | ||
| 135 | +// blockFactor=CeilAlign(CeilDiv(7,64)=1,32)=32, usedCore=1, ubFactor=7264 | ||
| 136 | +// =========================================================================== | ||
| 137 | +TEST_F(AcoshGradTilingTest, test_tiling_fp32_small_tail_004) | ||
| 138 | +{ | ||
| 139 | + optiling::AcoshGradCompileInfo compileInfo; | ||
| 140 | + gert::TilingContextPara tilingContextPara( | ||
| 141 | + "AcoshGrad", | ||
| 142 | + { | ||
| 143 | + {{{7}, {7}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 144 | + {{{7}, {7}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 145 | + }, | ||
| 146 | + { | ||
| 147 | + {{{7}, {7}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 148 | + }, | ||
| 149 | + &compileInfo); | ||
| 150 | + uint64_t expectTilingKey = 0; | ||
| 151 | + string expectTilingData = "7 32 7264 "; | ||
| 152 | + std::vector<size_t> expectWorkspaces = {0}; | ||
| 153 | + ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces); | ||
| 154 | +} | ||
| 155 | + | ||
| 156 | +// =========================================================================== | ||
| 157 | +// 5) FP16 unaligned single-core — {17} elem | ||
| 158 | +// blockFactor=32, usedCore=1, ubFactor=10912 | ||
| 159 | +// =========================================================================== | ||
| 160 | +TEST_F(AcoshGradTilingTest, test_tiling_fp16_unalign_005) | ||
| 161 | +{ | ||
| 162 | + optiling::AcoshGradCompileInfo compileInfo; | ||
| 163 | + gert::TilingContextPara tilingContextPara( | ||
| 164 | + "AcoshGrad", | ||
| 165 | + { | ||
| 166 | + {{{17}, {17}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 167 | + {{{17}, {17}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 168 | + }, | ||
| 169 | + { | ||
| 170 | + {{{17}, {17}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 171 | + }, | ||
| 172 | + &compileInfo); | ||
| 173 | + uint64_t expectTilingKey = 0; | ||
| 174 | + string expectTilingData = "17 32 10912 "; | ||
| 175 | + std::vector<size_t> expectWorkspaces = {0}; | ||
| 176 | + ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces); | ||
| 177 | +} | ||
| 178 | + | ||
| 179 | +// =========================================================================== | ||
| 180 | +// 6) FP32 large multi-core — {416910} elem | ||
| 181 | +// blockFactor=CeilAlign(CeilDiv(416910,64)=6515,32)=6528, ubFactor=7264 | ||
| 182 | +// =========================================================================== | ||
| 183 | +TEST_F(AcoshGradTilingTest, test_tiling_fp32_large_multi_core_006) | ||
| 184 | +{ | ||
| 185 | + optiling::AcoshGradCompileInfo compileInfo; | ||
| 186 | + gert::TilingContextPara tilingContextPara( | ||
| 187 | + "AcoshGrad", | ||
| 188 | + { | ||
| 189 | + {{{416910}, {416910}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 190 | + {{{416910}, {416910}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 191 | + }, | ||
| 192 | + { | ||
| 193 | + {{{416910}, {416910}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 194 | + }, | ||
| 195 | + &compileInfo); | ||
| 196 | + uint64_t expectTilingKey = 0; | ||
| 197 | + string expectTilingData = "416910 6528 7264 "; | ||
| 198 | + std::vector<size_t> expectWorkspaces = {0}; | ||
| 199 | + ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces); | ||
| 200 | +} | ||
| 201 | + | ||
| 202 | +// =========================================================================== | ||
| 203 | +// 7) FP16 2D large multi-core — {60882, 23} = 1400286 elem | ||
| 204 | +// blockFactor=CeilAlign(CeilDiv(1400286,64)=21880,32)=21888, ubFactor=10912 | ||
| 205 | +// =========================================================================== | ||
| 206 | +TEST_F(AcoshGradTilingTest, test_tiling_fp16_2d_large_multi_core_007) | ||
| 207 | +{ | ||
| 208 | + optiling::AcoshGradCompileInfo compileInfo; | ||
| 209 | + gert::TilingContextPara tilingContextPara( | ||
| 210 | + "AcoshGrad", | ||
| 211 | + { | ||
| 212 | + {{{60882, 23}, {60882, 23}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 213 | + {{{60882, 23}, {60882, 23}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 214 | + }, | ||
| 215 | + { | ||
| 216 | + {{{60882, 23}, {60882, 23}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 217 | + }, | ||
| 218 | + &compileInfo); | ||
| 219 | + uint64_t expectTilingKey = 0; | ||
| 220 | + string expectTilingData = "1400286 21888 10912 "; | ||
| 221 | + std::vector<size_t> expectWorkspaces = {0}; | ||
| 222 | + ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces); | ||
| 223 | +} | ||
| 224 | + | ||
| 225 | +// =========================================================================== | ||
| 226 | +// 8) Empty tensor FP32 — early-return branch, all fields zero | ||
| 227 | +// =========================================================================== | ||
| 228 | +TEST_F(AcoshGradTilingTest, test_tiling_empty_fp32_008) | ||
| 229 | +{ | ||
| 230 | + optiling::AcoshGradCompileInfo compileInfo; | ||
| 231 | + gert::TilingContextPara tilingContextPara( | ||
| 232 | + "AcoshGrad", | ||
| 233 | + { | ||
| 234 | + {{{0}, {0}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 235 | + {{{0}, {0}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 236 | + }, | ||
| 237 | + { | ||
| 238 | + {{{0}, {0}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 239 | + }, | ||
| 240 | + &compileInfo); | ||
| 241 | + uint64_t expectTilingKey = 0; | ||
| 242 | + string expectTilingData = "0 0 0 "; | ||
| 243 | + std::vector<size_t> expectWorkspaces = {0}; | ||
| 244 | + ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces); | ||
| 245 | +} | ||
| 246 | + | ||
| 247 | +// =========================================================================== | ||
| 248 | +// 9) Empty tensor BF16 multi-dim — early-return | ||
| 249 | +// =========================================================================== | ||
| 250 | +TEST_F(AcoshGradTilingTest, test_tiling_empty_bf16_009) | ||
| 251 | +{ | ||
| 252 | + optiling::AcoshGradCompileInfo compileInfo; | ||
| 253 | + gert::TilingContextPara tilingContextPara( | ||
| 254 | + "AcoshGrad", | ||
| 255 | + { | ||
| 256 | + {{{0, 8}, {0, 8}}, ge::DT_BF16, ge::FORMAT_ND}, | ||
| 257 | + {{{0, 8}, {0, 8}}, ge::DT_BF16, ge::FORMAT_ND}, | ||
| 258 | + }, | ||
| 259 | + { | ||
| 260 | + {{{0, 8}, {0, 8}}, ge::DT_BF16, ge::FORMAT_ND}, | ||
| 261 | + }, | ||
| 262 | + &compileInfo); | ||
| 263 | + uint64_t expectTilingKey = 0; | ||
| 264 | + string expectTilingData = "0 0 0 "; | ||
| 265 | + std::vector<size_t> expectWorkspaces = {0}; | ||
| 266 | + ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces); | ||
| 267 | +} | ||
| 268 | + | ||
| 269 | +// =========================================================================== | ||
| 270 | +// 10) FAIL: shape mismatch (different sizes) → GRAPH_FAILED | ||
| 271 | +// =========================================================================== | ||
| 272 | +TEST_F(AcoshGradTilingTest, test_tiling_fail_shape_mismatch_010) | ||
| 273 | +{ | ||
| 274 | + optiling::AcoshGradCompileInfo compileInfo; | ||
| 275 | + gert::TilingContextPara tilingContextPara( | ||
| 276 | + "AcoshGrad", | ||
| 277 | + { | ||
| 278 | + {{{16}, {16}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 279 | + {{{8}, {8}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 280 | + }, | ||
| 281 | + { | ||
| 282 | + {{{16}, {16}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 283 | + }, | ||
| 284 | + &compileInfo); | ||
| 285 | + uint64_t expectTilingKey = 0; | ||
| 286 | + string expectTilingData = ""; | ||
| 287 | + std::vector<size_t> expectWorkspaces = {0}; | ||
| 288 | + ExecuteTestCase(tilingContextPara, ge::GRAPH_FAILED, expectTilingKey, expectTilingData, expectWorkspaces); | ||
| 289 | +} | ||
| 290 | + | ||
| 291 | +// =========================================================================== | ||
| 292 | +// 11) FAIL: unsupported dtype (DT_DOUBLE) → GRAPH_FAILED | ||
| 293 | +// =========================================================================== | ||
| 294 | +TEST_F(AcoshGradTilingTest, test_tiling_fail_unsupported_dtype_011) | ||
| 295 | +{ | ||
| 296 | + optiling::AcoshGradCompileInfo compileInfo; | ||
| 297 | + gert::TilingContextPara tilingContextPara( | ||
| 298 | + "AcoshGrad", | ||
| 299 | + { | ||
| 300 | + {{{8}, {8}}, ge::DT_DOUBLE, ge::FORMAT_ND}, | ||
| 301 | + {{{8}, {8}}, ge::DT_DOUBLE, ge::FORMAT_ND}, | ||
| 302 | + }, | ||
| 303 | + { | ||
| 304 | + {{{8}, {8}}, ge::DT_DOUBLE, ge::FORMAT_ND}, | ||
| 305 | + }, | ||
| 306 | + &compileInfo); | ||
| 307 | + uint64_t expectTilingKey = 0; | ||
| 308 | + string expectTilingData = ""; | ||
| 309 | + std::vector<size_t> expectWorkspaces = {0}; | ||
| 310 | + ExecuteTestCase(tilingContextPara, ge::GRAPH_FAILED, expectTilingKey, expectTilingData, expectWorkspaces); | ||
| 311 | +} | ||
| @@ -0,0 +1,168 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | + * Generated By CANNBot | ||
| 11 | + */ | ||
| 12 | + | ||
| 13 | +/*! | ||
| 14 | + * \file test_acosh_grad_infershape.cpp | ||
| 15 | + * \brief AcoshGrad InferShape UT — output shape copies input[0] shape. | ||
| 16 | + * | ||
| 17 | + * Op signature (aligned with proto.h / def.cpp): | ||
| 18 | + * Input 0: y (forward output of Acosh) | ||
| 19 | + * Input 1: dy (upstream gradient) | ||
| 20 | + * Output 0: z (gradient w.r.t. original input, same shape as y) | ||
| 21 | + * | ||
| 22 | + * Supported dtypes (per def.cpp): FLOAT16, BF16, FLOAT. Format: ND only. | ||
| 23 | + * Shape rule: z.shape = y.shape (acosh_grad_infershape.cpp: *output_shape = *input_shape). | ||
| 24 | + */ | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 31 | +class AcoshGradInfershape : public testing::Test { | ||
| 32 | +protected: | ||
| 33 | + static void SetUpTestCase() | ||
| 34 | + { | ||
| 35 | + std::cout << "AcoshGradInfershape SetUp" << std::endl; | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + static void TearDownTestCase() | ||
| 39 | + { | ||
| 40 | + std::cout << "AcoshGradInfershape TearDown" << std::endl; | ||
| 41 | + } | ||
| 42 | +}; | ||
| 43 | + | ||
| 44 | +// --------------------------------------------------------------------------- | ||
| 45 | +// 1D, fp32 — small shape | ||
| 46 | +// --------------------------------------------------------------------------- | ||
| 47 | +TEST_F(AcoshGradInfershape, acosh_grad_infershape_1d_fp32) | ||
| 48 | +{ | ||
| 49 | + gert::InfershapeContextPara infershapeContextPara( | ||
| 50 | + "AcoshGrad", | ||
| 51 | + { | ||
| 52 | + {{{16}, {16}}, ge::DT_FLOAT, ge::FORMAT_ND}, // y | ||
| 53 | + {{{16}, {16}}, ge::DT_FLOAT, ge::FORMAT_ND}, // dy | ||
| 54 | + }, | ||
| 55 | + { | ||
| 56 | + {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND}, // z (to infer) | ||
| 57 | + }); | ||
| 58 | + std::vector<std::vector<int64_t>> expectOutputShape = {{16}}; | ||
| 59 | + ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape); | ||
| 60 | +} | ||
| 61 | + | ||
| 62 | +// --------------------------------------------------------------------------- | ||
| 63 | +// 1D non-aligned, fp32 | ||
| 64 | +// --------------------------------------------------------------------------- | ||
| 65 | +TEST_F(AcoshGradInfershape, acosh_grad_infershape_1d_tail_fp32) | ||
| 66 | +{ | ||
| 67 | + gert::InfershapeContextPara infershapeContextPara( | ||
| 68 | + "AcoshGrad", | ||
| 69 | + { | ||
| 70 | + {{{7}, {7}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 71 | + {{{7}, {7}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 72 | + }, | ||
| 73 | + { | ||
| 74 | + {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 75 | + }); | ||
| 76 | + std::vector<std::vector<int64_t>> expectOutputShape = {{7}}; | ||
| 77 | + ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape); | ||
| 78 | +} | ||
| 79 | + | ||
| 80 | +// --------------------------------------------------------------------------- | ||
| 81 | +// 2D, fp16 | ||
| 82 | +// --------------------------------------------------------------------------- | ||
| 83 | +TEST_F(AcoshGradInfershape, acosh_grad_infershape_2d_fp16) | ||
| 84 | +{ | ||
| 85 | + gert::InfershapeContextPara infershapeContextPara( | ||
| 86 | + "AcoshGrad", | ||
| 87 | + { | ||
| 88 | + {{{4, 8}, {4, 8}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 89 | + {{{4, 8}, {4, 8}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 90 | + }, | ||
| 91 | + { | ||
| 92 | + {{{}, {}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 93 | + }); | ||
| 94 | + std::vector<std::vector<int64_t>> expectOutputShape = {{4, 8}}; | ||
| 95 | + ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape); | ||
| 96 | +} | ||
| 97 | + | ||
| 98 | +// --------------------------------------------------------------------------- | ||
| 99 | +// 4D, bf16 | ||
| 100 | +// --------------------------------------------------------------------------- | ||
| 101 | +TEST_F(AcoshGradInfershape, acosh_grad_infershape_4d_bf16) | ||
| 102 | +{ | ||
| 103 | + gert::InfershapeContextPara infershapeContextPara( | ||
| 104 | + "AcoshGrad", | ||
| 105 | + { | ||
| 106 | + {{{2, 3, 4, 5}, {2, 3, 4, 5}}, ge::DT_BF16, ge::FORMAT_ND}, | ||
| 107 | + {{{2, 3, 4, 5}, {2, 3, 4, 5}}, ge::DT_BF16, ge::FORMAT_ND}, | ||
| 108 | + }, | ||
| 109 | + { | ||
| 110 | + {{{}, {}}, ge::DT_BF16, ge::FORMAT_ND}, | ||
| 111 | + }); | ||
| 112 | + std::vector<std::vector<int64_t>> expectOutputShape = {{2, 3, 4, 5}}; | ||
| 113 | + ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape); | ||
| 114 | +} | ||
| 115 | + | ||
| 116 | +// --------------------------------------------------------------------------- | ||
| 117 | +// Large multi-core shape, fp32 | ||
| 118 | +// --------------------------------------------------------------------------- | ||
| 119 | +TEST_F(AcoshGradInfershape, acosh_grad_infershape_large_fp32) | ||
| 120 | +{ | ||
| 121 | + gert::InfershapeContextPara infershapeContextPara( | ||
| 122 | + "AcoshGrad", | ||
| 123 | + { | ||
| 124 | + {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 125 | + {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 126 | + }, | ||
| 127 | + { | ||
| 128 | + {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 129 | + }); | ||
| 130 | + std::vector<std::vector<int64_t>> expectOutputShape = {{1, 64, 2, 64}}; | ||
| 131 | + ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape); | ||
| 132 | +} | ||
| 133 | + | ||
| 134 | +// --------------------------------------------------------------------------- | ||
| 135 | +// Large 1D, fp16 — stress test | ||
| 136 | +// --------------------------------------------------------------------------- | ||
| 137 | +TEST_F(AcoshGradInfershape, acosh_grad_infershape_large_1d_fp16) | ||
| 138 | +{ | ||
| 139 | + gert::InfershapeContextPara infershapeContextPara( | ||
| 140 | + "AcoshGrad", | ||
| 141 | + { | ||
| 142 | + {{{416910}, {416910}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 143 | + {{{416910}, {416910}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 144 | + }, | ||
| 145 | + { | ||
| 146 | + {{{}, {}}, ge::DT_FLOAT16, ge::FORMAT_ND}, | ||
| 147 | + }); | ||
| 148 | + std::vector<std::vector<int64_t>> expectOutputShape = {{416910}}; | ||
| 149 | + ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape); | ||
| 150 | +} | ||
| 151 | + | ||
| 152 | +// --------------------------------------------------------------------------- | ||
| 153 | +// Empty tensor, fp32 | ||
| 154 | +// --------------------------------------------------------------------------- | ||
| 155 | +TEST_F(AcoshGradInfershape, acosh_grad_infershape_empty_fp32) | ||
| 156 | +{ | ||
| 157 | + gert::InfershapeContextPara infershapeContextPara( | ||
| 158 | + "AcoshGrad", | ||
| 159 | + { | ||
| 160 | + {{{0}, {0}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 161 | + {{{0}, {0}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 162 | + }, | ||
| 163 | + { | ||
| 164 | + {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND}, | ||
| 165 | + }); | ||
| 166 | + std::vector<std::vector<int64_t>> expectOutputShape = {{0}}; | ||
| 167 | + ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape); | ||
| 168 | +} | ||


这里标记 op_api 为 ×,需要确认算子是否真的没有 aclnn 调用接口。如果有接口实现,应该标记为 √。