已合并
补齐FakeQuantWithMinMaxVars系列4个算子的geir cpp调用example #8633
补齐FakeQuantWithMinMaxVars系列4个算子的geir cpp调用example #8633
已合并
zhoulong50创建于 8月13日
共 4 个文件变更+1119-0
@@ -0,0 +1,275 @@
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+/*!
12+ * \file test_geir_fake_quant_with_min_max_vars.cpp
13+ * \brief
14+ */
15+ 
16+#include <iostream>
17+#include <fstream>
18+#include <string.h>
19+#include <stdint.h>
20+#include <vector>
21+#include <string>
22+#include <map>
23+#include <cstdlib>
24+#include <ctime>
25+#include "assert.h"
26+#include "graph.h"
27+#include "types.h"
28+#include "tensor.h"
29+#include "ge_error_codes.h"
30+#include "ge_api_types.h"
31+#include "ge_api.h"
32+#include "array_ops.h"
33+#include "ge_ir_build.h"
34+#include "../op_graph/fake_quant_with_min_max_vars_proto.h"
35+ 
36+#define FAILED -1
37+#define SUCCESS 0
38+ 
39+using namespace ge;
40+using std::map;
41+using std::string;
42+using std::vector;
43+ 
44+#define ADD_INPUT(intputIndex, intputName, intputDtype, inputShape, useRandom, minVal, maxVal, fixedValue) \
45+ vector<int64_t> placeholder##intputIndex##_shape = inputShape; \
46+ auto placeholder##intputIndex = op::Data("placeholder" + intputIndex).set_attr_index(0); \
atomgit-bot
atomgit-botatomgit-bot8月13日

🟡 Medium Priority

op::Data("placeholder" + intputIndex) adds the integer index to a const char* literal, which is pointer arithmetic, not string concatenation. For intputIndex 1/2/3/4 the resulting Data node names become "laceholder1"/"aceholder2"/"holder3"/"eholder4" instead of "placeholder1".."placeholder4". The node names are wrong (misleading dump/debug output and a latent collision risk); combined with the hard-coded .set_attr_index(0) on every input, the Data nodes are only distinguishable by these mangled names.

