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.

profiling.cc 5.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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 "minddata/dataset/engine/perf/profiling.h"
  17. #include <sys/time.h>
  18. #include <cstdlib>
  19. #include <fstream>
  20. #include "utils/ms_utils.h"
  21. #include "minddata/dataset/util/path.h"
  22. #include "minddata/dataset/engine/perf/monitor.h"
  23. #include "minddata/dataset/engine/perf/device_queue_tracing.h"
  24. #include "minddata/dataset/engine/perf/connector_size.h"
  25. #include "minddata/dataset/engine/perf/connector_throughput.h"
  26. #include "minddata/dataset/engine/perf/dataset_iterator_tracing.h"
  27. #include "utils/log_adapter.h"
  28. namespace mindspore {
  29. namespace dataset {
  30. bool ProfilingManager::IsProfilingEnable() const {
  31. auto profiling = common::GetEnv("PROFILING_MODE");
  32. if (profiling.empty() || profiling != "true") {
  33. return false;
  34. }
  35. return true;
  36. }
  37. Status ProfilingManager::Initialize() {
  38. // Register nodes based on config
  39. std::string dir = common::GetEnv("MINDDATA_PROFILING_DIR");
  40. if (dir.empty()) {
  41. RETURN_STATUS_UNEXPECTED("Profiling dir is not set.");
  42. }
  43. char real_path[PATH_MAX] = {0};
  44. if (dir.size() >= PATH_MAX) {
  45. RETURN_STATUS_UNEXPECTED("Profiling dir is invalid.");
  46. }
  47. #if defined(_WIN32) || defined(_WIN64)
  48. if (_fullpath(real_path, common::SafeCStr(dir), PATH_MAX) == nullptr) {
  49. RETURN_STATUS_UNEXPECTED("Profiling dir is invalid.");
  50. }
  51. #else
  52. if (realpath(common::SafeCStr(dir), real_path) == nullptr) {
  53. RETURN_STATUS_UNEXPECTED("Profiling dir is invalid.");
  54. }
  55. #endif
  56. dir_path_ = real_path;
  57. // If DEVICE_ID is not set,defult value is 0
  58. device_id_ = common::GetEnv("DEVICE_ID");
  59. if (device_id_.empty()) {
  60. device_id_ = "0";
  61. }
  62. // Register all profiling node.
  63. // device_queue node is used for graph mode
  64. std::shared_ptr<Tracing> device_queue_tracing = std::make_shared<DeviceQueueTracing>();
  65. RETURN_IF_NOT_OK(RegisterTracingNode(device_queue_tracing));
  66. // dataset_iterator node is used for graph mode
  67. std::shared_ptr<Tracing> dataset_iterator_tracing = std::make_shared<DatasetIteratorTracing>();
  68. RETURN_IF_NOT_OK(RegisterTracingNode(dataset_iterator_tracing));
  69. std::shared_ptr<Sampling> connector_size_sampling = std::make_shared<ConnectorSize>(tree_);
  70. RETURN_IF_NOT_OK(RegisterSamplingNode(connector_size_sampling));
  71. std::shared_ptr<Sampling> connector_thr_sampling = std::make_shared<ConnectorThroughput>(tree_);
  72. RETURN_IF_NOT_OK(RegisterSamplingNode(connector_thr_sampling));
  73. return Status::OK();
  74. }
  75. // Profiling node registration
  76. Status ProfilingManager::RegisterTracingNode(std::shared_ptr<Tracing> node) {
  77. // Check if node with the same name has already been registered.
  78. auto exist = tracing_nodes_.find(node->Name());
  79. if (exist != tracing_nodes_.end()) {
  80. return Status(StatusCode::kProfilingError, "Profiling node already exist: " + node->Name());
  81. }
  82. // Register the node with its name as key.
  83. RETURN_IF_NOT_OK(node->Init(dir_path_, device_id_));
  84. tracing_nodes_[node->Name()] = node;
  85. return Status::OK();
  86. }
  87. // Profiling node getter
  88. Status ProfilingManager::GetTracingNode(const std::string &name, std::shared_ptr<Tracing> *node) {
  89. // Check if node with the same name has already been registered.
  90. auto exist = tracing_nodes_.find(name);
  91. if (exist == tracing_nodes_.end()) {
  92. return Status(StatusCode::kProfilingError, "Profiling node does not exist: " + name);
  93. }
  94. // Fetch node.
  95. *node = tracing_nodes_[name];
  96. return Status::OK();
  97. }
  98. // Profiling node registration
  99. Status ProfilingManager::RegisterSamplingNode(std::shared_ptr<Sampling> node) {
  100. // Check if node with the same name has already been registered.
  101. auto exist = sampling_nodes_.find(node->Name());
  102. if (exist != sampling_nodes_.end()) {
  103. return Status(StatusCode::kProfilingError, "Profiling node already exist: " + node->Name());
  104. }
  105. // Register the node with its name as key.
  106. RETURN_IF_NOT_OK(node->Init(dir_path_, device_id_));
  107. sampling_nodes_[node->Name()] = node;
  108. return Status::OK();
  109. }
  110. // Profiling node getter
  111. Status ProfilingManager::GetSamplingNode(const std::string &name, std::shared_ptr<Sampling> *node) {
  112. // Check if node with the same name has already been registered.
  113. auto exist = sampling_nodes_.find(name);
  114. if (exist == sampling_nodes_.end()) {
  115. return Status(StatusCode::kProfilingError, "Profiling node does not exist: " + name);
  116. }
  117. // Fetch node.
  118. *node = sampling_nodes_[name];
  119. return Status::OK();
  120. }
  121. Status ProfilingManager::SaveProfilingData() {
  122. if (!IsProfilingEnable()) {
  123. return Status::OK();
  124. }
  125. MS_LOG(INFO) << "Start to save profiling data.";
  126. for (auto node : tracing_nodes_) {
  127. RETURN_IF_NOT_OK(node.second->SaveToFile());
  128. }
  129. for (auto node : sampling_nodes_) {
  130. RETURN_IF_NOT_OK(node.second->SaveToFile());
  131. }
  132. MS_LOG(INFO) << "Save profiling data end.";
  133. return Status::OK();
  134. }
  135. int64_t ProfilingTime::GetCurMilliSecond() {
  136. // because cpplint does not allow using namespace
  137. using std::chrono::duration_cast;
  138. using std::chrono::milliseconds;
  139. using std::chrono::steady_clock;
  140. return duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
  141. }
  142. } // namespace dataset
  143. } // namespace mindspore