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.

data_dumper.cc 19 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  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 "graph/load/new_model_manager/data_dumper.h"
  17. #include <ctime>
  18. #include <map>
  19. #include <utility>
  20. #include <vector>
  21. #include "common/properties_manager.h"
  22. #include "framework/common/debug/ge_log.h"
  23. #include "framework/common/util.h"
  24. #include "graph/anchor.h"
  25. #include "graph/debug/ge_attr_define.h"
  26. #include "graph/load/new_model_manager/model_utils.h"
  27. #include "graph/utils/attr_utils.h"
  28. #include "proto/ge_ir.pb.h"
  29. #include "proto/op_mapping_info.pb.h"
  30. #include "runtime/mem.h"
  31. namespace {
  32. const uint32_t kAicpuLoadFlag = 1;
  33. const uint32_t kAicpuUnloadFlag = 0;
  34. const char *const kDumpOutput = "output";
  35. const char *const kDumpInput = "input";
  36. const char *const kDumpAll = "all";
  37. } // namespace
  38. static int32_t GetIrDataType(ge::DataType data_type) {
  39. static const std::map<ge::DataType, ge::proto::DataType> data_type_map = {
  40. {ge::DT_UNDEFINED, ge::proto::DT_UNDEFINED},
  41. {ge::DT_FLOAT, ge::proto::DT_FLOAT},
  42. {ge::DT_FLOAT16, ge::proto::DT_FLOAT16},
  43. {ge::DT_INT8, ge::proto::DT_INT8},
  44. {ge::DT_UINT8, ge::proto::DT_UINT8},
  45. {ge::DT_INT16, ge::proto::DT_INT16},
  46. {ge::DT_UINT16, ge::proto::DT_UINT16},
  47. {ge::DT_INT32, ge::proto::DT_INT32},
  48. {ge::DT_INT64, ge::proto::DT_INT64},
  49. {ge::DT_UINT32, ge::proto::DT_UINT32},
  50. {ge::DT_UINT64, ge::proto::DT_UINT64},
  51. {ge::DT_BOOL, ge::proto::DT_BOOL},
  52. {ge::DT_DOUBLE, ge::proto::DT_DOUBLE},
  53. {ge::DT_DUAL, ge::proto::DT_DUAL},
  54. {ge::DT_DUAL_SUB_INT8, ge::proto::DT_DUAL_SUB_INT8},
  55. {ge::DT_DUAL_SUB_UINT8, ge::proto::DT_DUAL_SUB_UINT8},
  56. {ge::DT_COMPLEX64, ge::proto::DT_COMPLEX64},
  57. {ge::DT_COMPLEX128, ge::proto::DT_COMPLEX128},
  58. {ge::DT_QINT8, ge::proto::DT_QINT8},
  59. {ge::DT_QINT16, ge::proto::DT_QINT16},
  60. {ge::DT_QINT32, ge::proto::DT_QINT32},
  61. {ge::DT_QUINT8, ge::proto::DT_QUINT8},
  62. {ge::DT_QUINT16, ge::proto::DT_QUINT16},
  63. {ge::DT_RESOURCE, ge::proto::DT_RESOURCE},
  64. {ge::DT_STRING_REF, ge::proto::DT_STRING_REF},
  65. {ge::DT_STRING, ge::proto::DT_STRING},
  66. };
  67. auto iter = data_type_map.find(data_type);
  68. if (iter == data_type_map.end()) {
  69. return static_cast<int32_t>(ge::proto::DT_UNDEFINED);
  70. }
  71. return static_cast<int32_t>(iter->second);
  72. }
  73. namespace ge {
  74. DataDumper::~DataDumper() {
  75. ReleaseDevMem(&dev_mem_load_);
  76. ReleaseDevMem(&dev_mem_unload_);
  77. }
  78. void DataDumper::ReleaseDevMem(void **ptr) noexcept {
  79. if (ptr == nullptr) {
  80. return;
  81. }
  82. if (*ptr != nullptr) {
  83. rtError_t rt_ret = rtFree(*ptr);
  84. if (rt_ret != RT_ERROR_NONE) {
  85. GELOGE(RT_FAILED, "Call rtFree failed, ret: 0x%X", rt_ret);
  86. }
  87. *ptr = nullptr;
  88. }
  89. }
  90. void DataDumper::SetLoopAddr(void *global_step, void *loop_per_iter, void *loop_cond) {
  91. global_step_ = reinterpret_cast<uintptr_t>(global_step);
  92. loop_per_iter_ = reinterpret_cast<uintptr_t>(loop_per_iter);
  93. loop_cond_ = reinterpret_cast<uintptr_t>(loop_cond);
  94. }
  95. void DataDumper::SaveDumpInput(const std::shared_ptr<Node> &node) {
  96. if (node != nullptr) {
  97. auto input_op_desc = node->GetOpDesc();
  98. if (input_op_desc == nullptr) {
  99. GELOGE(PARAM_INVALID, "input op desc is null.");
  100. return;
  101. }
  102. for (auto &out_data_anchor : node->GetAllOutDataAnchors()) {
  103. for (auto &dst_in_data_anchor : out_data_anchor->GetPeerInDataAnchors()) {
  104. ge::NodePtr dst_node = dst_in_data_anchor->GetOwnerNode();
  105. auto op_desc = dst_node->GetOpDesc();
  106. if (op_desc == nullptr) {
  107. GELOGE(PARAM_INVALID, "input op desc is null.");
  108. return;
  109. }
  110. input_map_.insert(
  111. {op_desc->GetName(), {input_op_desc, dst_in_data_anchor->GetIdx(), out_data_anchor->GetIdx()}});
  112. }
  113. }
  114. }
  115. }
  116. void DataDumper::SaveEndGraphId(uint32_t task_id, uint32_t stream_id) {
  117. end_graph_task_id_ = task_id;
  118. end_graph_stream_id_ = stream_id;
  119. }
  120. void DataDumper::SaveDumpTask(uint32_t task_id, uint32_t stream_id, const std::shared_ptr<OpDesc> &op_desc,
  121. uintptr_t args) {
  122. if (op_desc == nullptr) {
  123. GELOGE(PARAM_INVALID, "Opdesc is nullptr");
  124. return;
  125. }
  126. GELOGI("Save dump task %s, task id: %u, stream id: %u", op_desc->GetName().c_str(), task_id, stream_id);
  127. op_list_.push_back({task_id, stream_id, op_desc, args, true});
  128. for (auto iter = input_map_.equal_range(op_desc->GetName()); iter.first != iter.second; ++iter.first) {
  129. InnerInputMapping &inner_input_mapping = iter.first->second;
  130. auto &data_op = inner_input_mapping.data_op;
  131. if (data_op == nullptr) {
  132. GELOGE(PARAM_INVALID, "data_op is null.");
  133. return;
  134. }
  135. auto input_tensor = op_desc->GetInputDescPtr(inner_input_mapping.input_anchor_index);
  136. if (input_tensor == nullptr) {
  137. GELOGE(PARAM_INVALID, "input_tensor is null, index: %d, size: %zu.", inner_input_mapping.input_anchor_index,
  138. op_desc->GetInputsSize());
  139. return;
  140. }
  141. GELOGI("Save input dump task %s, id: %u.", data_op->GetName().c_str(), task_id);
  142. op_list_.push_back({task_id, stream_id, data_op, args, false, inner_input_mapping.input_anchor_index,
  143. inner_input_mapping.output_anchor_index, input_tensor->GetShape().GetDims()});
  144. }
  145. }
  146. static void SetOpMappingLoopAddr(uintptr_t step_id, uintptr_t loop_per_iter, uintptr_t loop_cond,
  147. aicpu::dump::OpMappingInfo &op_mapping_info) {
  148. if (step_id != 0) {
  149. GELOGI("step_id exist.");
  150. op_mapping_info.set_step_id_addr(static_cast<uint64_t>(step_id));
  151. } else {
  152. GELOGI("step_id is null.");
  153. }
  154. if (loop_per_iter != 0) {
  155. GELOGI("loop_per_iter exist.");
  156. op_mapping_info.set_iterations_per_loop_addr(static_cast<uint64_t>(loop_per_iter));
  157. } else {
  158. GELOGI("loop_per_iter is null.");
  159. }
  160. if (loop_cond != 0) {
  161. GELOGI("loop_cond exist.");
  162. op_mapping_info.set_loop_cond_addr(static_cast<uint64_t>(loop_cond));
  163. } else {
  164. GELOGI("loop_cond is null.");
  165. }
  166. }
  167. Status DataDumper::DumpOutput(const InnerDumpInfo &inner_dump_info, aicpu::dump::Task &task) {
  168. GELOGI("Start dump output");
  169. if (inner_dump_info.is_task) {
  170. // tbe or aicpu op
  171. const auto &output_descs = inner_dump_info.op->GetAllOutputsDesc();
  172. const auto input_size = inner_dump_info.op->GetAllInputsDesc().size();
  173. const std::vector<void *> output_addrs = ModelUtils::GetOutputDataAddrs(runtime_param_, inner_dump_info.op, false);
  174. if (output_descs.size() != output_addrs.size()) {
  175. GELOGE(PARAM_INVALID, "Invalid output desc addrs size %zu, op %s has %zu output desc.", output_addrs.size(),
  176. inner_dump_info.op->GetName().c_str(), output_descs.size());
  177. return PARAM_INVALID;
  178. }
  179. for (size_t i = 0; i < output_descs.size(); ++i) {
  180. aicpu::dump::Output output;
  181. output.set_data_type(static_cast<int32_t>(GetIrDataType(output_descs.at(i).GetDataType())));
  182. output.set_format(static_cast<int32_t>(output_descs.at(i).GetFormat()));
  183. for (auto dim : output_descs.at(i).GetShape().GetDims()) {
  184. output.mutable_shape()->add_dim(dim);
  185. }
  186. std::string origin_name;
  187. int32_t origin_output_index = -1;
  188. (void)AttrUtils::GetStr(&output_descs.at(i), ATTR_NAME_DATA_DUMP_ORIGIN_NAME, origin_name);
  189. (void)AttrUtils::GetInt(&output_descs.at(i), ATTR_NAME_DATA_DUMP_ORIGIN_OUTPUT_INDEX, origin_output_index);
  190. output.set_original_name(origin_name);
  191. output.set_original_output_index(origin_output_index);
  192. output.set_original_output_format(static_cast<int32_t>(output_descs.at(i).GetOriginFormat()));
  193. output.set_original_output_data_type(static_cast<int32_t>(output_descs.at(i).GetOriginDataType()));
  194. output.set_address(static_cast<uint64_t>(inner_dump_info.args + (i + input_size) * sizeof(void *)));
  195. task.mutable_output()->Add(std::move(output));
  196. }
  197. return SUCCESS;
  198. }
  199. // else data, const or variable op
  200. aicpu::dump::Output output;
  201. auto output_tensor = inner_dump_info.op->GetOutputDescPtr(inner_dump_info.output_anchor_index);
  202. const std::vector<void *> output_addrs = ModelUtils::GetOutputDataAddrs(runtime_param_, inner_dump_info.op, false);
  203. if (output_tensor == nullptr) {
  204. GELOGE(PARAM_INVALID, "output_tensor is null, index: %d, size: %zu.", inner_dump_info.output_anchor_index,
  205. inner_dump_info.op->GetOutputsSize());
  206. return PARAM_INVALID;
  207. }
  208. output.set_data_type(static_cast<int32_t>(GetIrDataType(output_tensor->GetDataType())));
  209. output.set_format(static_cast<int32_t>(output_tensor->GetFormat()));
  210. for (auto dim : inner_dump_info.dims) {
  211. output.mutable_shape()->add_dim(dim);
  212. }
  213. std::string origin_name;
  214. int32_t origin_output_index = -1;
  215. (void)AttrUtils::GetStr(output_tensor, ATTR_NAME_DATA_DUMP_ORIGIN_NAME, origin_name);
  216. (void)AttrUtils::GetInt(output_tensor, ATTR_NAME_DATA_DUMP_ORIGIN_OUTPUT_INDEX, origin_output_index);
  217. output.set_original_name(origin_name);
  218. output.set_original_output_index(origin_output_index);
  219. output.set_original_output_format(static_cast<int32_t>(output_tensor->GetOriginFormat()));
  220. output.set_original_output_data_type(static_cast<int32_t>(output_tensor->GetOriginDataType()));
  221. // due to lhisi virtual addr bug, cannot use args now
  222. if (inner_dump_info.output_anchor_index >= static_cast<int>(output_addrs.size())) {
  223. GELOGE(FAILED, "Index is out of range.");
  224. return FAILED;
  225. }
  226. auto data_addr = inner_dump_info.args + sizeof(void *) * static_cast<uint32_t>(inner_dump_info.input_anchor_index);
  227. output.set_address(static_cast<uint64_t>(data_addr));
  228. task.mutable_output()->Add(std::move(output));
  229. return SUCCESS;
  230. }
  231. Status DataDumper::DumpInput(const InnerDumpInfo &inner_dump_info, aicpu::dump::Task &task) {
  232. GELOGI("Start dump input");
  233. const auto &input_descs = inner_dump_info.op->GetAllInputsDesc();
  234. const std::vector<void *> input_addrs = ModelUtils::GetInputDataAddrs(runtime_param_, inner_dump_info.op, false);
  235. if (input_descs.size() != input_addrs.size()) {
  236. GELOGE(PARAM_INVALID, "Invalid input desc addrs size %zu, op %s has %zu input desc.", input_addrs.size(),
  237. inner_dump_info.op->GetName().c_str(), input_descs.size());
  238. return PARAM_INVALID;
  239. }
  240. for (size_t i = 0; i < input_descs.size(); ++i) {
  241. aicpu::dump::Input input;
  242. input.set_data_type(static_cast<int32_t>(GetIrDataType(input_descs.at(i).GetDataType())));
  243. input.set_format(static_cast<int32_t>(input_descs.at(i).GetFormat()));
  244. for (auto dim : input_descs.at(i).GetShape().GetDims()) {
  245. input.mutable_shape()->add_dim(dim);
  246. }
  247. input.set_address(static_cast<uint64_t>(inner_dump_info.args + sizeof(void *) * i));
  248. task.mutable_input()->Add(std::move(input));
  249. }
  250. return SUCCESS;
  251. }
  252. Status DataDumper::ExecuteLoadDumpInfo(aicpu::dump::OpMappingInfo &op_mapping_info) {
  253. std::string proto_str;
  254. size_t proto_size = op_mapping_info.ByteSizeLong();
  255. bool ret = op_mapping_info.SerializeToString(&proto_str);
  256. if (!ret || proto_size == 0) {
  257. GELOGE(FAILED, "Protobuf SerializeToString failed, proto size %zu.", proto_size);
  258. return FAILED;
  259. }
  260. if (dev_mem_load_ != nullptr) {
  261. GELOGW("dev_mem_load_ has been used.");
  262. ReleaseDevMem(&dev_mem_load_);
  263. }
  264. rtError_t rt_ret = rtMalloc(&dev_mem_load_, proto_size, RT_MEMORY_HBM);
  265. if (rt_ret != RT_ERROR_NONE) {
  266. GELOGE(RT_FAILED, "Call rtMalloc failed, ret: 0x%X", rt_ret);
  267. return RT_FAILED;
  268. }
  269. GE_PRINT_DYNAMIC_MEMORY(rtMalloc, "load dump information.", proto_size)
  270. rt_ret = rtMemcpy(dev_mem_load_, proto_size, proto_str.c_str(), proto_size, RT_MEMCPY_HOST_TO_DEVICE);
  271. if (rt_ret != RT_ERROR_NONE) {
  272. GELOGE(RT_FAILED, "Call rtMemcpy failed, ret: 0x%X", rt_ret);
  273. return RT_FAILED;
  274. }
  275. rt_ret = rtDatadumpInfoLoad(dev_mem_load_, proto_size);
  276. if (rt_ret != RT_ERROR_NONE) {
  277. GELOGE(RT_FAILED, "Call rtDatadumpInfoLoad failed, ret: 0x%X", rt_ret);
  278. return RT_FAILED;
  279. }
  280. load_flag_ = true;
  281. GELOGI("LoadDumpInfo success, proto size: %zu.", proto_size);
  282. return SUCCESS;
  283. }
  284. Status DataDumper::ExecuteUnLoadDumpInfo(aicpu::dump::OpMappingInfo &op_mapping_info) {
  285. std::string proto_str;
  286. size_t proto_size = op_mapping_info.ByteSizeLong();
  287. bool ret = op_mapping_info.SerializeToString(&proto_str);
  288. if (!ret || proto_size == 0) {
  289. GELOGE(FAILED, "Protobuf SerializeToString failed, proto size %zu.", proto_size);
  290. return FAILED;
  291. }
  292. if (dev_mem_unload_ != nullptr) {
  293. GELOGW("dev_mem_unload_ has been used.");
  294. ReleaseDevMem(&dev_mem_unload_);
  295. }
  296. rtError_t rt_ret = rtMalloc(&dev_mem_unload_, proto_size, RT_MEMORY_HBM);
  297. if (rt_ret != RT_ERROR_NONE) {
  298. GELOGE(RT_FAILED, "Call rtMalloc failed, ret: 0x%X", rt_ret);
  299. return RT_FAILED;
  300. }
  301. GE_PRINT_DYNAMIC_MEMORY(rtMalloc, "unload dump information.", proto_size)
  302. rt_ret = rtMemcpy(dev_mem_unload_, proto_size, proto_str.c_str(), proto_size, RT_MEMCPY_HOST_TO_DEVICE);
  303. if (rt_ret != RT_ERROR_NONE) {
  304. GELOGE(RT_FAILED, "Call rtMemcpy failed, ret: 0x%X", rt_ret);
  305. return RT_FAILED;
  306. }
  307. rt_ret = rtDatadumpInfoLoad(dev_mem_unload_, proto_size);
  308. if (rt_ret != RT_ERROR_NONE) {
  309. GELOGE(RT_FAILED, "Call rtDatadumpInfoLoad failed, ret: 0x%X", rt_ret);
  310. return RT_FAILED;
  311. }
  312. load_flag_ = false;
  313. GELOGI("UnloadDumpInfo success, proto size: %zu.", proto_size);
  314. return SUCCESS;
  315. }
  316. Status DataDumper::LoadDumpInfo() {
  317. PrintCheckLog();
  318. if (op_list_.empty()) {
  319. return SUCCESS;
  320. }
  321. aicpu::dump::OpMappingInfo op_mapping_info;
  322. auto dump_path = PropertiesManager::Instance().GetDumpOutputPath();
  323. op_mapping_info.set_dump_path(PropertiesManager::Instance().GetDumpOutputPath() + std::to_string(device_id_) + "/");
  324. op_mapping_info.set_model_name(model_name_);
  325. op_mapping_info.set_model_id(model_id_);
  326. op_mapping_info.set_flag(kAicpuLoadFlag);
  327. op_mapping_info.set_dump_step(PropertiesManager::Instance().GetDumpStep());
  328. SetOpMappingLoopAddr(global_step_, loop_per_iter_, loop_cond_, op_mapping_info);
  329. GELOGD("Dump step in load dump info is %s", PropertiesManager::Instance().GetDumpStep().c_str());
  330. for (const auto &op_iter : op_list_) {
  331. aicpu::dump::Task task;
  332. auto op_desc = op_iter.op;
  333. task.set_end_graph(false);
  334. task.set_task_id(op_iter.task_id);
  335. task.set_stream_id(op_iter.stream_id);
  336. task.mutable_op()->set_op_name(op_desc->GetName());
  337. task.mutable_op()->set_op_type(op_desc->GetType());
  338. if (PropertiesManager::Instance().GetDumpMode() == kDumpOutput) {
  339. if (DumpOutput(op_iter, task) != SUCCESS) {
  340. GELOGE(FAILED, "Dump output failed");
  341. return FAILED;
  342. }
  343. op_mapping_info.mutable_task()->Add(std::move(task));
  344. continue;
  345. }
  346. if (PropertiesManager::Instance().GetDumpMode() == kDumpInput) {
  347. if (op_iter.is_task) {
  348. if (DumpInput(op_iter, task) != SUCCESS) {
  349. GELOGE(FAILED, "Dump input failed");
  350. return FAILED;
  351. }
  352. }
  353. op_mapping_info.mutable_task()->Add(std::move(task));
  354. continue;
  355. }
  356. if (PropertiesManager::Instance().GetDumpMode() == kDumpAll) {
  357. auto ret = DumpOutput(op_iter, task);
  358. if (ret != SUCCESS) {
  359. GELOGE(FAILED, "Dump output failed when in dumping all");
  360. return FAILED;
  361. }
  362. if (op_iter.is_task) {
  363. ret = DumpInput(op_iter, task);
  364. if (ret != SUCCESS) {
  365. GELOGE(FAILED, "Dump input failed when in dumping all");
  366. return FAILED;
  367. }
  368. }
  369. op_mapping_info.mutable_task()->Add(std::move(task));
  370. continue;
  371. }
  372. }
  373. SetEndGraphIdToAicpu(end_graph_task_id_, end_graph_stream_id_, op_mapping_info);
  374. auto ret = ExecuteLoadDumpInfo(op_mapping_info);
  375. if (ret != SUCCESS) {
  376. GELOGE(FAILED, "Execute load dump info failed");
  377. return FAILED;
  378. }
  379. return SUCCESS;
  380. }
  381. void DataDumper::SetEndGraphIdToAicpu(uint32_t task_id, uint32_t stream_id,
  382. aicpu::dump::OpMappingInfo &op_mapping_info) {
  383. if (PropertiesManager::Instance().GetDumpMode() == kDumpOutput ||
  384. PropertiesManager::Instance().GetDumpMode() == kDumpInput ||
  385. PropertiesManager::Instance().GetDumpMode() == kDumpAll) {
  386. GELOGI("add end_graph_info to aicpu, task_id is %u, stream_id is %u", end_graph_task_id_, end_graph_stream_id_);
  387. aicpu::dump::Task task;
  388. task.set_end_graph(true);
  389. task.set_task_id(end_graph_task_id_);
  390. task.set_stream_id(end_graph_stream_id_);
  391. task.mutable_op()->set_op_name(NODE_NAME_END_GRAPH);
  392. task.mutable_op()->set_op_type(ENDGRAPH);
  393. op_mapping_info.mutable_task()->Add(std::move(task));
  394. }
  395. }
  396. Status DataDumper::UnloadDumpInfo() {
  397. if (!load_flag_) {
  398. GELOGI("No need to UnloadDumpInfo.");
  399. load_flag_ = false;
  400. return SUCCESS;
  401. }
  402. GELOGI("UnloadDumpInfo start.");
  403. aicpu::dump::OpMappingInfo op_mapping_info;
  404. op_mapping_info.set_model_id(model_id_);
  405. op_mapping_info.set_flag(kAicpuUnloadFlag);
  406. for (const auto &op_iter : op_list_) {
  407. aicpu::dump::Task task;
  408. task.set_task_id(op_iter.task_id);
  409. op_mapping_info.mutable_task()->Add(std::move(task));
  410. }
  411. auto ret = ExecuteUnLoadDumpInfo(op_mapping_info);
  412. if (ret != SUCCESS) {
  413. GELOGE(FAILED, "Execute unload dump info failed");
  414. return FAILED;
  415. }
  416. return SUCCESS;
  417. }
  418. void DataDumper::PrintCheckLog() {
  419. std::set<std::string> model_list = PropertiesManager::Instance().GetAllDumpModel();
  420. if (model_list.empty()) {
  421. GELOGI("No model need dump.");
  422. return;
  423. }
  424. GELOGI("%zu op need dump in %s.", op_list_.size(), model_name_.c_str());
  425. if (model_list.find(ge::DUMP_ALL_MODEL) == model_list.end()) {
  426. if (model_list.find(model_name_) == model_list.end()) {
  427. std::string model_list_str;
  428. for (auto &model : model_list) {
  429. model_list_str += "[" + model + "].";
  430. }
  431. GELOGW("Model %s not be set to dump, dump list: %s", model_name_.c_str(), model_list_str.c_str());
  432. return;
  433. }
  434. }
  435. std::set<std::string> config_dump_op_list = PropertiesManager::Instance().GetDumpPropertyValue(model_name_);
  436. std::set<std::string> dump_op_list;
  437. for (auto &inner_dump_info : op_list_) {
  438. // oplist value OpDescPtr is not nullptr
  439. dump_op_list.insert(inner_dump_info.op->GetName());
  440. }
  441. for (auto &dump_op : config_dump_op_list) {
  442. if (dump_op_list.find(dump_op) == dump_op_list.end()) {
  443. GELOGW("Op %s set to dump but not exist in model %s or not a valid op.", dump_op.c_str(), model_name_.c_str());
  444. }
  445. }
  446. }
  447. } // namespace ge

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