• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2019-2022 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_CORE_UTILS_MS_UTILS_H_
17 #define MINDSPORE_CORE_UTILS_MS_UTILS_H_
18 
19 #include <memory>
20 #include <utility>
21 #include <string>
22 #include <vector>
23 #include <atomic>
24 #include <thread>
25 #include <limits>
26 #include <cmath>
27 #include <chrono>
28 #include <algorithm>
29 #include <cctype>
30 #include "mindapi/base/macros.h"
31 namespace mindspore {
32 class MSLogTime {
33  public:
MSLogTime()34   MSLogTime() {}
~MSLogTime()35   ~MSLogTime() {}
Start()36   inline void Start() { this->start = std::chrono::system_clock::now(); }
End()37   inline void End() { this->end = std::chrono::system_clock::now(); }
GetRunTimeUS()38   uint64_t GetRunTimeUS() {
39     auto ms_duration = std::chrono::duration_cast<std::chrono::microseconds>(this->end - this->start);
40     uint64_t ms = ms_duration.count();
41     return ms;
42   }
43 
44  private:
45   std::chrono::system_clock::time_point start;
46   std::chrono::system_clock::time_point end;
47 };
48 }  // namespace mindspore
49 
50 #define DISABLE_COPY_AND_ASSIGN(ClassType) \
51   ClassType(const ClassType &) = delete;   \
52   ClassType &operator=(const ClassType &) = delete;
53 
54 #define TRY_AND_CATCH_WITH_EXCEPTION(expr, error_msg)                               \
55   do {                                                                              \
56     try {                                                                           \
57       (expr);                                                                       \
58     } catch (const std::exception &e) {                                             \
59       MS_LOG(EXCEPTION) << "Caught exception of " << e.what() << ". " << error_msg; \
60     }                                                                               \
61   } while (0)
62 
63 namespace mindspore {
64 namespace common {
SafeCStr(const std::string & str)65 inline const char *SafeCStr(const std::string &str) { return str.c_str(); }
66 MS_CORE_API const char *SafeCStr(const std::string &&str);
67 
68 // Memory dev config.
69 const char kAllocConf[] = "MS_ALLOC_CONF";
70 const char kAllocEnableVmm[] = "enable_vmm";
71 const char kAllocVmmAlignSize[] = "vmm_align_size";
72 const char kAllocMemoryRecycle[] = "memory_recycle";
73 const char kAllocMemoryTracker[] = "memory_tracker";
74 const char kAllocDefragMemoryStepFreq[] = "defrag_memory_step_freq";
75 
76 // Runtime dev config.
77 const char kRuntimeConf[] = "MS_DEV_RUNTIME_CONF";
78 const char kRuntimeInline[] = "inline";
79 const char kRuntimeSwitchInline[] = "switch_inline";
80 const char kRuntimeMultiStream[] = "multi_stream";
81 const char kRuntimePipeline[] = "pipeline";
82 const char kRuntimeView[] = "view";
83 const char kRuntimeInsertTensorMove[] = "insert_tensormove";
84 const char kRuntimeAllfinite[] = "all_finite";
85 const char kRuntimeParalletAssignAddOpt[] = "parallel_assignadd_opt";
86 // Runtime debug config.
87 const char kRuntimeSynchronize[] = "synchronize";
88 const char kRuntimeMemoryTrack[] = "memory_track";
89 const char kRuntimeMemoryStat[] = "memory_statistics";
90 const char kRuntimeCompileStat[] = "compile_statistics";
91 const char kRuntimePerformanceStat[] = "performance_statistics";
92 const char kRuntimePerformanceStatTopNum[] = "performance_statistics_top_num";
93 MS_CORE_API void ResetConfig(const std::string &config);
94 MS_CORE_API std::string GetConfigValue(const std::string &config, const std::string &config_key);
95 MS_CORE_API bool IsEnableRuntimeConfig(const std::string &runtime_config);
96 MS_CORE_API bool IsDisableRuntimeConfig(const std::string &runtime_config);
97 MS_CORE_API std::string GetAllocConfigValue(const std::string &alloc_config);
98 MS_CORE_API bool IsEnableAlllocConfig(const std::string &alloc_config);
99 MS_CORE_API bool IsDisableAlllocConfig(const std::string &alloc_config);
100 
GetEnv(const std::string & envvar)101 static inline std::string GetEnv(const std::string &envvar) {
102   const char *value = std::getenv(envvar.c_str());
103 
104   if (value == nullptr) {
105     return std::string();
106   }
107 
108   return std::string(value);
109 }
110 
111 static inline int SetEnv(const char *envname, const char *envvar, int overwrite = 1) {
112 #if defined(_WIN32)
113   return 0;
114 #else
115   return ::setenv(envname, envvar, overwrite);
116 #endif
117 }
118 
SetOMPThreadNum()119 static inline void SetOMPThreadNum() {
120   const size_t kOMPThreadMaxNum = 16;
121   const size_t kOMPThreadMinNum = 1;
122   // The actor concurrent execution max num.
123   const size_t kActorConcurrentMaxNum = 4;
124 
125   size_t cpu_core_num = std::thread::hardware_concurrency();
126   size_t cpu_core_num_half = cpu_core_num / 2;
127   // Ensure that the calculated number of OMP threads is at most half the number of CPU cores.
128   size_t OMP_thread_num = cpu_core_num_half / kActorConcurrentMaxNum;
129 
130   OMP_thread_num = OMP_thread_num < kOMPThreadMinNum ? kOMPThreadMinNum : OMP_thread_num;
131   OMP_thread_num = OMP_thread_num > kOMPThreadMaxNum ? kOMPThreadMaxNum : OMP_thread_num;
132 
133   std::string OMP_env = std::to_string(OMP_thread_num);
134   (void)SetEnv("OMP_NUM_THREADS", OMP_env.c_str(), 0);
135 }
136 
IsLittleByteOrder()137 static inline bool IsLittleByteOrder() {
138   uint32_t check_code = 0x12345678;
139   auto check_pointer = reinterpret_cast<uint8_t *>(&check_code);
140   uint8_t head_code = 0x78;
141   if (check_pointer[0] == head_code) {
142     return true;
143   }
144   return false;
145 }
146 
UseMPI()147 static inline bool UseMPI() {
148   // If these OpenMPI environment variables are set, we consider this process is launched by OpenMPI.
149   std::string ompi_command_env = GetEnv("OMPI_COMMAND");
150   std::string pmix_rank_env = GetEnv("PMIX_RANK");
151   if (!ompi_command_env.empty() && !pmix_rank_env.empty()) {
152     if (!GetEnv("MS_ROLE").empty()) {
153       return false;
154     }
155     return true;
156   }
157   return false;
158 }
159 
UseDynamicCluster()160 static inline bool UseDynamicCluster() {
161   // If environment variable 'MS_ROLE' or 'MS_SCHED_HOST' is set, we consider this process is participating in cluster
162   // building.
163   return !common::GetEnv("MS_ROLE").empty() || !common::GetEnv("MS_SCHED_HOST").empty();
164 }
165 
166 // UseDynamicCluster or UseMPI. If false, means use rank table file.
UseHostCollective()167 static inline bool UseHostCollective() { return common::UseDynamicCluster() || common::UseMPI(); }
168 
169 template <typename T>
IsEqual(const T * a,const T * b)170 bool IsEqual(const T *a, const T *b) {
171   if (a == b) {
172     return true;
173   }
174   if (a == nullptr || b == nullptr) {
175     return false;
176   }
177   return *a == *b;
178 }
179 
180 template <typename T>
IsEqual(const std::shared_ptr<T> & a,const std::shared_ptr<T> & b)181 bool IsEqual(const std::shared_ptr<T> &a, const std::shared_ptr<T> &b) {
182   return IsEqual(a.get(), b.get());
183 }
184 
185 template <typename T>
IsAttrsEqual(const T & a,const T & b)186 bool IsAttrsEqual(const T &a, const T &b) {
187   if (&a == &b) {
188     return true;
189   }
190   if (a.size() != b.size()) {
191     return false;
192   }
193   auto iter1 = a.begin();
194   auto iter2 = b.begin();
195   while (iter1 != a.end()) {
196     if (iter1->first != iter2->first) {
197       return false;
198     }
199     if (!IsEqual(iter1->second, iter2->second)) {
200       return false;
201     }
202     ++iter1;
203     ++iter2;
204   }
205   return true;
206 }
207 
IsFloatEqual(const float & a,const float & b)208 inline bool IsFloatEqual(const float &a, const float &b) {
209   return (std::fabs(a - b) <= std::numeric_limits<float>::epsilon());
210 }
211 
IsDoubleEqual(const double & a,const double & b)212 inline bool IsDoubleEqual(const double &a, const double &b) {
213   return (std::fabs(a - b) <= std::numeric_limits<double>::epsilon());
214 }
215 
IsStrNumeric(const std::string & str)216 inline bool IsStrNumeric(const std::string &str) {
217   return std::all_of(str.begin(), str.end(), [](char c) { return std::isdigit(c); });
218 }
219 
IsNeedMemoryStatistic()220 inline bool IsNeedMemoryStatistic() {
221   static const char kMemoryStatistic[] = "MS_MEMORY_STATISTIC";
222   static const auto need_statistic = GetEnv(kMemoryStatistic);
223   return !need_statistic.empty() && need_statistic != "0";
224 }
225 
IsNeedProfileMemory()226 inline bool IsNeedProfileMemory() {
227   static const char kLaunchSkippedEnv[] = "MS_KERNEL_LAUNCH_SKIP";
228   static const char kSimulationLevel[] = "MS_SIMULATION_LEVEL";
229   static const auto launch_skipped = GetEnv(kLaunchSkippedEnv);
230   static const auto simulation_level = common::GetEnv(kSimulationLevel);
231   static const bool skip_launch = (launch_skipped == "all" || launch_skipped == "ALL" || !simulation_level.empty());
232   return skip_launch;
233 }
234 }  // namespace common
235 }  // namespace mindspore
236 
237 #endif  // MINDSPORE_CORE_UTILS_MS_UTILS_H_
238