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

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