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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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, test_single_op_exec) {
  102. GeExecutor exeutor;
  103. ModelData model_data;
  104. string model_name = "1234";
  105. EXPECT_EQ(exeutor.LoadSingleOp(model_name, model_data, nullptr, nullptr), ACL_ERROR_GE_INTERNAL_ERROR);
  106. EXPECT_EQ(exeutor.LoadDynamicSingleOp(model_name, model_data, nullptr, nullptr), PARAM_INVALID);
  107. }
  108. TEST_F(UtestGeExecutor, test_ge_initialize) {
  109. GeExecutor executor;
  110. EXPECT_EQ(executor.Initialize(), SUCCESS);
  111. EXPECT_EQ(executor.Initialize(), SUCCESS);
  112. }
  113. TEST_F(UtestGeExecutor, load_data_from_file) {
  114. GeExecutor ge_executor;
  115. ge_executor.isInit_ = true;
  116. string test_smap = "/tmp/" + std::to_string(getpid()) + "_maps";
  117. string self_smap = "/proc/" + std::to_string(getpid()) + "/maps";
  118. string copy_smap = "cp -f " + self_smap + " " + test_smap;
  119. EXPECT_EQ(system(copy_smap.c_str()), 0);
  120. ModelData model_data;
  121. EXPECT_EQ(ge_executor.LoadDataFromFile(test_smap, model_data), SUCCESS);
  122. EXPECT_NE(model_data.model_data, nullptr);
  123. delete[] static_cast<char *>(model_data.model_data);
  124. model_data.model_data = nullptr;
  125. ge_executor.isInit_ = false;
  126. }
  127. TEST_F(UtestGeExecutor, InitFeatureMapAndP2PMem_failed) {
  128. DavinciModel model(0, g_label_call_back);
  129. model.is_feature_map_mem_has_inited_ = true;
  130. EXPECT_EQ(model.InitFeatureMapAndP2PMem(nullptr, 0), PARAM_INVALID);
  131. }
  132. TEST_F(UtestGeExecutor, kernel_InitDumpArgs) {
  133. DavinciModel model(0, g_label_call_back);
  134. model.om_name_ = "testom";
  135. model.name_ = "test";
  136. OpDescPtr op_desc = CreateOpDesc("test", "test");
  137. std::map<std::string, std::set<std::string>> model_dump_properties_map;
  138. std::set<std::string> s;
  139. model_dump_properties_map[DUMP_ALL_MODEL] = s;
  140. DumpProperties dp;
  141. dp.model_dump_properties_map_ = model_dump_properties_map;
  142. model.SetDumpProperties(dp);
  143. KernelTaskInfo kernel_task_info;
  144. kernel_task_info.davinci_model_ = &model;
  145. kernel_task_info.op_desc_ = op_desc;
  146. kernel_task_info.InitDumpArgs(0);
  147. }
  148. TEST_F(UtestGeExecutor, kernel_ex_InitDumpArgs) {
  149. DavinciModel model(0, g_label_call_back);
  150. model.om_name_ = "testom";
  151. model.name_ = "test";
  152. OpDescPtr op_desc = CreateOpDesc("test", "test");
  153. std::map<std::string, std::set<std::string>> model_dump_properties_map;
  154. std::set<std::string> s;
  155. model_dump_properties_map[DUMP_ALL_MODEL] = s;
  156. DumpProperties dp;
  157. dp.model_dump_properties_map_ = model_dump_properties_map;
  158. model.SetDumpProperties(dp);
  159. KernelExTaskInfo kernel_ex_task_info;
  160. kernel_ex_task_info.davinci_model_ = &model;
  161. kernel_ex_task_info.InitDumpArgs(nullptr, op_desc);
  162. }
  163. TEST_F(UtestGeExecutor, kernel_ex_InitDumpFlag) {
  164. DavinciModel model(0, g_label_call_back);
  165. model.om_name_ = "testom";
  166. model.name_ = "test";
  167. OpDescPtr op_desc = CreateOpDesc("test", "test");
  168. std::map<std::string, std::set<std::string>> model_dump_properties_map;
  169. std::set<std::string> s;
  170. model_dump_properties_map[DUMP_ALL_MODEL] = s;
  171. DumpProperties dp;
  172. dp.model_dump_properties_map_ = model_dump_properties_map;
  173. model.SetDumpProperties(dp);
  174. KernelExTaskInfo kernel_ex_task_info;
  175. kernel_ex_task_info.davinci_model_ = &model;
  176. kernel_ex_task_info.InitDumpFlag(op_desc);
  177. }
  178. TEST_F(UtestGeExecutor, execute_graph_with_stream) {
  179. VarManager::Instance(0)->Init(0, 0, 0, 0);
  180. map<string, string> options;
  181. options[GRAPH_MEMORY_MAX_SIZE] = "1048576";
  182. VarManager::Instance(0)->SetMemoryMallocSize(options, 1024UL * 1024UL * 1024UL);
  183. DavinciModel model(0, nullptr);
  184. ComputeGraphPtr graph = make_shared<ComputeGraph>("default");
  185. GeModelPtr ge_model = make_shared<GeModel>();
  186. ge_model->SetGraph(GraphUtils::CreateGraphFromComputeGraph(graph));
  187. AttrUtils::SetInt(ge_model, ATTR_MODEL_MEMORY_SIZE, 10240);
  188. AttrUtils::SetInt(ge_model, ATTR_MODEL_STREAM_NUM, 1);
  189. shared_ptr<domi::ModelTaskDef> model_task_def = make_shared<domi::ModelTaskDef>();
  190. ge_model->SetModelTaskDef(model_task_def);
  191. GeTensorDesc tensor(GeShape(), FORMAT_NCHW, DT_FLOAT);
  192. TensorUtils::SetSize(tensor, 512);
  193. {
  194. OpDescPtr op_desc = CreateOpDesc("data", DATA);
  195. op_desc->AddInputDesc(tensor);
  196. op_desc->AddOutputDesc(tensor);
  197. op_desc->SetInputOffset({1024});
  198. op_desc->SetOutputOffset({1024});
  199. NodePtr node = graph->AddNode(op_desc); // op_index = 0
  200. }
  201. {
  202. OpDescPtr op_desc = CreateOpDesc("square", "Square");
  203. op_desc->AddInputDesc(tensor);
  204. op_desc->AddOutputDesc(tensor);
  205. op_desc->SetInputOffset({1024});
  206. op_desc->SetOutputOffset({1024});
  207. NodePtr node = graph->AddNode(op_desc); // op_index = 1
  208. domi::TaskDef *task_def = model_task_def->add_task();
  209. task_def->set_stream_id(0);
  210. task_def->set_type(RT_MODEL_TASK_KERNEL);
  211. domi::KernelDef *kernel_def = task_def->mutable_kernel();
  212. kernel_def->set_stub_func("stub_func");
  213. kernel_def->set_args_size(64);
  214. string args(64, '1');
  215. kernel_def->set_args(args.data(), 64);
  216. domi::KernelContext *context = kernel_def->mutable_context();
  217. context->set_op_index(op_desc->GetId());
  218. context->set_kernel_type(2); // ccKernelType::TE
  219. uint16_t args_offset[9] = {0};
  220. context->set_args_offset(args_offset, 9 * sizeof(uint16_t));
  221. }
  222. {
  223. OpDescPtr op_desc = CreateOpDesc("memcpy", MEMCPYASYNC);
  224. op_desc->AddInputDesc(tensor);
  225. op_desc->AddOutputDesc(tensor);
  226. op_desc->SetInputOffset({1024});
  227. op_desc->SetOutputOffset({5120});
  228. NodePtr node = graph->AddNode(op_desc); // op_index = 2
  229. domi::TaskDef *task_def = model_task_def->add_task();
  230. task_def->set_stream_id(0);
  231. task_def->set_type(RT_MODEL_TASK_MEMCPY_ASYNC);
  232. domi::MemcpyAsyncDef *memcpy_async = task_def->mutable_memcpy_async();
  233. memcpy_async->set_src(1024);
  234. memcpy_async->set_dst(5120);
  235. memcpy_async->set_dst_max(512);
  236. memcpy_async->set_count(1);
  237. memcpy_async->set_kind(RT_MEMCPY_DEVICE_TO_DEVICE);
  238. memcpy_async->set_op_index(op_desc->GetId());
  239. }
  240. {
  241. OpDescPtr op_desc = CreateOpDesc("output", NETOUTPUT);
  242. op_desc->AddInputDesc(tensor);
  243. op_desc->SetInputOffset({5120});
  244. op_desc->SetSrcName( { "memcpy" } );
  245. op_desc->SetSrcIndex( { 0 } );
  246. NodePtr node = graph->AddNode(op_desc); // op_index = 3
  247. }
  248. EXPECT_EQ(model.Assign(ge_model), SUCCESS);
  249. EXPECT_EQ(model.Init(), SUCCESS);
  250. EXPECT_EQ(model.input_addrs_list_.size(), 1);
  251. EXPECT_EQ(model.output_addrs_list_.size(), 1);
  252. EXPECT_EQ(model.task_list_.size(), 2);
  253. OutputData output_data;
  254. vector<Tensor> outputs;
  255. EXPECT_EQ(model.GenOutputTensorInfo(&output_data, outputs), SUCCESS);
  256. GraphExecutor graph_executer;
  257. graph_executer.init_flag_ = true;
  258. GeRootModelPtr ge_root_model = make_shared<GeRootModel>(graph);
  259. std::vector<GeTensor> input_tensor;
  260. std::vector<GeTensor> output_tensor;
  261. std::vector<InputOutputDescInfo> output_desc;
  262. InputOutputDescInfo desc0;
  263. output_desc.push_back(desc0);
  264. graph_executer.ExecuteGraphWithStream(0, nullptr, ge_root_model, input_tensor, output_tensor);
  265. }
  266. TEST_F(UtestGeExecutor, get_op_attr) {
  267. shared_ptr<DavinciModel> model = MakeShared<DavinciModel>(1, g_label_call_back);
  268. model->SetId(1);
  269. model->om_name_ = "testom";
  270. model->name_ = "test";
  271. shared_ptr<hybrid::HybridDavinciModel> hybrid_model = MakeShared<hybrid::HybridDavinciModel>();
  272. model->SetId(2);
  273. model->om_name_ = "testom_hybrid";
  274. model->name_ = "test_hybrid";
  275. std::shared_ptr<ModelManager> model_manager = ModelManager::GetInstance();
  276. model_manager->InsertModel(1, model);
  277. model_manager->InsertModel(2, hybrid_model);
  278. OpDescPtr op_desc = CreateOpDesc("test", "test");
  279. std::vector<std::string> value{"test"};
  280. ge::AttrUtils::SetListStr(op_desc, ge::ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, value);
  281. model->SaveSpecifyAttrValues(op_desc);
  282. GeExecutor ge_executor;
  283. GeExecutor::isInit_ = true;
  284. std::string attr_value;
  285. auto ret = ge_executor.GetOpAttr(1, "test", ge::ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, attr_value);
  286. EXPECT_EQ(ret, SUCCESS);
  287. EXPECT_EQ(attr_value, "[4]test");
  288. ret = ge_executor.GetOpAttr(2, "test", ge::ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, attr_value);
  289. EXPECT_EQ(ret, PARAM_INVALID);
  290. ret = ge_executor.GetOpAttr(3, "test", ge::ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, attr_value);
  291. EXPECT_EQ(ret, ACL_ERROR_GE_EXEC_MODEL_ID_INVALID);
  292. }
  293. }

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