1 /**
2 * Copyright 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
17 #include "include/common/utils/utils.h"
18
19 #if defined(_WIN32) || defined(_WIN64) || defined(__APPLE__)
20 #else
21 #include <sys/statfs.h>
22 #endif
23 #include <set>
24 #include <string>
25 #include "include/common/utils/parallel_context.h"
26 #include "ops/array_op_name.h"
27 #include "ops/ascend_op_name.h"
28 #include "ops/conv_pool_op_name.h"
29 #include "ops/framework_op_name.h"
30 #include "ops/image_op_name.h"
31 #include "ops/math_op_name.h"
32 #include "ops/nn_op_name.h"
33 #include "ops/nn_optimizer_op_name.h"
34 #include "ops/other_op_name.h"
35 #include "ops/random_op_name.h"
36 #include "ops/sequence_op_name.h"
37 #include "ops/sparse_op_name.h"
38 #include "ops/structure_op_name.h"
39 #include "utils/convert_utils_base.h"
40 #include "utils/ms_context.h"
41
42 #if !defined(BUILD_LITE)
43 #include "pybind11/pybind11.h"
44 namespace py = pybind11;
45 #endif
46
47 namespace mindspore {
48 namespace {
49 constexpr size_t kKBToByte = 1024;
50 constexpr size_t kLineMaxSize = 1024;
51 } // namespace
IsOneOfPosteriorOperator(const std::string & name)52 bool IsOneOfPosteriorOperator(const std::string &name) {
53 static const std::set<std::string> kPosteriorOperatorSet = {kPullOpName};
54
55 auto iter = kPosteriorOperatorSet.find(name);
56 return iter != kPosteriorOperatorSet.end();
57 }
58
IsOneOfCacheBlackList(const std::string & name)59 bool IsOneOfCacheBlackList(const std::string &name) {
60 static const std::set<std::string> kOpCacheBlackList = {kUniformCandidateSamplerOpName, kInitDatasetQueueOpName,
61 kGetNextOpName};
62
63 auto iter = kOpCacheBlackList.find(name);
64 return iter != kOpCacheBlackList.end();
65 }
66
GetPythonStack_()67 std::vector<std::tuple<std::string, int, std::string>> GetPythonStack_() {
68 std::vector<std::tuple<std::string, int, std::string>> all_stacks;
69 #if !defined(BUILD_LITE)
70 try {
71 const size_t func_name_index = 2;
72 const size_t min_frame_info_size = 3;
73 py::gil_scoped_acquire gil_acquire;
74 py::module traceback_module = py::module::import("traceback");
75 py::list extracted_stack = traceback_module.attr("extract_stack")();
76 for (size_t i = 0; i < extracted_stack.size(); ++i) {
77 py::tuple frame_info = extracted_stack[i].cast<py::tuple>();
78 if (frame_info.size() < min_frame_info_size) {
79 MS_LOG(ERROR) << "frame_info size is invalid, frame_info size:" << frame_info.size();
80 continue;
81 }
82 // frame_info: (filename, line number, function name, code_context)
83 std::string file_name = frame_info[0].cast<std::string>();
84 int line_number = frame_info[1].cast<int>();
85 std::string func_name = frame_info[func_name_index].cast<std::string>();
86 (void)all_stacks.emplace_back(std::tuple(file_name, line_number, func_name));
87 }
88 } catch (const std::exception &e) {
89 MS_LOG(ERROR) << "Error while accessing Python stack: " << e.what();
90 }
91 #endif
92
93 return all_stacks;
94 }
95
GetPythonStackStr_()96 std::string GetPythonStackStr_() {
97 const auto &stacks = GetPythonStack_();
98 const size_t func_name_index = 2;
99
100 std::stringstream ss;
101 for (const auto &stack_info : stacks) {
102 ss << "File:" << std::get<0>(stack_info) << ";Line:" << std::get<1>(stack_info)
103 << ";Function:" << std::get<func_name_index>(stack_info) << '|';
104 }
105 return ss.str();
106 }
107
IsOneOf3DFormat(const std::string & format)108 bool IsOneOf3DFormat(const std::string &format) {
109 static const std::set<std::string> k3DFormatSet = {kOpFormat_NCDHW, kOpFormat_NDC1HWC0, kOpFormat_FRACTAL_Z_3D,
110 kOpFormat_NDHWC, kOpFormat_DHWCN, kOpFormat_DHWNC};
111
112 auto iter = k3DFormatSet.find(format);
113 return iter != k3DFormatSet.end();
114 }
115
IsOneOfNoPaddingFormat(const std::string & format)116 bool IsOneOfNoPaddingFormat(const std::string &format) {
117 static const std::set<std::string> kNoPaddingFormatSet = {
118 kOpFormat_ChannelLast, kOpFormat_FRAC_NZ, kOpFormat_FRACTAL_ZN_RNN, kOpFormat_ND_RNN_BIAS, kOpFormat_DEFAULT};
119
120 auto iter = kNoPaddingFormatSet.find(format);
121 return iter != kNoPaddingFormatSet.end();
122 }
123
IsOneOfDynamicShapeConstInputToAttrGPU(const std::string & name)124 bool IsOneOfDynamicShapeConstInputToAttrGPU(const std::string &name) {
125 static const std::set<std::string> DynamicShapeConstInputToAttrGPU = {
126 kCastOpName, kExpandDimsOpName, kReshapeOpName, kEmbeddingLookupOpName, kTransposeOpName,
127 kReduceSumOpName, kReduceMinOpName, kReduceMeanOpName, kReduceMaxOpName, kReduceAllOpName,
128 kReduceAnyOpName, kConcatOpName, kScatterNdOpName, kGatherOpName, kAvgPool3DGradOpName};
129
130 auto iter = DynamicShapeConstInputToAttrGPU.find(name);
131 return iter != DynamicShapeConstInputToAttrGPU.end();
132 }
133
IsOneOfCustomAkgType(const std::string & name)134 bool IsOneOfCustomAkgType(const std::string &name) {
135 const std::set<std::string> kCustomTypeAkg = {"ir_builder", "tvm_compute", "hybrid"};
136
137 auto iter = kCustomTypeAkg.find(name);
138 return iter != kCustomTypeAkg.end();
139 }
140
IsOneOfOperator(const std::string & name)141 bool IsOneOfOperator(const std::string &name) {
142 static const std::set<std::string> kOptOperatorSet = {kMomentumOpName,
143 kApplyMomentumOpName,
144 kApplyMomentumDOpName,
145 kApplyAdadeltaOpName,
146 kApplyAdadeltaDOpName,
147 kApplyAdagradOpName,
148 kApplyAdagradDOpName,
149 kApplyAdagradDAOpName,
150 kApplyAdagradDADOpName,
151 kAdamOpName,
152 kApplyAdamDOpName,
153 kApplyAdamOpName,
154 kApplyAdaMaxOpName,
155 kApplyAdaMaxDOpName,
156 kApplyAddSignOpName,
157 kApplyAddSignDOpName,
158 kApplyCenteredRMSPOpName,
159 kApplyFtrlOpName,
160 kApplyFtrlDOpName,
161 kApplyFtrlV2OpName,
162 kApplyFtrlV2DOpName,
163 kApplyGradientDescentOpName,
164 kApplyPowerSignOpName,
165 kApplyPowerSignDOpName,
166 kApplyProximalAdagradOpName,
167 kApplyProximalAdagradDOpName,
168 kApplyProximalGradientDescentOpName,
169 kApplyRMSPropOpName,
170 kApplyRMSPropDOpName,
171 kAdamApplyOneWithDecayOpName,
172 kAdamApplyOneWithDecayAssignOpName,
173 kFusedAdamWeightDecayOpName,
174 kAdamWeightDecayOpName,
175 kFusedCastAdamWeightDecayOpName,
176 kFusedAdamOpName,
177 kFusedAdaFactorOpName,
178 kFusedAdaFactorWithGlobalNormOpName,
179 kFusedSparseAdamOpName,
180 kFusedMulApplyMomentumOpName,
181 kFusedWeightScaleApplyMomentumOpName,
182 kFusedScaleApplyMomentumOpName,
183 kApplyCenteredRMSPropOpName,
184 kApplyCenteredRMSPropDOpName,
185 kFusedSparseFtrlOpName,
186 kFusedSparseProximalAdagradOpName,
187 kFusedSparseLazyAdamOpName,
188 kSparseApplyFtrlOpName,
189 kSparseApplyFtrlDOpName,
190 kSparseApplyFtrlV2OpName,
191 kSparseApplyFtrlV2DOpName,
192 kSGDOpName,
193 kLARSUpdateOpName,
194 kLarsV2UpdateOpName,
195 kCombineWeightDecayScaleMomentumOpName,
196 kCombineScaleMomentumOpName,
197 kCombineMomentumOpName,
198 kScatterAddOpName,
199 kScatterUpdateOpName,
200 kSparseApplyProximalAdagradOpName,
201 kSparseApplyProximalAdagradDOpName,
202 kAdaptiveMaxPool2dOpName,
203 kApplyKerasMomentumDOpName};
204
205 auto iter = kOptOperatorSet.find(name);
206 return iter != kOptOperatorSet.end();
207 }
208
IsOneOfNotSupportedTransFormat(const std::string & format)209 bool IsOneOfNotSupportedTransFormat(const std::string &format) {
210 static const std::set<std::string> kNotSupportedFormat = {kOpFormat_DHWCN, kOpFormat_NDHWC, kOpFormat_CHWN};
211 return (kNotSupportedFormat.find(format) != kNotSupportedFormat.end());
212 }
213
IsOneOfComputeDepend(const std::string & name)214 bool IsOneOfComputeDepend(const std::string &name) {
215 static const std::set<std::string> kComputeDepend = {kUniqueOpName,
216 kUniqueConsecutiveOpName,
217 kComputeAccidentalHitsOpName,
218 kSubAndFilterOpName,
219 kPadAndShiftOpName,
220 kCTCGreedyDecoderOpName,
221 kMaskedSelectOpName,
222 kDynamicStitchOpName,
223 kGetNextOpName,
224 kListDiffOpName,
225 kNonMaxSuppressionV3OpName,
226 kNonMaxSuppressionWithOverlapsOpName,
227 kCoalesceOpName,
228 kTruncatedNormalOpName,
229 kNonDeterministicIntsOpName,
230 kFractionalAvgPoolGradOpName,
231 kDenseToDenseSetOperationOpName,
232 kDenseToSparseSetOperationOpName,
233 kSegmentMaxOpName,
234 kCSRSparseMatrixToSparseTensorOpName,
235 kSegmentMinOpName,
236 kLuUnpackOpName,
237 kSegmentSumOpName,
238 kResizeBicubicOpName,
239 kResizeAreaOpName,
240 kSegmentMeanOpName,
241 kSegmentProdOpName,
242 kSparseSliceOpName,
243 kNonZeroOpName,
244 kSparseSparseMinimumOpName,
245 kSparseSparseMaximumOpName,
246 kRpcRecvOpName,
247 kSparseFillEmptyRowsOpName,
248 kSparseCrossOpName,
249 kAdaptiveMaxPool3DOpName,
250 kDynamicBroadcastGradientArgsOpName};
251
252 auto iter = kComputeDepend.find(name);
253 return iter != kComputeDepend.end();
254 }
255
IsOneOfUnsignedType(const TypeId & type_id)256 bool IsOneOfUnsignedType(const TypeId &type_id) {
257 static const std::set<TypeId> unsigned_types{kNumberTypeUInt8, kNumberTypeUInt16, kNumberTypeUInt32,
258 kNumberTypeUInt64};
259 return unsigned_types.count(type_id) > 0;
260 }
261
IsOneOfHWSpecialFormat(const std::string & format)262 bool IsOneOfHWSpecialFormat(const std::string &format) {
263 static const std::set<std::string> kHWSpecialFormatSet = {
264 kOpFormat_FRACTAL_Z_3D, kOpFormat_NC1KHKWHWC0, kOpFormat_NC1HWC0, kOpFormat_FRAC_NZ,
265 kOpFormat_C1HWNCoC0, kOpFormat_NC1HWC0_C04, kOpFormat_FRACTAL_Z_C04, kOpFormat_FRACTAL_ZN_LSTM,
266 kOpFormat_FRACTAL_ZN_RNN, kOpFormat_NDC1HWC0, kOpFormat_FRAC_Z};
267
268 auto iter = kHWSpecialFormatSet.find(format);
269 return iter != kHWSpecialFormatSet.end();
270 }
271
IsOneOfDefaultFormat(const std::string & format)272 bool IsOneOfDefaultFormat(const std::string &format) {
273 static const std::set<std::string> kOpDefaultFormatList = {kOpFormat_DEFAULT, kOpFormat_ND, kOpFormat_NCDHW,
274 kOpFormat_NCHW};
275 return kOpDefaultFormatList.find(format) != kOpDefaultFormatList.end();
276 }
277
IsOneOfFormat(const std::string & format)278 bool IsOneOfFormat(const std::string &format) {
279 static const std::set<std::string> kOpFormatList = {
280 kOpFormat_DEFAULT, kOpFormat_NC1KHKWHWC0, kOpFormat_ND,
281 kOpFormat_NCHW, kOpFormat_NHWC, kOpFormat_HWCN,
282 kOpFormat_CHWN, kOpFormat_NC1HWC0, kOpFormat_FRAC_Z,
283 kOpFormat_C1HWNCoC0, kOpFormat_FRAC_NZ, kOpFormat_NC1HWC0_C04,
284 kOpFormat_FRACTAL_Z_C04, kOpFormat_NDHWC, kOpFormat_FRACTAL_ZN_LSTM,
285 kOpFormat_FRACTAL_ZN_RNN, kOpFormat_ND_RNN_BIAS, kOpFormat_NDC1HWC0,
286 kOpFormat_NCDHW, kOpFormat_FRACTAL_Z_3D, kOpFormat_DHWNC,
287 kOpFormat_DHWCN};
288
289 auto iter = kOpFormatList.find(format);
290 return iter != kOpFormatList.end();
291 }
292
IsOneOfServerFormatC04(const std::string & format)293 bool IsOneOfServerFormatC04(const std::string &format) {
294 static const std::set<std::string> kServerFormatC04List = {kOpFormat_NC1HWC0_C04, kOpFormat_FRACTAL_Z_C04};
295 return kServerFormatC04List.find(format) != kServerFormatC04List.end();
296 }
297
IsOneOfDynRankNeedPadShape(const std::string & format)298 bool IsOneOfDynRankNeedPadShape(const std::string &format) {
299 const std::set<std::string> kOpFormats = {kOpFormat_NC1HWC0, kOpFormat_NDC1HWC0, kOpFormat_FRAC_Z,
300 kOpFormat_NDC1HWC0, kOpFormat_C1HWNCoC0, kOpFormat_NC1HWC0_C04,
301 kOpFormat_FRACTAL_Z_3D, kOpFormat_FRACTAL_Z_C04, kOpFormat_NCDHW};
302 return kOpFormats.find(format) != kOpFormats.end();
303 }
304
IsEnableRefMode()305 bool IsEnableRefMode() {
306 static bool ret = !(common::GetEnv("MS_DISABLE_REF_MODE") == "1");
307 return ret;
308 }
309
IsMemoryPoolRecycle()310 bool IsMemoryPoolRecycle() {
311 static bool optimize_mem = !common::IsDisableAlllocConfig(common::kAllocMemoryRecycle);
312 static bool enable_ref_mode = IsEnableRefMode();
313 auto context_ptr = MsContext::GetInstance();
314 auto mode = context_ptr->get_param<int>(MS_CTX_EXECUTION_MODE);
315 auto task_sink = context_ptr->get_param<bool>(MS_CTX_ENABLE_TASK_SINK);
316 return optimize_mem && enable_ref_mode && mode == kGraphMode && task_sink;
317 }
318
GetSystemMemorySize(const std::string & key)319 size_t GetSystemMemorySize(const std::string &key) {
320 #if defined(_WIN32) || defined(_WIN64) || defined(__APPLE__)
321 return SIZE_MAX;
322 #else
323 FILE *file = fopen("/proc/meminfo", "r");
324 if (file == nullptr) {
325 MS_LOG(ERROR) << "Get system meminfo failed.";
326 return 0;
327 }
328
329 size_t mem_size = 0;
330 char buf[kLineMaxSize] = {0};
331 while (fgets(buf, kLineMaxSize, file)) {
332 // Get mem title.
333 std::string line(buf);
334 auto title_end_pos = line.find(":");
335 auto title = line.substr(0, title_end_pos);
336 // Get mem size.
337 if (title == key) {
338 auto mem_size_end_pos = line.find_last_of(" ");
339 auto mem_size_begin_pos = line.find_last_of(" ", mem_size_end_pos - 1);
340 if ((mem_size_end_pos != std::string::npos) && (mem_size_begin_pos != std::string::npos)) {
341 auto mem_size_string = line.substr(mem_size_begin_pos, mem_size_end_pos - mem_size_begin_pos);
342 mem_size = LongToSize(std::stol(mem_size_string));
343 }
344 break;
345 }
346 if (memset_s(buf, kLineMaxSize, 0, kLineMaxSize) != EOK) {
347 MS_LOG(ERROR) << "Set system meminfo failed.";
348 (void)fclose(file);
349 return 0;
350 }
351 }
352 (void)fclose(file);
353
354 MS_LOG(INFO) << "Get system memory(" << key << "): " << mem_size << " kB";
355 return mem_size * kKBToByte;
356 #endif
357 }
358
GetSystemFreeDiskSize(const std::string & path)359 size_t GetSystemFreeDiskSize(const std::string &path) {
360 #if defined(_WIN32) || defined(_WIN64) || defined(__APPLE__)
361 // Do not implement
362 return 0;
363 #else
364 struct statfs disk_info;
365 int ret = statfs(path.c_str(), &disk_info);
366 if (ret != 0) {
367 MS_LOG(INFO) << "Failed to get disk directory " << path << " size, check whether the directory is created.";
368 return 0;
369 }
370 size_t block_size = static_cast<size_t>(disk_info.f_bsize);
371 size_t fb_size = static_cast<size_t>(disk_info.f_bfree);
372 return block_size * fb_size;
373 #endif
374 }
375
SkipOrResetCopyAction(bool need_reset)376 bool SkipOrResetCopyAction(bool need_reset) {
377 static bool copy_action = false;
378 if (need_reset) {
379 MS_LOG(INFO) << "Step end, reset copy action flag";
380 copy_action = false;
381 return true;
382 }
383 if (!copy_action) {
384 copy_action = true;
385 return true;
386 }
387 return false;
388 }
389
SkipOrResetSyncAction(bool need_reset)390 bool SkipOrResetSyncAction(bool need_reset) {
391 static bool sync_action = false;
392 if (need_reset) {
393 MS_LOG(INFO) << "Step end, reset sync action flag";
394 sync_action = false;
395 return true;
396 }
397 if (!sync_action) {
398 sync_action = true;
399 return true;
400 }
401 return false;
402 }
403
GetPythonStack()404 std::vector<std::tuple<std::string, int, std::string>> GetPythonStack() {
405 std::vector<std::tuple<std::string, int, std::string>> all_stacks;
406 #if !defined(BUILD_LITE)
407 try {
408 const size_t func_name_index = 2;
409 const size_t min_frame_info_size = 3;
410 py::gil_scoped_acquire gil_acquire;
411 py::module traceback_module = py::module::import("traceback");
412 py::list extracted_stack = traceback_module.attr("extract_stack")();
413 for (size_t i = 0; i < extracted_stack.size(); ++i) {
414 py::tuple frame_info = extracted_stack[i].cast<py::tuple>();
415 if (frame_info.size() < min_frame_info_size) {
416 MS_LOG(ERROR) << "frame_info size is invalid, frame_info size:" << frame_info.size();
417 continue;
418 }
419
420 // frame_info: (filename, line number, function name, code_context)
421 std::string file_name = frame_info[0].cast<std::string>();
422 int line_number = frame_info[1].cast<int>();
423 std::string func_name = frame_info[func_name_index].cast<std::string>();
424 (void)all_stacks.emplace_back(std::tuple(file_name, line_number, func_name));
425 }
426 } catch (const std::exception &e) {
427 MS_LOG(ERROR) << "Error while accessing Python stack: " << e.what();
428 }
429 #endif
430
431 return all_stacks;
432 }
433
GetPythonStackStr()434 std::string GetPythonStackStr() {
435 const auto &stacks = GetPythonStack();
436 const size_t func_name_index = 2;
437
438 std::stringstream ss;
439 for (const auto &stack_info : stacks) {
440 ss << "File:" << std::get<0>(stack_info) << ";Line:" << std::get<1>(stack_info)
441 << ";Function:" << std::get<func_name_index>(stack_info) << '|';
442 }
443 return ss.str();
444 }
445 } // namespace mindspore
446