已合并
invert算子补充example #671
tan_xin创建于 1月6日
invert算子补充example #671
已合并
tan_xin创建于 1月6日
6 个文件变更+380-22
Mdocs/zh/op_list.md+48-7
@@ -1017,12 +1017,12 @@
1017 <tr>1017 <tr>
1018 <td>math</td>1018 <td>math</td>
1019 <td><a href="../../math/invert">invert</a></td>1019 <td><a href="../../math/invert">invert</a></td>
1020+ <td>√</td>
1021+ <td>√</td>
1020 <td>×</td>1022 <td>×</td>
1021- <td>×</td>1023+ <td></td>
1022- <td>×</td>
1023- <td>×</td>
1024 <td>AI Core</td>1024 <td>AI Core</td>
1025- <td>该算子暂无Ascend C代码实现,欢迎开发者补充贡献,贡献方式参考<a href="../../CONTRIBUTING.md">贡献指南</a>。</td>1025+ <td>为输入张量的每一个元素取反。</td>
1026 </tr>1026 </tr>
1027 <tr>1027 <tr>
1028 <td>math</td>1028 <td>math</td>
@@ -1727,12 +1727,12 @@
1727 <tr>1727 <tr>
1728 <td>conversion</td>1728 <td>conversion</td>
1729 <td><a href="../../conversion/as_strided">as_strided</a></td>1729 <td><a href="../../conversion/as_strided">as_strided</a></td>
1730- <td>×</td>1730+ <td></td>
1731- <td>×</td>1731+ <td></td>
1732 <td>×</td>1732 <td>×</td>
1733 <td>√</td>1733 <td>√</td>
1734 <td>AI Core</td>1734 <td>AI Core</td>
1735- <td>该算子暂无Ascend C代码实现,欢迎开发者补充贡献,贡献方式参考<a href="../../CONTRIBUTING.md">贡献指南</a>。</td>1735+ <td>允许用户通过制定新的形状和步长来创建一个与原张量共享相同数据内存的张量视图。</td>
1736 </tr>1736 </tr>
1737 <tr>1737 <tr>
1738 <td>conversion</td>1738 <td>conversion</td>
@@ -2113,5 +2113,46 @@
2113 <td>√</td>2113 <td>√</td>
2114 <td>AI Core</td>2114 <td>AI Core</td>
2115 <td>生成均匀分布随机数。</td>2115 <td>生成均匀分布随机数。</td>
2116+ </tr>
2117+ <tr>
2118+ <td>math</td>
2119+ <td><a href="../../math/assign_add/README.md">assign_add</a></td>
2120+ <td>√</td>
2121+ <td>√</td>
2122+ <td>×</td>
2123+ <td>√</td>
2124+ <td>AI CPU</td>
2125+ <td>该算子完成在原有tensor上的加法计算。</td>
2126+ </tr>ias
2127+ <tr>
2128+ <td>math</td>
2129+ <td><a href="../../math/assign_sub/README.md">assign_sub</a></td>
2130+ <td>√</td>
2131+ <td>√</td>
2132+ <td>×</td>
2133+ <td>√</td>
2134+ <td>AI CPU</td>
2135+ <td>该算子完成在原有tensor上的减法计算。</td>
2136+ </tr>
2137+ <tr>
2138+ <td>math</td>
2139+ <td><a href="../../math/square_sum_v1/README.md">square_sum_v1</a></td>
2140+ <td>√</td>
2141+ <td>√</td>
2142+ <td>×</td>
2143+ <td>√</td>
2144+ <td>AI CPU</td>
2145+ <td>用于计算输入张量在指定轴上的平方和。</td>
2146+ </tr>
2147+ <tr>
2148+ <td>math</td>
2149+ <td><a href="../../math/bias_add_grad/README.md">bias_add_grad</a></td>
2150+ <td>√</td>
2151+ <td>√</td>
2152+ <td>×</td>
2153+ <td>√</td>
2154+ <td>AI Core</td>
2155+ <td>计算偏置的梯度。</td>
2156+ </tr>
2116</tbody>2157</tbody>
2117</table>2158</table>
Mmath/invert/README.md+59-1
@@ -1,3 +1,61 @@
1# Invert1# Invert
2 2 
3-本目录仅包含Invert算子对应的aclnn接口;如您想要贡献该算子的AscendC实现,请参考[贡献流程](../../CONTRIBUTING.md)。3+## 产品支持情况
4+ 
5+| 产品 | 是否支持 |
6+| :----------------------------------------------------------- | :------: |
7+| <term>Ascend 950PR/Ascend 950DT</term> | √ |
8+ 
9+## 功能说明
10+ 
11+- 算子功能:为输入张量的每一个元素取反。
12+ 
13+- 计算公式:
14+ 
15+$$out_i=\sim input_i$$
16+ 
17+## 参数说明
18+ 
19+<table style="undefined;table-layout: fixed; width: 980px"><colgroup>
20+ <col style="width: 100px">
21+ <col style="width: 150px">
22+ <col style="width: 280px">
23+ <col style="width: 330px">
24+ <col style="width: 120px">
25+ </colgroup>
26+ <thead>
27+ <tr>
28+ <th>参数名</th>
29+ <th>输入/输出/属性</th>
30+ <th>描述</th>
31+ <th>数据类型</th>
32+ <th>数据格式</th>
33+ </tr></thead>
34+ <tbody>
35+ <tr>
36+ <td>x</td>
37+ <td>输入</td>
38+ <td>待进行invert计算的入参,公式中的input_i。</td>
39+ <td>INT8、INT16、INT32、INT64、UINT8、UINT16、UINT32、UINT64</td>
40+ <td>ND</td>
41+ </tr>
42+ <tr>
43+ <td>y</td>
44+ <td>输出</td>
45+ <td>待进行invert计算的出参,公式中的out_i。</td>
46+ <td>INT8、INT16、INT32、INT64、UINT8、UINT16、UINT32、UINT64</td>
47+ <td>ND</td>
48+ </tr>
49+ </tbody></table>
50+ 
51+- Atlas 训练系列产品、Atlas 推理系列产品: 不支持BFLOAT16。
52+ 
53+## 约束说明
54+ 
55+
56+ 
57+## 调用说明
58+ 
59+| 调用方式 | 调用样例 | 说明 |
60+|---------|----------------------------------------------------|----------------------------------------------------------------------------------------------|
61+| 图模式调用 | [test_geir_invert](./examples/test_geir_invert.cpp) | 通过[算子IR](./op_graph/invert_proto.h)构图方式调用invert算子
Amath/invert/examples/test_geir_invert.cpp+261-0
@@ -0,0 +1,261 @@
1+/**
2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+#include <iostream>
12+#include <fstream>
13+#include <string.h>
14+#include <stdint.h>
15+#include <vector>
16+#include <string>
17+#include <map>
18+#include "assert.h"
19+ 
20+#include "graph.h"
21+#include "types.h"
22+#include "tensor.h"
23+#include "ge_error_codes.h"
24+#include "ge_api_types.h"
25+#include "ge_api.h"
26+#include "array_ops.h"
27+#include "ge_ir_build.h"
28+ 
29+#include "experiment_ops.h"
30+#include "nn_other.h"
31+#include "../op_graph/invert_proto.h"
32+ 
33+#define FAILED -1
34+#define SUCCESS 0
35+ 
36+using namespace ge;
37+using std::map;
38+using std::string;
39+using std::vector;
40+#define ADD_INPUT(intputIndex, intputName, intputDtype, inputShape) \
41+ vector<int64_t> placeholder##intputIndex##_shape = inputShape; \
42+ auto placeholder##intputIndex = op::Data("placeholder" + intputIndex).set_attr_index(0); \
43+ TensorDesc placeholder##intputIndex##_desc = \
44+ TensorDesc(ge::Shape(placeholder##intputIndex##_shape), FORMAT_ND, intputDtype); \
45+ placeholder##intputIndex##_desc.SetPlacement(ge::kPlacementHost); \
46+ placeholder##intputIndex##_desc.SetFormat(FORMAT_ND); \
47+ Tensor tensor_placeholder##intputIndex; \
48+ ret = GenOnesData( \
49+ placeholder##intputIndex##_shape, tensor_placeholder##intputIndex, placeholder##intputIndex##_desc, \
50+ intputDtype, 2); \
51+ if (ret != SUCCESS) { \
52+ printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \
53+ return FAILED; \
54+ } \
55+ placeholder##intputIndex.update_input_desc_x(placeholder##intputIndex##_desc); \
56+ input.push_back(tensor_placeholder##intputIndex); \
57+ graph.AddOp(placeholder##intputIndex); \
58+ invert1.set_input_##intputName(placeholder##intputIndex); \
59+ inputs.push_back(placeholder##intputIndex);
60+ 
61+#define ADD_OUTPUT(outputIndex, outputName, outputDtype, outputShape) \
62+ TensorDesc outputName##outputIndex##_desc = TensorDesc(ge::Shape(outputShape), FORMAT_ND, outputDtype); \
63+ invert1.update_output_desc_##outputName(outputName##outputIndex##_desc);
64+ 
65+#define LOG_PRINT(message, ...) \
66+ do { \
67+ printf(message, ##__VA_ARGS__); \
68+ } while (0)
69+ 
70+string GetTime()
71+{
72+ time_t timep;
73+ time(&timep);
74+ char tmp[64];
75+ strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S,000", localtime(&timep));
76+ return tmp;
77+}
78+ 
79+uint32_t GetDataTypeSize(DataType dt)
80+{
81+ uint32_t dilation = 1;
82+ uint32_t oneByte = 1;
83+ uint32_t twoByte = 2;
84+ uint32_t fourByte = 4;
85+ uint32_t eightByte = 8;
86+ 
87+ if (dt == ge::DT_FLOAT) {
88+ dilation = fourByte;
89+ } else if (dt == ge::DT_FLOAT16) {
90+ dilation = twoByte;
91+ } else if (dt == ge::DT_BF16) {
92+ dilation = twoByte;
93+ } else if (dt == ge::DT_INT16) {
94+ dilation = twoByte;
95+ } else if (dt == ge::DT_UINT16) {
96+ dilation = twoByte;
97+ } else if (dt == ge::DT_INT32) {
98+ dilation = fourByte;
99+ } else if (dt == ge::DT_UINT32) {
100+ dilation = fourByte;
101+ } else if (dt == ge::DT_INT64) {
102+ dilation = eightByte;
103+ } else if (dt == ge::DT_UINT64) {
104+ dilation = eightByte;
105+ } else if (dt == ge::DT_INT8) {
106+ dilation = oneByte;
107+ }
108+ return dilation;
109+}
110+ 
111+int32_t GenOnesData(
112+ vector<int64_t> shapes, Tensor& input_tensor, TensorDesc& input_tensor_desc, DataType data_type, int value)
113+{
114+ input_tensor_desc.SetRealDimCnt(shapes.size());
115+ size_t size = 1;
116+ for (uint32_t i = 0; i < shapes.size(); i++) {
117+ size *= shapes[i];
118+ }
119+ uint32_t data_len = size * GetDataTypeSize(data_type);
120+ int32_t* pData = new (std::nothrow) int32_t[data_len];
121+ for (uint32_t i = 0; i < size; ++i) {
122+ *(pData + i) = value;
123+ }
124+ input_tensor = Tensor(input_tensor_desc, reinterpret_cast<uint8_t*>(pData), data_len);
125+ return SUCCESS;
126+}
127+ 
128+int32_t WriteDataToFile(string bin_file, uint64_t data_size, uint8_t* inputData)
129+{
130+ FILE* fp;
131+ fp = fopen(bin_file.c_str(), "w");
132+ fwrite(inputData, sizeof(uint8_t), data_size, fp);
133+ fclose(fp);
134+ return SUCCESS;
135+}
136+ 
137+int CreateOppInGraph(
138+ DataType inDtype, std::vector<ge::Tensor>& input, std::vector<Operator>& inputs, std::vector<Operator>& outputs,
139+ Graph& graph)
140+{
141+ Status ret = SUCCESS;
142+ // 自定义代码:添加单算子定义到图中
143+ auto invert1 = op::Invert("invert1");
144+ std::vector<int64_t> xShape = {4, 2};
145+ ADD_INPUT(1, x, inDtype, xShape);
146+ ADD_OUTPUT(1, y, inDtype, xShape);
147+ 
148+ outputs.push_back(invert1);
149+ // 添加完毕
150+ return SUCCESS;
151+}
152+ 
153+int main(int argc, char* argv[])
154+{
155+ const char* graph_name = "tc_ge_irrun_test";
156+ Graph graph(graph_name);
157+ std::vector<ge::Tensor> input;
158+ 
159+ printf("%s - INFO - [XIR]: Start to initialize ge using ge global options\n", GetTime().c_str());
160+ std::map<AscendString, AscendString> global_options = {{"ge.exec.deviceId", "0"}, {"ge.graphRunMode", "1"}};
161+ Status ret = ge::GEInitialize(global_options);
162+ if (ret != SUCCESS) {
163+ printf("%s - INFO - [XIR]: Initialize ge using ge global options failed\n", GetTime().c_str());
164+ return FAILED;
165+ }
166+ printf("%s - INFO - [XIR]: Initialize ge using ge global options success\n", GetTime().c_str());
167+ 
168+ std::vector<Operator> inputs{};
169+ std::vector<Operator> outputs{};
170+ 
171+ std::cout << argv[1] << std::endl;
172+ char* endptr;
173+ 
174+ DataType inDtype = DT_INT32;
175+ std::cout << inDtype << std::endl;
176+ 
177+ ret = CreateOppInGraph(inDtype, input, inputs, outputs, graph);
178+ if (ret != SUCCESS) {
179+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
180+ return FAILED;
181+ }
182+ 
183+ if (!inputs.empty() && !outputs.empty()) {
184+ graph.SetInputs(inputs).SetOutputs(outputs);
185+ }
186+ 
187+ std::map<AscendString, AscendString> build_options = {
188+ 
189+ };
190+ printf("%s - INFO - [XIR]: Start to create ir session using build options\n", GetTime().c_str());
191+ ge::Session* session = new Session(build_options);
192+ 
193+ if (session == nullptr) {
194+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
195+ return FAILED;
196+ }
197+ printf("%s - INFO - [XIR]: Create ir session using build options success\n", GetTime().c_str());
198+ printf("%s - INFO - [XIR]: Start to add compute graph to ir session\n", GetTime().c_str());
199+ 
200+ std::map<AscendString, AscendString> graph_options = {
201+ 
202+ };
203+ uint32_t graph_id = 0;
204+ ret = session->AddGraph(graph_id, graph, graph_options);
205+ 
206+ printf("%s - INFO - [XIR]: Session add ir compute graph to ir session success\n", GetTime().c_str());
207+ printf("%s - INFO - [XIR]: dump graph to txt\n", GetTime().c_str());
208+ std::string file_path = "./dump";
209+ aclgrphDumpGraph(graph, file_path.c_str(), file_path.length());
210+ printf("%s - INFO - [XIR]: Start to run ir compute graph\n", GetTime().c_str());
211+ std::vector<ge::Tensor> output;
212+ ret = session->RunGraph(graph_id, input, output);
213+ if (ret != SUCCESS) {
214+ printf("%s - INFO - [XIR]: Run graph failed\n", GetTime().c_str());
215+ delete session;
216+ GEFinalize();
217+ return FAILED;
218+ }
219+ printf("%s - INFO - [XIR]: Session run ir compute graph success\n", GetTime().c_str());
220+ 
221+ int input_num = input.size();
222+ for (int i = 0; i < input_num; i++) {
223+ std::cout << "input " << i << " dtype : " << input[i].GetTensorDesc().GetDataType() << std::endl;
224+ string input_file = "./tc_ge_irrun_test_0008_npu_input_" + std::to_string(i) + ".bin";
225+ uint8_t* input_data_i = input[i].GetData();
226+ int64_t input_shape = input[i].GetTensorDesc().GetShape().GetShapeSize();
227+ std::cout << "this is " << i << "th input, input shape size =" << input_shape << std::endl;
228+ uint32_t data_size = input_shape * GetDataTypeSize(input[i].GetTensorDesc().GetDataType());
229+ WriteDataToFile((const char*)input_file.c_str(), data_size, input_data_i);
230+ }
231+ 
232+ int output_num = output.size();
233+ for (int i = 0; i < output_num; i++) {
234+ std::cout << "output " << i << " dtype : " << output[i].GetTensorDesc().GetDataType() << std::endl;
235+ string output_file = "./tc_ge_irrun_test_0008_npu_output_" + std::to_string(i) + ".bin";
236+ uint8_t* output_data_i = output[i].GetData();
237+ int64_t output_shape = output[i].GetTensorDesc().GetShape().GetShapeSize();
238+ std::cout << "this is " << i << "th output, output shape size =" << output_shape << std::endl;
239+ uint32_t data_size = output_shape * GetDataTypeSize(output[i].GetTensorDesc().GetDataType());
240+ WriteDataToFile((const char*)output_file.c_str(), data_size, output_data_i);
241+ int32_t* result = (int32_t*)output_data_i;
242+ for (int64_t j = 0; j < output_shape; j++) {
243+ LOG_PRINT("result[%ld] is: %d\n", j, result[j]);
244+ }
245+ }
246+ 
247+ ge::AscendString error_msg = ge::GEGetErrorMsgV2();
248+ std::string error_str(error_msg.GetString());
249+ std::cout << "Error message: " << error_str << std::endl;
250+ ge::AscendString warning_msg = ge::GEGetWarningMsgV2();
251+ std::string warning_str(warning_msg.GetString());
252+ std::cout << "Warning message: " << warning_str << std::endl;
253+ printf("%s - INFO - [XIR]: Start to finalize ir graph session\n", GetTime().c_str());
254+ ret = ge::GEFinalize();
255+ if (ret != SUCCESS) {
256+ printf("%s - INFO - [XIR]: Finalize ir graph session failed\n", GetTime().c_str());
257+ return FAILED;
258+ }
259+ printf("%s - INFO - [XIR]: Finalize ir graph session success\n", GetTime().c_str());
260+ return SUCCESS;
261+}
Mmath/invert/op_host/arch35/invert_tiling_arch35.cpp+10-10
@@ -32,7 +32,7 @@ ge::graphStatus InvertTiling::SetTilingData()
32 size_t* currentWorkspace = context_->GetWorkspaceSizes(1);32 size_t* currentWorkspace = context_->GetWorkspaceSizes(1);
33 currentWorkspace[0] = INVERT_WORKSPACE_RESERVE_BYTE;33 currentWorkspace[0] = INVERT_WORKSPACE_RESERVE_BYTE;
34 context_->SetTilingKey(INVERT_TILING_KEY);34 context_->SetTilingKey(INVERT_TILING_KEY);
35- context_->SetBlockDim(td_.blockNum);35+ context_->SetBlockDim(td_->blockNum);
36 return ge::GRAPH_SUCCESS;36 return ge::GRAPH_SUCCESS;
37}37}
38 38 
@@ -58,38 +58,38 @@ ge::graphStatus InvertTiling::RunTiling()
58 OP_LOGE(context_->GetNodeName(), "get output dtype failed."), return ge::GRAPH_FAILED);58 OP_LOGE(context_->GetNodeName(), "get output dtype failed."), return ge::GRAPH_FAILED);
59 59 
60 ge::graphStatus res = ge::GRAPH_FAILED;60 ge::graphStatus res = ge::GRAPH_FAILED;
61- td_ = *context_->GetTilingData<EleBaseTilingData>();61+ td_ = context_->GetTilingData<EleBaseTilingData>();
62 switch (outputDtype) {62 switch (outputDtype) {
63 case ge::DataType::DT_INT8: {63 case ge::DataType::DT_INT8: {
64- res = DoTiling<InvertDag<int8_t>::OpDag>(td_);64+ res = DoTiling<InvertDag<int8_t>::OpDag>(*td_);
65 break;65 break;
66 }66 }
67 case ge::DataType::DT_INT16: {67 case ge::DataType::DT_INT16: {
68- res = DoTiling<InvertDag<int16_t>::OpDag>(td_);68+ res = DoTiling<InvertDag<int16_t>::OpDag>(*td_);
69 break;69 break;
70 }70 }
71 case ge::DataType::DT_INT32: {71 case ge::DataType::DT_INT32: {
72- res = DoTiling<InvertDag<int32_t>::OpDag>(td_);72+ res = DoTiling<InvertDag<int32_t>::OpDag>(*td_);
73 break;73 break;
74 }74 }
75 case ge::DataType::DT_INT64: {75 case ge::DataType::DT_INT64: {
76- res = DoTiling<InvertDag<int64_t>::OpDag>(td_);76+ res = DoTiling<InvertDag<int64_t>::OpDag>(*td_);
77 break;77 break;
78 }78 }
79 case ge::DataType::DT_UINT8: {79 case ge::DataType::DT_UINT8: {
80- res = DoTiling<InvertDag<uint8_t>::OpDag>(td_);80+ res = DoTiling<InvertDag<uint8_t>::OpDag>(*td_);
81 break;81 break;
82 }82 }
83 case ge::DataType::DT_UINT16: {83 case ge::DataType::DT_UINT16: {
84- res = DoTiling<InvertDag<uint16_t>::OpDag>(td_);84+ res = DoTiling<InvertDag<uint16_t>::OpDag>(*td_);
85 break;85 break;
86 }86 }
87 case ge::DataType::DT_UINT32: {87 case ge::DataType::DT_UINT32: {
88- res = DoTiling<InvertDag<uint32_t>::OpDag>(td_);88+ res = DoTiling<InvertDag<uint32_t>::OpDag>(*td_);
89 break;89 break;
90 }90 }
91 case ge::DataType::DT_UINT64: {91 case ge::DataType::DT_UINT64: {
92- res = DoTiling<InvertDag<uint64_t>::OpDag>(td_);92+ res = DoTiling<InvertDag<uint64_t>::OpDag>(*td_);
93 break;93 break;
94 }94 }
95 default: {95 default: {
Mmath/invert/op_host/arch35/invert_tiling_arch35.h+1-1
@@ -32,7 +32,7 @@ private:
32 32 
33private:33private:
34 gert::TilingContext* context_;34 gert::TilingContext* context_;
35- EleBaseTilingData td_;35+ EleBaseTilingData* td_;
36};36};
37 37 
38} // namespace optiling38} // namespace optiling
Mmath/invert/tests/ut/op_host/arch35/test_invert_tiling.cpp+1-3
@@ -114,7 +114,5 @@ TEST_F(InvertTilingTest, InvertTiling_005)
114 {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND},114 {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND},
115 },115 },
116 &compileInfo);116 &compileInfo);
117- uint64_t expectTilingKey = 2660;117+ ExecuteTestCase(tilingContextPara, ge::GRAPH_FAILED);
118- std::vector<size_t> expectWorkspaces = {16777216};
119- ExecuteTestCase(tilingContextPara, ge::GRAPH_FAILED, expectTilingKey, expectWorkspaces);
120}118}