已合并
补充assign_add、assign_sub、square_sum_v1算子readme、example、ut #618
tan_xin创建于 2025年12月31日
补充assign_add、assign_sub、square_sum_v1算子readme、example、ut #618
已合并
tan_xin创建于 2025年12月31日
10 个文件变更+1493-0
@@ -0,0 +1,74 @@
1+# AssignAdd
2+ 
3+## 产品支持情况
4+ 
5+| 产品 | 是否支持 |
6+| :----------------------------------------------------------- | :------: |
7+| <term>Ascend 950PR/Ascend 950DT</term> | √ |
8+ 
9+## 功能说明
10+ 
11+- 算子功能:完成在原有tensor上的加法计算。
12+ 
13+- 计算公式:
14+ 
15+$$out_i = ref_i + value_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>ref</td>
37+ <td>输入</td>
38+ <td>输入张量,公式中的ref_i。</td>
39+ <td>BFLOAT16、FLOAT16、FLOAT、INT8、INT32、INT64、UINT8</td>
40+ <td>ND</td>
41+ </tr>
42+ <tr>
43+ <td>value</td>
44+ <td>输入</td>
45+ <td>输入张量,表示要加到ref_i上的值,公式中的value_i。</td>
46+ <td>BFLOAT16、FLOAT16、FLOAT、INT8、INT32、INT64、UINT8</td>
47+ <td>ND</td>
48+ </tr>
49+ <tr>
50+ <td>ref</td>
51+ <td>输出</td>
52+ <td>输出张量,公式中的out_i,与ref同地址。</td>
53+ <td>BFLOAT16、FLOAT16、FLOAT、INT8、INT32、INT64、UINT8</td>
54+ <td>ND</td>
55+ </tr>
56+ <tr>
57+ <td>use_locking</td>
58+ <td>属性</td>
59+ <td>可选,是否使用锁来保护更新操作。</td>
60+ <td>bool</td>
61+ <td>ND</td>
62+ </tr>
63+ </tbody></table>
64+ 
65+ 
66+## 约束说明
67+ 
68+
69+ 
70+## 调用说明
71+| 调用方式 | 调用样例 | 说明 |
72+|--------------|-----------------------------------------------------|----------------------------------------------------------------|
73+| 图模式调用 | [test_geir_assign_add.cpp](examples/test_geir_assign_add.cpp) | 通过[算子IR](op_graph/assign_add_proto.h)构图方式调用AssignAdd算子。 |
74+ 
@@ -0,0 +1,271 @@
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/assign_add_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(placeholder##intputIndex##_shape, \
49+ tensor_placeholder##intputIndex, \
50+ placeholder##intputIndex##_desc, \
51+ intputDtype, \
52+ 2); \
53+ if (ret != SUCCESS) { \
54+ printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \
55+ return FAILED; \
56+ } \
57+ placeholder##intputIndex.update_input_desc_x(placeholder##intputIndex##_desc); \
58+ input.push_back(tensor_placeholder##intputIndex); \
59+ graph.AddOp(placeholder##intputIndex); \
60+ assignAdd1.set_input_##intputName(placeholder##intputIndex); \
61+ inputs.push_back(placeholder##intputIndex);
62+ 
63+#define ADD_INPUT_ATTR(attrName, attrValue) \
64+ assignAdd1.set_attr_##attrName(attrValue);
65+ 
66+#define ADD_OUTPUT(outputIndex, outputName, outputDtype, outputShape) \
67+ TensorDesc outputName##outputIndex##_desc = \
68+ TensorDesc(ge::Shape(outputShape), FORMAT_ND, outputDtype); \
69+ assignAdd1.update_output_desc_##outputName(outputName##outputIndex##_desc);
70+ 
71+#define LOG_PRINT(message, ...) \
72+ do { \
73+ printf(message, ##__VA_ARGS__); \
74+ } while (0)
75+ 
76+string GetTime()
77+{
78+ time_t timep;
79+ time(&timep);
80+ char tmp[64];
81+ strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S,000", localtime(&timep));
82+ return tmp;
83+}
84+ 
85+uint32_t GetDataTypeSize(DataType dt)
86+{
87+ uint32_t dilation = 1;
88+ uint32_t oneByte = 1;
89+ uint32_t twoByte = 2;
90+ uint32_t fourByte = 4;
91+ uint32_t eightByte = 8;
92+ 
93+ if (dt == ge::DT_FLOAT) {
94+ dilation = fourByte;
95+ } else if (dt == ge::DT_FLOAT16) {
96+ dilation = twoByte;
97+ } else if (dt == ge::DT_BF16) {
98+ dilation = twoByte;
99+ } else if (dt == ge::DT_INT16) {
100+ dilation = twoByte;
101+ } else if (dt == ge::DT_UINT16) {
102+ dilation = twoByte;
103+ } else if (dt == ge::DT_INT32) {
104+ dilation = fourByte;
105+ } else if (dt == ge::DT_UINT32) {
106+ dilation = fourByte;
107+ } else if (dt == ge::DT_INT64) {
108+ dilation = eightByte;
109+ } else if (dt == ge::DT_UINT64) {
110+ dilation = eightByte;
111+ } else if (dt == ge::DT_INT8) {
112+ dilation = oneByte;
113+ }
114+ return dilation;
115+}
116+ 
117+int32_t GenOnesData(
118+ vector<int64_t> shapes, Tensor &input_tensor, TensorDesc &input_tensor_desc, DataType data_type, int value)
119+{
120+ input_tensor_desc.SetRealDimCnt(shapes.size());
121+ size_t size = 1;
122+ for (uint32_t i = 0; i < shapes.size(); i++) {
123+ size *= shapes[i];
124+ }
125+ uint32_t data_len = size * GetDataTypeSize(data_type);
126+ int32_t *pData = new (std::nothrow) int32_t[data_len];
127+ for (uint32_t i = 0; i < size; ++i) {
128+ *(pData + i) = value;
129+ }
130+ input_tensor = Tensor(input_tensor_desc, reinterpret_cast<uint8_t *>(pData), data_len);
131+ return SUCCESS;
132+}
133+ 
134+int32_t WriteDataToFile(string bin_file, uint64_t data_size, uint8_t *inputData)
135+{
136+ FILE *fp;
137+ fp = fopen(bin_file.c_str(), "w");
138+ fwrite(inputData, sizeof(uint8_t), data_size, fp);
139+ fclose(fp);
140+ return SUCCESS;
141+}
142+ 
143+int CreateOppInGraph(DataType inDtype, std::vector<ge::Tensor> &input, std::vector<Operator> &inputs,
144+ std::vector<Operator> &outputs, Graph &graph)
145+{
146+ Status ret = SUCCESS;
147+ // 自定义代码:添加单算子定义到图中
148+ auto assignAdd1 = op::AssignAdd("assignAdd1");
149+ std::vector<int64_t> xShape = {1, 16};
150+ std::vector<int64_t> yShape = {1, 16};
151+ ADD_INPUT(1, ref, inDtype, yShape);
152+ ADD_INPUT(2, value, inDtype, xShape);
153+
154+ ADD_INPUT_ATTR(use_locking, false);
155+ 
156+ ADD_OUTPUT(1, ref, inDtype, yShape);
157+ 
158+ outputs.push_back(assignAdd1);
159+ // 添加完毕
160+ return SUCCESS;
161+}
162+ 
163+int main(int argc, char *argv[])
164+{
165+ const char *graph_name = "tc_ge_irrun_test";
166+ Graph graph(graph_name);
167+ std::vector<ge::Tensor> input;
168+ 
169+ printf("%s - INFO - [XIR]: Start to initialize ge using ge global options\n", GetTime().c_str());
170+ std::map<AscendString, AscendString> global_options = {{"ge.exec.deviceId", "0"}, {"ge.graphRunMode", "1"}};
171+ Status ret = ge::GEInitialize(global_options);
172+ if (ret != SUCCESS) {
173+ printf("%s - INFO - [XIR]: Initialize ge using ge global options failed\n", GetTime().c_str());
174+ return FAILED;
175+ }
176+ printf("%s - INFO - [XIR]: Initialize ge using ge global options success\n", GetTime().c_str());
177+ 
178+ std::vector<Operator> inputs{};
179+ std::vector<Operator> outputs{};
180+ 
181+ std::cout << argv[1] << std::endl;
182+ char *endptr;
183+ 
184+ DataType inDtype = DT_FLOAT16;
185+ std::cout << inDtype << std::endl;
186+ 
187+ ret = CreateOppInGraph(inDtype, input, inputs, outputs, graph);
188+ if (ret != SUCCESS) {
189+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
190+ return FAILED;
191+ }
192+ 
193+ if (!inputs.empty() && !outputs.empty()) {
194+ graph.SetInputs(inputs).SetOutputs(outputs);
195+ }
196+ 
197+ std::map<AscendString, AscendString> build_options = {
198+ 
199+ };
200+ printf("%s - INFO - [XIR]: Start to create ir session using build options\n", GetTime().c_str());
201+ ge::Session *session = new Session(build_options);
202+ 
203+ if (session == nullptr) {
204+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
205+ return FAILED;
206+ }
207+ printf("%s - INFO - [XIR]: Create ir session using build options success\n", GetTime().c_str());
208+ printf("%s - INFO - [XIR]: Start to add compute graph to ir session\n", GetTime().c_str());
209+ 
210+ std::map<AscendString, AscendString> graph_options = {
211+ 
212+ };
213+ uint32_t graph_id = 0;
214+ ret = session->AddGraph(graph_id, graph, graph_options);
215+ 
216+ printf("%s - INFO - [XIR]: Session add ir compute graph to ir session success\n", GetTime().c_str());
217+ printf("%s - INFO - [XIR]: dump graph to txt\n", GetTime().c_str());
218+ std::string file_path = "./dump";
219+ aclgrphDumpGraph(graph, file_path.c_str(), file_path.length());
220+ printf("%s - INFO - [XIR]: Start to run ir compute graph\n", GetTime().c_str());
221+ std::vector<ge::Tensor> output;
222+ ret = session->RunGraph(graph_id, input, output);
223+ if (ret != SUCCESS) {
224+ printf("%s - INFO - [XIR]: Run graph failed\n", GetTime().c_str());
225+ delete session;
226+ GEFinalize();
227+ return FAILED;
228+ }
229+ printf("%s - INFO - [XIR]: Session run ir compute graph success\n", GetTime().c_str());
230+ 
231+ int input_num = input.size();
232+ for (int i = 0; i < input_num; i++) {
233+ std::cout << "input " << i << " dtype : " << input[i].GetTensorDesc().GetDataType() << std::endl;
234+ string input_file = "./tc_ge_irrun_test_0008_npu_input_" + std::to_string(i) + ".bin";
235+ uint8_t *input_data_i = input[i].GetData();
236+ int64_t input_shape = input[i].GetTensorDesc().GetShape().GetShapeSize();
237+ std::cout << "this is " << i << "th input, input shape size =" << input_shape << std::endl;
238+ uint32_t data_size = input_shape * GetDataTypeSize(input[i].GetTensorDesc().GetDataType());
239+ WriteDataToFile((const char *)input_file.c_str(), data_size, input_data_i);
240+ }
241+ 
242+ int output_num = output.size();
243+ for (int i = 0; i < output_num; i++) {
244+ std::cout << "output " << i << " dtype : " << output[i].GetTensorDesc().GetDataType() << std::endl;
245+ string output_file = "./tc_ge_irrun_test_0008_npu_output_" + std::to_string(i) + ".bin";
246+ uint8_t *output_data_i = output[i].GetData();
247+ int64_t output_shape = output[i].GetTensorDesc().GetShape().GetShapeSize();
248+ std::cout << "this is " << i << "th output, output shape size =" << output_shape << std::endl;
249+ uint32_t data_size = output_shape * GetDataTypeSize(output[i].GetTensorDesc().GetDataType());
250+ WriteDataToFile((const char *)output_file.c_str(), data_size, output_data_i);
251+ int32_t *result = (int32_t*)output_data_i;
252+ for (int64_t j = 0; j < output_shape; j++) {
253+ LOG_PRINT("result[%ld] is: %d\n", j, result[j]);
254+ }
255+ }
256+ 
257+ ge::AscendString error_msg = ge::GEGetErrorMsgV2();
258+ std::string error_str(error_msg.GetString());
259+ std::cout << "Error message: " << error_str << std::endl;
260+ ge::AscendString warning_msg = ge::GEGetWarningMsgV2();
261+ std::string warning_str(warning_msg.GetString());
262+ std::cout << "Warning message: " << warning_str << std::endl;
263+ printf("%s - INFO - [XIR]: Start to finalize ir graph session\n", GetTime().c_str());
264+ ret = ge::GEFinalize();
265+ if (ret != SUCCESS) {
266+ printf("%s - INFO - [XIR]: Finalize ir graph session failed\n", GetTime().c_str());
267+ return FAILED;
268+ }
269+ printf("%s - INFO - [XIR]: Finalize ir graph session success\n", GetTime().c_str());
270+ return SUCCESS;
271+}
@@ -0,0 +1,251 @@
1+/**
2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+/*!
12+ * \file test_assign_add_tiling.cpp
13+ * \brief
14+ */
15+#include <iostream>
16+#include <gtest/gtest.h>
17+#include "tiling_context_faker.h"
18+#include "tiling_case_executor.h"
19+#include "atvoss/elewise/elewise_tiling.h"
20+#include "../../../../op_host/arch35/assign_add_tiling_arch35.h"
21+ 
22+using namespace std;
23+ 
24+class AssignAddTiling : public testing::Test {
25+protected:
26+ static void SetUpTestCase()
27+ {
28+ std::cout << "AssignAddTiling SetUp" << std::endl;
29+ }
30+ 
31+ static void TearDownTestCase()
32+ {
33+ std::cout << "AssignAddTiling TearDown" << std::endl;
34+ }
35+};
36+ 
37+TEST_F(AssignAddTiling, BiasAdd_tiling1)
38+{
39+ optiling::AssignAddCompileInfo compileInfo = {64, 262144};
40+ gert::TilingContextPara tilingContextPara(
41+ "AssignAdd",
42+ {
43+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT16, ge::FORMAT_ND},
44+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT16, ge::FORMAT_ND},
45+ },
46+ {
47+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT16, ge::FORMAT_ND},
48+ },
49+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
50+ uint64_t expectTilingKey = 3;
51+ std::vector<size_t> expectWorkspaces = {16777216};
52+ ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectWorkspaces);
53+}
54+ 
55+TEST_F(AssignAddTiling, test_assign_add_tiling_bf16_002)
56+{
57+ optiling::AssignAddCompileInfo compileInfo = {64, 262144};
58+ gert::TilingContextPara tilingContextPara(
59+ "AssignAdd",
60+ {
61+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_BF16, ge::FORMAT_ND},
62+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_BF16, ge::FORMAT_ND},
63+ },
64+ {
65+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_BF16, ge::FORMAT_ND},
66+ },
67+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
68+ uint64_t expectTilingKey = 3;
69+ std::vector<size_t> expectWorkspaces = {16777216};
70+ ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectWorkspaces);
71+}
72+ 
73+TEST_F(AssignAddTiling, test_assign_add_tiling_fp32_003)
74+{
75+ optiling::AssignAddCompileInfo compileInfo = {64, 262144};
76+ gert::TilingContextPara tilingContextPara(
77+ "AssignAdd",
78+ {
79+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND},
80+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND},
81+ },
82+ {
83+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND},
84+ },
85+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
86+ uint64_t expectTilingKey = 3;
87+ std::vector<size_t> expectWorkspaces = {16777216};
88+ ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectWorkspaces);
89+}
90+ 
91+TEST_F(AssignAddTiling, test_assign_add_tiling_fp32_004)
92+{
93+ optiling::AssignAddCompileInfo compileInfo = {64, 262144};
94+ gert::TilingContextPara tilingContextPara(
95+ "AssignAdd",
96+ {
97+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND},
98+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND},
99+ },
100+ {
101+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND},
102+ },
103+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
104+ uint64_t expectTilingKey = 3;
105+ std::vector<size_t> expectWorkspaces = {16777216};
106+ ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectWorkspaces);
107+}
108+ 
109+TEST_F(AssignAddTiling, test_assign_add_tiling_int8_005)
110+{
111+ optiling::AssignAddCompileInfo compileInfo = {64, 262144};
112+ gert::TilingContextPara tilingContextPara(
113+ "AssignAdd",
114+ {
115+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT8, ge::FORMAT_ND},
116+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT8, ge::FORMAT_ND},
117+ },
118+ {
119+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT8, ge::FORMAT_ND},
120+ },
121+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
122+ uint64_t expectTilingKey = 3;
123+ std::vector<size_t> expectWorkspaces = {16777216};
124+ ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectWorkspaces);
125+}
126+ 
127+TEST_F(AssignAddTiling, test_assign_add_tiling_int32_006)
128+{
129+ optiling::AssignAddCompileInfo compileInfo = {64, 262144};
130+ gert::TilingContextPara tilingContextPara(
131+ "AssignAdd",
132+ {
133+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT32, ge::FORMAT_ND},
134+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT32, ge::FORMAT_ND},
135+ },
136+ {
137+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT32, ge::FORMAT_ND},
138+ },
139+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
140+ uint64_t expectTilingKey = 3;
141+ std::vector<size_t> expectWorkspaces = {16777216};
142+ ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectWorkspaces);
143+}
144+ 
145+TEST_F(AssignAddTiling, test_assign_add_tiling_int64_007)
146+{
147+ optiling::AssignAddCompileInfo compileInfo = {64, 262144};
148+ gert::TilingContextPara tilingContextPara(
149+ "AssignAdd",
150+ {
151+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT64, ge::FORMAT_ND},
152+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT64, ge::FORMAT_ND},
153+ },
154+ {
155+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT64, ge::FORMAT_ND},
156+ },
157+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
158+ uint64_t expectTilingKey = 3;
159+ std::vector<size_t> expectWorkspaces = {16777216};
160+ ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectWorkspaces);
161+}
162+ 
163+TEST_F(AssignAddTiling, test_assign_add_tiling_uint8_008)
164+{
165+ optiling::AssignAddCompileInfo compileInfo = {64, 262144};
166+ gert::TilingContextPara tilingContextPara(
167+ "AssignAdd",
168+ {
169+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_UINT8, ge::FORMAT_ND},
170+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_UINT8, ge::FORMAT_ND},
171+ },
172+ {
173+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_UINT8, ge::FORMAT_ND},
174+ },
175+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
176+ uint64_t expectTilingKey = 3;
177+ std::vector<size_t> expectWorkspaces = {16777216};
178+ ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectWorkspaces);
179+}
180+ 
181+TEST_F(AssignAddTiling, test_assign_add_tiling_exception_dtype_009)
182+{
183+ optiling::AssignAddCompileInfo compileInfo = {64, 262144};
184+ gert::TilingContextPara tilingContextPara(
185+ "AssignAdd",
186+ {
187+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_UINT32, ge::FORMAT_ND},
188+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_UINT32, ge::FORMAT_ND},
189+ },
190+ {
191+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_UINT32, ge::FORMAT_ND},
192+ },
193+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
194+ uint64_t expectTilingKey = 2660;
195+ std::vector<size_t> expectWorkspaces = {16777216};
196+ ExecuteTestCase(tilingContextPara, ge::GRAPH_FAILED, expectTilingKey, expectWorkspaces);
197+}
198+ 
199+TEST_F(AssignAddTiling, test_assign_add_tiling_exception_dtype_010)
200+{
201+ optiling::AssignAddCompileInfo compileInfo = {64, 262144};
202+ gert::TilingContextPara tilingContextPara(
203+ "AssignAdd",
204+ {
205+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_UINT8, ge::FORMAT_ND},
206+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_UINT8, ge::FORMAT_ND},
207+ },
208+ {
209+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_UINT8, ge::FORMAT_ND},
210+ },
211+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
212+ uint64_t expectTilingKey = 3;
213+ std::vector<size_t> expectWorkspaces = {16777216};
214+ ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectWorkspaces);
215+}
216+ 
217+TEST_F(AssignAddTiling, test_assign_add_tiling_exception_shape_011)
218+{
219+ optiling::AssignAddCompileInfo compileInfo = {64, 262144};
220+ gert::TilingContextPara tilingContextPara(
221+ "AssignAdd",
222+ {
223+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_UINT8, ge::FORMAT_ND},
224+ {{{1, 32, 2, 32}, {1, 32, 2, 32}}, ge::DT_UINT8, ge::FORMAT_ND},
225+ },
226+ {
227+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_UINT8, ge::FORMAT_ND},
228+ },
229+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
230+ uint64_t expectTilingKey = 2660;
231+ std::vector<size_t> expectWorkspaces = {16777216};
232+ ExecuteTestCase(tilingContextPara, ge::GRAPH_FAILED, expectTilingKey, expectWorkspaces);
233+}
234+ 
235+TEST_F(AssignAddTiling, test_assign_add_tiling_mix_fp32_fp16_001)
236+{
237+ optiling::AssignAddCompileInfo compileInfo = {64, 262144};
238+ gert::TilingContextPara tilingContextPara(
239+ "AssignAdd",
240+ {
241+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND},
242+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND},
243+ },
244+ {
245+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_FLOAT, ge::FORMAT_ND},
246+ },
247+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
248+ uint64_t expectTilingKey = 3;
249+ std::vector<size_t> expectWorkspaces = {16777216};
250+ ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectWorkspaces);
251+}
@@ -0,0 +1,57 @@
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 <gtest/gtest.h>
12+#include <iostream>
13+#include "infershape_context_faker.h"
14+#include "infershape_case_executor.h"
15+ 
16+class AssignAddInferShape : public testing::Test {
17+protected:
18+ static void SetUpTestCase()
19+ {
20+ std::cout << "AssignAddInferShape SetUp" << std::endl;
21+ }
22+ 
23+ static void TearDownTestCase()
24+ {
25+ std::cout << "AssignAddInferShape TearDown" << std::endl;
26+ }
27+};
28+ 
29+TEST_F(AssignAddInferShape, assign_sub_infer_shape_fp16)
30+{
31+ gert::InfershapeContextPara infershapeContextPara(
32+ "AssignAdd",
33+ {
34+ {{{-1}, {-1}}, ge::DT_FLOAT16, ge::FORMAT_ND},
35+ {{{-1}, {-1}}, ge::DT_FLOAT16, ge::FORMAT_ND},
36+ },
37+ {
38+ {{{}, {}}, ge::DT_FLOAT16, ge::FORMAT_ND},
39+ });
40+ std::vector<std::vector<int64_t>> expectOutputShape = {{-1}};
41+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
42+}
43+ 
44+TEST_F(AssignAddInferShape, VerifyAssignAdd_001)
45+{
46+ gert::InfershapeContextPara infershapeContextPara(
47+ "AssignAdd",
48+ {
49+ {{{16, 16}, {16, 16}}, ge::DT_FLOAT, ge::FORMAT_ND},
50+ {{{16, 16}, {16, 16}}, ge::DT_FLOAT16, ge::FORMAT_ND},
51+ },
52+ {
53+ {{{}, {}}, ge::DT_FLOAT16, ge::FORMAT_ND},
54+ });
55+ std::vector<std::vector<int64_t>> expectOutputShape = {{16, 16}};
56+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
57+}
@@ -0,0 +1,75 @@
1+# AssignSub
2+ 
3+## 产品支持情况
4+ 
5+| 产品 | 是否支持 |
6+| :----------------------------------------------------------- | :------: |
7+| <term>Ascend 950PR/Ascend 950DT</term> | √ |
8+ 
9+## 功能说明
10+ 
11+- 算子功能:完成在原有tensor上的减法计算。
12+ 
13+- 计算公式:
14+ 
15+$$out_i = var_i - value_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>var</td>
37+ <td>输入</td>
38+ <td>输入张量,公式中的var_i。</td>
39+ <td>BFLOAT16、FLOAT16、FLOAT、INT8、INT32、INT64、UINT8</td>
40+ <td>ND</td>
41+ </tr>
42+ <tr>
43+ <td>value</td>
44+ <td>输入</td>
45+ <td>输入张量,表示要从var_i上减去的值,公式中的out_i。</td>
46+ <td>BFLOAT16、FLOAT16、FLOAT、INT8、INT32、INT64、UINT8</td>
47+ <td>ND</td>
48+ </tr>
49+ <tr>
50+ <td>var</td>
51+ <td>输出</td>
52+ <td>输出张量,公式中的out_i,与var_i同地址。</td>
53+ <td>BFOAT16、FLOAT16、FLOAT、INT8、INT32、INT64、UINT8</td>
54+ <td>ND</td>
55+ </tr>
56+ <tr>
57+ <td>use_locking</td>
58+ <td>属性</td>
59+ <td>可选,是否使用锁来保护更新操作。</td>
60+ <td>bool</td>
61+ <td>ND</td>
62+ </tr>
63+ </tbody></table>
64+ 
65+ 
66+## 约束说明
67+ 
68+
69+ 
70+## 调用说明
71+| 调用方式 | 调用样例 | 说明 |
72+|--------------|-----------------------------------------------------|----------------------------------------------------------------|
73+| 图模式调用 | [test_geir_assign_sub.cpp](examples/test_geir_assign_sub.cpp) | 通过[算子IR](op_graph/assign_sub_proto.h)构图方式调用AssignSub算子。 |
74+ 
75+ 
@@ -0,0 +1,271 @@
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/assign_sub_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(placeholder##intputIndex##_shape, \
49+ tensor_placeholder##intputIndex, \
50+ placeholder##intputIndex##_desc, \
51+ intputDtype, \
52+ 2); \
53+ if (ret != SUCCESS) { \
54+ printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \
55+ return FAILED; \
56+ } \
57+ placeholder##intputIndex.update_input_desc_x(placeholder##intputIndex##_desc); \
58+ input.push_back(tensor_placeholder##intputIndex); \
59+ graph.AddOp(placeholder##intputIndex); \
60+ assignSub1.set_input_##intputName(placeholder##intputIndex); \
61+ inputs.push_back(placeholder##intputIndex);
62+ 
63+#define ADD_INPUT_ATTR(attrName, attrValue) \
64+ assignSub1.set_attr_##attrName(attrValue);
65+ 
66+#define ADD_OUTPUT(outputIndex, outputName, outputDtype, outputShape) \
67+ TensorDesc outputName##outputIndex##_desc = \
68+ TensorDesc(ge::Shape(outputShape), FORMAT_ND, outputDtype); \
69+ assignSub1.update_output_desc_##outputName(outputName##outputIndex##_desc);
70+ 
71+#define LOG_PRINT(message, ...) \
72+ do { \
73+ printf(message, ##__VA_ARGS__); \
74+ } while (0)
75+ 
76+string GetTime()
77+{
78+ time_t timep;
79+ time(&timep);
80+ char tmp[64];
81+ strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S,000", localtime(&timep));
82+ return tmp;
83+}
84+ 
85+uint32_t GetDataTypeSize(DataType dt)
86+{
87+ uint32_t dilation = 1;
88+ uint32_t oneByte = 1;
89+ uint32_t twoByte = 2;
90+ uint32_t fourByte = 4;
91+ uint32_t eightByte = 8;
92+ 
93+ if (dt == ge::DT_FLOAT) {
94+ dilation = fourByte;
95+ } else if (dt == ge::DT_FLOAT16) {
96+ dilation = twoByte;
97+ } else if (dt == ge::DT_BF16) {
98+ dilation = twoByte;
99+ } else if (dt == ge::DT_INT16) {
100+ dilation = twoByte;
101+ } else if (dt == ge::DT_UINT16) {
102+ dilation = twoByte;
103+ } else if (dt == ge::DT_INT32) {
104+ dilation = fourByte;
105+ } else if (dt == ge::DT_UINT32) {
106+ dilation = fourByte;
107+ } else if (dt == ge::DT_INT64) {
108+ dilation = eightByte;
109+ } else if (dt == ge::DT_UINT64) {
110+ dilation = eightByte;
111+ } else if (dt == ge::DT_INT8) {
112+ dilation = oneByte;
113+ }
114+ return dilation;
115+}
116+ 
117+int32_t GenOnesData(
118+ vector<int64_t> shapes, Tensor &input_tensor, TensorDesc &input_tensor_desc, DataType data_type, int value)
119+{
120+ input_tensor_desc.SetRealDimCnt(shapes.size());
121+ size_t size = 1;
122+ for (uint32_t i = 0; i < shapes.size(); i++) {
123+ size *= shapes[i];
124+ }
125+ uint32_t data_len = size * GetDataTypeSize(data_type);
126+ int32_t *pData = new (std::nothrow) int32_t[data_len];
127+ for (uint32_t i = 0; i < size; ++i) {
128+ *(pData + i) = value;
129+ }
130+ input_tensor = Tensor(input_tensor_desc, reinterpret_cast<uint8_t *>(pData), data_len);
131+ return SUCCESS;
132+}
133+ 
134+int32_t WriteDataToFile(string bin_file, uint64_t data_size, uint8_t *inputData)
135+{
136+ FILE *fp;
137+ fp = fopen(bin_file.c_str(), "w");
138+ fwrite(inputData, sizeof(uint8_t), data_size, fp);
139+ fclose(fp);
140+ return SUCCESS;
141+}
142+ 
143+int CreateOppInGraph(DataType inDtype, std::vector<ge::Tensor> &input, std::vector<Operator> &inputs,
144+ std::vector<Operator> &outputs, Graph &graph)
145+{
146+ Status ret = SUCCESS;
147+ // 自定义代码:添加单算子定义到图中
148+ auto assignSub1 = op::AssignSub("assignSub1");
149+ std::vector<int64_t> xShape = {1, 16};
150+ std::vector<int64_t> yShape = {1, 16};
151+ ADD_INPUT(1, var, inDtype, yShape);
152+ ADD_INPUT(2, value, inDtype, xShape);
153+
154+ ADD_INPUT_ATTR(use_locking, false);
155+ 
156+ ADD_OUTPUT(1, var, inDtype, yShape);
157+ 
158+ outputs.push_back(assignSub1);
159+ // 添加完毕
160+ return SUCCESS;
161+}
162+ 
163+int main(int argc, char *argv[])
164+{
165+ const char *graph_name = "tc_ge_irrun_test";
166+ Graph graph(graph_name);
167+ std::vector<ge::Tensor> input;
168+ 
169+ printf("%s - INFO - [XIR]: Start to initialize ge using ge global options\n", GetTime().c_str());
170+ std::map<AscendString, AscendString> global_options = {{"ge.exec.deviceId", "0"}, {"ge.graphRunMode", "1"}};
171+ Status ret = ge::GEInitialize(global_options);
172+ if (ret != SUCCESS) {
173+ printf("%s - INFO - [XIR]: Initialize ge using ge global options failed\n", GetTime().c_str());
174+ return FAILED;
175+ }
176+ printf("%s - INFO - [XIR]: Initialize ge using ge global options success\n", GetTime().c_str());
177+ 
178+ std::vector<Operator> inputs{};
179+ std::vector<Operator> outputs{};
180+ 
181+ std::cout << argv[1] << std::endl;
182+ char *endptr;
183+ 
184+ DataType inDtype = DT_FLOAT16;
185+ std::cout << inDtype << std::endl;
186+ 
187+ ret = CreateOppInGraph(inDtype, input, inputs, outputs, graph);
188+ if (ret != SUCCESS) {
189+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
190+ return FAILED;
191+ }
192+ 
193+ if (!inputs.empty() && !outputs.empty()) {
194+ graph.SetInputs(inputs).SetOutputs(outputs);
195+ }
196+ 
197+ std::map<AscendString, AscendString> build_options = {
198+ 
199+ };
200+ printf("%s - INFO - [XIR]: Start to create ir session using build options\n", GetTime().c_str());
201+ ge::Session *session = new Session(build_options);
202+ 
203+ if (session == nullptr) {
204+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
205+ return FAILED;
206+ }
207+ printf("%s - INFO - [XIR]: Create ir session using build options success\n", GetTime().c_str());
208+ printf("%s - INFO - [XIR]: Start to add compute graph to ir session\n", GetTime().c_str());
209+ 
210+ std::map<AscendString, AscendString> graph_options = {
211+ 
212+ };
213+ uint32_t graph_id = 0;
214+ ret = session->AddGraph(graph_id, graph, graph_options);
215+ 
216+ printf("%s - INFO - [XIR]: Session add ir compute graph to ir session success\n", GetTime().c_str());
217+ printf("%s - INFO - [XIR]: dump graph to txt\n", GetTime().c_str());
218+ std::string file_path = "./dump";
219+ aclgrphDumpGraph(graph, file_path.c_str(), file_path.length());
220+ printf("%s - INFO - [XIR]: Start to run ir compute graph\n", GetTime().c_str());
221+ std::vector<ge::Tensor> output;
222+ ret = session->RunGraph(graph_id, input, output);
223+ if (ret != SUCCESS) {
224+ printf("%s - INFO - [XIR]: Run graph failed\n", GetTime().c_str());
225+ delete session;
226+ GEFinalize();
227+ return FAILED;
228+ }
229+ printf("%s - INFO - [XIR]: Session run ir compute graph success\n", GetTime().c_str());
230+ 
231+ int input_num = input.size();
232+ for (int i = 0; i < input_num; i++) {
233+ std::cout << "input " << i << " dtype : " << input[i].GetTensorDesc().GetDataType() << std::endl;
234+ string input_file = "./tc_ge_irrun_test_0008_npu_input_" + std::to_string(i) + ".bin";
235+ uint8_t *input_data_i = input[i].GetData();
236+ int64_t input_shape = input[i].GetTensorDesc().GetShape().GetShapeSize();
237+ std::cout << "this is " << i << "th input, input shape size =" << input_shape << std::endl;
238+ uint32_t data_size = input_shape * GetDataTypeSize(input[i].GetTensorDesc().GetDataType());
239+ WriteDataToFile((const char *)input_file.c_str(), data_size, input_data_i);
240+ }
241+ 
242+ int output_num = output.size();
243+ for (int i = 0; i < output_num; i++) {
244+ std::cout << "output " << i << " dtype : " << output[i].GetTensorDesc().GetDataType() << std::endl;
245+ string output_file = "./tc_ge_irrun_test_0008_npu_output_" + std::to_string(i) + ".bin";
246+ uint8_t *output_data_i = output[i].GetData();
247+ int64_t output_shape = output[i].GetTensorDesc().GetShape().GetShapeSize();
248+ std::cout << "this is " << i << "th output, output shape size =" << output_shape << std::endl;
249+ uint32_t data_size = output_shape * GetDataTypeSize(output[i].GetTensorDesc().GetDataType());
250+ WriteDataToFile((const char *)output_file.c_str(), data_size, output_data_i);
251+ int32_t *result = (int32_t*)output_data_i;
252+ for (int64_t j = 0; j < output_shape; j++) {
253+ LOG_PRINT("result[%ld] is: %d\n", j, result[j]);
254+ }
255+ }
256+ 
257+ ge::AscendString error_msg = ge::GEGetErrorMsgV2();
258+ std::string error_str(error_msg.GetString());
259+ std::cout << "Error message: " << error_str << std::endl;
260+ ge::AscendString warning_msg = ge::GEGetWarningMsgV2();
261+ std::string warning_str(warning_msg.GetString());
262+ std::cout << "Warning message: " << warning_str << std::endl;
263+ printf("%s - INFO - [XIR]: Start to finalize ir graph session\n", GetTime().c_str());
264+ ret = ge::GEFinalize();
265+ if (ret != SUCCESS) {
266+ printf("%s - INFO - [XIR]: Finalize ir graph session failed\n", GetTime().c_str());
267+ return FAILED;
268+ }
269+ printf("%s - INFO - [XIR]: Finalize ir graph session success\n", GetTime().c_str());
270+ return SUCCESS;
271+}
@@ -0,0 +1,108 @@
1+/**
2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+/*!
12+ * \file test_assign_sub_tiling.cpp
13+ * \brief
14+ */
15+ 
16+#include <iostream>
17+#include <gtest/gtest.h>
18+#include "../../../../op_host/arch35/assign_sub_tiling_arch35.h"
19+#include "tiling_context_faker.h"
20+#include "tiling_case_executor.h"
21+#include "atvoss/elewise/elewise_tiling.h"
22+ 
23+using namespace std;
24+ 
25+class AssignSubTilingTest : public testing::Test {
26+protected:
27+ static void SetUpTestCase()
28+ {
29+ std::cout << "AssignSubTilingTest SetUp" << std::endl;
30+ }
31+ 
32+ static void TearDownTestCase()
33+ {
34+ std::cout << "AssignSubTilingTest TearDown" << std::endl;
35+ }
36+};
37+ 
38+TEST_F(AssignSubTilingTest, test_assign_sub_tiling_exception_dtype_001)
39+{
40+ optiling::AssignSubCompileInfo compileInfo = {64, 262144};
41+ gert::TilingContextPara tilingContextPara(
42+ "AssignSub",
43+ {
44+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT32, ge::FORMAT_ND},
45+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT32, ge::FORMAT_ND},
46+ },
47+ {
48+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT32, ge::FORMAT_ND},
49+ },
50+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
51+ uint64_t expectTilingKey = 105;
52+ std::vector<size_t> expectWorkspaces = {16777216};
53+ ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectWorkspaces);
54+}
55+ 
56+TEST_F(AssignSubTilingTest, test_assign_sub_tiling_exception_dtype_0002)
57+{
58+ optiling::AssignSubCompileInfo compileInfo = {64, 262144};
59+ gert::TilingContextPara tilingContextPara(
60+ "AssignSub",
61+ {
62+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT8, ge::FORMAT_ND},
63+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT8, ge::FORMAT_ND},
64+ },
65+ {
66+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT8, ge::FORMAT_ND},
67+ },
68+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
69+ uint64_t expectTilingKey = 104;
70+ std::vector<size_t> expectWorkspaces = {16777216};
71+ ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectWorkspaces);
72+}
73+ 
74+TEST_F(AssignSubTilingTest, test_assign_sub_tiling_exception_dtype_0003)
75+{
76+ optiling::AssignSubCompileInfo compileInfo = {64, 262144};
77+ gert::TilingContextPara tilingContextPara(
78+ "AssignSub",
79+ {
80+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_UINT8, ge::FORMAT_ND},
81+ {{{1, 32, 2, 32}, {1, 32, 2, 32}}, ge::DT_UINT8, ge::FORMAT_ND},
82+ },
83+ {
84+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_INT8, ge::FORMAT_ND},
85+ },
86+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
87+ uint64_t expectTilingKey = 2660;
88+ std::vector<size_t> expectWorkspaces = {16777216};
89+ ExecuteTestCase(tilingContextPara, ge::GRAPH_FAILED, expectTilingKey, expectWorkspaces);
90+}
91+ 
92+TEST_F(AssignSubTilingTest, test_assign_sub_tiling_exception_dtype_0004)
93+{
94+ optiling::AssignSubCompileInfo compileInfo = {64, 262144};
95+ gert::TilingContextPara tilingContextPara(
96+ "AssignSub",
97+ {
98+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_UINT8, ge::FORMAT_ND},
99+ {{{1, 32, 2, 32}, {1, 32, 2, 32}}, ge::DT_UINT8, ge::FORMAT_ND},
100+ },
101+ {
102+ {{{1, 64, 2, 64}, {1, 64, 2, 64}}, ge::DT_UINT8, ge::FORMAT_ND},
103+ },
104+ {gert::TilingContextPara::OpAttr("use_locking", Ops::Math::AnyValue::CreateFrom<bool>(false))}, &compileInfo);
105+ uint64_t expectTilingKey = 2660;
106+ std::vector<size_t> expectWorkspaces = {16777216};
107+ ExecuteTestCase(tilingContextPara, ge::GRAPH_FAILED, expectTilingKey, expectWorkspaces);
108+}
@@ -0,0 +1,38 @@
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 <gtest/gtest.h>
12+#include <iostream>
13+#include "infershape_context_faker.h"
14+#include "infershape_case_executor.h"
15+ 
16+class AssignSubInfershape : public testing::Test {
17+protected:
18+ static void SetUpTestCase()
19+ {
20+ std::cout << "AssignSubInfershape SetUp" << std::endl;
21+ }
22+ 
23+ static void TearDownTestCase()
24+ {
25+ std::cout << "AssignSubInfershape TearDown" << std::endl;
26+ }
27+};
28+ 
29+TEST_F(AssignSubInfershape, assign_sub_infer_shape_fp16)
30+{
31+ gert::InfershapeContextPara infershapeContextPara(
32+ "AssignSub", {{{{-1}, {-1}}, ge::DT_FLOAT16, ge::FORMAT_ND}, {{{-1}, {-1}}, ge::DT_FLOAT16, ge::FORMAT_ND}},
33+ {
34+ {{{}, {}}, ge::DT_BOOL, ge::FORMAT_ND},
35+ });
36+ std::vector<std::vector<int64_t>> expectOutputShape = {{-1}};
37+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
38+}
@@ -0,0 +1,77 @@
1+# SquareSumV1
2+ 
3+## 产品支持情况
4+ 
5+| 产品 | 是否支持 |
6+| :----------------------------------------------------------- | :------: |
7+| <term>Ascend 950PR/Ascend 950DT</term> | √ |
8+ 
9+## 功能说明
10+ 
11+- 算子功能: 用于计算输入张量在指定轴上的平方和。
12+ 
13+- 计算公式:
14+ 
15+$$
16+y = \sum_{i\in\text{axis}}x_i^2
17+$$
18+ 
19+## 参数说明
20+ 
21+<table style="undefined;table-layout: fixed; width: 980px"><colgroup>
22+ <col style="width: 100px">
23+ <col style="width: 150px">
24+ <col style="width: 280px">
25+ <col style="width: 330px">
26+ <col style="width: 120px">
27+ </colgroup>
28+ <thead>
29+ <tr>
30+ <th>参数名</th>
31+ <th>输入/输出/属性</th>
32+ <th>描述</th>
33+ <th>数据类型</th>
34+ <th>数据格式</th>
35+ </tr></thead>
36+ <tbody>
37+ <tr>
38+ <td>x</td>
39+ <td>输入</td>
40+ <td>公式中输入张量x。</td>
41+ <td>FLOAT16、FLOAT、BFloat16</td>
42+ <td>ND</td>
43+ </tr>
44+ <tr>
45+ <td>y</td>
46+ <td>输出</td>
47+ <td>公式中输出张量y。</td>
48+ <td>FLOAT16、FLOAT、BFloat16</td>
49+ <td>ND</td>
50+ </tr>
51+ <tr>
52+ <td>axis</td>
53+ <td>属性</td>
54+ <td>一个整数列表,指定在哪些轴上进行求和。</td>
55+ <td>INT32_ARRAY</td>
56+ <td>ND</td>
57+ </tr>
58+ <tr>
59+ <td>keep_dims</td>
60+ <td>属性</td>
61+ <td>是否在输出中保留减少的维度,默认为false。</td>
62+ <td>bool</td>
63+ <td>ND</td>
64+ </tr>
65+ </tbody></table>
66+ 
67+## 约束说明
68+ 
69+
70+ 
71+## 调用说明
72+| 调用方式 | 调用样例 | 说明 |
73+|--------------|-----------------------------------------------------|----------------------------------------------------------------|
74+| 图模式调用 | [test_geir_square_sum_v1.cpp](examples/test_geir_square_sum_v1.cpp) | 通过[算子IR](op_graph/square_sum_v1_proto.h)构图方式调用SquareSumV1算子。 |
75+ 
76+ 
77+ 
@@ -0,0 +1,271 @@
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/square_sum_v1_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(placeholder##intputIndex##_shape, \
49+ tensor_placeholder##intputIndex, \
50+ placeholder##intputIndex##_desc, \
51+ intputDtype, \
52+ 2); \
53+ if (ret != SUCCESS) { \
54+ printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \
55+ return FAILED; \
56+ } \
57+ placeholder##intputIndex.update_input_desc_x(placeholder##intputIndex##_desc); \
58+ input.push_back(tensor_placeholder##intputIndex); \
59+ graph.AddOp(placeholder##intputIndex); \
60+ squareSumV1.set_input_##intputName(placeholder##intputIndex); \
61+ inputs.push_back(placeholder##intputIndex);
62+ 
63+#define ADD_INPUT_ATTR(attrName, attrValue) \
64+ squareSumV1.set_attr_##attrName(attrValue);
65+ 
66+#define ADD_OUTPUT(outputIndex, outputName, outputDtype, outputShape) \
67+ TensorDesc outputName##outputIndex##_desc = \
68+ TensorDesc(ge::Shape(outputShape), FORMAT_ND, outputDtype); \
69+ squareSumV1.update_output_desc_##outputName(outputName##outputIndex##_desc);
70+ 
71+#define LOG_PRINT(message, ...) \
72+ do { \
73+ printf(message, ##__VA_ARGS__); \
74+ } while (0)
75+ 
76+string GetTime()
77+{
78+ time_t timep;
79+ time(&timep);
80+ char tmp[64];
81+ strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S,000", localtime(&timep));
82+ return tmp;
83+}
84+ 
85+uint32_t GetDataTypeSize(DataType dt)
86+{
87+ uint32_t dilation = 1;
88+ uint32_t oneByte = 1;
89+ uint32_t twoByte = 2;
90+ uint32_t fourByte = 4;
91+ uint32_t eightByte = 8;
92+ 
93+ if (dt == ge::DT_FLOAT) {
94+ dilation = fourByte;
95+ } else if (dt == ge::DT_FLOAT16) {
96+ dilation = twoByte;
97+ } else if (dt == ge::DT_BF16) {
98+ dilation = twoByte;
99+ } else if (dt == ge::DT_INT16) {
100+ dilation = twoByte;
101+ } else if (dt == ge::DT_UINT16) {
102+ dilation = twoByte;
103+ } else if (dt == ge::DT_INT32) {
104+ dilation = fourByte;
105+ } else if (dt == ge::DT_UINT32) {
106+ dilation = fourByte;
107+ } else if (dt == ge::DT_INT64) {
108+ dilation = eightByte;
109+ } else if (dt == ge::DT_UINT64) {
110+ dilation = eightByte;
111+ } else if (dt == ge::DT_INT8) {
112+ dilation = oneByte;
113+ }
114+ return dilation;
115+}
116+ 
117+int32_t GenOnesData(
118+ vector<int64_t> shapes, Tensor &input_tensor, TensorDesc &input_tensor_desc, DataType data_type, int value)
119+{
120+ input_tensor_desc.SetRealDimCnt(shapes.size());
121+ size_t size = 1;
122+ for (uint32_t i = 0; i < shapes.size(); i++) {
123+ size *= shapes[i];
124+ }
125+ uint32_t data_len = size * GetDataTypeSize(data_type);
126+ int32_t *pData = new (std::nothrow) int32_t[data_len];
127+ for (uint32_t i = 0; i < size; ++i) {
128+ *(pData + i) = value;
129+ }
130+ input_tensor = Tensor(input_tensor_desc, reinterpret_cast<uint8_t *>(pData), data_len);
131+ return SUCCESS;
132+}
133+ 
134+int32_t WriteDataToFile(string bin_file, uint64_t data_size, uint8_t *inputData)
135+{
136+ FILE *fp;
137+ fp = fopen(bin_file.c_str(), "w");
138+ fwrite(inputData, sizeof(uint8_t), data_size, fp);
139+ fclose(fp);
140+ return SUCCESS;
141+}
142+ 
143+int CreateOppInGraph(DataType inDtype, std::vector<ge::Tensor> &input, std::vector<Operator> &inputs,
144+ std::vector<Operator> &outputs, Graph &graph)
145+{
146+ Status ret = SUCCESS;
147+ // 自定义代码:添加单算子定义到图中
148+ auto squareSumV1 = op::SquareSumV1("squareSumV1");
149+ std::vector<int64_t> xShape = {4, 8};
150+ std::vector<int64_t> yShape = {8};
151+ ADD_INPUT(1, x, inDtype, xShape);
152+
153+ ADD_INPUT_ATTR(axis, {1});
154+ ADD_INPUT_ATTR(keep_dims, false);
155+ 
156+ ADD_OUTPUT(1, y, inDtype, yShape);
157+ 
158+ outputs.push_back(squareSumV1);
159+ // 添加完毕
160+ return SUCCESS;
161+}
162+ 
163+int main(int argc, char *argv[])
164+{
165+ const char *graph_name = "tc_ge_irrun_test";
166+ Graph graph(graph_name);
167+ std::vector<ge::Tensor> input;
168+ 
169+ printf("%s - INFO - [XIR]: Start to initialize ge using ge global options\n", GetTime().c_str());
170+ std::map<AscendString, AscendString> global_options = {{"ge.exec.deviceId", "0"}, {"ge.graphRunMode", "1"}};
171+ Status ret = ge::GEInitialize(global_options);
172+ if (ret != SUCCESS) {
173+ printf("%s - INFO - [XIR]: Initialize ge using ge global options failed\n", GetTime().c_str());
174+ return FAILED;
175+ }
176+ printf("%s - INFO - [XIR]: Initialize ge using ge global options success\n", GetTime().c_str());
177+ 
178+ std::vector<Operator> inputs{};
179+ std::vector<Operator> outputs{};
180+ 
181+ std::cout << argv[1] << std::endl;
182+ char *endptr;
183+ 
184+ DataType inDtype = DT_FLOAT16;
185+ std::cout << inDtype << std::endl;
186+ 
187+ ret = CreateOppInGraph(inDtype, input, inputs, outputs, graph);
188+ if (ret != SUCCESS) {
189+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
190+ return FAILED;
191+ }
192+ 
193+ if (!inputs.empty() && !outputs.empty()) {
194+ graph.SetInputs(inputs).SetOutputs(outputs);
195+ }
196+ 
197+ std::map<AscendString, AscendString> build_options = {
198+ 
199+ };
200+ printf("%s - INFO - [XIR]: Start to create ir session using build options\n", GetTime().c_str());
201+ ge::Session *session = new Session(build_options);
202+ 
203+ if (session == nullptr) {
204+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
205+ return FAILED;
206+ }
207+ printf("%s - INFO - [XIR]: Create ir session using build options success\n", GetTime().c_str());
208+ printf("%s - INFO - [XIR]: Start to add compute graph to ir session\n", GetTime().c_str());
209+ 
210+ std::map<AscendString, AscendString> graph_options = {
211+ 
212+ };
213+ uint32_t graph_id = 0;
214+ ret = session->AddGraph(graph_id, graph, graph_options);
215+ 
216+ printf("%s - INFO - [XIR]: Session add ir compute graph to ir session success\n", GetTime().c_str());
217+ printf("%s - INFO - [XIR]: dump graph to txt\n", GetTime().c_str());
218+ std::string file_path = "./dump";
219+ aclgrphDumpGraph(graph, file_path.c_str(), file_path.length());
220+ printf("%s - INFO - [XIR]: Start to run ir compute graph\n", GetTime().c_str());
221+ std::vector<ge::Tensor> output;
222+ ret = session->RunGraph(graph_id, input, output);
223+ if (ret != SUCCESS) {
224+ printf("%s - INFO - [XIR]: Run graph failed\n", GetTime().c_str());
225+ delete session;
226+ GEFinalize();
227+ return FAILED;
228+ }
229+ printf("%s - INFO - [XIR]: Session run ir compute graph success\n", GetTime().c_str());
230+ 
231+ int input_num = input.size();
232+ for (int i = 0; i < input_num; i++) {
233+ std::cout << "input " << i << " dtype : " << input[i].GetTensorDesc().GetDataType() << std::endl;
234+ string input_file = "./tc_ge_irrun_test_0008_npu_input_" + std::to_string(i) + ".bin";
235+ uint8_t *input_data_i = input[i].GetData();
236+ int64_t input_shape = input[i].GetTensorDesc().GetShape().GetShapeSize();
237+ std::cout << "this is " << i << "th input, input shape size =" << input_shape << std::endl;
238+ uint32_t data_size = input_shape * GetDataTypeSize(input[i].GetTensorDesc().GetDataType());
239+ WriteDataToFile((const char *)input_file.c_str(), data_size, input_data_i);
240+ }
241+ 
242+ int output_num = output.size();
243+ for (int i = 0; i < output_num; i++) {
244+ std::cout << "output " << i << " dtype : " << output[i].GetTensorDesc().GetDataType() << std::endl;
245+ string output_file = "./tc_ge_irrun_test_0008_npu_output_" + std::to_string(i) + ".bin";
246+ uint8_t *output_data_i = output[i].GetData();
247+ int64_t output_shape = output[i].GetTensorDesc().GetShape().GetShapeSize();
248+ std::cout << "this is " << i << "th output, output shape size =" << output_shape << std::endl;
249+ uint32_t data_size = output_shape * GetDataTypeSize(output[i].GetTensorDesc().GetDataType());
250+ WriteDataToFile((const char *)output_file.c_str(), data_size, output_data_i);
251+ int32_t *result = (int32_t*)output_data_i;
252+ for (int64_t j = 0; j < output_shape; j++) {
253+ LOG_PRINT("result[%ld] is: %d\n", j, result[j]);
254+ }
255+ }
256+ 
257+ ge::AscendString error_msg = ge::GEGetErrorMsgV2();
258+ std::string error_str(error_msg.GetString());
259+ std::cout << "Error message: " << error_str << std::endl;
260+ ge::AscendString warning_msg = ge::GEGetWarningMsgV2();
261+ std::string warning_str(warning_msg.GetString());
262+ std::cout << "Warning message: " << warning_str << std::endl;
263+ printf("%s - INFO - [XIR]: Start to finalize ir graph session\n", GetTime().c_str());
264+ ret = ge::GEFinalize();
265+ if (ret != SUCCESS) {
266+ printf("%s - INFO - [XIR]: Finalize ir graph session failed\n", GetTime().c_str());
267+ return FAILED;
268+ }
269+ printf("%s - INFO - [XIR]: Finalize ir graph session success\n", GetTime().c_str());
270+ return SUCCESS;
271+}