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.

graph_optimize_unittest.cc 9.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /**
  2. * Copyright 2021 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 <memory>
  18. #include <iostream>
  19. #define protected public
  20. #define private public
  21. #include "graph/optimize/graph_optimize.h"
  22. #include "init/gelib.h"
  23. #include "ge/ge_api.h"
  24. #undef private
  25. #undef protected
  26. using namespace std;
  27. using namespace testing;
  28. using namespace ge;
  29. namespace {
  30. const char *const kVectorCore = "VectorCore";
  31. const char *const kAicoreEngine = "AIcoreEngine";
  32. string CreateEngineConfigJson() {
  33. GELOGI("Begin to create engine config json file.");
  34. string base_path = PluginManager::GetPath();
  35. GELOGI("Base path is %s.", base_path.c_str());
  36. string dir_path = base_path.substr(0, base_path.rfind('/') + 1) + "plugin/nnengine/ge_config";
  37. string cmd = "mkdir -p " + dir_path;
  38. system(cmd.c_str());
  39. string file_path = dir_path + "/engine_conf.json";
  40. GELOGI("Begin to write into the config file: %s.", file_path.c_str());
  41. ofstream ofs(file_path, ios::out);
  42. EXPECT_EQ(!ofs, false);
  43. ofs << "{\n"
  44. " \"schedule_units\" : [ {\n"
  45. " \"id\" : \"TS_1\",\n"
  46. " \"name\" : \"1980_hwts\",\n"
  47. " \"ex_attrs\" : \"\",\n"
  48. " \"cal_engines\" : [\n"
  49. " {\"id\" : \"DNN_VM_GE_LOCAL\", \"name\" : \"GE_LOCAL\", \"independent\" : false, \"attch\" : true, \"skip_assign_stream\" : true },\n"
  50. " {\"id\" : \"AIcoreEngine\", \"name\" : \"AICORE\", \"independent\" : false, \"attch\" : false, \"skip_assign_stream\" : false}\n"
  51. " ]\n"
  52. " } ]\n"
  53. "}";
  54. ofs.close();
  55. GELOGI("Json config file %s has been written.", file_path.c_str());
  56. return file_path;
  57. }
  58. void DeleteFile(const string &file_name) {
  59. auto ret = remove(file_name.c_str());
  60. if (ret == 0) {
  61. GELOGI("Delete file successfully, file:%s.", file_name.c_str());
  62. }
  63. }
  64. }
  65. class UtestGraphOptimizeTest : public testing::Test {
  66. protected:
  67. void SetUp() {
  68. config_file_ = CreateEngineConfigJson();
  69. }
  70. void TearDown() {
  71. DeleteFile(config_file_);
  72. }
  73. private:
  74. string config_file_;
  75. };
  76. class TestGraphOptimizerSuccess : public GraphOptimizer {
  77. public:
  78. ~TestGraphOptimizerSuccess() override { Finalize(); }
  79. Status Initialize(const map<string, string> &options) override { return SUCCESS; }
  80. Status Finalize() override { return SUCCESS; }
  81. Status OptimizeGraphPrepare(ComputeGraph& graph) override { return SUCCESS; }
  82. Status OptimizeGraphBeforeBuild(ComputeGraph& graph) override { return SUCCESS; }
  83. Status OptimizeOriginalGraph(ComputeGraph &graph) override { return SUCCESS; }
  84. Status OptimizeOriginalGraphJudgeInsert(ComputeGraph &graph) override { return SUCCESS; }
  85. Status OptimizeFusedGraph(ComputeGraph &graph) override { return SUCCESS; }
  86. Status OptimizeWholeGraph(ComputeGraph &graph) override { return SUCCESS; }
  87. Status GetAttributes(GraphOptimizerAttribute &attrs) const override {
  88. attrs.engineName = "AIcoreEngine";
  89. attrs.scope = OPTIMIZER_SCOPE::ENGINE;
  90. return SUCCESS;
  91. }
  92. Status OptimizeStreamGraph(ComputeGraph &graph, const RunContext &context) override { return SUCCESS; }
  93. Status OptimizeFusedGraphAfterGraphSlice(ComputeGraph &graph) override { return SUCCESS; }
  94. Status OptimizeAfterStage1(ComputeGraph &graph) override { return SUCCESS; }
  95. };
  96. class TestGraphOptimizerFail : public GraphOptimizer {
  97. public:
  98. ~TestGraphOptimizerFail() override { Finalize(); }
  99. Status Initialize(const map<string, string> &options) override { return SUCCESS; }
  100. Status Finalize() override { return SUCCESS; }
  101. Status OptimizeGraphPrepare(ComputeGraph& graph) override { return FAILED; }
  102. Status OptimizeGraphBeforeBuild(ComputeGraph& graph) override { return FAILED; }
  103. Status OptimizeOriginalGraph(ComputeGraph &graph) override { return FAILED; }
  104. Status OptimizeOriginalGraphJudgeInsert(ComputeGraph &graph) override { return FAILED; }
  105. Status OptimizeFusedGraph(ComputeGraph &graph) override { return FAILED; }
  106. Status OptimizeWholeGraph(ComputeGraph &graph) override { return FAILED; }
  107. Status GetAttributes(GraphOptimizerAttribute &attrs) const override {
  108. attrs.engineName = "AIcoreEngine";
  109. attrs.scope = OPTIMIZER_SCOPE::ENGINE;
  110. return SUCCESS;
  111. }
  112. Status OptimizeStreamGraph(ComputeGraph &graph, const RunContext &context) override { return FAILED; }
  113. Status OptimizeFusedGraphAfterGraphSlice(ComputeGraph &graph) override { return FAILED; }
  114. Status OptimizeAfterStage1(ComputeGraph &graph) override { return FAILED; }
  115. };
  116. TEST_F(UtestGraphOptimizeTest, test_OptimizeAfterStage1_succ) {
  117. map<string, string> options;
  118. Status ret = ge::GELib::Initialize(options);
  119. EXPECT_EQ(ret, SUCCESS);
  120. shared_ptr<GELib> instance_ptr = ge::GELib::GetInstance();
  121. EXPECT_NE(instance_ptr, nullptr);
  122. GraphOptimizerPtr graph_opt = MakeShared<TestGraphOptimizerSuccess>();
  123. instance_ptr->opsManager_.graph_optimizers_by_priority_.push_back(make_pair("AIcoreEngine", graph_opt));
  124. ComputeGraphPtr compute_graph = MakeShared<ComputeGraph>("test_graph");
  125. GraphOptimize base_optimize;
  126. ret = base_optimize.OptimizeAfterStage1(compute_graph);
  127. EXPECT_EQ(ret, SUCCESS);
  128. base_optimize.core_type_ = kVectorCore;
  129. ret = base_optimize.OptimizeAfterStage1(compute_graph);
  130. EXPECT_EQ(ret, SUCCESS);
  131. ret = instance_ptr->Finalize();
  132. EXPECT_EQ(ret, SUCCESS);
  133. }
  134. TEST_F(UtestGraphOptimizeTest, test_OptimizeAfterStage1_fail) {
  135. ComputeGraphPtr compute_graph = nullptr;
  136. GraphOptimize base_optimize;
  137. // 1. Input graph is nullptr.
  138. Status ret = base_optimize.OptimizeAfterStage1(compute_graph);
  139. EXPECT_EQ(ret, PARAM_INVALID);
  140. // 2. GELib is not initialized.
  141. compute_graph = MakeShared<ComputeGraph>("test_graph");
  142. ret = base_optimize.OptimizeAfterStage1(compute_graph);
  143. EXPECT_EQ(ret, GE_CLI_GE_NOT_INITIALIZED);
  144. // 3. The optimizer registered with the engine returned a failure.
  145. map<string, string> options;
  146. ret = ge::GELib::Initialize(options);
  147. EXPECT_EQ(ret, SUCCESS);
  148. shared_ptr<GELib> instance_ptr = ge::GELib::GetInstance();
  149. EXPECT_NE(instance_ptr, nullptr);
  150. GraphOptimizerPtr graph_opt = MakeShared<TestGraphOptimizerFail>();
  151. instance_ptr->opsManager_.graph_optimizers_by_priority_.push_back(make_pair("AIcoreEngine", graph_opt));
  152. ret = base_optimize.OptimizeAfterStage1(compute_graph);
  153. EXPECT_EQ(ret, FAILED);
  154. ret = instance_ptr->Finalize();
  155. EXPECT_EQ(ret, SUCCESS);
  156. }
  157. TEST_F(UtestGraphOptimizeTest, test_optimizers_succ) {
  158. map<string, string> options;
  159. Status ret = ge::GELib::Initialize(options);
  160. EXPECT_EQ(ret, SUCCESS);
  161. shared_ptr<GELib> instance_ptr = ge::GELib::GetInstance();
  162. EXPECT_NE(instance_ptr, nullptr);
  163. GraphOptimizerPtr graph_opt = MakeShared<TestGraphOptimizerSuccess>();
  164. instance_ptr->opsManager_.graph_optimizers_by_priority_.push_back(make_pair("AIcoreEngine", graph_opt));
  165. ComputeGraphPtr compute_graph = MakeShared<ComputeGraph>("test_graph");
  166. GraphOptimize base_optimize;
  167. ret = base_optimize.OptimizeOriginalGraph(compute_graph);
  168. EXPECT_EQ(ret, SUCCESS);
  169. ret = base_optimize.OptimizeOriginalGraphJudgeInsert(compute_graph);
  170. EXPECT_EQ(ret, SUCCESS);
  171. ret = base_optimize.OptimizeOriginalGraphForQuantize(compute_graph);
  172. EXPECT_EQ(ret, SUCCESS);
  173. ret = base_optimize.OptimizeGraphBeforeBuildForRts(compute_graph);
  174. EXPECT_EQ(ret, SUCCESS);
  175. ret = base_optimize.OptimizeWholeGraph(compute_graph);
  176. EXPECT_EQ(ret, SUCCESS);
  177. ret = instance_ptr->Finalize();
  178. EXPECT_EQ(ret, SUCCESS);
  179. }
  180. TEST_F(UtestGraphOptimizeTest, test_optimizers_fail) {
  181. map<string, string> options;
  182. Status ret = ge::GELib::Initialize(options);
  183. EXPECT_EQ(ret, SUCCESS);
  184. shared_ptr<GELib> instance_ptr = ge::GELib::GetInstance();
  185. EXPECT_NE(instance_ptr, nullptr);
  186. GraphOptimizerPtr graph_opt = MakeShared<TestGraphOptimizerFail>();
  187. instance_ptr->opsManager_.graph_optimizers_by_priority_.push_back(make_pair("AIcoreEngine", graph_opt));
  188. ComputeGraphPtr compute_graph = MakeShared<ComputeGraph>("test_graph");
  189. GraphOptimize base_optimize;
  190. ret = base_optimize.OptimizeOriginalGraph(compute_graph);
  191. EXPECT_EQ(ret, FAILED);
  192. ret = base_optimize.OptimizeOriginalGraphJudgeInsert(compute_graph);
  193. EXPECT_EQ(ret, FAILED);
  194. ret = base_optimize.OptimizeOriginalGraphForQuantize(compute_graph);
  195. EXPECT_EQ(ret, FAILED);
  196. ret = base_optimize.OptimizeGraphBeforeBuildForRts(compute_graph);
  197. EXPECT_EQ(ret, FAILED);
  198. ret = base_optimize.OptimizeWholeGraph(compute_graph);
  199. EXPECT_EQ(ret, FAILED);
  200. ret = instance_ptr->Finalize();
  201. EXPECT_EQ(ret, SUCCESS);
  202. }

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