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.

profile.h 5.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. #ifndef MINDSPORE_CCSRC_UTILS_PROFILE_H_
  17. #define MINDSPORE_CCSRC_UTILS_PROFILE_H_
  18. #include <map>
  19. #include <string>
  20. #include <fstream>
  21. #include <iomanip>
  22. #include <sstream>
  23. #include "utils/log_adapter.h"
  24. namespace mindspore {
  25. struct TimeInfo;
  26. using TimeInfoMap = std::map<std::string, const TimeInfo *>;
  27. extern double GetTime();
  28. class ProfileBase;
  29. struct TimeInfo {
  30. explicit TimeInfo(double time = -1.0) : time_(time), dict_(nullptr), actionNum_(0) {}
  31. TimeInfo(const TimeInfo &) = delete;
  32. ~TimeInfo();
  33. double time_;
  34. TimeInfoMap *dict_;
  35. size_t actionNum_;
  36. };
  37. // Utility class for Profile.
  38. class ProfContext {
  39. friend class Profile;
  40. friend class ProfileBase;
  41. friend class ProfTransaction;
  42. public:
  43. ProfContext(const std::string &name, ProfileBase *prof);
  44. ~ProfContext();
  45. ProfContext(const ProfContext &) = delete;
  46. ProfContext &operator=(const ProfContext &) = delete;
  47. void SetTime(double time) noexcept;
  48. void Insert(const std::string &name, const TimeInfo *time) noexcept;
  49. bool IsTopContext() const noexcept;
  50. private:
  51. std::string name_;
  52. ProfileBase *prof_;
  53. ProfContext *parent_;
  54. TimeInfo *time_info_;
  55. };
  56. class ProfileBase {
  57. friend class ProfContext;
  58. friend class ProfTransaction;
  59. public:
  60. ProfileBase();
  61. virtual ~ProfileBase();
  62. virtual void Print(void) {}
  63. virtual ProfContext *Step(const std::string &) { return nullptr; }
  64. virtual ProfContext *Lap(int) { return nullptr; }
  65. virtual void Pop(void) {}
  66. // top level profile context
  67. ProfContext context_;
  68. // profile context pointer, act as a stack pointer
  69. ProfContext *ctx_ptr_ = nullptr;
  70. };
  71. class Profile : public ProfileBase {
  72. public:
  73. Profile() = default;
  74. ~Profile() override = default;
  75. Profile(const Profile &) = delete;
  76. Profile &operator=(const Profile &) = delete;
  77. void Print(void) override;
  78. ProfContext *Step(const std::string &name) override;
  79. ProfContext *Lap(int count) override;
  80. void Pop(void) noexcept override;
  81. };
  82. class ProfTransaction {
  83. public:
  84. explicit ProfTransaction(const ProfileBase *prof);
  85. explicit ProfTransaction(ProfContext *const ctx) : ctx_(ctx) {}
  86. ProfTransaction(const ProfTransaction &) = delete;
  87. ~ProfTransaction();
  88. template <class Function>
  89. void operator-(const Function &func) {
  90. double start_time = GetTime();
  91. func();
  92. double end_time = GetTime();
  93. if (ctx_ != nullptr) {
  94. ctx_->SetTime(end_time - start_time);
  95. }
  96. }
  97. private:
  98. ProfContext *ctx_ = nullptr;
  99. };
  100. class NoProfTransaction {
  101. public:
  102. explicit NoProfTransaction(ProfileBase *prof) {}
  103. explicit NoProfTransaction(ProfContext *ctx) {}
  104. ~NoProfTransaction() = default;
  105. template <class Function>
  106. void operator-(const Function &func) {
  107. func();
  108. }
  109. };
  110. class DumpTime {
  111. public:
  112. ~DumpTime() {
  113. try {
  114. Save();
  115. } catch (const std::exception &e) {
  116. MS_LOG(ERROR) << "Cannot save file by profile::DumpTime::save";
  117. } catch (...) {
  118. MS_LOG(ERROR) << "Uncaught exception";
  119. }
  120. }
  121. DumpTime(const DumpTime &) = delete;
  122. DumpTime &operator=(const DumpTime &) = delete;
  123. static DumpTime &GetInstance() {
  124. static DumpTime instance;
  125. return instance;
  126. }
  127. void set_file_path(const std::string &save_path) { file_path_ = save_path; }
  128. void Record(const std::string &name, const double time, const bool is_start);
  129. void Save();
  130. private:
  131. DumpTime() = default;
  132. std::stringstream file_ss_;
  133. std::ofstream file_out_;
  134. std::string file_path_ = "./timeline.json";
  135. };
  136. struct TimeStat {
  137. TimeStat() {
  138. time_ = 0.0;
  139. count_ = 0;
  140. }
  141. ~TimeStat() = default;
  142. void operator+=(double t) {
  143. time_ += t;
  144. count_ += 1;
  145. }
  146. TimeStat operator+(double t) {
  147. TimeStat ts = *this;
  148. ts += t;
  149. return ts;
  150. }
  151. double time_;
  152. int count_;
  153. };
  154. class MsProfile {
  155. public:
  156. ~MsProfile() { Clear(); }
  157. static void Reset() { GetSingleton().Clear(); }
  158. static ProfileBase *GetProfile() {
  159. MsProfile &ms_prof = GetSingleton();
  160. if (ms_prof.profile_ == nullptr) {
  161. #ifdef ENABLE_PROFILE
  162. ms_prof.profile_ = new Profile();
  163. #else
  164. ms_prof.profile_ = new ProfileBase();
  165. #endif
  166. }
  167. return ms_prof.profile_;
  168. }
  169. static void StatTime(const std::string &id, double time) { GetSingleton().time_stat_[id] += time; }
  170. static void Print();
  171. private:
  172. MsProfile() = default;
  173. static MsProfile &GetSingleton() {
  174. static MsProfile profile;
  175. return profile;
  176. }
  177. void Clear() {
  178. time_stat_.clear();
  179. if (profile_ != nullptr) {
  180. delete profile_;
  181. profile_ = nullptr;
  182. }
  183. }
  184. std::map<std::string, TimeStat> time_stat_; // record time and count info from some activity
  185. ProfileBase *profile_ = nullptr; // record hierarchical profile info
  186. };
  187. } // namespace mindspore
  188. #ifdef ENABLE_PROFILE
  189. #define WITH(x) ProfTransaction(x) -
  190. #else
  191. #define WITH(x) NoProfTransaction(x) -
  192. #endif
  193. #endif // MINDSPORE_CCSRC_UTILS_PROFILE_H_