You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ge_ir_build_unittest.cc 12 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /**
  2. * Copyright 2019-2020 Huawei Technologies Co., Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <gtest/gtest.h>
  17. #include "ir_build/option_utils.h"
  18. #include "graph/testcase/ge_graph/graph_builder_utils.h"
  19. #include "graph/debug/ge_attr_define.h"
  20. #include "graph/utils/graph_utils.h"
  21. #include "ge/ge_ir_build.h"
  22. #include "graph/ops_stub.h"
  23. #define protected public
  24. #define private public
  25. #undef private
  26. #undef protected
  27. const string DATA = "Data";
  28. const string AddNYes = "AddNYes";
  29. const string NETOUTPUT = "NetOutput";
  30. using namespace ge;
  31. class UtestIrCommon : public testing::Test {
  32. protected:
  33. void SetUp() {}
  34. void TearDown() {}
  35. };
  36. class UtestIrBuild : public testing::Test {
  37. protected:
  38. void SetUp() {}
  39. void TearDown() {}
  40. };
  41. static ge::OpDescPtr CreateOpDesc(const std::string &name, const std::string &type) {
  42. OpDescPtr op_desc = std::make_shared<ge::OpDesc>(name, type);
  43. ge::GeTensorDesc ge_tensor_desc;
  44. op_desc->AddInputDesc("input", ge_tensor_desc);
  45. op_desc->AddOutputDesc("output", ge_tensor_desc);
  46. return op_desc;
  47. }
  48. static ComputeGraphPtr BuildComputeGraph() {
  49. auto builder = ut::GraphBuilder("test");
  50. auto data1 = builder.AddNode("input1", DATA, 1, 1, FORMAT_NCHW, DT_FLOAT, {1, 2, 3});
  51. auto data2 = builder.AddNode("input2", DATA, 1, 1, FORMAT_NCHW, DT_FLOAT, {4, 10});
  52. auto addn1 = builder.AddNode("addn1", AddNYes, 2, 1);
  53. auto netoutput = builder.AddNode("netoutput", NETOUTPUT, 1, 0);
  54. builder.AddDataEdge(data1, 0, addn1, 0);
  55. builder.AddDataEdge(data2, 0, addn1, 1);
  56. builder.AddDataEdge(addn1, 0,netoutput, 0);
  57. return builder.GetGraph();
  58. }
  59. // data not set attr index;
  60. // but becasue of op proto, register attr index. so all data index is zero;
  61. static Graph BuildIrGraph() {
  62. auto data1 = op::Data("data1");
  63. auto data2 = op::Data("data2");
  64. auto data3 = op::Data("data3");
  65. std::vector<Operator> inputs {data1, data2, data3};
  66. std::vector<Operator> outputs;
  67. Graph graph("test_graph");
  68. graph.SetInputs(inputs).SetOutputs(outputs);
  69. return graph;
  70. }
  71. // data set attr index, but is not valid
  72. static Graph BuildIrGraph1() {
  73. auto data1 = op::Data("data1").set_attr_index(0);
  74. auto data2 = op::Data("data2").set_attr_index(1);
  75. auto data3 = op::Data("data3");
  76. std::vector<Operator> inputs {data1, data2, data3};
  77. std::vector<Operator> outputs;
  78. Graph graph("test_graph");
  79. graph.SetInputs(inputs).SetOutputs(outputs);
  80. return graph;
  81. }
  82. // data set attr index, but is not valid
  83. static Graph BuildIrGraph2() {
  84. auto data1 = op::Data("data1").set_attr_index(0);
  85. auto data2 = op::Data("data2");
  86. auto data3 = op::Data("data3").set_attr_index(2);
  87. std::vector<Operator> inputs {data1, data2, data3};
  88. std::vector<Operator> outputs;
  89. Graph graph("test_graph");
  90. graph.SetInputs(inputs).SetOutputs(outputs);
  91. return graph;
  92. }
  93. // data set attr index
  94. static Graph BuildIrGraph3() {
  95. auto data1 = op::Data("data1").set_attr_index(0);
  96. auto data2 = op::Data("data2").set_attr_index(1);
  97. auto data3 = op::Data("data3").set_attr_index(2);
  98. std::vector<Operator> inputs {data1, data2, data3};
  99. std::vector<Operator> outputs;
  100. Graph graph("test_graph");
  101. graph.SetInputs(inputs).SetOutputs(outputs);
  102. return graph;
  103. }
  104. TEST(UtestIrCommon, update_data_op_shape) {
  105. ge::OpDescPtr op_desc = CreateOpDesc("Data", "Data");
  106. map<string, vector<int64_t>> shape_map;
  107. shape_map["Data"] = {{1,2}};
  108. Status ret = UpdateDataOpShape(op_desc, shape_map);
  109. EXPECT_EQ(ret, ge::SUCCESS);
  110. }
  111. TEST(UtestIrCommon, update_data_op_shape_range) {
  112. ge::OpDescPtr op_desc = CreateOpDesc("Data", "Data");
  113. std::vector<std::vector<std::pair<int64_t, int64_t>>> index_shape_range_map;
  114. std::pair<int64_t, int64_t> range_pair(1, 2);
  115. vector<pair<int64_t, int64_t>> range_pair_tmp = { range_pair };
  116. index_shape_range_map.push_back(range_pair_tmp);
  117. AttrUtils::SetInt(op_desc, ATTR_NAME_INDEX, 0);
  118. Status ret = UpdateDataOpShapeRange(op_desc, index_shape_range_map);
  119. EXPECT_EQ(ret, ge::SUCCESS);
  120. }
  121. TEST(UtestIrCommon, update_dynamic_shape_range_success) {
  122. ComputeGraphPtr graph = BuildComputeGraph();
  123. std::string input_shape_range = "input1:[1, 2~3, -1];input2:[3~5, 10]";
  124. Status ret = UpdateDynamicInputShapeRange(graph, input_shape_range);
  125. EXPECT_EQ(ret, ge::SUCCESS);
  126. }
  127. TEST(UtestIrCommon, update_dynamic_shape_range_failed) {
  128. ComputeGraphPtr graph = BuildComputeGraph();
  129. // 1
  130. std::string input_shape_range = "input1;[1, 2~3, -1]";
  131. Status ret = UpdateDynamicInputShapeRange(graph, input_shape_range);
  132. EXPECT_EQ(ret, ge::PARAM_INVALID);
  133. // 2
  134. input_shape_range = "input1:[1, 2~3, -1)";
  135. ret = UpdateDynamicInputShapeRange(graph, input_shape_range);
  136. EXPECT_EQ(ret, ge::PARAM_INVALID);
  137. //3
  138. input_shape_range = "input1:[1, 3~2, -1];input2:[3~5, 10]";
  139. ret = UpdateDynamicInputShapeRange(graph, input_shape_range);
  140. EXPECT_EQ(ret, ge::FAILED);
  141. //4
  142. input_shape_range = "input1:[1, 2~-3, -1]";
  143. ret = UpdateDynamicInputShapeRange(graph, input_shape_range);
  144. EXPECT_EQ(ret, ge::PARAM_INVALID);
  145. //5
  146. input_shape_range = "input:[1, 2~3, -1]";
  147. ret = UpdateDynamicInputShapeRange(graph, input_shape_range);
  148. EXPECT_EQ(ret, ge::PARAM_INVALID);
  149. //6
  150. input_shape_range = "addn1:[1, 2~3, -1]";
  151. ret = UpdateDynamicInputShapeRange(graph, input_shape_range);
  152. EXPECT_EQ(ret, ge::PARAM_INVALID);
  153. }
  154. TEST(UtestIrCommon, check_dynamic_image_size_fail) {
  155. map<string, vector<int64_t>> shape_map;
  156. shape_map["input1"] = {8, 3, -1, -1};
  157. string input_format = "NCHW";
  158. string dynamic_image_size = "@64,64;128,128;";
  159. bool ret = CheckDynamicImagesizeInputShapeValid(shape_map, input_format, dynamic_image_size);
  160. EXPECT_EQ(ret, false);
  161. }
  162. TEST(UtestIrCommon, check_input_format_failed) {
  163. std::string format = "invalid";
  164. Status ret = CheckInputFormat(format);
  165. EXPECT_EQ(ret, ge::PARAM_INVALID);
  166. }
  167. TEST(UtestIrCommon, check_dynamic_batch_size_input_shape_succ) {
  168. map<string, vector<int64_t>> shape_map;
  169. shape_map.insert(std::pair<string, vector<int64_t>>("data", {-1, 2, 3}));
  170. std::string dynamic_batch_size = "11";
  171. bool ret = CheckDynamicBatchSizeInputShapeValid(shape_map, dynamic_batch_size);
  172. EXPECT_EQ(ret, true);
  173. }
  174. TEST(UtestIrCommon, check_dynamic_images_size_input_shape_succ) {
  175. map<string, vector<int64_t>> shape_map;
  176. shape_map.insert(std::pair<string, vector<int64_t>>("data", {4, -1, -1, 5}));
  177. std::string input_format = "NCHW";
  178. std::string dynamic_image_size = "4,5";
  179. Status ret = CheckDynamicImagesizeInputShapeValid(shape_map, input_format, dynamic_image_size);
  180. EXPECT_EQ(ret, ge::SUCCESS);
  181. }
  182. TEST(UtestIrCommon, check_dynamic_input_param_succ) {
  183. string dynamic_batch_size = "1";
  184. string dynamic_image_size;
  185. string dynamic_dims;
  186. string input_shape = "data:-1,3,244,244";
  187. string input_shape_range;
  188. string input_format = "NCHW";
  189. bool is_dynamic_input = false;
  190. Status ret = CheckDynamicInputParamValid(dynamic_batch_size, dynamic_image_size, dynamic_dims,
  191. input_shape, input_shape_range, input_format,is_dynamic_input);
  192. EXPECT_EQ(ret, ge::SUCCESS);
  193. }
  194. TEST(UtestIrCommon, check_dynamic_input_param_failed) {
  195. string dynamic_batch_size = "1";
  196. string dynamic_image_size;
  197. string dynamic_dims;
  198. string input_shape = "data:1,3,244,244";
  199. string input_shape_range;
  200. string input_format = "NCHW";
  201. bool is_dynamic_input = false;
  202. Status ret = CheckDynamicInputParamValid(dynamic_batch_size, dynamic_image_size, dynamic_dims,
  203. input_shape, input_shape_range, input_format,is_dynamic_input);
  204. EXPECT_EQ(ret, ge::PARAM_INVALID);
  205. }
  206. TEST(UtestIrCommon, check_compress_weight) {
  207. std::string enable_compress_weight = "true";
  208. std::string compress_weight_conf="./";
  209. Status ret = CheckCompressWeightParamValid(enable_compress_weight, compress_weight_conf);
  210. EXPECT_EQ(ret, PARAM_INVALID);
  211. enable_compress_weight = "yes";
  212. compress_weight_conf = "./";
  213. ret = CheckCompressWeightParamValid(enable_compress_weight, compress_weight_conf);
  214. EXPECT_EQ(ret, PARAM_INVALID);
  215. }
  216. TEST(UtestIrCommon, check_param_failed) {
  217. std::string param_invalid = "invalid";
  218. Status ret = CheckOutputTypeParamValid(param_invalid);
  219. EXPECT_EQ(ret, PARAM_INVALID);
  220. ret = CheckBufferOptimizeParamValid(param_invalid);
  221. EXPECT_EQ(ret, PARAM_INVALID);
  222. ret = CheckKeepTypeParamValid(param_invalid);
  223. EXPECT_EQ(ret, PARAM_INVALID);
  224. ret = CheckInsertOpConfParamValid(param_invalid);
  225. EXPECT_EQ(ret, PARAM_INVALID);
  226. ret = CheckDisableReuseMemoryParamValid(param_invalid);
  227. EXPECT_EQ(ret, PARAM_INVALID);
  228. ret = CheckEnableSingleStreamParamValid(param_invalid);
  229. EXPECT_EQ(ret, PARAM_INVALID);
  230. std::string optypelist_for_implmode;
  231. std::string op_select_implmode = "1";
  232. ret = CheckImplmodeParamValid(optypelist_for_implmode, op_select_implmode);
  233. EXPECT_EQ(ret, PARAM_INVALID);
  234. ret = CheckLogParamValidAndSetLogLevel(param_invalid);
  235. }
  236. // Get attr index failed, when set input shape range
  237. TEST(UtestIrBuild, check_data_op_attr_index_invalid_0) {
  238. ComputeGraphPtr compute_graph = BuildComputeGraph();
  239. Graph graph = GraphUtils::CreateGraphFromComputeGraph(compute_graph);
  240. const map<string, string> build_options = {
  241. {"input_shape_range", "[1, 2~3, -1],[4~5, 3~5, 10],[1, 2~3, -1]"}
  242. };
  243. ModelBufferData model;
  244. graphStatus ret = aclgrphBuildModel(graph, build_options, model);
  245. EXPECT_EQ(ret, GRAPH_FAILED);
  246. }
  247. // not set attr index, when set input shape range
  248. TEST(UtestIrBuild, check_data_op_attr_index_invalid_1) {
  249. Graph graph = BuildIrGraph();
  250. const map<string, string> build_options = {
  251. {"input_shape_range", "[1, 2~3, -1],[4~5, 3~5, 10],[1, 2~3, -1]"}
  252. };
  253. ModelBufferData model;
  254. graphStatus ret = aclgrphBuildModel(graph, build_options, model);
  255. EXPECT_EQ(ret, GRAPH_FAILED);
  256. }
  257. // set attr index, but not valid, when set input shape range
  258. TEST(UtestIrBuild, check_data_op_attr_index_invalid_2) {
  259. Graph graph = BuildIrGraph1();
  260. const map<string, string> build_options = {
  261. {"input_shape_range", "[1, 2~3, -1],[4~5, 3~5, 10],[1, 2~3, -1]"}
  262. };
  263. ModelBufferData model;
  264. graphStatus ret = aclgrphBuildModel(graph, build_options, model);
  265. EXPECT_EQ(ret, GRAPH_FAILED);
  266. Graph graph2 = BuildIrGraph2();
  267. ret = aclgrphBuildModel(graph2, build_options, model);
  268. EXPECT_EQ(ret, GRAPH_FAILED);
  269. }
  270. // set attr index valid, when set input shape range
  271. // only check data op attr index valid func.
  272. TEST(UtestIrBuild, check_data_op_attr_index_valid) {
  273. Graph graph = BuildIrGraph3();
  274. const map<string, string> build_options = {
  275. {"input_shape_range", "[1, 2~3, -1],[4~5, 3~5, 10],[1, 2~3, -1]"}
  276. };
  277. ModelBufferData model;
  278. graphStatus ret = aclgrphBuildModel(graph, build_options, model);
  279. EXPECT_EQ(ret, GE_GENERATOR_GRAPH_MANAGER_BUILD_GRAPH_FAILED);
  280. }
  281. // set attr index invalid, when not set input shape range
  282. // only check data op attr index valid func.
  283. TEST(UtestIrBuild, check_data_attr_index_succ_no_input_range) {
  284. Graph graph = BuildIrGraph1();
  285. const map<string, string> build_options;
  286. ModelBufferData model;
  287. graphStatus ret = aclgrphBuildModel(graph, build_options, model);
  288. EXPECT_EQ(ret, GE_GENERATOR_GRAPH_MANAGER_BUILD_GRAPH_FAILED);
  289. }

图引擎模块(GE)是MindSpore的一个子模块,其代码由C++实现,位于前端模块ME和底层硬件之间,起到承接作用。图引擎模块以ME下发的图作为输入,然后进行一系列的深度图优化操作,最后输出一张可以在底层硬件上高效运行的图。GE针对昇腾AI处理器的硬件结构特点,做了特定的优化工作,以此来充分发挥出昇腾AI处理器的强大算力。在进行模型训练/推理时,GE会被自动调用而用户并不感知。GE主要由GE API和GE Core两部分组成,详细的架构图如下所示