已合并
strided_slice算子example补充 #595
hawdonz创建于 2025年12月30日
strided_slice算子example补充 #595
已合并
hawdonz创建于 2025年12月30日
1 个文件变更+237-112
@@ -7,136 +7,261 @@
7* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.7* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8* See LICENSE in the root of the software repository for the full text of the License.8* See LICENSE in the root of the software repository for the full text of the License.
9*/9*/
10- 10+
11#include <iostream>11#include <iostream>
12+#include <fstream>
13+#include <string.h>
14+#include <stdint.h>
12#include <vector>15#include <vector>
13-#include "acl/acl.h"16+#include <string>
14-#include "aclnnop/aclnn_slice.h"17+#include <map>
18+#include "assert.h"
15 19 
16-#define CHECK_RET(cond, return_expr) \20+#include "graph.h"
17-do { \21+#include "types.h"
18- if (!(cond)) { \22+#include "tensor.h"
19- return_expr; \23+#include "ge_error_codes.h"
20- } \24+#include "ge_api_types.h"
21-} while (0)25+#include "ge_api.h"
26+#include "array_ops.h"
27+#include "ge_ir_build.h"
22 28 
23-#define LOG_PRINT(message, ...) \29+#include "experiment_ops.h"
24-do { \30+#include "nn_other.h"
25- printf(message, ##__VA_ARGS__); \31+#include "../op_graph/strided_slice_proto.h"
26-} while (0)
27 32 
28-int64_t GetShapeSize(const std::vector<int64_t>& shape) {33+#define FAILED -1
29-int64_t shapeSize = 1;34+#define SUCCESS 0
30-for (auto i : shape) {35+ 
31- shapeSize *= i;36+using namespace ge;
32-}37+using std::map;
33-return shapeSize;38+using std::string;
39+using std::vector;
40+ 
41+#define ADD_INPUT(inputIndex, inputName, inputDtype, inputShape) \
42+ do { \
43+ std::string name##inputIndex = "placeholder" + std::to_string(inputIndex); \
44+ auto placeholder##inputIndex = op::Data(name##inputIndex.c_str()).set_attr_index(0); \
45+ TensorDesc placeholder##inputIndex##_desc = TensorDesc(ge::Shape(inputShape), FORMAT_ND, inputDtype); \
46+ placeholder##inputIndex##_desc.SetPlacement(ge::kPlacementHost); \
47+ placeholder##inputIndex##_desc.SetFormat(FORMAT_ND); \
48+ Tensor tensor_placeholder##inputIndex; \
49+ ret = GenOnesDataFloat32(inputShape, tensor_placeholder##inputIndex, placeholder##inputIndex##_desc, 2.3f); \
50+ if (ret != SUCCESS) { \
51+ printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \
52+ return FAILED; \
53+ } \
54+ placeholder##inputIndex.update_input_desc_x(placeholder##inputIndex##_desc); \
55+ graph.AddOp(placeholder##inputIndex); \
56+ input.push_back(tensor_placeholder##inputIndex); \
57+ stridedslice1.set_input_##inputName(placeholder##inputIndex); \
58+ inputs.push_back(placeholder##inputIndex); \
59+ } while (0)
60+ 
61+#define ADD_OUTPUT(outputIndex, outputName, outputDtype, outputShape) \
62+ do { \
63+ TensorDesc outputName##outputIndex##_desc = TensorDesc(ge::Shape(outputShape), FORMAT_ND, outputDtype); \
64+ stridedslice1.update_output_desc_##outputName(outputName##outputIndex##_desc); \
65+ } while (0)
66+ 
67+#define ADD_INPUT_ATTR(attrName, attrValue) stridedslice1.set_attr_##attrName(attrValue)
68+ 
69+#define LOG_PRINT(message, ...) \
70+ do { \
71+ printf(message, ##__VA_ARGS__); \
72+ } while (0)
73+ 
74+string GetTime()
75+{
76+ time_t timep;
77+ time(&timep);
78+ char tmp[64];
79+ strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S,000", localtime(&timep));
80+ return tmp;
34}81}
35 82 
36-int Init(int32_t deviceId, aclrtStream* stream) {83+uint32_t GetDataTypeSize(DataType dt)
37-// 固定写法,资源初始化84+{
38-auto ret = aclInit(nullptr);85+ if (dt == ge::DT_FLOAT)
39-CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);86+ return 4;
40-ret = aclrtSetDevice(deviceId);87+ if (dt == ge::DT_FLOAT16)
41-CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);88+ return 2;
42-ret = aclrtCreateStream(stream);89+ if (dt == ge::DT_BF16)
43-CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);90+ return 2;
44-return 0;91+ return 4;
45}92}
46 93 
47-template <typename T>94+int32_t GenOnesDataFloat32(vector<int64_t> shapes, Tensor& input_tensor, TensorDesc& input_tensor_desc, float value)
48-int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr,95+{
49- aclDataType dataType, aclTensor** tensor) {96+ input_tensor_desc.SetRealDimCnt(shapes.size());
50-auto size = GetShapeSize(shape) * sizeof(T);97+ size_t size = 1;
51-// 调用aclrtMalloc申请device侧内存98+ for (uint32_t i = 0; i < shapes.size(); i++) {
52-auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);99+ size *= shapes[i];
53-CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);100+ }
54-// 调用aclrtMemcpy将host侧数据拷贝到device侧内存上101+ uint32_t data_len = size * 4;
55-ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);102+ float* pData = new (std::nothrow) float[size];
56-CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);
57 103 
58-// 计算连续tensor的strides104+ for (size_t i = 0; i < size; ++i) {
59-std::vector<int64_t> strides(shape.size(), 1);105+ pData[i] = value + (i % 3) * 0.4f; // 让数据更有意义
60-for (int64_t i = shape.size() - 2; i >= 0; i--) {106+ }
61- strides[i] = shape[i + 1] * strides[i + 1];107+ input_tensor = Tensor(input_tensor_desc, (uint8_t*)pData, data_len);
108+ return SUCCESS;
62}109}
63 110 
64-// 调用aclCreateTensor接口创建aclTensor111+int32_t WriteDataToFile(string bin_file, uint64_t data_size, uint8_t* inputData)
65-*tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND,112+{
66- shape.data(), shape.size(), *deviceAddr);113+ FILE* fp = fopen(bin_file.c_str(), "wb");
67-return 0;114+ if (fp == nullptr) {
115+ return FAILED;
116+ }
117+ size_t written = fwrite(inputData, 1, data_size, fp);
118+ fclose(fp);
119+ if (written != data_size) {
120+ return FAILED;
121+ }
122+ return SUCCESS;
68}123}
69 124 
70-int main() {125+int CreateOppInGraph(DataType inDtype, std::vector<ge::Tensor> &input, std::vector<Operator> &inputs,
71-// 1. (固定写法)device/stream初始化,参考acl API手册126+ std::vector<Operator> &outputs, Graph &graph)
72-// 根据自己的实际device填写deviceId127+{
73-int32_t deviceId = 0;128+ Status ret = SUCCESS;
74-aclrtStream stream;129+ // 自定义代码:添加单算子定义到图中
75-auto ret = Init(deviceId, &stream);130+ auto stridedslice1 = op::StridedSlice("test_geir_strided_slice");
76-CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);131+ // 输入shape
132+ std::vector<int64_t> xShape = {1, 1, 1, 1};
133+ std::vector<int64_t> beginShape = {0, 0, 0};
134+ std::vector<int64_t> endShape = {1, 1, 1};
135+ std::vector<int64_t> stridesShape = {1, 1, 1};
136+ // 输出shape
137+ std::vector<int64_t> yShape = {1, 1, 1, 1};
77 138 
78-// 2. 构造输入与输出,需要根据API的接口自定义构造139+ ADD_INPUT(1, x, inDtype, xShape);
79-std::vector<int64_t> selfShape = {4, 2};140+ ADD_INPUT(2, begin, inDtype, beginShape);
80-std::vector<int64_t> outShape = {2, 2};141+ ADD_INPUT(3, end, inDtype, endShape);
81-void* selfDeviceAddr = nullptr;142+ ADD_INPUT(4, strides, inDtype, stridesShape);
82-void* outDeviceAddr = nullptr;
83-aclTensor* self = nullptr;
84-aclTensor* out = nullptr;
85-std::vector<float> selfHostData = {0, 1, 2, 3, 4, 5, 6, 7};
86-std::vector<float> outHostData = {0, 0, 0, 0};
87-int64_t dim = 0;
88-int64_t start = 1;
89-int64_t end = 3;
90-int64_t step = 1;
91-// 创建self aclTensor
92-ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self);
93-CHECK_RET(ret == ACL_SUCCESS, return ret);
94-// 创建out aclTensor
95-ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out);
96-CHECK_RET(ret == ACL_SUCCESS, return ret);
97 143 
98-// 3. 调用CANN算子库API,需要修改为具体的Api名称144+ // 添加必选属性
99-uint64_t workspaceSize = 0;145+ ADD_INPUT_ATTR(begin_mask, 13);
100-aclOpExecutor* executor;146+ ADD_INPUT_ATTR(end_mask, 11);
101-// 调用aclnnSlice第一段接口147+ ADD_INPUT_ATTR(ellipsis_mask, 1);
102-ret = aclnnSliceGetWorkspaceSize(self, dim, start, end, step, out, &workspaceSize, &executor);148+ ADD_INPUT_ATTR(new_axis_mask, 9);
103-CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnSliceGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);149+ ADD_INPUT_ATTR(shrink_axis_mask, 0);
104-// 根据第一段接口计算的workspaceSize申请device内存150+ // 添加输
105-void* workspaceAddr = nullptr;151+ ADD_OUTPUT(1, y, inDtype, yShape);
106-if (workspaceSize > 0) {
107- ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
108- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
109-}
110-// 调用aclnnSlice第二段接口
111-ret = aclnnSlice(workspaceAddr, workspaceSize, executor, stream);
112-CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnSlice failed. ERROR: %d\n", ret); return ret);
113 152 
114-// 4. (固定写法)同步等待任务执行结束153+ outputs.push_back(stridedslice1);
115-ret = aclrtSynchronizeStream(stream);154+ // 添加完毕
116-CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);155+ return SUCCESS;
117- 
118-// 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改
119-auto size = GetShapeSize(outShape);
120-std::vector<float> resultData(size, 0);
121-ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr,
122- size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST);
123-CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
124-for (int64_t i = 0; i < size; i++) {
125- LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]);
126}156}
127 157 
128-// 6. 释放aclTensor,需要根据具体API的接口定义修改158+int main(int argc, char *argv[])
129-aclDestroyTensor(self);159+{
130-aclDestroyTensor(out);160+ const char *graph_name = "tc_ge_irrun_test";
161+ Graph graph(graph_name);
162+ std::vector<ge::Tensor> input;
131 163 
132-// 7. 释放device资源,需要根据具体API的接口定义修改164+ printf("%s - INFO - [XIR]: Start to initialize ge using ge global options\n", GetTime().c_str());
133-aclrtFree(selfDeviceAddr);165+ std::map<AscendString, AscendString> global_options = {{"ge.exec.deviceId", "0"}, {"ge.graphRunMode", "1"}};
134-aclrtFree(outDeviceAddr);166+ Status ret = ge::GEInitialize(global_options);
135-if (workspaceSize > 0) {167+ if (ret != SUCCESS) {
136- aclrtFree(workspaceAddr);168+ printf("%s - INFO - [XIR]: Initialize ge using ge global options failed\n", GetTime().c_str());
137-}169+ return FAILED;
138-aclrtDestroyStream(stream);170+ }
139-aclrtResetDevice(deviceId);171+ printf("%s - INFO - [XIR]: Initialize ge using ge global options success\n", GetTime().c_str());
140-aclFinalize();172+ 
141-return 0;173+ std::vector<Operator> inputs{};
174+ std::vector<Operator> outputs{};
175+ 
176+ std::cout << argv[1] << std::endl;
177+ char *endptr;
178+ 
179+ DataType inDtype = DT_INT32;
180+ 
181+ std::cout << inDtype << std::endl;
182+ 
183+ ret = CreateOppInGraph(inDtype, input, inputs, outputs, graph);
184+ if (ret != SUCCESS) {
185+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
186+ return FAILED;
187+ }
188+ 
189+ if (!inputs.empty() && !outputs.empty()) {
190+ graph.SetInputs(inputs).SetOutputs(outputs);
191+ }
192+ 
193+ std::map<AscendString, AscendString> build_options = {
194+ 
195+ };
196+ printf("%s - INFO - [XIR]: Start to create ir session using build options\n", GetTime().c_str());
197+ ge::Session *session = new Session(build_options);
198+ 
199+ if (session == nullptr) {
200+ printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str());
201+ return FAILED;
202+ }
203+ printf("%s - INFO - [XIR]: Create ir session using build options success\n", GetTime().c_str());
204+ printf("%s - INFO - [XIR]: Start to add compute graph to ir session\n", GetTime().c_str());
205+ 
206+ std::map<AscendString, AscendString> graph_options = {
207+ 
208+ };
209+ uint32_t graph_id = 0;
210+ ret = session->AddGraph(graph_id, graph, graph_options);
211+ 
212+ printf("%s - INFO - [XIR]: Session add ir compute graph to ir session success\n", GetTime().c_str());
213+ printf("%s - INFO - [XIR]: dump graph to txt\n", GetTime().c_str());
214+ std::string file_path = "./dump";
215+ aclgrphDumpGraph(graph, file_path.c_str(), file_path.length());
216+ printf("%s - INFO - [XIR]: Start to run ir compute graph\n", GetTime().c_str());
217+ std::vector<ge::Tensor> output;
218+ ret = session->RunGraph(graph_id, input, output);
219+ if (ret != SUCCESS) {
220+ printf("%s - INFO - [XIR]: Run graph failed\n", GetTime().c_str());
221+ delete session;
222+ GEFinalize();
223+ return FAILED;
224+ }
225+ printf("%s - INFO - [XIR]: Session run ir compute graph success\n", GetTime().c_str());
226+ 
227+ int input_num = input.size();
228+ for (int i = 0; i < input_num; i++) {
229+ std::cout << "input " << i << " dtype : " << input[i].GetTensorDesc().GetDataType() << std::endl;
230+ string input_file = "./tc_ge_irrun_test_0008_npu_input_" + std::to_string(i) + ".bin";
231+ uint8_t *input_data_i = input[i].GetData();
232+ int64_t input_shape = input[i].GetTensorDesc().GetShape().GetShapeSize();
233+ std::cout << "this is " << i << "th input, input shape size =" << input_shape << std::endl;
234+ uint32_t data_size = input_shape * GetDataTypeSize(input[i].GetTensorDesc().GetDataType());
235+ WriteDataToFile((const char *)input_file.c_str(), data_size, input_data_i);
236+ }
237+ 
238+ int output_num = output.size();
239+ for (int i = 0; i < output_num; i++) {
240+ std::cout << "output " << i << " dtype : " << output[i].GetTensorDesc().GetDataType() << std::endl;
241+ string output_file = "./tc_ge_irrun_test_0008_npu_output_" + std::to_string(i) + ".bin";
242+ uint8_t *output_data_i = output[i].GetData();
243+ int64_t output_shape = output[i].GetTensorDesc().GetShape().GetShapeSize();
244+ std::cout << "this is " << i << "th output, output shape size =" << output_shape << std::endl;
245+ uint32_t data_size = output_shape * GetDataTypeSize(output[i].GetTensorDesc().GetDataType());
246+ WriteDataToFile((const char *)output_file.c_str(), data_size, output_data_i);
247+ float *resultData = (float*)output_data_i;
248+ for (int64_t j = 0; j < output_shape; j++) {
249+ LOG_PRINT("result[%ld] is: %f\n", j, resultData[j]);
250+ }
251+ }
252+ 
253+ ge::AscendString error_msg = ge::GEGetErrorMsgV2();
254+ std::string error_str(error_msg.GetString());
255+ std::cout << "Error message: " << error_str << std::endl;
256+ ge::AscendString warning_msg = ge::GEGetWarningMsgV2();
257+ std::string warning_str(warning_msg.GetString());
258+ std::cout << "Warning message: " << warning_str << std::endl;
259+ printf("%s - INFO - [XIR]: Start to finalize ir graph session\n", GetTime().c_str());
260+ ret = ge::GEFinalize();
261+ if (ret != SUCCESS) {
262+ printf("%s - INFO - [XIR]: Finalize ir graph session failed\n", GetTime().c_str());
263+ return FAILED;
264+ }
265+ printf("%s - INFO - [XIR]: Finalize ir graph session success\n", GetTime().c_str());
266+ return SUCCESS;
142}267}