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.

e2e_dump.cc 8.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /**
  2. * Copyright 2019 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 "debug/e2e_dump.h"
  17. #include <limits.h>
  18. #include <fstream>
  19. #include <string>
  20. #include <nlohmann/json.hpp>
  21. #include "utils/log_adapter.h"
  22. #include "utils/system/file_system.h"
  23. #include "utils/system/env.h"
  24. #include "utils/convert_utils.h"
  25. #include "utils/context/ms_context.h"
  26. using json = nlohmann::json;
  27. namespace mindspore {
  28. Dump::Dump()
  29. : dump_enable_(false),
  30. trans_flag_(false),
  31. dump_path_("/tmp/"),
  32. dump_net_name_("net_name"),
  33. dump_mode_(0),
  34. dump_iter_(0),
  35. cur_iter_(0) {}
  36. bool Dump::IsKernelNeedDump(const std::string &kernel_name) {
  37. if (dump_mode_ == 0) {
  38. // Dump All Kernels mode
  39. return true;
  40. } else {
  41. auto iter = std::find(dump_kernels_.begin(), dump_kernels_.end(), kernel_name);
  42. if (iter != dump_kernels_.end()) {
  43. return true;
  44. }
  45. }
  46. return false;
  47. }
  48. bool Dump::ParseDumpConfig(const std::string &dump_config_file) {
  49. std::ifstream jsonFile(dump_config_file);
  50. if (!jsonFile.is_open()) {
  51. MS_LOG(ERROR) << dump_config_file << " open failed.";
  52. dump_enable_ = false;
  53. return false;
  54. }
  55. json j;
  56. jsonFile >> j;
  57. if (j.find("DumpSettings") == j.end()) {
  58. MS_LOG(ERROR) << "DumpSettings is not exist.";
  59. dump_enable_ = false;
  60. return false;
  61. } else {
  62. json dumpSettings = j.at("DumpSettings");
  63. // convert json to string
  64. std::stringstream ss;
  65. ss << dumpSettings;
  66. std::string cfg = ss.str();
  67. MS_LOG(INFO) << "E2E Dump Settings Json: " << cfg;
  68. if (!IsConfigExist(dumpSettings)) {
  69. return false;
  70. }
  71. if (!IsConfigValid(dumpSettings)) {
  72. return false;
  73. }
  74. }
  75. return true;
  76. }
  77. bool Dump::IsConfigExist(const nlohmann::json &dumpSettings) {
  78. if (dumpSettings.find("trans_flag") == dumpSettings.end() || dumpSettings.find("enable") == dumpSettings.end() ||
  79. dumpSettings.find("mode") == dumpSettings.end() || dumpSettings.find("path") == dumpSettings.end() ||
  80. dumpSettings.find("net_name") == dumpSettings.end() || dumpSettings.find("iteration") == dumpSettings.end() ||
  81. dumpSettings.find("kernels") == dumpSettings.end()) {
  82. MS_LOG(ERROR) << "DumpSettings keys is not exist.";
  83. dump_enable_ = false;
  84. return false;
  85. }
  86. return true;
  87. }
  88. bool Dump::IsConfigValid(const nlohmann::json &dumpSettings) {
  89. auto trans_flag = dumpSettings.at("trans_flag");
  90. auto enable = dumpSettings.at("enable");
  91. auto mode = dumpSettings.at("mode");
  92. auto path = dumpSettings.at("path");
  93. auto net_name = dumpSettings.at("net_name");
  94. auto iteration = dumpSettings.at("iteration");
  95. auto kernels = dumpSettings.at("kernels");
  96. if (!(enable.is_boolean() && trans_flag.is_boolean() && mode.is_number() && path.is_string() &&
  97. net_name.is_string() && iteration.is_number() && kernels.is_array())) {
  98. MS_LOG(ERROR) << "Element's type in Dump config json is invalid.";
  99. dump_enable_ = false;
  100. return false;
  101. }
  102. dump_enable_ = enable;
  103. auto context_ptr = MsContext::GetInstance();
  104. MS_EXCEPTION_IF_NULL(context_ptr);
  105. // dump_enable_ is true, close mem reuse
  106. context_ptr->set_enable_mem_reuse(!dump_enable_);
  107. trans_flag_ = trans_flag;
  108. dump_mode_ = mode;
  109. dump_path_ = path;
  110. dump_net_name_ = net_name;
  111. dump_iter_ = iteration;
  112. for (const auto &kernel : kernels) {
  113. dump_kernels_.push_back(kernel);
  114. }
  115. return true;
  116. }
  117. bool Dump::SetDumpConfFromJsonFile() {
  118. const char *config_path_str = std::getenv("MINDSPORE_CONFIG_PATH");
  119. if (config_path_str != nullptr) {
  120. MS_LOG(INFO) << "Getenv MINDSPORE_CONFIG_PATH :" << config_path_str;
  121. } else {
  122. MS_LOG(INFO) << "No need E2E Dump. please export MINDSPORE_CONFIG_PATH eg: MINDSPORE_CONFIG_PATH=/etc";
  123. dump_enable_ = false;
  124. return false;
  125. }
  126. auto context_ptr = MsContext::GetInstance();
  127. MS_EXCEPTION_IF_NULL(context_ptr);
  128. auto id = context_ptr->device_id();
  129. char real_path[PATH_MAX] = {0};
  130. if (nullptr == realpath(config_path_str, real_path)) {
  131. MS_LOG(ERROR) << "Env e2e dump path error, " << config_path_str;
  132. dump_enable_ = false;
  133. return false;
  134. }
  135. std::string dump_config_file = std::string(real_path) + "/e2e_dump_config_" + std::to_string(id) + ".json";
  136. std::shared_ptr<system::FileSystem> fs = system::Env::GetFileSystem();
  137. MS_EXCEPTION_IF_NULL(fs);
  138. if (!fs->FileExist(dump_config_file)) {
  139. MS_LOG(ERROR) << dump_config_file << " not exist.";
  140. dump_enable_ = false;
  141. return false;
  142. }
  143. return ParseDumpConfig(dump_config_file);
  144. }
  145. bool Dump::DumpToFile(const std::string &filename, const void *data, size_t len) {
  146. if (filename.empty() || data == nullptr || len == 0) {
  147. MS_LOG(ERROR) << "Incorrect parameter.";
  148. return false;
  149. }
  150. std::string realpath;
  151. bool ret = GetRealPath(filename, &realpath);
  152. if (!ret) {
  153. MS_LOG(ERROR) << "Get real path failed.";
  154. return false;
  155. }
  156. std::ofstream fd;
  157. fd.open(realpath, std::ios::binary | std::ios::out);
  158. if (!fd.is_open()) {
  159. MS_LOG(ERROR) << "Open file " << realpath << " fail.";
  160. return false;
  161. }
  162. (void)fd.write(reinterpret_cast<const char *>(data), SizeToLong(len));
  163. fd.close();
  164. return true;
  165. }
  166. bool Dump::GetRealPath(const std::string &inpath, std::string *outpath) {
  167. MS_EXCEPTION_IF_NULL(outpath);
  168. auto path_split_pos = inpath.find_last_of('/');
  169. if (path_split_pos == std::string::npos) {
  170. path_split_pos = inpath.find_last_of('\\');
  171. }
  172. // get real path
  173. char real_path[PATH_MAX] = {0};
  174. if (path_split_pos != std::string::npos) {
  175. std::string prefix_path = inpath.substr(0, path_split_pos);
  176. if (prefix_path.length() >= PATH_MAX) {
  177. MS_LOG(ERROR) << "Prefix path is too longer!";
  178. return false;
  179. }
  180. std::string last_path = inpath.substr(path_split_pos, inpath.length() - path_split_pos);
  181. auto ret = CreateNotExistDirs(prefix_path);
  182. if (ret == false) {
  183. MS_LOG(ERROR) << "CreateNotExistDirs Failed!";
  184. return false;
  185. }
  186. if (nullptr == realpath(prefix_path.c_str(), real_path)) {
  187. MS_LOG(ERROR) << "dir " << prefix_path << " does not exit.";
  188. return false;
  189. }
  190. *outpath = std::string(real_path) + last_path;
  191. }
  192. if (path_split_pos == std::string::npos) {
  193. if (inpath.length() >= PATH_MAX) {
  194. MS_LOG(ERROR) << "Prefix path is too longer!";
  195. return false;
  196. }
  197. if (nullptr == realpath(inpath.c_str(), real_path)) {
  198. MS_LOG(ERROR) << "File " << inpath << " does not exit, it will be created.";
  199. }
  200. *outpath = std::string(real_path);
  201. }
  202. return true;
  203. }
  204. bool Dump::CreateNotExistDirs(const std::string &path) {
  205. std::shared_ptr<system::FileSystem> fs = system::Env::GetFileSystem();
  206. MS_EXCEPTION_IF_NULL(fs);
  207. char temp_path[PATH_MAX] = {0};
  208. if (path.length() > PATH_MAX) {
  209. MS_LOG(ERROR) << "Path lens is max than " << PATH_MAX;
  210. return false;
  211. }
  212. for (uint32_t i = 0; i < path.length(); i++) {
  213. temp_path[i] = path[i];
  214. if (temp_path[i] == '\\' || temp_path[i] == '/') {
  215. if (i != 0) {
  216. char tmp_char = temp_path[i];
  217. temp_path[i] = '\0';
  218. std::string path_handle(temp_path);
  219. if (!fs->FileExist(temp_path)) {
  220. MS_LOG(INFO) << "Dir " << path_handle << " does not exit, creating...";
  221. if (!fs->CreateDir(temp_path)) {
  222. MS_LOG(ERROR) << "Create " << path_handle << " dir error";
  223. return false;
  224. }
  225. }
  226. temp_path[i] = tmp_char;
  227. }
  228. }
  229. }
  230. if (!fs->FileExist(path)) {
  231. MS_LOG(INFO) << "Dir " << path << " does not exit, creating...";
  232. if (!fs->CreateDir(path)) {
  233. MS_LOG(ERROR) << "Create " << path << " dir error";
  234. return false;
  235. }
  236. }
  237. return true;
  238. }
  239. } // namespace mindspore