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_dump_parser.cc 6.0 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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /**
  2. * Copyright 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 "debug/data_dump_parser.h"
  17. #include <fstream>
  18. #include "utils/context/ms_context.h"
  19. #include "debug/common.h"
  20. constexpr auto kDataDumpConfigPtah = "DATA_DUMP_CONFIG_PATH";
  21. constexpr auto kEnableDataDump = "ENABLE_DATA_DUMP";
  22. constexpr auto kDataDumpPath = "DATA_DUMP_PATH";
  23. namespace mindspore {
  24. void DataDumpParser::ResetParam() {
  25. enable_ = false;
  26. net_name_.clear();
  27. dump_mode_ = 0;
  28. dump_step_ = 0;
  29. kernel_map_.clear();
  30. }
  31. bool DataDumpParser::DumpEnabled() const {
  32. auto enable_dump = std::getenv(kEnableDataDump);
  33. if (enable_dump == nullptr) {
  34. MS_LOG(INFO) << "[DataDump] enable dump is null. Please export ENABLE_DATA_DUMP";
  35. return false;
  36. }
  37. auto enabled = std::atoi(enable_dump);
  38. if (enabled != 1) {
  39. MS_LOG(WARNING) << "[DataDump] Please export ENABLE_DATA_DUMP=1";
  40. return false;
  41. }
  42. auto context = MsContext::GetInstance();
  43. MS_EXCEPTION_IF_NULL(context);
  44. if (context->execution_mode() == kPynativeMode) {
  45. MS_LOG(EXCEPTION) << "[DataDump] PyNative mode not support data dump";
  46. }
  47. return true;
  48. }
  49. std::optional<std::string> DataDumpParser::GetDumpPath() const {
  50. auto dump_path = std::getenv(kDataDumpPath);
  51. if (dump_path == nullptr) {
  52. MS_LOG(ERROR) << "[DataDump] dump path is null. Please export DATA_DUMP_PATH";
  53. return {};
  54. }
  55. std::string dump_path_str(dump_path);
  56. if (!std::all_of(dump_path_str.begin(), dump_path_str.end(),
  57. [](char c) { return ::isalpha(c) || ::isdigit(c) || c == '-' || c == '_' || c == '/'; })) {
  58. MS_LOG(EXCEPTION) << "[DataDump] dump path only support alphabets, digit or {'-', '_', '/'}, but got:"
  59. << dump_path_str;
  60. }
  61. return dump_path_str;
  62. }
  63. std::string GetIfstreamString(const std::ifstream &ifstream) {
  64. std::stringstream buffer;
  65. buffer << ifstream.rdbuf();
  66. return buffer.str();
  67. }
  68. void DataDumpParser::ParseDumpConfig() {
  69. std::lock_guard<std::mutex> guard(lock_);
  70. MS_LOG(INFO) << "[DataDump] parse start";
  71. if (!DumpEnabled()) {
  72. MS_LOG(INFO) << "[DataDump] dump not enable";
  73. return;
  74. }
  75. ResetParam();
  76. auto dump_config_file = Common::GetConfigFile(kDataDumpConfigPtah);
  77. if (!dump_config_file.has_value()) {
  78. MS_LOG(EXCEPTION) << "[DataDump] Get config file failed";
  79. }
  80. std::ifstream json_file(dump_config_file.value());
  81. if (!json_file.is_open()) {
  82. MS_LOG(EXCEPTION) << "[DataDump] " << dump_config_file.value() << " open failed.";
  83. }
  84. nlohmann::json j;
  85. try {
  86. json_file >> j;
  87. } catch (nlohmann::json::parse_error &e) {
  88. MS_LOG(ERROR) << "[DataDump] json contents:" << GetIfstreamString(json_file);
  89. MS_LOG(EXCEPTION) << "[DataDump] parse json failed, error:" << e.what();
  90. }
  91. if (j.find("DumpSettings") == j.end()) {
  92. MS_LOG(EXCEPTION) << "[DataDump] DumpSettings is not exist.";
  93. }
  94. nlohmann::json dump_settings = j.at("DumpSettings");
  95. // convert json to string
  96. std::stringstream ss;
  97. ss << dump_settings;
  98. std::string cfg = ss.str();
  99. MS_LOG(INFO) << "[DataDump] Async dump settings Json: " << cfg;
  100. if (!IsConfigExist(dump_settings)) {
  101. MS_LOG(EXCEPTION) << "[DataDump] Async dump json invalid";
  102. }
  103. if (!ParseDumpSetting(dump_settings)) {
  104. MS_LOG(EXCEPTION) << "[DataDump] Parse dump json failed";
  105. }
  106. }
  107. bool DataDumpParser::NeedDump(const std::string &op_full_name) const {
  108. if (!DumpEnabled()) {
  109. return false;
  110. }
  111. if (dump_mode_ == 0) {
  112. return true;
  113. }
  114. auto iter = kernel_map_.find(op_full_name);
  115. return iter != kernel_map_.end();
  116. }
  117. bool DataDumpParser::IsConfigExist(const nlohmann::json &dump_settings) const {
  118. if (dump_settings.find("mode") == dump_settings.end() || dump_settings.find("net_name") == dump_settings.end() ||
  119. dump_settings.find("iteration") == dump_settings.end() || dump_settings.find("kernels") == dump_settings.end()) {
  120. MS_LOG(ERROR) << "[DataDump] DumpSettings keys are not exist.";
  121. return false;
  122. }
  123. return true;
  124. }
  125. bool DataDumpParser::ParseDumpSetting(const nlohmann::json &dump_settings) {
  126. auto mode = dump_settings.at("mode");
  127. auto net_name = dump_settings.at("net_name");
  128. auto iteration = dump_settings.at("iteration");
  129. auto kernels = dump_settings.at("kernels");
  130. if (!(mode.is_number() && net_name.is_string() && iteration.is_number() && kernels.is_array())) {
  131. MS_LOG(ERROR) << "[DataDump] Element's type in Dump config json is invalid.";
  132. enable_ = false;
  133. return false;
  134. }
  135. enable_ = true;
  136. auto context_ptr = MsContext::GetInstance();
  137. MS_EXCEPTION_IF_NULL(context_ptr);
  138. dump_mode_ = mode;
  139. net_name_ = net_name;
  140. dump_step_ = iteration;
  141. for (const auto &kernel : kernels) {
  142. auto kernel_str = kernel.dump();
  143. kernel_str.erase(std::remove(kernel_str.begin(), kernel_str.end(), '\"'), kernel_str.end());
  144. MS_LOG(INFO) << "[DataDump] Need dump kernel:" << kernel_str;
  145. kernel_map_.insert({kernel_str, 0});
  146. }
  147. return true;
  148. }
  149. void DataDumpParser::MatchKernel(const std::string &kernel_name) {
  150. auto iter = kernel_map_.find(kernel_name);
  151. if (iter == kernel_map_.end()) {
  152. return;
  153. }
  154. iter->second = iter->second + 1;
  155. MS_LOG(INFO) << "Match dump kernel:" << iter->first << " match times:" << iter->second;
  156. }
  157. void DataDumpParser::PrintUnusedKernel() {
  158. for (const auto &iter : kernel_map_) {
  159. if (iter.second == 0) {
  160. MS_LOG(WARNING) << "[DataDump] Unused Kernel in json:" << iter.first;
  161. }
  162. }
  163. }
  164. } // namespace mindspore