mindstudio-probe 1.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mindstudio_probe-1.0.1.dist-info/LICENSE +201 -0
- mindstudio_probe-1.0.1.dist-info/METADATA +30 -0
- mindstudio_probe-1.0.1.dist-info/RECORD +228 -0
- mindstudio_probe-1.0.1.dist-info/WHEEL +5 -0
- mindstudio_probe-1.0.1.dist-info/entry_points.txt +2 -0
- mindstudio_probe-1.0.1.dist-info/top_level.txt +1 -0
- msprobe/README.md +182 -0
- msprobe/__init__.py +0 -0
- msprobe/config/README.md +397 -0
- msprobe/config/config.json +28 -0
- msprobe/config/img/free_benchmark.png +0 -0
- msprobe/core/common/const.py +241 -0
- msprobe/core/common/exceptions.py +88 -0
- msprobe/core/common/file_check.py +265 -0
- msprobe/core/common/log.py +55 -0
- msprobe/core/common/utils.py +516 -0
- msprobe/core/common_config.py +58 -0
- msprobe/core/data_dump/data_collector.py +140 -0
- msprobe/core/data_dump/data_processor/base.py +245 -0
- msprobe/core/data_dump/data_processor/factory.py +61 -0
- msprobe/core/data_dump/data_processor/pytorch_processor.py +346 -0
- msprobe/core/data_dump/json_writer.py +116 -0
- msprobe/core/data_dump/scope.py +178 -0
- msprobe/mindspore/__init__.py +1 -0
- msprobe/mindspore/debugger/__init__.py +0 -0
- msprobe/mindspore/debugger/debugger_config.py +51 -0
- msprobe/mindspore/debugger/precision_debugger.py +32 -0
- msprobe/mindspore/doc/dump.md +65 -0
- msprobe/mindspore/dump/__init__.py +0 -0
- msprobe/mindspore/dump/api_kbk_dump.py +55 -0
- msprobe/mindspore/dump/dump_tool_factory.py +38 -0
- msprobe/mindspore/dump/kernel_graph_dump.py +60 -0
- msprobe/mindspore/ms_config.py +78 -0
- msprobe/mindspore/overflow_check/__init__.py +0 -0
- msprobe/mindspore/overflow_check/kernel_graph_overflow_check.py +45 -0
- msprobe/mindspore/overflow_check/overflow_check_tool_factory.py +32 -0
- msprobe/mindspore/task_handler_factory.py +21 -0
- msprobe/msprobe.py +67 -0
- msprobe/pytorch/__init__.py +4 -0
- msprobe/pytorch/advisor/advisor.py +124 -0
- msprobe/pytorch/advisor/advisor_const.py +59 -0
- msprobe/pytorch/advisor/advisor_result.py +58 -0
- msprobe/pytorch/api_accuracy_checker/.keep +0 -0
- msprobe/pytorch/api_accuracy_checker/__init__.py +0 -0
- msprobe/pytorch/api_accuracy_checker/common/.keep +0 -0
- msprobe/pytorch/api_accuracy_checker/common/__init__.py +0 -0
- msprobe/pytorch/api_accuracy_checker/common/config.py +50 -0
- msprobe/pytorch/api_accuracy_checker/common/utils.py +224 -0
- msprobe/pytorch/api_accuracy_checker/compare/__init__.py +0 -0
- msprobe/pytorch/api_accuracy_checker/compare/algorithm.py +216 -0
- msprobe/pytorch/api_accuracy_checker/compare/api_precision_compare.py +545 -0
- msprobe/pytorch/api_accuracy_checker/compare/api_precision_standard.yaml +133 -0
- msprobe/pytorch/api_accuracy_checker/compare/api_precision_threshold.yaml +390 -0
- msprobe/pytorch/api_accuracy_checker/compare/compare.py +345 -0
- msprobe/pytorch/api_accuracy_checker/compare/compare_column.py +74 -0
- msprobe/pytorch/api_accuracy_checker/compare/compare_utils.py +249 -0
- msprobe/pytorch/api_accuracy_checker/config.yaml +4 -0
- msprobe/pytorch/api_accuracy_checker/run_ut/.keep +0 -0
- msprobe/pytorch/api_accuracy_checker/run_ut/__init__.py +0 -0
- msprobe/pytorch/api_accuracy_checker/run_ut/data_generate.py +328 -0
- msprobe/pytorch/api_accuracy_checker/run_ut/multi_run_ut.py +203 -0
- msprobe/pytorch/api_accuracy_checker/run_ut/run_overflow_check.py +127 -0
- msprobe/pytorch/api_accuracy_checker/run_ut/run_ut.py +493 -0
- msprobe/pytorch/api_accuracy_checker/run_ut/run_ut_utils.py +7 -0
- msprobe/pytorch/api_accuracy_checker/run_ut/torch_ut_setting.json +5 -0
- msprobe/pytorch/common/__init__.py +2 -0
- msprobe/pytorch/common/compare_script.template +14 -0
- msprobe/pytorch/common/log.py +32 -0
- msprobe/pytorch/common/parse_json.py +37 -0
- msprobe/pytorch/common/utils.py +224 -0
- msprobe/pytorch/compare/acc_compare.py +1024 -0
- msprobe/pytorch/compare/distributed_compare.py +111 -0
- msprobe/pytorch/compare/highlight.py +100 -0
- msprobe/pytorch/compare/mapping.yaml +607 -0
- msprobe/pytorch/compare/match.py +36 -0
- msprobe/pytorch/compare/npy_compare.py +244 -0
- msprobe/pytorch/debugger/__init__.py +0 -0
- msprobe/pytorch/debugger/debugger_config.py +86 -0
- msprobe/pytorch/debugger/precision_debugger.py +95 -0
- msprobe/pytorch/doc/FAQ.md +193 -0
- msprobe/pytorch/doc/api_accuracy_checker.md +269 -0
- msprobe/pytorch/doc/atat/321/207/342/226/223/342/225/233/321/205/342/225/221/320/266/321/205/342/225/226/320/265/321/205/320/225/342/225/226/321/206/320/245/342/226/221/321/206/320/235/320/276dump/321/206/320/260/320/227/321/205/320/227/320/226/321/206/320/220/320/267/321/210/320/223/342/225/234/321/205/320/257/342/225/221/321/207/342/225/221/342/224/220/321/206/320/232/320/265/321/205/320/241/320/232.md +182 -0
- msprobe/pytorch/doc/dump.md +207 -0
- msprobe/pytorch/doc/img/BLOOM-7B_1.png +0 -0
- msprobe/pytorch/doc/img/BLOOM-7B_2.png +0 -0
- msprobe/pytorch/doc/img/BLOOM-7B_3.png +0 -0
- msprobe/pytorch/doc/img/BLOOM-7B_4.png +0 -0
- msprobe/pytorch/doc/img/GPT-3_1.png +0 -0
- msprobe/pytorch/doc/img/GPT-3_2.png +0 -0
- msprobe/pytorch/doc/img/GPT-3_3.png +0 -0
- msprobe/pytorch/doc/img/GPT-3_4.png +0 -0
- msprobe/pytorch/doc/img/GPT-3_5.png +0 -0
- msprobe/pytorch/doc/img/GPT-3_6.png +0 -0
- msprobe/pytorch/doc/img/GPT-3_7.png +0 -0
- msprobe/pytorch/doc/img/GPT-3_8.png +0 -0
- msprobe/pytorch/doc/img/YOLOV5S_1.png +0 -0
- msprobe/pytorch/doc/img/YOLOV5S_2.png +0 -0
- msprobe/pytorch/doc/img/accuracy_checking_details.png +0 -0
- msprobe/pytorch/doc/img/accuracy_checking_result.png +0 -0
- msprobe/pytorch/doc/img/api_precision_compare_details.png +0 -0
- msprobe/pytorch/doc/img/api_precision_compare_result.png +0 -0
- msprobe/pytorch/doc/img/auto_analyze_log.png +0 -0
- msprobe/pytorch/doc/img/compare_result_pkl.png +0 -0
- msprobe/pytorch/doc/img/compare_result_pkl_md5.png.png +0 -0
- msprobe/pytorch/doc/img/cpu_info.png +0 -0
- msprobe/pytorch/doc/img/module_compare.png +0 -0
- msprobe/pytorch/doc/parse_tool.md +286 -0
- msprobe/pytorch/doc/ptdbg_ascend_compare.md +176 -0
- msprobe/pytorch/doc/ptdbg_ascend_overview.md +68 -0
- msprobe/pytorch/doc/ptdbg_ascend_quickstart.md +381 -0
- msprobe/pytorch/doc/run_overflow_check.md +25 -0
- msprobe/pytorch/doc//321/205/320/254/320/270/321/207/342/225/221/342/224/220/321/207/342/226/223/342/225/233/321/205/342/225/221/320/266/321/206/320/277/320/244/321/205/320/277/342/225/243.md +90 -0
- msprobe/pytorch/free_benchmark/__init__.py +8 -0
- msprobe/pytorch/free_benchmark/common/__init__.py +0 -0
- msprobe/pytorch/free_benchmark/common/constant.py +67 -0
- msprobe/pytorch/free_benchmark/common/counter.py +72 -0
- msprobe/pytorch/free_benchmark/common/enums.py +37 -0
- msprobe/pytorch/free_benchmark/common/params.py +129 -0
- msprobe/pytorch/free_benchmark/common/utils.py +98 -0
- msprobe/pytorch/free_benchmark/compare/grad_saver.py +183 -0
- msprobe/pytorch/free_benchmark/compare/single_benchmark.py +104 -0
- msprobe/pytorch/free_benchmark/main.py +102 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/__init__.py +0 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/base_layer.py +13 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/layer_factory.py +41 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/__init__.py +0 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/add_noise.py +90 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/bit_noise.py +104 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/change_value.py +63 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/improve_precision.py +68 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/no_change.py +28 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/npu_base_layser.py +45 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/run_cpu.py +19 -0
- msprobe/pytorch/free_benchmark/result_handlers/__init__.py +0 -0
- msprobe/pytorch/free_benchmark/result_handlers/base_handler.py +203 -0
- msprobe/pytorch/free_benchmark/result_handlers/check_handler.py +39 -0
- msprobe/pytorch/free_benchmark/result_handlers/fix_handler.py +24 -0
- msprobe/pytorch/free_benchmark/result_handlers/handler_factory.py +31 -0
- msprobe/pytorch/free_benchmark/result_handlers/preheat_handler.py +170 -0
- msprobe/pytorch/functional/__init__.py +0 -0
- msprobe/pytorch/functional/data_processor.py +0 -0
- msprobe/pytorch/functional/dump_module.py +39 -0
- msprobe/pytorch/hook_module/__init__.py +1 -0
- msprobe/pytorch/hook_module/api_registry.py +161 -0
- msprobe/pytorch/hook_module/hook_module.py +109 -0
- msprobe/pytorch/hook_module/support_wrap_ops.yaml +1876 -0
- msprobe/pytorch/hook_module/utils.py +29 -0
- msprobe/pytorch/hook_module/wrap_aten.py +100 -0
- msprobe/pytorch/hook_module/wrap_distributed.py +75 -0
- msprobe/pytorch/hook_module/wrap_functional.py +108 -0
- msprobe/pytorch/hook_module/wrap_npu_custom.py +73 -0
- msprobe/pytorch/hook_module/wrap_tensor.py +72 -0
- msprobe/pytorch/hook_module/wrap_torch.py +88 -0
- msprobe/pytorch/hook_module/wrap_vf.py +64 -0
- msprobe/pytorch/module_processer.py +98 -0
- msprobe/pytorch/online_dispatch/__init__.py +20 -0
- msprobe/pytorch/online_dispatch/compare.py +236 -0
- msprobe/pytorch/online_dispatch/dispatch.py +274 -0
- msprobe/pytorch/online_dispatch/dump_compare.py +186 -0
- msprobe/pytorch/online_dispatch/single_compare.py +391 -0
- msprobe/pytorch/online_dispatch/torch_ops_config.yaml +50 -0
- msprobe/pytorch/online_dispatch/utils.py +187 -0
- msprobe/pytorch/parse.py +4 -0
- msprobe/pytorch/parse_tool/__init__.py +0 -0
- msprobe/pytorch/parse_tool/cli.py +32 -0
- msprobe/pytorch/parse_tool/lib/__init__.py +0 -0
- msprobe/pytorch/parse_tool/lib/compare.py +259 -0
- msprobe/pytorch/parse_tool/lib/config.py +51 -0
- msprobe/pytorch/parse_tool/lib/file_desc.py +31 -0
- msprobe/pytorch/parse_tool/lib/interactive_cli.py +102 -0
- msprobe/pytorch/parse_tool/lib/parse_exception.py +54 -0
- msprobe/pytorch/parse_tool/lib/parse_tool.py +158 -0
- msprobe/pytorch/parse_tool/lib/utils.py +367 -0
- msprobe/pytorch/parse_tool/lib/visualization.py +90 -0
- msprobe/pytorch/pt_config.py +93 -0
- msprobe/pytorch/service.py +167 -0
- msprobe/test/core_ut/common/test_utils.py +345 -0
- msprobe/test/core_ut/data_dump/test_data_collector.py +47 -0
- msprobe/test/core_ut/data_dump/test_json_writer.py +183 -0
- msprobe/test/core_ut/data_dump/test_scope.py +151 -0
- msprobe/test/core_ut/test_common_config.py +152 -0
- msprobe/test/core_ut/test_file_check.py +218 -0
- msprobe/test/core_ut/test_log.py +109 -0
- msprobe/test/mindspore_ut/test_api_kbk_dump.py +51 -0
- msprobe/test/mindspore_ut/test_debugger_config.py +42 -0
- msprobe/test/mindspore_ut/test_dump_tool_factory.py +51 -0
- msprobe/test/mindspore_ut/test_kernel_graph_dump.py +66 -0
- msprobe/test/mindspore_ut/test_kernel_graph_overflow_check.py +63 -0
- msprobe/test/mindspore_ut/test_ms_config.py +69 -0
- msprobe/test/mindspore_ut/test_overflow_check_tool_factory.py +51 -0
- msprobe/test/mindspore_ut/test_precision_debugger.py +56 -0
- msprobe/test/mindspore_ut/test_task_handler_factory.py +58 -0
- msprobe/test/pytorch_ut/advisor/test_advisor.py +83 -0
- msprobe/test/pytorch_ut/api_accuracy_checker/common/test_common_utils.py +108 -0
- msprobe/test/pytorch_ut/api_accuracy_checker/common/test_config.py +39 -0
- msprobe/test/pytorch_ut/api_accuracy_checker/compare/test_algorithm.py +112 -0
- msprobe/test/pytorch_ut/api_accuracy_checker/compare/test_api_precision_compare.py +77 -0
- msprobe/test/pytorch_ut/api_accuracy_checker/compare/test_compare.py +125 -0
- msprobe/test/pytorch_ut/api_accuracy_checker/compare/test_compare_column.py +10 -0
- msprobe/test/pytorch_ut/api_accuracy_checker/compare/test_compare_utils.py +43 -0
- msprobe/test/pytorch_ut/api_accuracy_checker/run_ut/dump.json +179 -0
- msprobe/test/pytorch_ut/api_accuracy_checker/run_ut/forward.json +63 -0
- msprobe/test/pytorch_ut/api_accuracy_checker/run_ut/test_data_generate.py +99 -0
- msprobe/test/pytorch_ut/api_accuracy_checker/run_ut/test_multi_run_ut.py +115 -0
- msprobe/test/pytorch_ut/api_accuracy_checker/run_ut/test_run_ut.py +72 -0
- msprobe/test/pytorch_ut/compare/test_acc_compare.py +17 -0
- msprobe/test/pytorch_ut/free_benchmark/perturbed_layers/test_perturbed_layser.py +105 -0
- msprobe/test/pytorch_ut/free_benchmark/result_handlers/test_result_handler.py +121 -0
- msprobe/test/pytorch_ut/free_benchmark/test_main.py +101 -0
- msprobe/test/pytorch_ut/functional/test_dump_module.py +15 -0
- msprobe/test/pytorch_ut/hook_module/test_api_registry.py +130 -0
- msprobe/test/pytorch_ut/hook_module/test_hook_module.py +42 -0
- msprobe/test/pytorch_ut/hook_module/test_wrap_aten.py +65 -0
- msprobe/test/pytorch_ut/hook_module/test_wrap_distributed.py +35 -0
- msprobe/test/pytorch_ut/hook_module/test_wrap_functional.py +20 -0
- msprobe/test/pytorch_ut/hook_module/test_wrap_tensor.py +35 -0
- msprobe/test/pytorch_ut/hook_module/test_wrap_torch.py +43 -0
- msprobe/test/pytorch_ut/hook_module/test_wrap_vf.py +11 -0
- msprobe/test/pytorch_ut/test_pt_config.py +69 -0
- msprobe/test/pytorch_ut/test_service.py +59 -0
- msprobe/test/resources/advisor.txt +3 -0
- msprobe/test/resources/compare_result_20230703104808.csv +9 -0
- msprobe/test/resources/compare_result_without_accuracy.csv +9 -0
- msprobe/test/resources/config.yaml +3 -0
- msprobe/test/resources/npu_test.pkl +8 -0
- msprobe/test/run_test.sh +30 -0
- msprobe/test/run_ut.py +58 -0
- msprobe/test/test_module_processer.py +64 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import stat
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
class Const:
|
|
6
|
+
"""
|
|
7
|
+
Class for const
|
|
8
|
+
"""
|
|
9
|
+
SEP = "."
|
|
10
|
+
REGEX_PREFIX_MAX_LENGTH = 20
|
|
11
|
+
REGEX_PREFIX_PATTERN = r"^[a-zA-Z0-9_-]+$"
|
|
12
|
+
FILE_PATTERN = r'^[a-zA-Z0-9_./-]+$'
|
|
13
|
+
COMMA = ","
|
|
14
|
+
FLOAT_EPSILON = np.finfo(float).eps
|
|
15
|
+
OFF = 'OFF'
|
|
16
|
+
BACKWARD = 'backward'
|
|
17
|
+
FORWARD = 'forward'
|
|
18
|
+
|
|
19
|
+
# dump mode
|
|
20
|
+
ALL = "all"
|
|
21
|
+
LIST = "list"
|
|
22
|
+
RANGE = "range"
|
|
23
|
+
STACK = "stack"
|
|
24
|
+
ACL = "acl"
|
|
25
|
+
API_LIST = "api_list"
|
|
26
|
+
API_STACK = "api_stack"
|
|
27
|
+
DUMP_MODE = [ALL, LIST, RANGE, STACK, ACL, API_LIST, API_STACK]
|
|
28
|
+
SUMMARY = "summary"
|
|
29
|
+
MD5 = "md5"
|
|
30
|
+
SUMMARY_MODE = [ALL, SUMMARY, MD5]
|
|
31
|
+
|
|
32
|
+
WRITE_FLAGS = os.O_WRONLY | os.O_CREAT
|
|
33
|
+
WRITE_MODES = stat.S_IWUSR | stat.S_IRUSR
|
|
34
|
+
OVERWRITE_FLAGS = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
|
|
35
|
+
|
|
36
|
+
PKL_SUFFIX = ".pkl"
|
|
37
|
+
NUMPY_SUFFIX = ".npy"
|
|
38
|
+
ONE_GB = 1073741824 # 1 * 1024 * 1024 * 1024
|
|
39
|
+
TEN_GB = 10737418240 # 10 * 1024 * 1024 * 1024
|
|
40
|
+
FILE_PATTERN = r'^[a-zA-Z0-9_./-]+$'
|
|
41
|
+
DISTRIBUTED_PREFIX_LENGTH = 60
|
|
42
|
+
# env dump path
|
|
43
|
+
KWARGS = 'kwargs'
|
|
44
|
+
INPUT = 'input'
|
|
45
|
+
OUTPUT = 'output'
|
|
46
|
+
INPUT_ARGS = 'input_args'
|
|
47
|
+
INPUT_KWARGS = 'input_kwargs'
|
|
48
|
+
GRAD_INPUT = 'grad_input'
|
|
49
|
+
GRAD_OUTPUT = 'grad_output'
|
|
50
|
+
START = "start"
|
|
51
|
+
STOP = "stop"
|
|
52
|
+
ENV_ENABLE = "1"
|
|
53
|
+
ENV_DISABLE = "0"
|
|
54
|
+
MAX_SEED_VALUE = 4294967295 # 2**32 - 1
|
|
55
|
+
TASK_LIST = ["tensor", "statistics", "overflow_check", "free_benchmark"]
|
|
56
|
+
LEVEL_LIST = ["L0", "L1", "L2", "mix"]
|
|
57
|
+
STATISTICS = "statistics"
|
|
58
|
+
TENSOR = "tensor"
|
|
59
|
+
OVERFLOW_CHECK = "overflow_check"
|
|
60
|
+
FREE_BENCHMARK = "free_benchmark"
|
|
61
|
+
ATTR_NAME_PREFIX = "wrap_"
|
|
62
|
+
KERNEL_DUMP = "kernel_dump"
|
|
63
|
+
DATA = "data"
|
|
64
|
+
PT_FRAMEWORK = "pytorch"
|
|
65
|
+
MS_FRAMEWORK = "mindspore"
|
|
66
|
+
DIRECTORY_LENGTH = 4096
|
|
67
|
+
FILE_NAME_LENGTH = 255
|
|
68
|
+
FLOAT_TYPE = [np.half, np.single, float, np.double, np.float64, np.longdouble, np.float32, np.float16]
|
|
69
|
+
BOOL_TYPE = [bool, np.uint8]
|
|
70
|
+
INT_TYPE = [np.int32, np.int64]
|
|
71
|
+
NPU = 'NPU'
|
|
72
|
+
DISTRIBUTED = 'Distributed'
|
|
73
|
+
|
|
74
|
+
INPLACE_LIST = [
|
|
75
|
+
"broadcast", "all_reduce", "reduce", "all_gather", "gather", "scatter", "reduce_scatter",
|
|
76
|
+
"_reduce_scatter_base", "_all_gather_base", "send", "recv", "irecv", "isend", "all_to_all_single"
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
CONVERT = {
|
|
80
|
+
"int32_to_int64": ["torch.int32", "torch.int64"],
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
CONVERT_API = {
|
|
84
|
+
"int32_to_int64": ["cross_entropy"]
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
class CompareConst:
|
|
88
|
+
"""
|
|
89
|
+
Class for compare module const
|
|
90
|
+
"""
|
|
91
|
+
SPACE = " "
|
|
92
|
+
# compare result column name
|
|
93
|
+
NPU_NAME = "NPU Name"
|
|
94
|
+
BENCH_NAME = "Bench Name"
|
|
95
|
+
NPU_DTYPE = "NPU Dtype"
|
|
96
|
+
BENCH_DTYPE = "Bench Dtype"
|
|
97
|
+
NPU_SHAPE = "NPU Tensor Shape"
|
|
98
|
+
BENCH_SHAPE = "Bench Tensor Shape"
|
|
99
|
+
NPU_MAX = "NPU max"
|
|
100
|
+
NPU_MIN = "NPU min"
|
|
101
|
+
NPU_MEAN = "NPU mean"
|
|
102
|
+
NPU_NORM = "NPU l2norm"
|
|
103
|
+
BENCH_MAX = "Bench max"
|
|
104
|
+
BENCH_MIN = "Bench min"
|
|
105
|
+
BENCH_MEAN = "Bench mean"
|
|
106
|
+
BENCH_NORM = "Bench l2norm"
|
|
107
|
+
MAX_DIFF = "Max diff"
|
|
108
|
+
MIN_DIFF = "Min diff"
|
|
109
|
+
MEAN_DIFF = "Mean diff"
|
|
110
|
+
NORM_DIFF = "L2norm diff"
|
|
111
|
+
COSINE = "Cosine"
|
|
112
|
+
MAX_ABS_ERR = "MaxAbsErr"
|
|
113
|
+
MAX_RELATIVE_ERR = "MaxRelativeErr"
|
|
114
|
+
MIN_RELATIVE_ERR = "MinRelativeErr"
|
|
115
|
+
MEAN_RELATIVE_ERR = "MeanRelativeErr"
|
|
116
|
+
NORM_RELATIVE_ERR = "NormRelativeErr"
|
|
117
|
+
ACCURACY = "Accuracy Reached or Not"
|
|
118
|
+
STACK = "NPU_Stack_Info"
|
|
119
|
+
DATA_NAME = "Data_name"
|
|
120
|
+
ERROR_MESSAGE = "Err_message"
|
|
121
|
+
ONE_THOUSANDTH_ERR_RATIO = "One Thousandth Err Ratio"
|
|
122
|
+
FIVE_THOUSANDTHS_ERR_RATIO = "Five Thousandths Err Ratio"
|
|
123
|
+
NPU_MD5 = "NPU MD5"
|
|
124
|
+
BENCH_MD5 = "BENCH MD5"
|
|
125
|
+
RESULT = "Result"
|
|
126
|
+
|
|
127
|
+
COMPARE_RESULT_HEADER = [
|
|
128
|
+
NPU_NAME, BENCH_NAME, NPU_DTYPE, BENCH_DTYPE, NPU_SHAPE, BENCH_SHAPE, COSINE, MAX_ABS_ERR, MAX_RELATIVE_ERR,
|
|
129
|
+
ONE_THOUSANDTH_ERR_RATIO, FIVE_THOUSANDTHS_ERR_RATIO,
|
|
130
|
+
NPU_MAX, NPU_MIN, NPU_MEAN, NPU_NORM, BENCH_MAX, BENCH_MIN, BENCH_MEAN, BENCH_NORM, ACCURACY, ERROR_MESSAGE
|
|
131
|
+
]
|
|
132
|
+
|
|
133
|
+
SUMMARY_COMPARE_RESULT_HEADER = [
|
|
134
|
+
NPU_NAME, BENCH_NAME, NPU_DTYPE, BENCH_DTYPE, NPU_SHAPE, BENCH_SHAPE, MAX_DIFF, MIN_DIFF, MEAN_DIFF, NORM_DIFF,
|
|
135
|
+
MAX_RELATIVE_ERR, MIN_RELATIVE_ERR, MEAN_RELATIVE_ERR, NORM_RELATIVE_ERR,
|
|
136
|
+
NPU_MAX, NPU_MIN, NPU_MEAN, NPU_NORM, BENCH_MAX, BENCH_MIN, BENCH_MEAN, BENCH_NORM, RESULT, ERROR_MESSAGE
|
|
137
|
+
]
|
|
138
|
+
|
|
139
|
+
MD5_COMPARE_RESULT_HEADER = [
|
|
140
|
+
NPU_NAME, BENCH_NAME, NPU_DTYPE, BENCH_DTYPE, NPU_SHAPE, BENCH_SHAPE, NPU_MD5, BENCH_MD5, RESULT
|
|
141
|
+
]
|
|
142
|
+
|
|
143
|
+
# compare standard
|
|
144
|
+
HUNDRED_RATIO_THRESHOLD = 0.01
|
|
145
|
+
THOUSAND_RATIO_THRESHOLD = 0.001
|
|
146
|
+
FIVE_THOUSAND_RATIO_THRESHOLD = 0.005
|
|
147
|
+
TEN_THOUSAND_RATIO_THRESHOLD = 0.0001
|
|
148
|
+
COSINE_THRESHOLD = 0.9999
|
|
149
|
+
ULP_FLOAT32_THRESHOLD = 32
|
|
150
|
+
ULP_FLOAT16_THRESHOLD = 1
|
|
151
|
+
|
|
152
|
+
# compare result data
|
|
153
|
+
READ_NONE = 'No data'
|
|
154
|
+
NONE = 'None'
|
|
155
|
+
SHAPE_UNMATCH = 'shape unmatched'
|
|
156
|
+
DIFF = 'Different'
|
|
157
|
+
UNSUPPORTED = 'unsupported'
|
|
158
|
+
NAN = 'Nan'
|
|
159
|
+
PASS = 'pass'
|
|
160
|
+
WARNING = 'Warning'
|
|
161
|
+
ERROR = 'error'
|
|
162
|
+
SKIP = 'SKIP'
|
|
163
|
+
BFLOAT16_MIN = -3.3895313892515355e+38
|
|
164
|
+
BFLOAT16_MAX = 3.3895313892515355e+38
|
|
165
|
+
BFLOAT16_EPS = 3.90625e-3 # 2 ** -8
|
|
166
|
+
|
|
167
|
+
# accuracy standards
|
|
168
|
+
COS_THRESHOLD = 0.99
|
|
169
|
+
MAX_ABS_ERR_THRESHOLD = 0.001
|
|
170
|
+
COS_MAX_THRESHOLD = 0.9
|
|
171
|
+
MAX_ABS_ERR_MAX_THRESHOLD = 1
|
|
172
|
+
ACCURACY_CHECK_YES = "Yes"
|
|
173
|
+
ACCURACY_CHECK_NO = "No"
|
|
174
|
+
ACCURACY_CHECK_UNMATCH = "Unmatched"
|
|
175
|
+
|
|
176
|
+
# error message
|
|
177
|
+
NO_BENCH = "No bench data matched."
|
|
178
|
+
|
|
179
|
+
# compare const
|
|
180
|
+
FLOAT_TYPE = [np.half, np.single, float, np.double, np.float64, np.longdouble]
|
|
181
|
+
|
|
182
|
+
# highlight xlsx color const
|
|
183
|
+
RED = "FFFF0000"
|
|
184
|
+
YELLOW = "FFFF00"
|
|
185
|
+
BLUE = "0000FF"
|
|
186
|
+
|
|
187
|
+
# highlight rules const
|
|
188
|
+
OVERFLOW_LIST = ['nan\t', 'inf\t', '-inf\t', 'nan', 'inf', '-inf']
|
|
189
|
+
MAX_DIFF_RED = 1e+10
|
|
190
|
+
ORDER_MAGNITUDE_DIFF_YELLOW = 1
|
|
191
|
+
ONE_THOUSAND_ERROR_IN_RED = 0.9
|
|
192
|
+
ONE_THOUSAND_ERROR_OUT_RED = 0.6
|
|
193
|
+
ONE_THOUSAND_ERROR_DIFF_YELLOW = 0.1
|
|
194
|
+
COSINE_DIFF_YELLOW = 0.1
|
|
195
|
+
MAX_RELATIVE_OUT_RED = 0.5
|
|
196
|
+
MAX_RELATIVE_OUT_YELLOW = 0.1
|
|
197
|
+
MAX_RELATIVE_IN_YELLOW = 0.01
|
|
198
|
+
|
|
199
|
+
class FileCheckConst:
|
|
200
|
+
"""
|
|
201
|
+
Class for file check const
|
|
202
|
+
"""
|
|
203
|
+
READ_ABLE = "read"
|
|
204
|
+
WRITE_ABLE = "write"
|
|
205
|
+
READ_WRITE_ABLE = "read and write"
|
|
206
|
+
DIRECTORY_LENGTH = 4096
|
|
207
|
+
FILE_NAME_LENGTH = 255
|
|
208
|
+
FILE_VALID_PATTERN = r"^[a-zA-Z0-9_.:/-]+$"
|
|
209
|
+
FILE_PATTERN = r'^[a-zA-Z0-9_./-]+$'
|
|
210
|
+
PKL_SUFFIX = ".pkl"
|
|
211
|
+
NUMPY_SUFFIX = ".npy"
|
|
212
|
+
JSON_SUFFIX = ".json"
|
|
213
|
+
PT_SUFFIX = ".pt"
|
|
214
|
+
CSV_SUFFIX = ".csv"
|
|
215
|
+
YAML_SUFFIX = ".yaml"
|
|
216
|
+
MAX_PKL_SIZE = 1073741824 # 1 * 1024 * 1024 * 1024
|
|
217
|
+
MAX_NUMPY_SIZE = 10737418240 # 10 * 1024 * 1024 * 1024
|
|
218
|
+
MAX_JSON_SIZE = 1073741824 # 1 * 1024 * 1024 * 1024
|
|
219
|
+
MAX_PT_SIZE = 10737418240 # 10 * 1024 * 1024 * 1024
|
|
220
|
+
MAX_CSV_SIZE = 1073741824 # 1 * 1024 * 1024 * 1024
|
|
221
|
+
MAX_YAML_SIZE = 1048576 # 10 * 1024 * 1024
|
|
222
|
+
DIR = "dir"
|
|
223
|
+
FILE = "file"
|
|
224
|
+
DATA_DIR_AUTHORITY = 0o750
|
|
225
|
+
DATA_FILE_AUTHORITY = 0o640
|
|
226
|
+
FILE_SIZE_DICT = {
|
|
227
|
+
PKL_SUFFIX: MAX_PKL_SIZE,
|
|
228
|
+
NUMPY_SUFFIX: MAX_NUMPY_SIZE,
|
|
229
|
+
JSON_SUFFIX: MAX_JSON_SIZE,
|
|
230
|
+
PT_SUFFIX: MAX_PT_SIZE,
|
|
231
|
+
CSV_SUFFIX: MAX_CSV_SIZE,
|
|
232
|
+
YAML_SUFFIX: MAX_YAML_SIZE
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
class OverflowConst:
|
|
236
|
+
"""
|
|
237
|
+
Class for Overflow
|
|
238
|
+
"""
|
|
239
|
+
OVERFLOW_DEBUG_MODE_ENABLE = "OVERFLOW_DEBUG_MODE_ENABLE"
|
|
240
|
+
OVERFLOW_ORIGINAL_MODE = 0
|
|
241
|
+
OVERFLOW_DEBUG_MODE = 1
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
class CodedException(Exception):
|
|
2
|
+
def __init__(self, code, error_info=''):
|
|
3
|
+
super().__init__()
|
|
4
|
+
self.code = code
|
|
5
|
+
self.error_info = self.err_strs.get(code) + error_info
|
|
6
|
+
|
|
7
|
+
def __str__(self):
|
|
8
|
+
return self.error_info
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MsaccException(CodedException):
|
|
12
|
+
INVALID_PARAM_ERROR = 0
|
|
13
|
+
OVERFLOW_NUMS_ERROR = 1
|
|
14
|
+
|
|
15
|
+
err_strs = {
|
|
16
|
+
INVALID_PARAM_ERROR: "[msacc] 无效参数: ",
|
|
17
|
+
OVERFLOW_NUMS_ERROR: "[msacc] 超过预设溢出次数 当前溢出次数:"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class FileCheckException(CodedException):
|
|
22
|
+
INVALID_FILE_ERROR = 0
|
|
23
|
+
FILE_PERMISSION_ERROR = 1
|
|
24
|
+
SOFT_LINK_ERROR = 2
|
|
25
|
+
ILLEGAL_PATH_ERROR = 3
|
|
26
|
+
ILLEGAL_PARAM_ERROR = 4
|
|
27
|
+
FILE_TOO_LARGE_ERROR = 5
|
|
28
|
+
|
|
29
|
+
err_strs = {
|
|
30
|
+
SOFT_LINK_ERROR: "[msacc] 检测到软链接: ",
|
|
31
|
+
FILE_PERMISSION_ERROR: "[msacc] 文件权限错误: ",
|
|
32
|
+
INVALID_FILE_ERROR: "[msacc] 无效文件: ",
|
|
33
|
+
ILLEGAL_PATH_ERROR: "[msacc] 非法文件路径: ",
|
|
34
|
+
ILLEGAL_PARAM_ERROR: "[msacc] 非法打开方式: ",
|
|
35
|
+
FILE_TOO_LARGE_ERROR: "[msacc] 文件过大: "
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ParseJsonException(CodedException):
|
|
40
|
+
UnexpectedNameStruct = 0
|
|
41
|
+
InvalidDumpJson = 1
|
|
42
|
+
err_strs = {
|
|
43
|
+
UnexpectedNameStruct: "[msacc] Unexpected name in json: ",
|
|
44
|
+
InvalidDumpJson: "[msacc] json格式不正确: ",
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class ScopeException(CodedException):
|
|
49
|
+
InvalidApiStr = 0
|
|
50
|
+
InvalidScope = 1
|
|
51
|
+
ArgConflict = 2
|
|
52
|
+
err_strs = {
|
|
53
|
+
InvalidApiStr: "[msacc] Invalid api_list: ",
|
|
54
|
+
InvalidScope: "[msacc] Invalid scope: ",
|
|
55
|
+
ArgConflict: "[msacc] Scope and api_list conflict: ",
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class RepairException(CodedException):
|
|
60
|
+
InvalidRepairType = 0
|
|
61
|
+
err_strs = {
|
|
62
|
+
InvalidRepairType: "[msacc] Invalid repair_type: "
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class StepException(CodedException):
|
|
67
|
+
InvalidPostProcess = 0
|
|
68
|
+
err_strs = {
|
|
69
|
+
InvalidPostProcess: "[msacc] 错误的step后处理配置: ",
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class FreeBenchmarkException(CodedException):
|
|
74
|
+
UnsupportedType = 0
|
|
75
|
+
InvalidGrad = 1
|
|
76
|
+
err_strs = {
|
|
77
|
+
UnsupportedType: "[msacc] Free benchmark get unsupported type: ",
|
|
78
|
+
InvalidGrad: "[msacc] Free benchmark gradient invalid: ",
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class DistributedNotInitializedError(Exception):
|
|
83
|
+
def __init__(self, msg):
|
|
84
|
+
super().__init__()
|
|
85
|
+
self.msg = msg
|
|
86
|
+
|
|
87
|
+
def __str__(self):
|
|
88
|
+
return self.msg
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
# Copyright (C) 2022-2023. Huawei Technologies Co., Ltd. All rights reserved.
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
"""
|
|
17
|
+
import os
|
|
18
|
+
import re
|
|
19
|
+
|
|
20
|
+
from msprobe.core.common.log import logger
|
|
21
|
+
from msprobe.core.common.exceptions import FileCheckException
|
|
22
|
+
from msprobe.core.common.const import FileCheckConst
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class FileChecker:
|
|
26
|
+
"""
|
|
27
|
+
The class for check file.
|
|
28
|
+
|
|
29
|
+
Attributes:
|
|
30
|
+
file_path: The file or dictionary path to be verified.
|
|
31
|
+
path_type: file or dictionary
|
|
32
|
+
ability(str): FileCheckConst.WRITE_ABLE or FileCheckConst.READ_ABLE to set file has writability or readability
|
|
33
|
+
file_type(str): The correct file type for file
|
|
34
|
+
"""
|
|
35
|
+
def __init__(self, file_path, path_type, ability=None, file_type=None, is_script=True):
|
|
36
|
+
self.file_path = file_path
|
|
37
|
+
self.path_type = self._check_path_type(path_type)
|
|
38
|
+
self.ability = ability
|
|
39
|
+
self.file_type = file_type
|
|
40
|
+
self.is_script = is_script
|
|
41
|
+
|
|
42
|
+
@staticmethod
|
|
43
|
+
def _check_path_type(path_type):
|
|
44
|
+
if path_type not in [FileCheckConst.DIR, FileCheckConst.FILE]:
|
|
45
|
+
logger.error(f'The path_type must be {FileCheckConst.DIR} or {FileCheckConst.FILE}.')
|
|
46
|
+
raise FileCheckException(FileCheckException.ILLEGAL_PARAM_ERROR)
|
|
47
|
+
return path_type
|
|
48
|
+
|
|
49
|
+
def common_check(self):
|
|
50
|
+
"""
|
|
51
|
+
功能:用户校验基本文件权限:软连接、文件长度、是否存在、读写权限、文件属组、文件特殊字符
|
|
52
|
+
注意:文件后缀的合法性,非通用操作,可使用其他独立接口实现
|
|
53
|
+
"""
|
|
54
|
+
check_path_exists(self.file_path)
|
|
55
|
+
check_link(self.file_path)
|
|
56
|
+
self.file_path = os.path.realpath(self.file_path)
|
|
57
|
+
check_path_length(self.file_path)
|
|
58
|
+
check_path_type(self.file_path, self.path_type)
|
|
59
|
+
self.check_path_ability()
|
|
60
|
+
if self.is_script:
|
|
61
|
+
check_path_owner_consistent(self.file_path)
|
|
62
|
+
check_path_pattern_vaild(self.file_path)
|
|
63
|
+
check_common_file_size(self.file_path)
|
|
64
|
+
check_file_suffix(self.file_path, self.file_type)
|
|
65
|
+
return self.file_path
|
|
66
|
+
|
|
67
|
+
def check_path_ability(self):
|
|
68
|
+
if self.ability == FileCheckConst.WRITE_ABLE:
|
|
69
|
+
check_path_writability(self.file_path)
|
|
70
|
+
if self.ability == FileCheckConst.READ_ABLE:
|
|
71
|
+
check_path_readability(self.file_path)
|
|
72
|
+
if self.ability == FileCheckConst.READ_WRITE_ABLE:
|
|
73
|
+
check_path_readability(self.file_path)
|
|
74
|
+
check_path_writability(self.file_path)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class FileOpen:
|
|
78
|
+
"""
|
|
79
|
+
The class for open file by a safe way.
|
|
80
|
+
|
|
81
|
+
Attributes:
|
|
82
|
+
file_path: The file or dictionary path to be opened.
|
|
83
|
+
mode(str): The file open mode
|
|
84
|
+
"""
|
|
85
|
+
SUPPORT_READ_MODE = ["r", "rb"]
|
|
86
|
+
SUPPORT_WRITE_MODE = ["w", "wb", "a", "ab"]
|
|
87
|
+
SUPPORT_READ_WRITE_MODE = ["r+", "rb+", "w+", "wb+", "a+", "ab+"]
|
|
88
|
+
|
|
89
|
+
def __init__(self, file_path, mode, encoding='utf-8'):
|
|
90
|
+
self.file_path = file_path
|
|
91
|
+
self.mode = mode
|
|
92
|
+
self.encoding = encoding
|
|
93
|
+
self._handle = None
|
|
94
|
+
|
|
95
|
+
def __enter__(self):
|
|
96
|
+
self.check_file_path()
|
|
97
|
+
binary_mode = "b"
|
|
98
|
+
if binary_mode not in self.mode:
|
|
99
|
+
self._handle = open(self.file_path, self.mode, encoding=self.encoding)
|
|
100
|
+
else:
|
|
101
|
+
self._handle = open(self.file_path, self.mode)
|
|
102
|
+
return self._handle
|
|
103
|
+
|
|
104
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
105
|
+
if self._handle:
|
|
106
|
+
self._handle.close()
|
|
107
|
+
|
|
108
|
+
def check_file_path(self):
|
|
109
|
+
support_mode = self.SUPPORT_READ_MODE + self.SUPPORT_WRITE_MODE + self.SUPPORT_READ_WRITE_MODE
|
|
110
|
+
if self.mode not in support_mode:
|
|
111
|
+
logger.error("File open not support %s mode" % self.mode)
|
|
112
|
+
raise FileCheckException(FileCheckException.ILLEGAL_PARAM_ERROR)
|
|
113
|
+
check_link(self.file_path)
|
|
114
|
+
self.file_path = os.path.realpath(self.file_path)
|
|
115
|
+
check_path_length(self.file_path)
|
|
116
|
+
self.check_ability_and_owner()
|
|
117
|
+
check_path_pattern_vaild(self.file_path)
|
|
118
|
+
if os.path.exists(self.file_path):
|
|
119
|
+
check_common_file_size(self.file_path)
|
|
120
|
+
|
|
121
|
+
def check_ability_and_owner(self):
|
|
122
|
+
if self.mode in self.SUPPORT_READ_MODE:
|
|
123
|
+
check_path_exists(self.file_path)
|
|
124
|
+
check_path_readability(self.file_path)
|
|
125
|
+
check_path_owner_consistent(self.file_path)
|
|
126
|
+
if self.mode in self.SUPPORT_WRITE_MODE and os.path.exists(self.file_path):
|
|
127
|
+
check_path_writability(self.file_path)
|
|
128
|
+
check_path_owner_consistent(self.file_path)
|
|
129
|
+
if self.mode in self.SUPPORT_READ_WRITE_MODE and os.path.exists(self.file_path):
|
|
130
|
+
check_path_readability(self.file_path)
|
|
131
|
+
check_path_writability(self.file_path)
|
|
132
|
+
check_path_owner_consistent(self.file_path)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def check_link(path):
|
|
136
|
+
abs_path = os.path.abspath(path)
|
|
137
|
+
if os.path.islink(abs_path):
|
|
138
|
+
logger.error('The file path {} is a soft link.'.format(path))
|
|
139
|
+
raise FileCheckException(FileCheckException.SOFT_LINK_ERROR)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def check_path_length(path, name_length=None):
|
|
143
|
+
file_max_name_length = name_length if name_length else FileCheckConst.FILE_NAME_LENGTH
|
|
144
|
+
if len(path) > FileCheckConst.DIRECTORY_LENGTH or \
|
|
145
|
+
len(os.path.basename(path)) > file_max_name_length:
|
|
146
|
+
logger.error('The file path length exceeds limit.')
|
|
147
|
+
raise FileCheckException(FileCheckException.ILLEGAL_PATH_ERROR)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def check_path_exists(path):
|
|
151
|
+
if not os.path.exists(path):
|
|
152
|
+
logger.error('The file path %s does not exist.' % path)
|
|
153
|
+
raise FileCheckException(FileCheckException.ILLEGAL_PATH_ERROR)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def check_path_readability(path):
|
|
157
|
+
if not os.access(path, os.R_OK):
|
|
158
|
+
logger.error('The file path %s is not readable.' % path)
|
|
159
|
+
raise FileCheckException(FileCheckException.FILE_PERMISSION_ERROR)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def check_path_writability(path):
|
|
163
|
+
if not os.access(path, os.W_OK):
|
|
164
|
+
logger.error('The file path %s is not writable.' % path)
|
|
165
|
+
raise FileCheckException(FileCheckException.FILE_PERMISSION_ERROR)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def check_path_executable(path):
|
|
169
|
+
if not os.access(path, os.X_OK):
|
|
170
|
+
logger.error('The file path %s is not executable.' % path)
|
|
171
|
+
raise FileCheckException(FileCheckException.FILE_PERMISSION_ERROR)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def check_other_user_writable(path):
|
|
175
|
+
st = os.stat(path)
|
|
176
|
+
if st.st_mode & 0o002:
|
|
177
|
+
logger.error('The file path %s may be insecure because other users have write permissions. ' % path)
|
|
178
|
+
raise FileCheckException(FileCheckException.FILE_PERMISSION_ERROR)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def check_path_owner_consistent(path):
|
|
182
|
+
file_owner = os.stat(path).st_uid
|
|
183
|
+
if file_owner != os.getuid():
|
|
184
|
+
logger.error('The file path %s may be insecure because is does not belong to you.' % path)
|
|
185
|
+
raise FileCheckException(FileCheckException.FILE_PERMISSION_ERROR)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def check_path_pattern_vaild(path):
|
|
189
|
+
if not re.match(FileCheckConst.FILE_VALID_PATTERN, path):
|
|
190
|
+
logger.error('The file path %s contains special characters.' %(path))
|
|
191
|
+
raise FileCheckException(FileCheckException.ILLEGAL_PATH_ERROR)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def check_file_size(file_path, max_size):
|
|
195
|
+
file_size = os.path.getsize(file_path)
|
|
196
|
+
if file_size >= max_size:
|
|
197
|
+
logger.error(f'The size of file path {file_path} exceeds {max_size} bytes.')
|
|
198
|
+
raise FileCheckException(FileCheckException.FILE_TOO_LARGE_ERROR)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def check_common_file_size(file_path):
|
|
202
|
+
if os.path.isfile(file_path):
|
|
203
|
+
for suffix, max_size in FileCheckConst.FILE_SIZE_DICT.items():
|
|
204
|
+
if file_path.endswith(suffix):
|
|
205
|
+
check_file_size(file_path, max_size)
|
|
206
|
+
break
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def check_file_suffix(file_path, file_suffix):
|
|
210
|
+
if file_suffix:
|
|
211
|
+
if not file_path.endswith(file_suffix):
|
|
212
|
+
logger.error(f"The {file_path} should be a {file_suffix} file!")
|
|
213
|
+
raise FileCheckException(FileCheckException.INVALID_FILE_ERROR)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def check_path_type(file_path, file_type):
|
|
217
|
+
if file_type == FileCheckConst.FILE:
|
|
218
|
+
if not os.path.isfile(file_path):
|
|
219
|
+
logger.error(f"The {file_path} should be a file!")
|
|
220
|
+
raise FileCheckException(FileCheckException.INVALID_FILE_ERROR)
|
|
221
|
+
if file_type == FileCheckConst.DIR:
|
|
222
|
+
if not os.path.isdir(file_path):
|
|
223
|
+
logger.error(f"The {file_path} should be a dictionary!")
|
|
224
|
+
raise FileCheckException(FileCheckException.INVALID_FILE_ERROR)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def create_directory(dir_path):
|
|
228
|
+
"""
|
|
229
|
+
Function Description:
|
|
230
|
+
creating a directory with specified permissions
|
|
231
|
+
Parameter:
|
|
232
|
+
dir_path: directory path
|
|
233
|
+
Exception Description:
|
|
234
|
+
when invalid data throw exception
|
|
235
|
+
"""
|
|
236
|
+
dir_path = os.path.realpath(dir_path)
|
|
237
|
+
try:
|
|
238
|
+
os.makedirs(dir_path, mode=FileCheckConst.DATA_DIR_AUTHORITY, exist_ok=True)
|
|
239
|
+
except OSError as ex:
|
|
240
|
+
raise FileCheckException(FileCheckException.ILLEGAL_PATH_ERROR,
|
|
241
|
+
'Failed to create {}. Please check the path permission or disk space .{}'.format(dir_path, str(ex))) from ex
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def check_path_before_create(path):
|
|
245
|
+
if path_len_exceeds_limit(path):
|
|
246
|
+
raise FileCheckException(FileCheckException.ILLEGAL_PATH_ERROR, 'The file path length exceeds limit.')
|
|
247
|
+
|
|
248
|
+
if not re.match(FileCheckConst.FILE_PATTERN, os.path.realpath(path)):
|
|
249
|
+
raise FileCheckException(FileCheckException.ILLEGAL_PATH_ERROR,
|
|
250
|
+
'The file path {} contains special characters.'.format(path))
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def change_mode(path, mode):
|
|
254
|
+
if not os.path.exists(path) or os.path.islink(path):
|
|
255
|
+
return
|
|
256
|
+
try:
|
|
257
|
+
os.chmod(path, mode)
|
|
258
|
+
except PermissionError as ex:
|
|
259
|
+
raise FileCheckException(FileCheckException.FILE_PERMISSION_ERROR,
|
|
260
|
+
'Failed to change {} authority. {}'.format(path, str(ex))) from ex
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def path_len_exceeds_limit(file_path):
|
|
264
|
+
return len(os.path.realpath(file_path)) > FileCheckConst.DIRECTORY_LENGTH or \
|
|
265
|
+
len(os.path.basename(file_path)) > FileCheckConst.FILE_NAME_LENGTH
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import time
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
class BaseLogger:
|
|
6
|
+
def __init__(self):
|
|
7
|
+
self.warning_level = "WARNING"
|
|
8
|
+
self.error_level = "ERROR"
|
|
9
|
+
self.info_level = "INFO"
|
|
10
|
+
self.rank = None
|
|
11
|
+
|
|
12
|
+
@staticmethod
|
|
13
|
+
def _print_log(level, msg, end='\n'):
|
|
14
|
+
current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
|
15
|
+
pid = os.getpid()
|
|
16
|
+
full_msg = f"{current_time} ({pid}) [{level}] {msg}"
|
|
17
|
+
print(full_msg, end=end)
|
|
18
|
+
sys.stdout.flush()
|
|
19
|
+
|
|
20
|
+
def get_rank(self):
|
|
21
|
+
return self.rank
|
|
22
|
+
|
|
23
|
+
def info(self, msg):
|
|
24
|
+
self._print_log(self.info_level, msg)
|
|
25
|
+
|
|
26
|
+
def error(self, msg):
|
|
27
|
+
self._print_log(self.error_level, msg)
|
|
28
|
+
|
|
29
|
+
def warning(self, msg):
|
|
30
|
+
self._print_log(self.warning_level, msg)
|
|
31
|
+
|
|
32
|
+
def on_rank_0(self, func):
|
|
33
|
+
def func_rank_0(*args, **kwargs):
|
|
34
|
+
current_rank = self.get_rank()
|
|
35
|
+
if current_rank is None or current_rank == 0:
|
|
36
|
+
return func(*args, **kwargs)
|
|
37
|
+
else:
|
|
38
|
+
return None
|
|
39
|
+
return func_rank_0
|
|
40
|
+
|
|
41
|
+
def info_on_rank_0(self, msg):
|
|
42
|
+
return self.on_rank_0(self.info)(msg)
|
|
43
|
+
|
|
44
|
+
def error_on_rank_0(self, msg):
|
|
45
|
+
return self.on_rank_0(self.error)(msg)
|
|
46
|
+
|
|
47
|
+
def warning_on_rank_0(self, msg):
|
|
48
|
+
return self.on_rank_0(self.warning)(msg)
|
|
49
|
+
|
|
50
|
+
def error_log_with_exp(self, msg, exception):
|
|
51
|
+
self.error(msg)
|
|
52
|
+
raise exception
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
logger = BaseLogger()
|