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_executor_unittest.cc 12 kB

5 years ago
4 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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 <memory>
  18. #include "common/ge_inner_error_codes.h"
  19. #include "common/types.h"
  20. #include "common/util.h"
  21. #include "runtime/mem.h"
  22. #include "common/util.h"
  23. #include "omg/omg_inner_types.h"
  24. #define private public
  25. #define protected public
  26. #include "executor/ge_executor.h"
  27. #include "common/auth/file_saver.h"
  28. #include "common/debug/log.h"
  29. #include "common/properties_manager.h"
  30. #include "common/types.h"
  31. #include "graph/load/graph_loader.h"
  32. #include "graph/load/model_manager/davinci_model.h"
  33. #include "hybrid/hybrid_davinci_model.h"
  34. #include "graph/load/model_manager/model_manager.h"
  35. #include "graph/load/model_manager/task_info/kernel_task_info.h"
  36. #include "graph/load/model_manager/task_info/kernel_ex_task_info.h"
  37. #include "graph/execute/graph_execute.h"
  38. #include "ge/common/dump/dump_properties.h"
  39. #include "graph/manager/graph_mem_allocator.h"
  40. #include "graph/utils/graph_utils.h"
  41. #include "proto/ge_ir.pb.h"
  42. #undef private
  43. #undef protected
  44. using namespace std;
  45. namespace ge {
  46. class UtestGeExecutor : public testing::Test {
  47. protected:
  48. static void InitModelDefault(ge::Model &model) {
  49. ge::AttrUtils::SetInt(&model, ATTR_MODEL_MEMORY_SIZE, 0);
  50. ge::AttrUtils::SetInt(&model, ATTR_MODEL_WEIGHT_SIZE, 0);
  51. ge::AttrUtils::SetInt(&model, ATTR_MODEL_STREAM_NUM, 0);
  52. ge::AttrUtils::SetInt(&model, ATTR_MODEL_EVENT_NUM, 0);
  53. ge::AttrUtils::SetStr(&model, ATTR_MODEL_TARGET_TYPE, "MINI"); // domi::MINI
  54. auto compute_graph = std::make_shared<ge::ComputeGraph>("graph");
  55. auto graph = ge::GraphUtils::CreateGraphFromComputeGraph(compute_graph);
  56. model.SetGraph(graph);
  57. }
  58. void SetUp() {
  59. unsetenv("FMK_SYSMODE");
  60. unsetenv("FMK_DUMP_PATH");
  61. unsetenv("FMK_USE_FUSION");
  62. unsetenv("DAVINCI_TIMESTAT_ENABLE");
  63. }
  64. };
  65. class DModelListener : public ge::ModelListener {
  66. public:
  67. DModelListener() {
  68. };
  69. Status OnComputeDone(uint32_t model_id, uint32_t data_index, uint32_t resultCode,
  70. std::vector<ge::OutputTensorInfo> &outputs) {
  71. GELOGI("In Call back. OnComputeDone");
  72. return SUCCESS;
  73. }
  74. };
  75. shared_ptr<ge::ModelListener> g_label_call_back(new DModelListener());
  76. static ge::OpDescPtr CreateOpDesc(string name = "", string type = "") {
  77. auto op_desc = std::make_shared<ge::OpDesc>(name, type);
  78. op_desc->SetStreamId(0);
  79. op_desc->SetId(0);
  80. ge::AttrUtils::SetFloat(op_desc, ge::ATTR_NAME_ALPHA, 0);
  81. ge::AttrUtils::SetFloat(op_desc, ge::ATTR_NAME_BETA, 0);
  82. op_desc->SetWorkspace({});
  83. ;
  84. op_desc->SetWorkspaceBytes({});
  85. op_desc->SetInputOffset({});
  86. op_desc->SetOutputOffset({});
  87. ge::AttrUtils::SetListStr(op_desc, ge::ATTR_NAME_WEIGHT_NAME, {});
  88. ge::AttrUtils::SetInt(op_desc, ge::POOLING_ATTR_MODE, 0);
  89. ge::AttrUtils::SetInt(op_desc, ge::POOLING_ATTR_PAD_MODE, 0);
  90. ge::AttrUtils::SetInt(op_desc, ge::POOLING_ATTR_DATA_MODE, 0);
  91. ge::AttrUtils::SetInt(op_desc, ge::POOLING_ATTR_CEIL_MODE, 0);
  92. ge::AttrUtils::SetInt(op_desc, ge::POOLING_ATTR_NAN_OPT, 0);
  93. ge::AttrUtils::SetListInt(op_desc, ge::POOLING_ATTR_WINDOW, {});
  94. ge::AttrUtils::SetListInt(op_desc, ge::POOLING_ATTR_PAD, {});
  95. ge::AttrUtils::SetListInt(op_desc, ge::POOLING_ATTR_STRIDE, {});
  96. ge::AttrUtils::SetListInt(op_desc, ge::ATTR_NAME_ACTIVE_STREAM_LIST, {1, 1});
  97. ge::AttrUtils::SetInt(op_desc, ge::ATTR_NAME_STREAM_SWITCH_COND, 0);
  98. return op_desc;
  99. }
  100. TEST_F(UtestGeExecutor, load_data_from_file) {
  101. GeExecutor ge_executor;
  102. ge_executor.isInit_ = true;
  103. string test_smap = "/tmp/" + std::to_string(getpid()) + "_maps";
  104. string self_smap = "/proc/" + std::to_string(getpid()) + "/maps";
  105. string copy_smap = "cp -f " + self_smap + " " + test_smap;
  106. EXPECT_EQ(system(copy_smap.c_str()), 0);
  107. ModelData model_data;
  108. EXPECT_EQ(ge_executor.LoadDataFromFile(test_smap, model_data), SUCCESS);
  109. EXPECT_NE(model_data.model_data, nullptr);
  110. delete[] static_cast<char *>(model_data.model_data);
  111. model_data.model_data = nullptr;
  112. ge_executor.isInit_ = false;
  113. }
  114. /*
  115. TEST_F(UtestGeExecutor, fail_UnloadModel_model_manager_stop_unload_error) {
  116. uint32_t model_id = 1;
  117. ge::GeExecutor ge_executor;
  118. ge_executor.isInit_ = true;
  119. ge::Status ret = ge_executor.UnloadModel(model_id);
  120. EXPECT_EQ(ge::PARAM_INVALID, ret);
  121. ge_executor.isInit_ = false;
  122. ret = ge_executor.UnloadModel(model_id);
  123. EXPECT_EQ(ge::GE_EXEC_NOT_INIT, ret);
  124. }
  125. TEST_F(UtestGeExecutor, fail_CommandHandle_model_manager_HandleCommand_error) {
  126. ge::Command cmd;
  127. ge::GeExecutor ge_executor;
  128. ge::Status ret = ge_executor.CommandHandle(cmd);
  129. EXPECT_EQ(ge::PARAM_INVALID, ret);
  130. }
  131. */
  132. TEST_F(UtestGeExecutor, InitFeatureMapAndP2PMem_failed) {
  133. DavinciModel model(0, g_label_call_back);
  134. model.is_feature_map_mem_has_inited_ = true;
  135. EXPECT_EQ(model.InitFeatureMapAndP2PMem(nullptr, 0), PARAM_INVALID);
  136. }
  137. TEST_F(UtestGeExecutor, kernel_InitDumpTask) {
  138. DavinciModel model(0, g_label_call_back);
  139. model.om_name_ = "testom";
  140. model.name_ = "test";
  141. OpDescPtr op_desc = CreateOpDesc("test", "test");
  142. std::map<std::string, std::set<std::string>> model_dump_properties_map;
  143. std::set<std::string> s;
  144. model_dump_properties_map[DUMP_ALL_MODEL] = s;
  145. DumpProperties dp;
  146. dp.model_dump_properties_map_ = model_dump_properties_map;
  147. model.SetDumpProperties(dp);
  148. KernelTaskInfo kernel_task_info;
  149. kernel_task_info.davinci_model_ = &model;
  150. kernel_task_info.op_desc_ = op_desc;
  151. kernel_task_info.InitDumpTask(0);
  152. }
  153. TEST_F(UtestGeExecutor, kernel_ex_InitDumpTask) {
  154. DavinciModel model(0, g_label_call_back);
  155. model.om_name_ = "testom";
  156. model.name_ = "test";
  157. OpDescPtr op_desc = CreateOpDesc("test", "test");
  158. std::map<std::string, std::set<std::string>> model_dump_properties_map;
  159. std::set<std::string> s;
  160. model_dump_properties_map[DUMP_ALL_MODEL] = s;
  161. DumpProperties dp;
  162. dp.model_dump_properties_map_ = model_dump_properties_map;
  163. model.SetDumpProperties(dp);
  164. KernelExTaskInfo kernel_ex_task_info;
  165. kernel_ex_task_info.davinci_model_ = &model;
  166. kernel_ex_task_info.InitDumpTask(nullptr, op_desc);
  167. }
  168. TEST_F(UtestGeExecutor, execute_graph_with_stream) {
  169. DavinciModel model(0, nullptr);
  170. ComputeGraphPtr graph = make_shared<ComputeGraph>("default");
  171. GeModelPtr ge_model = make_shared<GeModel>();
  172. ge_model->SetGraph(GraphUtils::CreateGraphFromComputeGraph(graph));
  173. AttrUtils::SetInt(ge_model, ATTR_MODEL_MEMORY_SIZE, 10240);
  174. AttrUtils::SetInt(ge_model, ATTR_MODEL_STREAM_NUM, 1);
  175. shared_ptr<domi::ModelTaskDef> model_task_def = make_shared<domi::ModelTaskDef>();
  176. ge_model->SetModelTaskDef(model_task_def);
  177. GeTensorDesc tensor(GeShape(), FORMAT_NCHW, DT_FLOAT);
  178. TensorUtils::SetSize(tensor, 512);
  179. {
  180. OpDescPtr op_desc = CreateOpDesc("data", DATA);
  181. op_desc->AddInputDesc(tensor);
  182. op_desc->AddOutputDesc(tensor);
  183. op_desc->SetInputOffset({1024});
  184. op_desc->SetOutputOffset({1024});
  185. NodePtr node = graph->AddNode(op_desc); // op_index = 0
  186. }
  187. {
  188. OpDescPtr op_desc = CreateOpDesc("square", "Square");
  189. op_desc->AddInputDesc(tensor);
  190. op_desc->AddOutputDesc(tensor);
  191. op_desc->SetInputOffset({1024});
  192. op_desc->SetOutputOffset({1024});
  193. NodePtr node = graph->AddNode(op_desc); // op_index = 1
  194. domi::TaskDef *task_def = model_task_def->add_task();
  195. task_def->set_stream_id(0);
  196. task_def->set_type(RT_MODEL_TASK_KERNEL);
  197. domi::KernelDef *kernel_def = task_def->mutable_kernel();
  198. kernel_def->set_stub_func("stub_func");
  199. kernel_def->set_args_size(64);
  200. string args(64, '1');
  201. kernel_def->set_args(args.data(), 64);
  202. domi::KernelContext *context = kernel_def->mutable_context();
  203. context->set_op_index(op_desc->GetId());
  204. context->set_kernel_type(2); // ccKernelType::TE
  205. uint16_t args_offset[9] = {0};
  206. context->set_args_offset(args_offset, 9 * sizeof(uint16_t));
  207. }
  208. {
  209. OpDescPtr op_desc = CreateOpDesc("memcpy", MEMCPYASYNC);
  210. op_desc->AddInputDesc(tensor);
  211. op_desc->AddOutputDesc(tensor);
  212. op_desc->SetInputOffset({1024});
  213. op_desc->SetOutputOffset({5120});
  214. NodePtr node = graph->AddNode(op_desc); // op_index = 2
  215. domi::TaskDef *task_def = model_task_def->add_task();
  216. task_def->set_stream_id(0);
  217. task_def->set_type(RT_MODEL_TASK_MEMCPY_ASYNC);
  218. domi::MemcpyAsyncDef *memcpy_async = task_def->mutable_memcpy_async();
  219. memcpy_async->set_src(1024);
  220. memcpy_async->set_dst(5120);
  221. memcpy_async->set_dst_max(512);
  222. memcpy_async->set_count(1);
  223. memcpy_async->set_kind(RT_MEMCPY_DEVICE_TO_DEVICE);
  224. memcpy_async->set_op_index(op_desc->GetId());
  225. }
  226. {
  227. OpDescPtr op_desc = CreateOpDesc("output", NETOUTPUT);
  228. op_desc->AddInputDesc(tensor);
  229. op_desc->SetInputOffset({5120});
  230. op_desc->SetSrcName( { "memcpy" } );
  231. op_desc->SetSrcIndex( { 0 } );
  232. NodePtr node = graph->AddNode(op_desc); // op_index = 3
  233. }
  234. EXPECT_EQ(model.Assign(ge_model), SUCCESS);
  235. EXPECT_EQ(model.Init(), SUCCESS);
  236. EXPECT_EQ(model.input_addrs_list_.size(), 1);
  237. EXPECT_EQ(model.output_addrs_list_.size(), 1);
  238. EXPECT_EQ(model.task_list_.size(), 2);
  239. OutputData output_data;
  240. vector<OutputTensorInfo> outputs;
  241. EXPECT_EQ(model.GenOutputTensorInfo(&output_data, outputs), SUCCESS);
  242. GraphExecutor graph_executer;
  243. graph_executer.init_flag_ = true;
  244. GeRootModelPtr ge_root_model = make_shared<GeRootModel>(graph);
  245. std::vector<GeTensor> input_tensor;
  246. std::vector<GeTensor> output_tensor;
  247. std::vector<InputOutputDescInfo> output_desc;
  248. InputOutputDescInfo desc0;
  249. output_desc.push_back(desc0);
  250. graph_executer.ExecuteGraphWithStream(0, nullptr, ge_root_model, input_tensor, output_tensor);
  251. }
  252. TEST_F(UtestGeExecutor, get_op_attr) {
  253. shared_ptr<DavinciModel> model = MakeShared<DavinciModel>(1, g_label_call_back);
  254. model->SetId(1);
  255. model->om_name_ = "testom";
  256. model->name_ = "test";
  257. shared_ptr<hybrid::HybridDavinciModel> hybrid_model = MakeShared<hybrid::HybridDavinciModel>();
  258. model->SetId(2);
  259. model->om_name_ = "testom_hybrid";
  260. model->name_ = "test_hybrid";
  261. std::shared_ptr<ModelManager> model_manager = ModelManager::GetInstance();
  262. model_manager->InsertModel(1, model);
  263. model_manager->InsertModel(2, hybrid_model);
  264. OpDescPtr op_desc = CreateOpDesc("test", "test");
  265. std::vector<std::string> value{"test"};
  266. ge::AttrUtils::SetListStr(op_desc, ge::ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, value);
  267. model->SaveSpecifyAttrValues(op_desc);
  268. GeExecutor ge_executor;
  269. GeExecutor::isInit_ = true;
  270. std::string attr_value;
  271. auto ret = ge_executor.GetOpAttr(1, "test", ge::ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, attr_value);
  272. EXPECT_EQ(ret, SUCCESS);
  273. EXPECT_EQ(attr_value, "[4]test");
  274. ret = ge_executor.GetOpAttr(2, "test", ge::ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, attr_value);
  275. EXPECT_EQ(ret, PARAM_INVALID);
  276. ret = ge_executor.GetOpAttr(3, "test", ge::ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, attr_value);
  277. EXPECT_EQ(ret, ACL_ERROR_GE_EXEC_MODEL_ID_INVALID);
  278. }
  279. }

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