likedislike
不准确?
47+ TensorDesc placeholder##intputIndex##_desc = TensorDesc(ge::Shape(placeholder##intputIndex##_shape), FORMAT_ND, \
48+ intputDtype); \
49+ placeholder##intputIndex##_desc.SetPlacement(ge::kPlacementHost); \
50+ placeholder##intputIndex##_desc.SetFormat(FORMAT_ND); \
51+ Tensor tensor_placeholder##intputIndex; \
52+ if (useRandom) { \
53+ ret = GenRandomDataFloat32(placeholder##intputIndex##_shape, tensor_placeholder##intputIndex, \
54+ placeholder##intputIndex##_desc, minVal, maxVal); \
55+ } else { \
56+ ret = GenOnesDataFloat32(placeholder##intputIndex##_shape, tensor_placeholder##intputIndex, \
57+ placeholder##intputIndex##_desc, fixedValue); \
58+ } \
59+ if (ret != SUCCESS) { \
60+ printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \
61+ return FAILED; \
62+ } \
63+ placeholder##intputIndex.update_input_desc_x(placeholder##intputIndex##_desc); \
64+ placeholder##intputIndex.update_output_desc_y(placeholder##intputIndex##_desc); \
65+ input.push_back(tensor_placeholder##intputIndex); \
66+ graph.AddOp(placeholder##intputIndex); \
67+ fakeQuantOp.set_input_##intputName(placeholder##intputIndex); \
68+ inputs.push_back(placeholder##intputIndex)
69+ 
70+#define ADD_INPUT_ATTR(attrName, attrValue) fakeQuantOp.set_attr_##attrName(attrValue)
71+ 
72+#define ADD_OUTPUT(outputIndex, outputName, outputDtype, outputShape) \
73+ TensorDesc outputName##outputIndex##_desc_ = TensorDesc(ge::Shape(outputShape), FORMAT_ND, outputDtype); \
74+ fakeQuantOp.update_output_desc_##outputName(outputName##outputIndex##_desc_)
75+ 
76+#define LOG_PRINT(message, ...) \
77+ do { \
78+ printf(message, ##__VA_ARGS__); \
79+ } while (0)
80+ 
81+string GetTime()
82+{
83+ time_t timep;
84+ time(&timep);
85+ char tmp[64];
86+ strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S,000", localtime(&timep));
87+ return tmp;
88+}
89+ 
90+uint32_t GetDataTypeSize(DataType dt)
91+{
92+ uint32_t dilation = 1;
93+ if (dt == ge::DT_FLOAT) {
94+ dilation = 4;
95+ } else if (dt == ge::DT_FLOAT16 || dt == ge::DT_BF16) {
96+ dilation = 2;
97+ } else if (dt == ge::DT_INT32) {
98+ dilation = 4;
99+ } else if (dt == ge::DT_INT64) {
100+ dilation = 8;
101+ } else if (dt == ge::DT_INT8) {
102+ dilation = 1;
103+ }
104+ return dilation;
105+}
106+ 
107+int32_t GenRandomDataFloat32(vector<int64_t> shapes, Tensor& input_tensor, TensorDesc& input_tensor_desc, float minVal,
108+ float maxVal)
109+{
110+ input_tensor_desc.SetRealDimCnt(shapes.size());
111+ size_t size = 1;
112+ for (uint32_t i = 0; i < shapes.size(); i++) {
113+ size *= shapes[i];
114+ }
115+ uint32_t data_len = size * sizeof(float);
116+ float* pData = new (std::nothrow) float[size];
117+ for (size_t i = 0; i < size; ++i) {
118+ *(pData + i) = minVal + static_cast<float>(rand()) / static_cast<float>(RAND_MAX) * (maxVal - minVal);
119+ }
120+ input_tensor = Tensor(input_tensor_desc, (uint8_t*)pData, data_len);
121+ return SUCCESS;
122+}
123+ 
124+int32_t GenOnesDataFloat32(vector<int64_t> shapes, Tensor& input_tensor, TensorDesc& input_tensor_desc, float value)
125+{
126+ input_tensor_desc.SetRealDimCnt(shapes.size());
127+ size_t size = 1;
128+ for (uint32_t i = 0; i < shapes.size(); i++) {
129+ size *= shapes[i];
130+ }
131+ uint32_t data_len = size * sizeof(float);
132+ float* pData = new (std::nothrow) float[size];
133+ for (size_t i = 0; i < size; ++i) {
134+ *(pData + i) = value;
135+ }
136+ input_tensor = Tensor(input_tensor_desc, (uint8_t*)pData, data_len);
137+ return SUCCESS;
138+}
139+ 
140+int32_t WriteDataToFile(string bin_file, uint64_t data_size, uint8_t* inputData)
141+{
142+ FILE* fp = fopen(bin_file.c_str(), "w");
143+ fwrite(inputData, sizeof(uint8_t), data_size, fp);
144+ fclose(fp);
145+ return SUCCESS;
146+}
147+ 
148+int CreateOppInGraph(DataType inDtype, std::vector<ge::Tensor>& input, std::vector<Operator>& inputs,
149+ std::vector<Operator>& outputs, Graph& graph)
150+{
151+ Status ret = SUCCESS;
152+ auto fakeQuantOp = op::FakeQuantWithMinMaxVars("fakeQuantWithMinMaxVars1");
153+ 
154+ std::vector<int64_t> xShape = {16};
155+ std::vector<int64_t> minMaxShape = {1};
156+ ADD_INPUT(1, x, inDtype, xShape, true, -8.0f, 8.0f, 0.0f);
157+ ADD_INPUT(2, min, inDtype, minMaxShape, false, 0.0f, 0.0f, -6.0f);
158+ ADD_INPUT(3, max, inDtype, minMaxShape, false, 0.0f, 0.0f, 6.0f);
159+ 
160+ ADD_INPUT_ATTR(num_bits, 8);
161+ ADD_INPUT_ATTR(narrow_range, false);
162+ 
163+ ADD_OUTPUT(1, y, inDtype, xShape);
164+ 
165+ outputs.push_back(fakeQuantOp);
166+ return SUCCESS;
167+}
168+ 
169+int main(int argc, char* argv[])
170+{
171+ srand(time(NULL));
172+ const char* graph_name = "tc_ge_irrun_test";
173+ Graph graph(graph_name);
174+ std::vector<ge::Tensor> input;
175+ 
176+ printf("%s - INFO - [XIR]: Start to initialize ge using ge global options\n", GetTime().c_str());
177+ std::map<AscendString, AscendString> global_options = {{"ge.exec.deviceId", "0"}, {"ge.graphRunMode", "1"}};
178+ Status ret = ge::GEInitialize(global_options);
179+ if (ret != SUCCESS) {
180+ printf("%s - INFO - [XIR]: Initialize ge using ge global options failed\n", GetTime().c_str());
181+ return FAILED;
182+ }
183+ printf("%s - INFO - [XIR]: Initialize ge using ge global options success\n", GetTime().c_str());
184+ 
185+ std::vector<Operator> inputs{};
186+ std::vector<Operator> outputs{};
187+ 
188+ DataType inDtype = DT_FLOAT;
189+ std::cout << inDtype << std::endl;
190+ 
191+ ret = CreateOppInGraph(inDtype, input, inputs, outputs, graph);
192+ if (ret != SUCCESS) {
193+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
194+ return FAILED;
195+ }
196+ 
197+ if (!inputs.empty() && !outputs.empty()) {
198+ graph.SetInputs(inputs).SetOutputs(outputs);
199+ }
200+ 
201+ std::map<AscendString, AscendString> build_options = {};
202+ printf("%s - INFO - [XIR]: Start to create ir session using build options\n", GetTime().c_str());
203+ ge::Session* session = new Session(build_options);
204+ 
205+ if (session == nullptr) {
206+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
207+ return FAILED;
208+ }
209+ printf("%s - INFO - [XIR]: Create ir session using build options success\n", GetTime().c_str());
210+ printf("%s - INFO - [XIR]: Start to add compute graph to ir session\n", GetTime().c_str());
211+ 
212+ std::map<AscendString, AscendString> graph_options = {};
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+ float* xData = (float*)input[0].GetData();
252+ float* resultData = (float*)output_data_i;
253+ LOG_PRINT("\n========== fake_quant_with_min_max_vars result ==========\n");
254+ LOG_PRINT("x y\n");
255+ for (int64_t j = 0; j < output_shape; j++) {
256+ LOG_PRINT("%f %f\n", xData[j], resultData[j]);
257+ }
258+ LOG_PRINT("==========================================================\n");
259+ }
260+ 
261+ ge::AscendString error_msg = ge::GEGetErrorMsgV2();
262+ std::string error_str(error_msg.GetString());
263+ std::cout << "Error message: " << error_str << std::endl;
264+ ge::AscendString warning_msg = ge::GEGetWarningMsgV2();
265+ std::string warning_str(warning_msg.GetString());
266+ std::cout << "Warning message: " << warning_str << std::endl;
267+ printf("%s - INFO - [XIR]: Start to finalize ir graph session\n", GetTime().c_str());
268+ ret = ge::GEFinalize();
269+ if (ret != SUCCESS) {
270+ printf("%s - INFO - [XIR]: Finalize ir graph session failed\n", GetTime().c_str());
271+ return FAILED;
272+ }
273+ printf("%s - INFO - [XIR]: Finalize ir graph session success\n", GetTime().c_str());
274+ return SUCCESS;
275+}
@@ -0,0 +1,283 @@
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+/*!
12+ * \file test_geir_fake_quant_with_min_max_vars_gradient.cpp
13+ * \brief
14+ */
15+ 
16+#include <iostream>
17+#include <fstream>
18+#include <string.h>
19+#include <stdint.h>
20+#include <vector>
21+#include <string>
22+#include <map>
23+#include <cstdlib>
24+#include <ctime>
25+#include "assert.h"
26+#include "graph.h"
27+#include "types.h"
28+#include "tensor.h"
29+#include "ge_error_codes.h"
30+#include "ge_api_types.h"
31+#include "ge_api.h"
32+#include "array_ops.h"
33+#include "ge_ir_build.h"
34+#include "../op_graph/fake_quant_with_min_max_vars_gradient_proto.h"
35+ 
36+#define FAILED -1
37+#define SUCCESS 0
38+ 
39+using namespace ge;
40+using std::map;
41+using std::string;
42+using std::vector;
43+ 
44+#define ADD_INPUT(intputIndex, intputName, intputDtype, inputShape, useRandom, minVal, maxVal, fixedValue) \
45+ vector<int64_t> placeholder##intputIndex##_shape = inputShape; \
46+ auto placeholder##intputIndex = op::Data("placeholder" + intputIndex).set_attr_index(0); \
atomgit-bot
atomgit-botatomgit-bot8月13日

🟡 Medium Priority

op::Data("placeholder" + intputIndex) adds the integer index to a const char* literal, which is pointer arithmetic, not string concatenation. For intputIndex 1/2/3/4 the resulting Data node names become "laceholder1"/"aceholder2"/"holder3"/"eholder4" instead of "placeholder1".."placeholder4". The node names are wrong (misleading dump/debug output and a latent collision risk); combined with the hard-coded .set_attr_index(0) on every input, the Data nodes are only distinguishable by these mangled names.

likedislike
不准确?
47+ TensorDesc placeholder##intputIndex##_desc = TensorDesc(ge::Shape(placeholder##intputIndex##_shape), FORMAT_ND, \
48+ intputDtype); \
49+ placeholder##intputIndex##_desc.SetPlacement(ge::kPlacementHost); \
50+ placeholder##intputIndex##_desc.SetFormat(FORMAT_ND); \
51+ Tensor tensor_placeholder##intputIndex; \
52+ if (useRandom) { \
53+ ret = GenRandomDataFloat32(placeholder##intputIndex##_shape, tensor_placeholder##intputIndex, \
54+ placeholder##intputIndex##_desc, minVal, maxVal); \
55+ } else { \
56+ ret = GenOnesDataFloat32(placeholder##intputIndex##_shape, tensor_placeholder##intputIndex, \
57+ placeholder##intputIndex##_desc, fixedValue); \
58+ } \
59+ if (ret != SUCCESS) { \
60+ printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \
61+ return FAILED; \
62+ } \
63+ placeholder##intputIndex.update_input_desc_x(placeholder##intputIndex##_desc); \
64+ placeholder##intputIndex.update_output_desc_y(placeholder##intputIndex##_desc); \
65+ input.push_back(tensor_placeholder##intputIndex); \
66+ graph.AddOp(placeholder##intputIndex); \
67+ fakeQuantGradOp.set_input_##intputName(placeholder##intputIndex); \
68+ inputs.push_back(placeholder##intputIndex)
69+ 
70+#define ADD_INPUT_ATTR(attrName, attrValue) fakeQuantGradOp.set_attr_##attrName(attrValue)
71+ 
72+#define ADD_OUTPUT(outputIndex, outputName, outputDtype, outputShape) \
73+ TensorDesc outputName##outputIndex##_desc_ = TensorDesc(ge::Shape(outputShape), FORMAT_ND, outputDtype); \
74+ fakeQuantGradOp.update_output_desc_##outputName(outputName##outputIndex##_desc_)
75+ 
76+#define LOG_PRINT(message, ...) \
77+ do { \
78+ printf(message, ##__VA_ARGS__); \
79+ } while (0)
80+ 
81+string GetTime()
82+{
83+ time_t timep;
84+ time(&timep);
85+ char tmp[64];
86+ strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S,000", localtime(&timep));
87+ return tmp;
88+}
89+ 
90+uint32_t GetDataTypeSize(DataType dt)
91+{
92+ uint32_t dilation = 1;
93+ if (dt == ge::DT_FLOAT) {
94+ dilation = 4;
95+ } else if (dt == ge::DT_FLOAT16 || dt == ge::DT_BF16) {
96+ dilation = 2;
97+ } else if (dt == ge::DT_INT32) {
98+ dilation = 4;
99+ } else if (dt == ge::DT_INT64) {
100+ dilation = 8;
101+ } else if (dt == ge::DT_INT8) {
102+ dilation = 1;
103+ }
104+ return dilation;
105+}
106+ 
107+int32_t GenRandomDataFloat32(vector<int64_t> shapes, Tensor& input_tensor, TensorDesc& input_tensor_desc, float minVal,
108+ float maxVal)
109+{
110+ input_tensor_desc.SetRealDimCnt(shapes.size());
111+ size_t size = 1;
112+ for (uint32_t i = 0; i < shapes.size(); i++) {
113+ size *= shapes[i];
114+ }
115+ uint32_t data_len = size * sizeof(float);
116+ float* pData = new (std::nothrow) float[size];
117+ for (size_t i = 0; i < size; ++i) {
118+ *(pData + i) = minVal + static_cast<float>(rand()) / static_cast<float>(RAND_MAX) * (maxVal - minVal);
119+ }
120+ input_tensor = Tensor(input_tensor_desc, (uint8_t*)pData, data_len);
121+ return SUCCESS;
122+}
123+ 
124+int32_t GenOnesDataFloat32(vector<int64_t> shapes, Tensor& input_tensor, TensorDesc& input_tensor_desc, float value)
125+{
126+ input_tensor_desc.SetRealDimCnt(shapes.size());
127+ size_t size = 1;
128+ for (uint32_t i = 0; i < shapes.size(); i++) {
129+ size *= shapes[i];
130+ }
131+ uint32_t data_len = size * sizeof(float);
132+ float* pData = new (std::nothrow) float[size];
133+ for (size_t i = 0; i < size; ++i) {
134+ *(pData + i) = value;
135+ }
136+ input_tensor = Tensor(input_tensor_desc, (uint8_t*)pData, data_len);
137+ return SUCCESS;
138+}
139+ 
140+int32_t WriteDataToFile(string bin_file, uint64_t data_size, uint8_t* inputData)
141+{
142+ FILE* fp = fopen(bin_file.c_str(), "w");
143+ fwrite(inputData, sizeof(uint8_t), data_size, fp);
144+ fclose(fp);
145+ return SUCCESS;
146+}
147+ 
148+int CreateOppInGraph(DataType inDtype, std::vector<ge::Tensor>& input, std::vector<Operator>& inputs,
149+ std::vector<Operator>& outputs, Graph& graph)
150+{
151+ Status ret = SUCCESS;
152+ auto fakeQuantGradOp = op::FakeQuantWithMinMaxVarsGradient("fakeQuantWithMinMaxVarsGradient1");
153+ 
154+ std::vector<int64_t> shape = {16};
155+ std::vector<int64_t> minMaxShape = {1};
156+ ADD_INPUT(1, gradients, inDtype, shape, true, -1.0f, 1.0f, 0.0f);
157+ ADD_INPUT(2, x, inDtype, shape, true, -8.0f, 8.0f, 0.0f);
158+ ADD_INPUT(3, min, inDtype, minMaxShape, false, 0.0f, 0.0f, -6.0f);
159+ ADD_INPUT(4, max, inDtype, minMaxShape, false, 0.0f, 0.0f, 6.0f);
160+ 
161+ ADD_INPUT_ATTR(num_bits, 8);
162+ ADD_INPUT_ATTR(narrow_range, false);
163+ 
164+ ADD_OUTPUT(1, backprops_wrt_x, inDtype, shape);
165+ ADD_OUTPUT(2, backprop_wrt_min, inDtype, minMaxShape);
166+ ADD_OUTPUT(3, backprop_wrt_max, inDtype, minMaxShape);
167+ 
168+ outputs.push_back(fakeQuantGradOp);
169+ return SUCCESS;
170+}
171+ 
172+int main(int argc, char* argv[])
173+{
174+ srand(time(NULL));
175+ const char* graph_name = "tc_ge_irrun_test";
176+ Graph graph(graph_name);
177+ std::vector<ge::Tensor> input;
178+ 
179+ printf("%s - INFO - [XIR]: Start to initialize ge using ge global options\n", GetTime().c_str());
180+ std::map<AscendString, AscendString> global_options = {{"ge.exec.deviceId", "0"}, {"ge.graphRunMode", "1"}};
181+ Status ret = ge::GEInitialize(global_options);
182+ if (ret != SUCCESS) {
183+ printf("%s - INFO - [XIR]: Initialize ge using ge global options failed\n", GetTime().c_str());
184+ return FAILED;
185+ }
186+ printf("%s - INFO - [XIR]: Initialize ge using ge global options success\n", GetTime().c_str());
187+ 
188+ std::vector<Operator> inputs{};
189+ std::vector<Operator> outputs{};
190+ 
191+ DataType inDtype = DT_FLOAT;
192+ std::cout << inDtype << std::endl;
193+ 
194+ ret = CreateOppInGraph(inDtype, input, inputs, outputs, graph);
195+ if (ret != SUCCESS) {
196+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
197+ return FAILED;
198+ }
199+ 
200+ if (!inputs.empty() && !outputs.empty()) {
201+ graph.SetInputs(inputs).SetOutputs(outputs);
202+ }
203+ 
204+ std::map<AscendString, AscendString> build_options = {};
205+ printf("%s - INFO - [XIR]: Start to create ir session using build options\n", GetTime().c_str());
206+ ge::Session* session = new Session(build_options);
207+ 
208+ if (session == nullptr) {
209+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
210+ return FAILED;
211+ }
212+ printf("%s - INFO - [XIR]: Create ir session using build options success\n", GetTime().c_str());
213+ printf("%s - INFO - [XIR]: Start to add compute graph to ir session\n", GetTime().c_str());
214+ 
215+ std::map<AscendString, AscendString> graph_options = {};
216+ uint32_t graph_id = 0;
217+ ret = session->AddGraph(graph_id, graph, graph_options);
218+ 
219+ printf("%s - INFO - [XIR]: Session add ir compute graph to ir session success\n", GetTime().c_str());
220+ printf("%s - INFO - [XIR]: dump graph to txt\n", GetTime().c_str());
221+ std::string file_path = "./dump";
222+ aclgrphDumpGraph(graph, file_path.c_str(), file_path.length());
223+ printf("%s - INFO - [XIR]: Start to run ir compute graph\n", GetTime().c_str());
224+ std::vector<ge::Tensor> output;
225+ ret = session->RunGraph(graph_id, input, output);
226+ if (ret != SUCCESS) {
227+ printf("%s - INFO - [XIR]: Run graph failed\n", GetTime().c_str());
228+ delete session;
229+ GEFinalize();
230+ return FAILED;
231+ }
232+ printf("%s - INFO - [XIR]: Session run ir compute graph success\n", GetTime().c_str());
233+ 
234+ int input_num = input.size();
235+ for (int i = 0; i < input_num; i++) {
236+ std::cout << "input " << i << " dtype : " << input[i].GetTensorDesc().GetDataType() << std::endl;
237+ string input_file = "./tc_ge_irrun_test_0008_npu_input_" + std::to_string(i) + ".bin";
238+ uint8_t* input_data_i = input[i].GetData();
239+ int64_t input_shape = input[i].GetTensorDesc().GetShape().GetShapeSize();
240+ std::cout << "this is " << i << "th input, input shape size =" << input_shape << std::endl;
241+ uint32_t data_size = input_shape * GetDataTypeSize(input[i].GetTensorDesc().GetDataType());
242+ WriteDataToFile((const char*)input_file.c_str(), data_size, input_data_i);
243+ }
244+ 
245+ int output_num = output.size();
246+ for (int i = 0; i < output_num; i++) {
247+ std::cout << "output " << i << " dtype : " << output[i].GetTensorDesc().GetDataType() << std::endl;
248+ string output_file = "./tc_ge_irrun_test_0008_npu_output_" + std::to_string(i) + ".bin";
249+ uint8_t* output_data_i = output[i].GetData();
250+ int64_t output_shape = output[i].GetTensorDesc().GetShape().GetShapeSize();
251+ std::cout << "this is " << i << "th output, output shape size =" << output_shape << std::endl;
252+ uint32_t data_size = output_shape * GetDataTypeSize(output[i].GetTensorDesc().GetDataType());
253+ WriteDataToFile((const char*)output_file.c_str(), data_size, output_data_i);
254+ float* resultData = (float*)output_data_i;
255+ if (i == 0) {
256+ float* gradData = (float*)input[0].GetData();
257+ float* xData = (float*)input[1].GetData();
258+ LOG_PRINT("\n========== fake_quant_with_min_max_vars_gradient result ==========\n");
259+ LOG_PRINT("gradients x backprops_wrt_x\n");
260+ for (int64_t j = 0; j < output_shape; j++) {
261+ LOG_PRINT("%f %f %f\n", gradData[j], xData[j], resultData[j]);
262+ }
263+ LOG_PRINT("===================================================================\n");
264+ } else {
265+ LOG_PRINT("backprop_wrt_%s = %f\n", (i == 1 ? "min" : "max"), resultData[0]);
266+ }
267+ }
268+ 
269+ ge::AscendString error_msg = ge::GEGetErrorMsgV2();
270+ std::string error_str(error_msg.GetString());
271+ std::cout << "Error message: " << error_str << std::endl;
272+ ge::AscendString warning_msg = ge::GEGetWarningMsgV2();
273+ std::string warning_str(warning_msg.GetString());
274+ std::cout << "Warning message: " << warning_str << std::endl;
275+ printf("%s - INFO - [XIR]: Start to finalize ir graph session\n", GetTime().c_str());
276+ ret = ge::GEFinalize();
277+ if (ret != SUCCESS) {
278+ printf("%s - INFO - [XIR]: Finalize ir graph session failed\n", GetTime().c_str());
279+ return FAILED;
280+ }
281+ printf("%s - INFO - [XIR]: Finalize ir graph session success\n", GetTime().c_str());
282+ return SUCCESS;
283+}
@@ -0,0 +1,275 @@
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+/*!
12+ * \file test_geir_fake_quant_with_min_max_vars_per_channel.cpp
13+ * \brief
14+ */
15+ 
16+#include <iostream>
17+#include <fstream>
18+#include <string.h>
19+#include <stdint.h>
20+#include <vector>
21+#include <string>
22+#include <map>
23+#include <cstdlib>
24+#include <ctime>
25+#include "assert.h"
26+#include "graph.h"
27+#include "types.h"
28+#include "tensor.h"
29+#include "ge_error_codes.h"
30+#include "ge_api_types.h"
31+#include "ge_api.h"
32+#include "array_ops.h"
33+#include "ge_ir_build.h"
34+#include "../op_graph/fake_quant_with_min_max_vars_per_channel_proto.h"
35+ 
36+#define FAILED -1
37+#define SUCCESS 0
38+ 
39+using namespace ge;
40+using std::map;
41+using std::string;
42+using std::vector;
43+ 
44+#define ADD_INPUT(intputIndex, intputName, intputDtype, inputShape, useRandom, minVal, maxVal, fixedValue) \
45+ vector<int64_t> placeholder##intputIndex##_shape = inputShape; \
46+ auto placeholder##intputIndex = op::Data("placeholder" + intputIndex).set_attr_index(0); \
atomgit-bot
atomgit-botatomgit-bot8月13日

🟡 Medium Priority

op::Data("placeholder" + intputIndex) adds the integer index to a const char* literal, which is pointer arithmetic, not string concatenation. For intputIndex 1/2/3 the resulting Data node names become "laceholder1"/"aceholder2"/"holder3" instead of "placeholder1".."placeholder3". The node names are wrong (misleading dump/debug output and a latent collision risk); combined with the hard-coded .set_attr_index(0) on every input, the Data nodes are only distinguishable by these mangled names.

likedislike
不准确?
47+ TensorDesc placeholder##intputIndex##_desc = TensorDesc(ge::Shape(placeholder##intputIndex##_shape), FORMAT_ND, \
48+ intputDtype); \
49+ placeholder##intputIndex##_desc.SetPlacement(ge::kPlacementHost); \
50+ placeholder##intputIndex##_desc.SetFormat(FORMAT_ND); \
51+ Tensor tensor_placeholder##intputIndex; \
52+ if (useRandom) { \
53+ ret = GenRandomDataFloat32(placeholder##intputIndex##_shape, tensor_placeholder##intputIndex, \
54+ placeholder##intputIndex##_desc, minVal, maxVal); \
55+ } else { \
56+ ret = GenOnesDataFloat32(placeholder##intputIndex##_shape, tensor_placeholder##intputIndex, \
57+ placeholder##intputIndex##_desc, fixedValue); \
58+ } \
59+ if (ret != SUCCESS) { \
60+ printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \
61+ return FAILED; \
62+ } \
63+ placeholder##intputIndex.update_input_desc_x(placeholder##intputIndex##_desc); \
64+ placeholder##intputIndex.update_output_desc_y(placeholder##intputIndex##_desc); \
65+ input.push_back(tensor_placeholder##intputIndex); \
66+ graph.AddOp(placeholder##intputIndex); \
67+ fakeQuantOp.set_input_##intputName(placeholder##intputIndex); \
68+ inputs.push_back(placeholder##intputIndex)
69+ 
70+#define ADD_INPUT_ATTR(attrName, attrValue) fakeQuantOp.set_attr_##attrName(attrValue)
71+ 
72+#define ADD_OUTPUT(outputIndex, outputName, outputDtype, outputShape) \
73+ TensorDesc outputName##outputIndex##_desc_ = TensorDesc(ge::Shape(outputShape), FORMAT_ND, outputDtype); \
74+ fakeQuantOp.update_output_desc_##outputName(outputName##outputIndex##_desc_)
75+ 
76+#define LOG_PRINT(message, ...) \
77+ do { \
78+ printf(message, ##__VA_ARGS__); \
79+ } while (0)
80+ 
81+string GetTime()
82+{
83+ time_t timep;
84+ time(&timep);
85+ char tmp[64];
86+ strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S,000", localtime(&timep));
87+ return tmp;
88+}
89+ 
90+uint32_t GetDataTypeSize(DataType dt)
91+{
92+ uint32_t dilation = 1;
93+ if (dt == ge::DT_FLOAT) {
94+ dilation = 4;
95+ } else if (dt == ge::DT_FLOAT16 || dt == ge::DT_BF16) {
96+ dilation = 2;
97+ } else if (dt == ge::DT_INT32) {
98+ dilation = 4;
99+ } else if (dt == ge::DT_INT64) {
100+ dilation = 8;
101+ } else if (dt == ge::DT_INT8) {
102+ dilation = 1;
103+ }
104+ return dilation;
105+}
106+ 
107+int32_t GenRandomDataFloat32(vector<int64_t> shapes, Tensor& input_tensor, TensorDesc& input_tensor_desc, float minVal,
108+ float maxVal)
109+{
110+ input_tensor_desc.SetRealDimCnt(shapes.size());
111+ size_t size = 1;
112+ for (uint32_t i = 0; i < shapes.size(); i++) {
113+ size *= shapes[i];
114+ }
115+ uint32_t data_len = size * sizeof(float);
116+ float* pData = new (std::nothrow) float[size];
117+ for (size_t i = 0; i < size; ++i) {
118+ *(pData + i) = minVal + static_cast<float>(rand()) / static_cast<float>(RAND_MAX) * (maxVal - minVal);
119+ }
120+ input_tensor = Tensor(input_tensor_desc, (uint8_t*)pData, data_len);
121+ return SUCCESS;
122+}
123+ 
124+int32_t GenOnesDataFloat32(vector<int64_t> shapes, Tensor& input_tensor, TensorDesc& input_tensor_desc, float value)
125+{
126+ input_tensor_desc.SetRealDimCnt(shapes.size());
127+ size_t size = 1;
128+ for (uint32_t i = 0; i < shapes.size(); i++) {
129+ size *= shapes[i];
130+ }
131+ uint32_t data_len = size * sizeof(float);
132+ float* pData = new (std::nothrow) float[size];
133+ for (size_t i = 0; i < size; ++i) {
134+ *(pData + i) = value;
135+ }
136+ input_tensor = Tensor(input_tensor_desc, (uint8_t*)pData, data_len);
137+ return SUCCESS;
138+}
139+ 
140+int32_t WriteDataToFile(string bin_file, uint64_t data_size, uint8_t* inputData)
141+{
142+ FILE* fp = fopen(bin_file.c_str(), "w");
143+ fwrite(inputData, sizeof(uint8_t), data_size, fp);
144+ fclose(fp);
145+ return SUCCESS;
146+}
147+ 
148+int CreateOppInGraph(DataType inDtype, std::vector<ge::Tensor>& input, std::vector<Operator>& inputs,
149+ std::vector<Operator>& outputs, Graph& graph)
150+{
151+ Status ret = SUCCESS;
152+ auto fakeQuantOp = op::FakeQuantWithMinMaxVarsPerChannel("fakeQuantWithMinMaxVarsPerChannel1");
153+ 
154+ std::vector<int64_t> xShape = {4, 4};
155+ std::vector<int64_t> channelShape = {4};
156+ ADD_INPUT(1, x, inDtype, xShape, true, -8.0f, 8.0f, 0.0f);
157+ ADD_INPUT(2, min, inDtype, channelShape, false, 0.0f, 0.0f, -6.0f);
158+ ADD_INPUT(3, max, inDtype, channelShape, false, 0.0f, 0.0f, 6.0f);
159+ 
160+ ADD_INPUT_ATTR(num_bits, 8);
161+ ADD_INPUT_ATTR(narrow_range, false);
162+ 
163+ ADD_OUTPUT(1, y, inDtype, xShape);
164+ 
165+ outputs.push_back(fakeQuantOp);
166+ return SUCCESS;
167+}
168+ 
169+int main(int argc, char* argv[])
170+{
171+ srand(time(NULL));
172+ const char* graph_name = "tc_ge_irrun_test";
173+ Graph graph(graph_name);
174+ std::vector<ge::Tensor> input;
175+ 
176+ printf("%s - INFO - [XIR]: Start to initialize ge using ge global options\n", GetTime().c_str());
177+ std::map<AscendString, AscendString> global_options = {{"ge.exec.deviceId", "0"}, {"ge.graphRunMode", "1"}};
178+ Status ret = ge::GEInitialize(global_options);
179+ if (ret != SUCCESS) {
180+ printf("%s - INFO - [XIR]: Initialize ge using ge global options failed\n", GetTime().c_str());
181+ return FAILED;
182+ }
183+ printf("%s - INFO - [XIR]: Initialize ge using ge global options success\n", GetTime().c_str());
184+ 
185+ std::vector<Operator> inputs{};
186+ std::vector<Operator> outputs{};
187+ 
188+ DataType inDtype = DT_FLOAT;
189+ std::cout << inDtype << std::endl;
190+ 
191+ ret = CreateOppInGraph(inDtype, input, inputs, outputs, graph);
192+ if (ret != SUCCESS) {
193+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
194+ return FAILED;
195+ }
196+ 
197+ if (!inputs.empty() && !outputs.empty()) {
198+ graph.SetInputs(inputs).SetOutputs(outputs);
199+ }
200+ 
201+ std::map<AscendString, AscendString> build_options = {};
202+ printf("%s - INFO - [XIR]: Start to create ir session using build options\n", GetTime().c_str());
203+ ge::Session* session = new Session(build_options);
204+ 
205+ if (session == nullptr) {
206+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
207+ return FAILED;
208+ }
209+ printf("%s - INFO - [XIR]: Create ir session using build options success\n", GetTime().c_str());
210+ printf("%s - INFO - [XIR]: Start to add compute graph to ir session\n", GetTime().c_str());
211+ 
212+ std::map<AscendString, AscendString> graph_options = {};
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+ float* xData = (float*)input[0].GetData();
252+ float* resultData = (float*)output_data_i;
253+ LOG_PRINT("\n========== fake_quant_with_min_max_vars_per_channel result ==========\n");
254+ LOG_PRINT("x y\n");
255+ for (int64_t j = 0; j < output_shape; j++) {
256+ LOG_PRINT("%f %f\n", xData[j], resultData[j]);
257+ }
258+ LOG_PRINT("===================================================================\n");
259+ }
260+ 
261+ ge::AscendString error_msg = ge::GEGetErrorMsgV2();
262+ std::string error_str(error_msg.GetString());
263+ std::cout << "Error message: " << error_str << std::endl;
264+ ge::AscendString warning_msg = ge::GEGetWarningMsgV2();
265+ std::string warning_str(warning_msg.GetString());
266+ std::cout << "Warning message: " << warning_str << std::endl;
267+ printf("%s - INFO - [XIR]: Start to finalize ir graph session\n", GetTime().c_str());
268+ ret = ge::GEFinalize();
269+ if (ret != SUCCESS) {
270+ printf("%s - INFO - [XIR]: Finalize ir graph session failed\n", GetTime().c_str());
271+ return FAILED;
272+ }
273+ printf("%s - INFO - [XIR]: Finalize ir graph session success\n", GetTime().c_str());
274+ return SUCCESS;
275+}
@@ -0,0 +1,286 @@
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+/*!
12+ * \file test_geir_fake_quant_with_min_max_vars_per_channel_gradient.cpp
13+ * \brief
14+ */
15+ 
16+#include <iostream>
17+#include <fstream>
18+#include <string.h>
19+#include <stdint.h>
20+#include <vector>
21+#include <string>
22+#include <map>
23+#include <cstdlib>
24+#include <ctime>
25+#include "assert.h"
26+#include "graph.h"
27+#include "types.h"
28+#include "tensor.h"
29+#include "ge_error_codes.h"
30+#include "ge_api_types.h"
31+#include "ge_api.h"
32+#include "array_ops.h"
33+#include "ge_ir_build.h"
34+#include "../op_graph/fake_quant_with_min_max_vars_per_channel_gradient_proto.h"
35+ 
36+#define FAILED -1
37+#define SUCCESS 0
38+ 
39+using namespace ge;
40+using std::map;
41+using std::string;
42+using std::vector;
43+ 
44+#define ADD_INPUT(intputIndex, intputName, intputDtype, inputShape, useRandom, minVal, maxVal, fixedValue) \
45+ vector<int64_t> placeholder##intputIndex##_shape = inputShape; \
46+ auto placeholder##intputIndex = op::Data("placeholder" + intputIndex).set_attr_index(0); \
atomgit-bot
atomgit-botatomgit-bot8月13日

🟡 Medium Priority

op::Data("placeholder" + intputIndex) adds the integer index to a const char* literal, which is pointer arithmetic, not string concatenation. For intputIndex 1/2/3/4 the resulting Data node names become "laceholder1"/"aceholder2"/"holder3"/"eholder4" instead of "placeholder1".."placeholder4". The node names are wrong (misleading dump/debug output and a latent collision risk); combined with the hard-coded .set_attr_index(0) on every input, the Data nodes are only distinguishable by these mangled names.

likedislike
不准确?
47+ TensorDesc placeholder##intputIndex##_desc = TensorDesc(ge::Shape(placeholder##intputIndex##_shape), FORMAT_ND, \
48+ intputDtype); \
49+ placeholder##intputIndex##_desc.SetPlacement(ge::kPlacementHost); \
50+ placeholder##intputIndex##_desc.SetFormat(FORMAT_ND); \
51+ Tensor tensor_placeholder##intputIndex; \
52+ if (useRandom) { \
53+ ret = GenRandomDataFloat32(placeholder##intputIndex##_shape, tensor_placeholder##intputIndex, \
54+ placeholder##intputIndex##_desc, minVal, maxVal); \
55+ } else { \
56+ ret = GenOnesDataFloat32(placeholder##intputIndex##_shape, tensor_placeholder##intputIndex, \
57+ placeholder##intputIndex##_desc, fixedValue); \
58+ } \
59+ if (ret != SUCCESS) { \
60+ printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \
61+ return FAILED; \
62+ } \
63+ placeholder##intputIndex.update_input_desc_x(placeholder##intputIndex##_desc); \
64+ placeholder##intputIndex.update_output_desc_y(placeholder##intputIndex##_desc); \
65+ input.push_back(tensor_placeholder##intputIndex); \
66+ graph.AddOp(placeholder##intputIndex); \
67+ fakeQuantGradOp.set_input_##intputName(placeholder##intputIndex); \
68+ inputs.push_back(placeholder##intputIndex)
69+ 
70+#define ADD_INPUT_ATTR(attrName, attrValue) fakeQuantGradOp.set_attr_##attrName(attrValue)
71+ 
72+#define ADD_OUTPUT(outputIndex, outputName, outputDtype, outputShape) \
73+ TensorDesc outputName##outputIndex##_desc_ = TensorDesc(ge::Shape(outputShape), FORMAT_ND, outputDtype); \
74+ fakeQuantGradOp.update_output_desc_##outputName(outputName##outputIndex##_desc_)
75+ 
76+#define LOG_PRINT(message, ...) \
77+ do { \
78+ printf(message, ##__VA_ARGS__); \
79+ } while (0)
80+ 
81+string GetTime()
82+{
83+ time_t timep;
84+ time(&timep);
85+ char tmp[64];
86+ strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S,000", localtime(&timep));
87+ return tmp;
88+}
89+ 
90+uint32_t GetDataTypeSize(DataType dt)
91+{
92+ uint32_t dilation = 1;
93+ if (dt == ge::DT_FLOAT) {
94+ dilation = 4;
95+ } else if (dt == ge::DT_FLOAT16 || dt == ge::DT_BF16) {
96+ dilation = 2;
97+ } else if (dt == ge::DT_INT32) {
98+ dilation = 4;
99+ } else if (dt == ge::DT_INT64) {
100+ dilation = 8;
101+ } else if (dt == ge::DT_INT8) {
102+ dilation = 1;
103+ }
104+ return dilation;
105+}
106+ 
107+int32_t GenRandomDataFloat32(vector<int64_t> shapes, Tensor& input_tensor, TensorDesc& input_tensor_desc, float minVal,
108+ float maxVal)
109+{
110+ input_tensor_desc.SetRealDimCnt(shapes.size());
111+ size_t size = 1;
112+ for (uint32_t i = 0; i < shapes.size(); i++) {
113+ size *= shapes[i];
114+ }
115+ uint32_t data_len = size * sizeof(float);
116+ float* pData = new (std::nothrow) float[size];
117+ for (size_t i = 0; i < size; ++i) {
118+ *(pData + i) = minVal + static_cast<float>(rand()) / static_cast<float>(RAND_MAX) * (maxVal - minVal);
119+ }
120+ input_tensor = Tensor(input_tensor_desc, (uint8_t*)pData, data_len);
121+ return SUCCESS;
122+}
123+ 
124+int32_t GenOnesDataFloat32(vector<int64_t> shapes, Tensor& input_tensor, TensorDesc& input_tensor_desc, float value)
125+{
126+ input_tensor_desc.SetRealDimCnt(shapes.size());
127+ size_t size = 1;
128+ for (uint32_t i = 0; i < shapes.size(); i++) {
129+ size *= shapes[i];
130+ }
131+ uint32_t data_len = size * sizeof(float);
132+ float* pData = new (std::nothrow) float[size];
133+ for (size_t i = 0; i < size; ++i) {
134+ *(pData + i) = value;
135+ }
136+ input_tensor = Tensor(input_tensor_desc, (uint8_t*)pData, data_len);
137+ return SUCCESS;
138+}
139+ 
140+int32_t WriteDataToFile(string bin_file, uint64_t data_size, uint8_t* inputData)
141+{
142+ FILE* fp = fopen(bin_file.c_str(), "w");
143+ fwrite(inputData, sizeof(uint8_t), data_size, fp);
144+ fclose(fp);
145+ return SUCCESS;
146+}
147+ 
148+int CreateOppInGraph(DataType inDtype, std::vector<ge::Tensor>& input, std::vector<Operator>& inputs,
149+ std::vector<Operator>& outputs, Graph& graph)
150+{
151+ Status ret = SUCCESS;
152+ auto fakeQuantGradOp = op::FakeQuantWithMinMaxVarsPerChannelGradient("fakeQuantWithMinMaxVarsPerChannelGradient1");
153+ 
154+ std::vector<int64_t> shape = {4, 4};
155+ std::vector<int64_t> channelShape = {4};
156+ ADD_INPUT(1, gradients, inDtype, shape, true, -1.0f, 1.0f, 0.0f);
157+ ADD_INPUT(2, x, inDtype, shape, true, -8.0f, 8.0f, 0.0f);
158+ ADD_INPUT(3, min, inDtype, channelShape, false, 0.0f, 0.0f, -6.0f);
159+ ADD_INPUT(4, max, inDtype, channelShape, false, 0.0f, 0.0f, 6.0f);
160+ 
161+ ADD_INPUT_ATTR(num_bits, 8);
162+ ADD_INPUT_ATTR(narrow_range, false);
163+ 
164+ ADD_OUTPUT(1, backprops_wrt_x, inDtype, shape);
165+ ADD_OUTPUT(2, backprops_wrt_min, inDtype, channelShape);
166+ ADD_OUTPUT(3, backprops_wrt_max, inDtype, channelShape);
167+ 
168+ outputs.push_back(fakeQuantGradOp);
169+ return SUCCESS;
170+}
171+ 
172+int main(int argc, char* argv[])
173+{
174+ srand(time(NULL));
175+ const char* graph_name = "tc_ge_irrun_test";
176+ Graph graph(graph_name);
177+ std::vector<ge::Tensor> input;
178+ 
179+ printf("%s - INFO - [XIR]: Start to initialize ge using ge global options\n", GetTime().c_str());
180+ std::map<AscendString, AscendString> global_options = {{"ge.exec.deviceId", "0"}, {"ge.graphRunMode", "1"}};
181+ Status ret = ge::GEInitialize(global_options);
182+ if (ret != SUCCESS) {
183+ printf("%s - INFO - [XIR]: Initialize ge using ge global options failed\n", GetTime().c_str());
184+ return FAILED;
185+ }
186+ printf("%s - INFO - [XIR]: Initialize ge using ge global options success\n", GetTime().c_str());
187+ 
188+ std::vector<Operator> inputs{};
189+ std::vector<Operator> outputs{};
190+ 
191+ DataType inDtype = DT_FLOAT;
192+ std::cout << inDtype << std::endl;
193+ 
194+ ret = CreateOppInGraph(inDtype, input, inputs, outputs, graph);
195+ if (ret != SUCCESS) {
196+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
197+ return FAILED;
198+ }
199+ 
200+ if (!inputs.empty() && !outputs.empty()) {
201+ graph.SetInputs(inputs).SetOutputs(outputs);
202+ }
203+ 
204+ std::map<AscendString, AscendString> build_options = {};
205+ printf("%s - INFO - [XIR]: Start to create ir session using build options\n", GetTime().c_str());
206+ ge::Session* session = new Session(build_options);
207+ 
208+ if (session == nullptr) {
209+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
210+ return FAILED;
211+ }
212+ printf("%s - INFO - [XIR]: Create ir session using build options success\n", GetTime().c_str());
213+ printf("%s - INFO - [XIR]: Start to add compute graph to ir session\n", GetTime().c_str());
214+ 
215+ std::map<AscendString, AscendString> graph_options = {};
216+ uint32_t graph_id = 0;
217+ ret = session->AddGraph(graph_id, graph, graph_options);
218+ 
219+ printf("%s - INFO - [XIR]: Session add ir compute graph to ir session success\n", GetTime().c_str());
220+ printf("%s - INFO - [XIR]: dump graph to txt\n", GetTime().c_str());
221+ std::string file_path = "./dump";
222+ aclgrphDumpGraph(graph, file_path.c_str(), file_path.length());
223+ printf("%s - INFO - [XIR]: Start to run ir compute graph\n", GetTime().c_str());
224+ std::vector<ge::Tensor> output;
225+ ret = session->RunGraph(graph_id, input, output);
226+ if (ret != SUCCESS) {
227+ printf("%s - INFO - [XIR]: Run graph failed\n", GetTime().c_str());
228+ delete session;
229+ GEFinalize();
230+ return FAILED;
231+ }
232+ printf("%s - INFO - [XIR]: Session run ir compute graph success\n", GetTime().c_str());
233+ 
234+ int input_num = input.size();
235+ for (int i = 0; i < input_num; i++) {
236+ std::cout << "input " << i << " dtype : " << input[i].GetTensorDesc().GetDataType() << std::endl;
237+ string input_file = "./tc_ge_irrun_test_0008_npu_input_" + std::to_string(i) + ".bin";
238+ uint8_t* input_data_i = input[i].GetData();
239+ int64_t input_shape = input[i].GetTensorDesc().GetShape().GetShapeSize();
240+ std::cout << "this is " << i << "th input, input shape size =" << input_shape << std::endl;
241+ uint32_t data_size = input_shape * GetDataTypeSize(input[i].GetTensorDesc().GetDataType());
242+ WriteDataToFile((const char*)input_file.c_str(), data_size, input_data_i);
243+ }
244+ 
245+ int output_num = output.size();
246+ for (int i = 0; i < output_num; i++) {
247+ std::cout << "output " << i << " dtype : " << output[i].GetTensorDesc().GetDataType() << std::endl;
248+ string output_file = "./tc_ge_irrun_test_0008_npu_output_" + std::to_string(i) + ".bin";
249+ uint8_t* output_data_i = output[i].GetData();
250+ int64_t output_shape = output[i].GetTensorDesc().GetShape().GetShapeSize();
251+ std::cout << "this is " << i << "th output, output shape size =" << output_shape << std::endl;
252+ uint32_t data_size = output_shape * GetDataTypeSize(output[i].GetTensorDesc().GetDataType());
253+ WriteDataToFile((const char*)output_file.c_str(), data_size, output_data_i);
254+ float* resultData = (float*)output_data_i;
255+ if (i == 0) {
256+ float* gradData = (float*)input[0].GetData();
257+ float* xData = (float*)input[1].GetData();
258+ LOG_PRINT("\n========== fake_quant_with_min_max_vars_per_channel_gradient result ==========\n");
259+ LOG_PRINT("gradients x backprops_wrt_x\n");
260+ for (int64_t j = 0; j < output_shape; j++) {
261+ LOG_PRINT("%f %f %f\n", gradData[j], xData[j], resultData[j]);
262+ }
263+ LOG_PRINT("===================================================================\n");
264+ } else {
265+ LOG_PRINT("backprops_wrt_%s:\n", (i == 1 ? "min" : "max"));
266+ for (int64_t j = 0; j < output_shape; j++) {
267+ LOG_PRINT("[%ld] %f\n", j, resultData[j]);
268+ }
269+ }
270+ }
271+ 
272+ ge::AscendString error_msg = ge::GEGetErrorMsgV2();
273+ std::string error_str(error_msg.GetString());
274+ std::cout << "Error message: " << error_str << std::endl;
275+ ge::AscendString warning_msg = ge::GEGetWarningMsgV2();
276+ std::string warning_str(warning_msg.GetString());
277+ std::cout << "Warning message: " << warning_str << std::endl;
278+ printf("%s - INFO - [XIR]: Start to finalize ir graph session\n", GetTime().c_str());
279+ ret = ge::GEFinalize();
280+ if (ret != SUCCESS) {
281+ printf("%s - INFO - [XIR]: Finalize ir graph session failed\n", GetTime().c_str());
282+ return FAILED;
283+ }
284+ printf("%s - INFO - [XIR]: Finalize ir graph session success\n", GetTime().c_str());
285+ return SUCCESS;
286+}