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,187 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import inspect
|
|
3
|
+
import logging
|
|
4
|
+
import psutil
|
|
5
|
+
import torch
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
import torch_npu
|
|
10
|
+
except ImportError:
|
|
11
|
+
pta_cpu_device = None
|
|
12
|
+
else:
|
|
13
|
+
pta_cpu_device = torch.device("cpu")
|
|
14
|
+
|
|
15
|
+
from msprobe.core.common.const import CompareConst, FileCheckConst
|
|
16
|
+
from msprobe.core.common.file_check import change_mode
|
|
17
|
+
|
|
18
|
+
cpu_device = torch._C.device("cpu")
|
|
19
|
+
COLOR_RED = '\033[31m'
|
|
20
|
+
COLOR_GREEN = '\033[32m'
|
|
21
|
+
COLOR_YELLOW = '\033[33m'
|
|
22
|
+
COLOR_BLUE = '\033[34m'
|
|
23
|
+
COLOR_PURPLE = '\033[35m'
|
|
24
|
+
COLOR_CYAN = '\033[36m'
|
|
25
|
+
COLOR_GRAY = '\033[37m'
|
|
26
|
+
COLOR_RESET = '\033[0m'
|
|
27
|
+
|
|
28
|
+
COMPARE_LOGO = '''
|
|
29
|
+
_ _
|
|
30
|
+
___ _ __ | (_)_ __ ___ ___ ___ _ __ ___ _ __ __ _ _ __ ___
|
|
31
|
+
/ _ \\| '_ \\| | | '_ \\ / _ \\ / __/ _ \\| '_ ` _ \\| '_ \\ / _` | '__/ _ \\
|
|
32
|
+
| (_) | | | | | | | | | __/ | (_| (_) | | | | | | |_) | (_| | | | __/
|
|
33
|
+
\\___/|_| |_|_|_|_| |_|\\___| \\___\\___/|_| |_| |_| .__/ \\__,_|_| \\___|
|
|
34
|
+
|_|
|
|
35
|
+
'''
|
|
36
|
+
|
|
37
|
+
CSV_COLUMN_NAME = [CompareConst.NPU_NAME,
|
|
38
|
+
CompareConst.BENCH_NAME,
|
|
39
|
+
CompareConst.NPU_DTYPE,
|
|
40
|
+
CompareConst.BENCH_DTYPE,
|
|
41
|
+
CompareConst.NPU_SHAPE,
|
|
42
|
+
CompareConst.BENCH_SHAPE,
|
|
43
|
+
CompareConst.NPU_MAX,
|
|
44
|
+
CompareConst.NPU_MIN,
|
|
45
|
+
CompareConst.NPU_MEAN,
|
|
46
|
+
CompareConst.BENCH_MAX,
|
|
47
|
+
CompareConst.BENCH_MIN,
|
|
48
|
+
CompareConst.BENCH_MEAN,
|
|
49
|
+
CompareConst.COSINE,
|
|
50
|
+
CompareConst.MAX_ABS_ERR,
|
|
51
|
+
CompareConst.MAX_RELATIVE_ERR,
|
|
52
|
+
CompareConst.ACCURACY,
|
|
53
|
+
CompareConst.STACK,
|
|
54
|
+
CompareConst.ERROR_MESSAGE]
|
|
55
|
+
|
|
56
|
+
FLOAT_TYPE = [np.half, np.single, float, np.double, np.float64, np.longdouble, np.float32, np.float16]
|
|
57
|
+
BOOL_TYPE = [bool, np.uint8]
|
|
58
|
+
INT_TYPE = [np.int32, np.int64]
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def get_callstack():
|
|
62
|
+
callstack = []
|
|
63
|
+
for (_, path, line, func, code, _) in inspect.stack()[2:]:
|
|
64
|
+
if code:
|
|
65
|
+
stack_line = [path, str(line), func, code[0].strip() if code else code]
|
|
66
|
+
else:
|
|
67
|
+
stack_line = [path, str(line), func, code]
|
|
68
|
+
callstack.append(stack_line)
|
|
69
|
+
return callstack
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def np_save_data(data, file_name, data_path):
|
|
73
|
+
try:
|
|
74
|
+
if hasattr(data, "numpy"):
|
|
75
|
+
data = data.numpy()
|
|
76
|
+
dump_path = os.path.join(data_path, f'{file_name}.npy')
|
|
77
|
+
np.save(dump_path, data)
|
|
78
|
+
change_mode(dump_path, FileCheckConst.DATA_FILE_AUTHORITY)
|
|
79
|
+
except Exception as e:
|
|
80
|
+
logger_error("save numpy failed, error: {}".format(e))
|
|
81
|
+
finally:
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def data_to_cpu(data, deep, data_cpu):
|
|
86
|
+
global cpu_device
|
|
87
|
+
list_cpu = []
|
|
88
|
+
if isinstance(data, torch.Tensor):
|
|
89
|
+
if data.device == cpu_device or data.device == pta_cpu_device:
|
|
90
|
+
tensor_copy = data.clone().detach()
|
|
91
|
+
else:
|
|
92
|
+
tensor_copy = data.cpu().detach()
|
|
93
|
+
if tensor_copy.dtype in [torch.float16, torch.half, torch.bfloat16]:
|
|
94
|
+
tensor_copy = tensor_copy.float()
|
|
95
|
+
|
|
96
|
+
if deep == 0:
|
|
97
|
+
data_cpu.append(tensor_copy)
|
|
98
|
+
return tensor_copy
|
|
99
|
+
elif isinstance(data, list):
|
|
100
|
+
for v in data:
|
|
101
|
+
list_cpu.append(data_to_cpu(v, deep + 1, data_cpu))
|
|
102
|
+
if deep == 0:
|
|
103
|
+
data_cpu.append(list_cpu)
|
|
104
|
+
return list_cpu
|
|
105
|
+
elif isinstance(data, tuple):
|
|
106
|
+
for v in data:
|
|
107
|
+
list_cpu.append(data_to_cpu(v, deep + 1, data_cpu))
|
|
108
|
+
tuple_cpu = tuple(list_cpu)
|
|
109
|
+
if deep == 0:
|
|
110
|
+
data_cpu.append(tuple_cpu)
|
|
111
|
+
return tuple_cpu
|
|
112
|
+
elif isinstance(data, dict):
|
|
113
|
+
dict_cpu = {}
|
|
114
|
+
for k, v in data.items():
|
|
115
|
+
dict_cpu[k] = data_to_cpu(v, deep + 1, data_cpu)
|
|
116
|
+
if deep == 0:
|
|
117
|
+
data_cpu.append(dict_cpu)
|
|
118
|
+
return dict_cpu
|
|
119
|
+
elif isinstance(data, torch._C.device):
|
|
120
|
+
return cpu_device
|
|
121
|
+
else:
|
|
122
|
+
if deep == 0:
|
|
123
|
+
data_cpu.append(data)
|
|
124
|
+
return data
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def get_mp_logger():
|
|
128
|
+
logger = logging.getLogger(__name__)
|
|
129
|
+
if not logger.handlers:
|
|
130
|
+
logger.setLevel(logging.INFO)
|
|
131
|
+
handler = logging.StreamHandler()
|
|
132
|
+
formatter = logging.Formatter('%(asctime)s %(message)s')
|
|
133
|
+
logger.propagate = True
|
|
134
|
+
handler.setFormatter(formatter)
|
|
135
|
+
logger.addHandler(handler)
|
|
136
|
+
return logger.info
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def logger_debug(mesg):
|
|
140
|
+
logger = get_mp_logger()
|
|
141
|
+
logger(f'DEBUG ' + mesg)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def logger_info(mesg):
|
|
145
|
+
logger = get_mp_logger()
|
|
146
|
+
logger(f'INFO ' + mesg)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def logger_warn(mesg):
|
|
150
|
+
logger = get_mp_logger()
|
|
151
|
+
logger(f'{COLOR_YELLOW}WARNING {mesg} {COLOR_RESET}')
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def logger_error(mesg):
|
|
155
|
+
logger = get_mp_logger()
|
|
156
|
+
logger(f'{COLOR_RED}ERROR {mesg} {COLOR_RESET}')
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def logger_user(mesg):
|
|
160
|
+
logger = get_mp_logger()
|
|
161
|
+
logger(mesg)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def logger_logo():
|
|
165
|
+
logger_user(f'{COLOR_CYAN}{COMPARE_LOGO} {COLOR_RESET}')
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def get_sys_info():
|
|
169
|
+
mem = psutil.virtual_memory()
|
|
170
|
+
cpu_percent = psutil.cpu_percent(interval=1)
|
|
171
|
+
sys_info = f'Total: {mem.total / 1024 / 1024:.2f}MB ' \
|
|
172
|
+
f'Free: {mem.available / 1024 / 1024:.2f} MB ' \
|
|
173
|
+
f'Used: {mem.used / 1024 / 1024:.2f} MB ' \
|
|
174
|
+
f'CPU: {cpu_percent}% '
|
|
175
|
+
return sys_info
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class DispatchException(Exception):
|
|
179
|
+
INVALID_PARAMETER = 0
|
|
180
|
+
|
|
181
|
+
def __init__(self, err_code, err_msg=""):
|
|
182
|
+
super(DispatchException, self).__init__()
|
|
183
|
+
self.err_code = err_code
|
|
184
|
+
self.err_msg = err_msg
|
|
185
|
+
|
|
186
|
+
def __str__(self):
|
|
187
|
+
return self.err_msg
|
msprobe/pytorch/parse.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
# Copyright (C) 2022-2024. 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
|
+
from msprobe.pytorch.parse_tool.lib.interactive_cli import InteractiveCli
|
|
18
|
+
from msprobe.pytorch.common.log import logger
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _run_interactive_cli(cli=None):
|
|
22
|
+
logger.info("Interactive command mode")
|
|
23
|
+
if not cli:
|
|
24
|
+
cli = InteractiveCli()
|
|
25
|
+
try:
|
|
26
|
+
cli.cmdloop(intro="Start Parsing........")
|
|
27
|
+
except KeyboardInterrupt:
|
|
28
|
+
logger.info("Exit parsing.......")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def parse():
|
|
32
|
+
_run_interactive_cli()
|
|
File without changes
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
# Copyright (C) 2022-2024. 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
|
+
|
|
18
|
+
import os
|
|
19
|
+
import time
|
|
20
|
+
import numpy as np
|
|
21
|
+
from collections import namedtuple
|
|
22
|
+
from msprobe.pytorch.parse_tool.lib.utils import Util
|
|
23
|
+
from msprobe.pytorch.parse_tool.lib.config import Const
|
|
24
|
+
from msprobe.pytorch.parse_tool.lib.parse_exception import ParseException
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Compare:
|
|
28
|
+
def __init__(self):
|
|
29
|
+
self.util = Util()
|
|
30
|
+
self.log = self.util.log
|
|
31
|
+
self.vector_compare_result = {}
|
|
32
|
+
|
|
33
|
+
def npu_vs_npu_compare(self, my_dump_path, golden_dump_path, result_dir, msaccucmp_path):
|
|
34
|
+
self.log.info("Start Compare ...............")
|
|
35
|
+
self.compare_vector(my_dump_path, golden_dump_path, result_dir, msaccucmp_path)
|
|
36
|
+
self.log.info("Compare finished!!")
|
|
37
|
+
|
|
38
|
+
def compare_vector(self, my_dump_path, golden_dump_path, result_dir, msaccucmp_path):
|
|
39
|
+
self.util.create_dir(result_dir)
|
|
40
|
+
self.util.check_path_valid(result_dir)
|
|
41
|
+
call_msaccucmp = self.util.check_msaccucmp(msaccucmp_path)
|
|
42
|
+
cmd = '%s %s compare -m %s -g %s -out %s' % (
|
|
43
|
+
self.util.python, call_msaccucmp, my_dump_path, golden_dump_path, result_dir
|
|
44
|
+
)
|
|
45
|
+
return self.util.execute_command(cmd)
|
|
46
|
+
|
|
47
|
+
def convert_dump_to_npy(self, dump_file, data_format, output, msaccucmp_path):
|
|
48
|
+
dump_file = self.util.path_strip(dump_file)
|
|
49
|
+
file_name = ""
|
|
50
|
+
if os.path.isfile(dump_file):
|
|
51
|
+
self.log.info("Covert file is: %s", dump_file)
|
|
52
|
+
file_name = os.path.basename(dump_file)
|
|
53
|
+
elif os.path.isdir(dump_file):
|
|
54
|
+
self.log.info("Convert all files in path: %s", dump_file)
|
|
55
|
+
file_name = ""
|
|
56
|
+
output = output if output else Const.DUMP_CONVERT_DIR
|
|
57
|
+
convert = self.convert(dump_file, data_format, output, msaccucmp_path)
|
|
58
|
+
if convert == 0:
|
|
59
|
+
convert_files = self.util.list_convert_files(output, file_name)
|
|
60
|
+
|
|
61
|
+
summary_txt = ["SrcFile: %s" % dump_file]
|
|
62
|
+
for convert_file in convert_files.values():
|
|
63
|
+
summary_txt.append(" - %s" % convert_file.file_name)
|
|
64
|
+
self.log.info("Transfer result is saved in : %s", os.path.realpath(output))
|
|
65
|
+
self.util.print_panel("\n".join(summary_txt))
|
|
66
|
+
|
|
67
|
+
def convert(self, dump_file, data_format, output, msaccucmp_path):
|
|
68
|
+
self.util.create_dir(output)
|
|
69
|
+
self.util.check_path_valid(output)
|
|
70
|
+
call_msaccucmp = self.util.check_msaccucmp(msaccucmp_path)
|
|
71
|
+
if data_format:
|
|
72
|
+
cmd = '%s %s convert -d %s -out %s -f %s' % (
|
|
73
|
+
self.util.python, call_msaccucmp, dump_file, output, data_format
|
|
74
|
+
)
|
|
75
|
+
else:
|
|
76
|
+
cmd = '%s %s convert -d %s -out %s' % (
|
|
77
|
+
self.util.python, call_msaccucmp, dump_file, output
|
|
78
|
+
)
|
|
79
|
+
return self.util.execute_command(cmd)
|
|
80
|
+
|
|
81
|
+
def compare_data(self, args):
|
|
82
|
+
"""Compare data"""
|
|
83
|
+
(left, right, save_txt, rl, al, diff_count) = args
|
|
84
|
+
if left is None or right is None:
|
|
85
|
+
raise ParseException("invalid input or output")
|
|
86
|
+
try:
|
|
87
|
+
left_data = np.load(left)
|
|
88
|
+
right_data = np.load(right)
|
|
89
|
+
except UnicodeError as e:
|
|
90
|
+
self.log.error("%s %s" % ("UnicodeError", str(e)))
|
|
91
|
+
self.log.warning("Please check the npy file")
|
|
92
|
+
raise ParseException(ParseException.PARSE_UNICODE_ERROR) from e
|
|
93
|
+
except IOError:
|
|
94
|
+
self.log.error("Failed to load npy %s or %s." % (left, right))
|
|
95
|
+
raise ParseException(ParseException.PARSE_LOAD_NPY_ERROR) from e
|
|
96
|
+
|
|
97
|
+
# save to txt
|
|
98
|
+
if save_txt:
|
|
99
|
+
self.util.save_npy_to_txt(left_data, left + ".txt")
|
|
100
|
+
self.util.save_npy_to_txt(right_data, right + ".txt")
|
|
101
|
+
# compare data
|
|
102
|
+
(total_cnt, all_close, cos_sim, err_percent) = self.do_compare_data(left_data, right_data, rl, al, diff_count)
|
|
103
|
+
content = ['Left:', ' ├─ NpyFile: %s' % left]
|
|
104
|
+
if save_txt:
|
|
105
|
+
content.append(' ├─ TxtFile: [green]%s.txt[/green]' % left)
|
|
106
|
+
content.append(' └─ NpySpec: [yellow]%s[/yellow]' % self.util.gen_npy_info_txt(left_data))
|
|
107
|
+
content.append('Right:')
|
|
108
|
+
content.append(' ├─ NpyFile: %s' % right)
|
|
109
|
+
if save_txt:
|
|
110
|
+
content.append(' ├─ TxtFile: [green]%s.txt[/green]' % right)
|
|
111
|
+
content.append(' └─ NpySpec: [yellow]%s[/yellow]' % self.util.gen_npy_info_txt(right_data))
|
|
112
|
+
content.append('NumCnt: %s' % total_cnt)
|
|
113
|
+
content.append('AllClose: %s' % all_close)
|
|
114
|
+
content.append('CosSim: %s' % cos_sim)
|
|
115
|
+
content.append('ErrorPer: %s (rl= %s, al= %s)' % (err_percent, rl, al))
|
|
116
|
+
self.util.print_panel("\n".join(content))
|
|
117
|
+
|
|
118
|
+
def do_compare_data(self, left, right, rl=0.001, al=0.001, diff_count=20):
|
|
119
|
+
data_left = left.astype(np.float32)
|
|
120
|
+
data_right = right.astype(np.float32)
|
|
121
|
+
shape_left = data_left.shape
|
|
122
|
+
shape_right = data_right.shape
|
|
123
|
+
if shape_left != shape_right:
|
|
124
|
+
self.log.warning("Data shape not equal: %s vs %s", data_left.shape, data_right.shape)
|
|
125
|
+
data_left = data_left.reshape(-1)
|
|
126
|
+
data_right = data_right.reshape(-1)
|
|
127
|
+
if data_left.shape[0] != data_right.shape[0]:
|
|
128
|
+
self.log.warning("Data size not equal: %s vs %s", data_left.shape, data_right.shape)
|
|
129
|
+
if data_left.shape[0] < data_right.shape[0]:
|
|
130
|
+
data_left = np.pad(data_left, (0, data_right.shape[0] - data_left.shape[0]), 'constant')
|
|
131
|
+
else:
|
|
132
|
+
data_right = np.pad(data_right, (0, data_left.shape[0] - data_right.shape[0]), 'constant')
|
|
133
|
+
all_close = np.allclose(data_left, data_right, atol=al, rtol=rl)
|
|
134
|
+
np.seterr(divide='raise')
|
|
135
|
+
cos_sim = np.dot(data_left, data_right) / (
|
|
136
|
+
np.sqrt(np.dot(data_left, data_left)) * np.sqrt(np.dot(data_right, data_right)))
|
|
137
|
+
err_cnt = 0
|
|
138
|
+
total_cnt = data_left.shape[0]
|
|
139
|
+
diff_table_columns = ['Index', 'Left', 'Right', 'Diff']
|
|
140
|
+
err_table = self.util.create_table("Error Item Table", diff_table_columns)
|
|
141
|
+
top_table = self.util.create_table("Top Item Table", diff_table_columns)
|
|
142
|
+
for i in range(total_cnt):
|
|
143
|
+
abs_diff = abs(data_left[i] - data_right[i])
|
|
144
|
+
if i < diff_count:
|
|
145
|
+
top_table.add_row(str(i), str(data_left[i]), str(data_right[i]), str(abs_diff))
|
|
146
|
+
if abs_diff > (al + rl * abs(data_right[i])):
|
|
147
|
+
if err_cnt < diff_count:
|
|
148
|
+
err_table.add_row(str(i), str(data_left[i]), str(data_right[i]), str(abs_diff))
|
|
149
|
+
err_cnt += 1
|
|
150
|
+
if total_cnt == 0:
|
|
151
|
+
err_percent = float(0)
|
|
152
|
+
else:
|
|
153
|
+
err_percent = float(err_cnt / total_cnt)
|
|
154
|
+
self.util.print(self.util.create_columns([err_table, top_table]))
|
|
155
|
+
do_compare_data_result = namedtuple('do_compare_data_result', ['cnt', 'close', 'cos', 'err'])
|
|
156
|
+
res = do_compare_data_result(total_cnt, all_close, cos_sim, err_percent)
|
|
157
|
+
return res
|
|
158
|
+
|
|
159
|
+
def compare_npy(self, file, bench_file, output_path):
|
|
160
|
+
data = np.load(file)
|
|
161
|
+
bench_data = np.load(bench_file)
|
|
162
|
+
shape, dtype = data.shape, data.dtype
|
|
163
|
+
bench_shape, bench_dtype = bench_data.shape, bench_data.dtype
|
|
164
|
+
filename = os.path.basename(file)
|
|
165
|
+
bench_filename = os.path.basename(bench_file)
|
|
166
|
+
if shape != bench_shape or dtype != bench_dtype:
|
|
167
|
+
self.log.error(
|
|
168
|
+
"Shape or dtype between two npy files is inconsistent. Please check the two files."
|
|
169
|
+
"File 1: %s, file 2: %s", file, bench_file)
|
|
170
|
+
self.util.deal_with_dir_or_file_inconsistency(output_path)
|
|
171
|
+
return
|
|
172
|
+
md5_consistency = False
|
|
173
|
+
if self.util.get_md5_for_numpy(data) == self.util.get_md5_for_numpy(bench_data):
|
|
174
|
+
md5_consistency = True
|
|
175
|
+
data_mean = np.mean(data)
|
|
176
|
+
bench_data_mean = np.mean(bench_data)
|
|
177
|
+
abs_error = np.abs(data - bench_data)
|
|
178
|
+
bench_data = self.util.deal_with_value_if_has_zero(bench_data)
|
|
179
|
+
rel_error = np.abs(abs_error / bench_data)
|
|
180
|
+
abs_diff_max = abs_error.max()
|
|
181
|
+
rel_diff_max = np.max(rel_error)
|
|
182
|
+
compare_result = [[filename, bench_filename, data_mean, bench_data_mean, md5_consistency, abs_diff_max,
|
|
183
|
+
rel_diff_max]]
|
|
184
|
+
self.util.write_csv(compare_result, output_path)
|
|
185
|
+
|
|
186
|
+
def compare_all_file_in_directory(self, my_dump_dir, golden_dump_dir, output_path):
|
|
187
|
+
if not (self.util.is_subdir_count_equal(my_dump_dir, golden_dump_dir)
|
|
188
|
+
and self.util.check_npy_files_valid_in_dir(my_dump_dir)
|
|
189
|
+
and self.util.check_npy_files_valid_in_dir(golden_dump_dir)):
|
|
190
|
+
self.log.error(
|
|
191
|
+
"Top level(Npy files level) directory structure is inconsistent. Please check the two directory.")
|
|
192
|
+
self.util.deal_with_dir_or_file_inconsistency(output_path)
|
|
193
|
+
return
|
|
194
|
+
my_npy_files = self.util.get_sorted_files_names(my_dump_dir)
|
|
195
|
+
golden_npy_files = self.util.get_sorted_files_names(golden_dump_dir)
|
|
196
|
+
for my_npy_file_name, golden_npy_file_name in zip(my_npy_files, golden_npy_files):
|
|
197
|
+
my_npy_path = os.path.join(my_dump_dir, my_npy_file_name)
|
|
198
|
+
golden_npy_path = os.path.join(golden_dump_dir, golden_npy_file_name)
|
|
199
|
+
self.compare_npy(my_npy_path, golden_npy_path, output_path)
|
|
200
|
+
|
|
201
|
+
def compare_timestamp_directory(self, my_dump_dir, golden_dump_dir, output_path):
|
|
202
|
+
if not self.util.is_subdir_count_equal(my_dump_dir, golden_dump_dir):
|
|
203
|
+
self.log.error(
|
|
204
|
+
"Second level(Timestamp level) directory structure is inconsistent. Please check the two directory.")
|
|
205
|
+
self.util.deal_with_dir_or_file_inconsistency(output_path)
|
|
206
|
+
return
|
|
207
|
+
my_ordered_subdirs = self.util.get_sorted_subdirectories_names(my_dump_dir)
|
|
208
|
+
golden_ordered_subdirs = self.util.get_sorted_subdirectories_names(golden_dump_dir)
|
|
209
|
+
for my_subdir_name, golden_subdir_name in zip(my_ordered_subdirs, golden_ordered_subdirs):
|
|
210
|
+
my_subdir_path = os.path.join(my_dump_dir, my_subdir_name)
|
|
211
|
+
golden_subdir_path = os.path.join(golden_dump_dir, golden_subdir_name)
|
|
212
|
+
self.compare_all_file_in_directory(my_subdir_path, golden_subdir_path, output_path)
|
|
213
|
+
|
|
214
|
+
def compare_converted_dir(self, my_dump_dir, golden_dump_dir, output_dir):
|
|
215
|
+
if not self.util.is_subdir_count_equal(my_dump_dir, golden_dump_dir):
|
|
216
|
+
self.log.error(
|
|
217
|
+
"Top level(Opname level) directory structure is inconsistent. Please check the two directory.")
|
|
218
|
+
return
|
|
219
|
+
timestamp = int(time.time())
|
|
220
|
+
output_file_name = f"batch_compare_{timestamp}.csv"
|
|
221
|
+
output_path = os.path.join(output_dir, output_file_name)
|
|
222
|
+
title_rows = [[
|
|
223
|
+
"NPU File Name",
|
|
224
|
+
"Bench File Name",
|
|
225
|
+
"Mean",
|
|
226
|
+
"Bench Mean",
|
|
227
|
+
"Md5 Consistency",
|
|
228
|
+
"Max Abs Error",
|
|
229
|
+
"Max Relative Error"
|
|
230
|
+
]]
|
|
231
|
+
self.util.write_csv(title_rows, output_path)
|
|
232
|
+
|
|
233
|
+
my_ordered_subdirs = self.util.get_sorted_subdirectories_names(my_dump_dir)
|
|
234
|
+
golden_ordered_subdirs = self.util.get_sorted_subdirectories_names(golden_dump_dir)
|
|
235
|
+
for my_subdir_name, golden_subdir_name in zip(my_ordered_subdirs, golden_ordered_subdirs):
|
|
236
|
+
if not my_subdir_name == golden_subdir_name:
|
|
237
|
+
self.log.error(
|
|
238
|
+
"Top level(Opname level) directory structure is inconsistent. Please check the two directory.")
|
|
239
|
+
self.util.deal_with_dir_or_file_inconsistency(output_path)
|
|
240
|
+
return
|
|
241
|
+
my_subdir_path = os.path.join(my_dump_dir, my_subdir_name)
|
|
242
|
+
golden_subdir_path = os.path.join(golden_dump_dir, golden_subdir_name)
|
|
243
|
+
self.compare_timestamp_directory(my_subdir_path, golden_subdir_path, output_path)
|
|
244
|
+
self.util.change_filemode_safe(output_path)
|
|
245
|
+
self.log.info("Compare result is saved in : %s", output_path)
|
|
246
|
+
|
|
247
|
+
def convert_api_dir_to_npy(self, dump_dir, param, output_dir, msaccucmp_path):
|
|
248
|
+
dump_dir = self.util.path_strip(dump_dir)
|
|
249
|
+
for root, _, files in os.walk(dump_dir):
|
|
250
|
+
for file in files:
|
|
251
|
+
file_path = os.path.join(root, file)
|
|
252
|
+
file_name = os.path.basename(file_path)
|
|
253
|
+
parts = file_name.split(".")
|
|
254
|
+
if len(parts) < 5:
|
|
255
|
+
continue
|
|
256
|
+
op_name = parts[1]
|
|
257
|
+
timestamp = parts[-1]
|
|
258
|
+
output_path = os.path.join(output_dir, op_name, timestamp)
|
|
259
|
+
self.convert_dump_to_npy(file_path, param, output_path, msaccucmp_path)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
# Copyright (C) 2022-2024. 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
|
+
|
|
18
|
+
import os
|
|
19
|
+
import numpy as np
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Const:
|
|
23
|
+
|
|
24
|
+
MS_ACCU_CMP_PATH = '/usr/local/Ascend/ascend-toolkit/latest/tools/operator_cmp/compare/msaccucmp.py'
|
|
25
|
+
MS_ACCU_CMP_FILE_NAME = 'msaccucmp.py'
|
|
26
|
+
ROOT_DIR = ""
|
|
27
|
+
LOG_LEVEL = "NOTSET"
|
|
28
|
+
DATA_ROOT_DIR = os.path.join(ROOT_DIR, 'parse_data')
|
|
29
|
+
DUMP_CONVERT_DIR = os.path.join(DATA_ROOT_DIR, 'dump_convert')
|
|
30
|
+
COMPARE_DIR = os.path.join(DATA_ROOT_DIR, 'compare_result')
|
|
31
|
+
BATCH_DUMP_CONVERT_DIR = os.path.join(DATA_ROOT_DIR, 'batch_dump_convert')
|
|
32
|
+
BATCH_COMPARE_DIR = os.path.join(DATA_ROOT_DIR, 'batch_compare_result')
|
|
33
|
+
OFFLINE_DUMP_CONVERT_PATTERN = \
|
|
34
|
+
r"^([A-Za-z0-9_-]+)\.([A-Za-z0-9_-]+)\.([0-9]+)(\.[0-9]+)?\.([0-9]{1,255})" \
|
|
35
|
+
r"\.([a-z]+)\.([0-9]{1,255})(\.[x0-9]+)?\.npy$"
|
|
36
|
+
NUMPY_PATTERN = r".*\.npy$"
|
|
37
|
+
NPY_SUFFIX = ".npy"
|
|
38
|
+
PKL_SUFFIX = ".pkl"
|
|
39
|
+
DIRECTORY_LENGTH = 4096
|
|
40
|
+
FILE_NAME_LENGTH = 255
|
|
41
|
+
FILE_PATTERN = r'^[a-zA-Z0-9_./-]+$'
|
|
42
|
+
ONE_GB = 1 * 1024 * 1024 * 1024
|
|
43
|
+
TEN_GB = 10 * 1024 * 1024 * 1024
|
|
44
|
+
FLOAT_TYPE = [np.half, np.single, float, np.double, np.float64, np.longdouble, np.float32, np.float16]
|
|
45
|
+
HEADER = r""" ____
|
|
46
|
+
/ __ \____ ______________
|
|
47
|
+
/ /_/ / __ `/ ___/ ___/ _ \
|
|
48
|
+
/ ____/ /_/ / / (__ ) __/
|
|
49
|
+
/_/ \__,_/_/ /____/\___/
|
|
50
|
+
|
|
51
|
+
"""
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class FileDesc(object):
|
|
6
|
+
def __init__(self, file_name, dir_path, timestamp=-1):
|
|
7
|
+
self.file_name = file_name
|
|
8
|
+
self.dir_path = dir_path
|
|
9
|
+
self.path = os.path.join(dir_path, file_name)
|
|
10
|
+
self.timestamp = timestamp
|
|
11
|
+
self.idx = 0
|
|
12
|
+
if self.timestamp == -1:
|
|
13
|
+
self.timestamp = os.path.getmtime(self.path)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class NpuDumpFileDesc(FileDesc):
|
|
17
|
+
def __init__(self, file_name, dir_path, timestamp, op_name, op_type, task_id, stream_id=0):
|
|
18
|
+
super(NpuDumpFileDesc, self).__init__(file_name, dir_path, timestamp)
|
|
19
|
+
self.op_name = op_name
|
|
20
|
+
self.op_type = op_type
|
|
21
|
+
self.task_id = task_id
|
|
22
|
+
stream_id = 0 if stream_id is None else int(stream_id)
|
|
23
|
+
self.stream_id = stream_id
|
|
24
|
+
self.idx = dir_path.split(os.sep)[-1]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class DumpDecodeFileDesc(NpuDumpFileDesc):
|
|
28
|
+
def __init__(self, file_name, dir_path, timestamp, op_name, op_type, task_id, anchor_type, anchor_idx):
|
|
29
|
+
super(DumpDecodeFileDesc, self).__init__(file_name, dir_path, timestamp, op_name, op_type, task_id)
|
|
30
|
+
self.type = anchor_type
|
|
31
|
+
self.idx = anchor_idx
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
# Copyright (C) 2022-2024. 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 cmd
|
|
18
|
+
import argparse
|
|
19
|
+
from msprobe.pytorch.parse_tool.lib.parse_tool import ParseTool
|
|
20
|
+
from msprobe.pytorch.parse_tool.lib.utils import Util
|
|
21
|
+
from msprobe.pytorch.parse_tool.lib.config import Const
|
|
22
|
+
from msprobe.pytorch.parse_tool.lib.parse_exception import catch_exception
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class InteractiveCli(cmd.Cmd):
|
|
26
|
+
def __init__(self):
|
|
27
|
+
super().__init__()
|
|
28
|
+
self.prompt = "Parse >>> "
|
|
29
|
+
self.parse_tool = ParseTool()
|
|
30
|
+
self.util = Util()
|
|
31
|
+
self.util.print_panel(Const.HEADER)
|
|
32
|
+
self.prepare()
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def _parse_argv(line, insert=None):
|
|
36
|
+
argv = line.split() if line != "" else []
|
|
37
|
+
if "-h" in argv:
|
|
38
|
+
return argv
|
|
39
|
+
if insert is not None and len(argv) and argv[0] != insert:
|
|
40
|
+
argv.insert(0, insert)
|
|
41
|
+
return argv
|
|
42
|
+
|
|
43
|
+
def prepare(self):
|
|
44
|
+
self.parse_tool.prepare()
|
|
45
|
+
|
|
46
|
+
@catch_exception
|
|
47
|
+
def default(self, line=""):
|
|
48
|
+
self.util.execute_command(line)
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
@catch_exception
|
|
52
|
+
def do_run(self, line=""):
|
|
53
|
+
self.util.execute_command(line)
|
|
54
|
+
|
|
55
|
+
@catch_exception
|
|
56
|
+
def do_vc(self, line=""):
|
|
57
|
+
parser = argparse.ArgumentParser()
|
|
58
|
+
parser.add_argument(
|
|
59
|
+
"-m", "--my_dump_path", dest="my_dump_path", default=None,
|
|
60
|
+
help="<Required> my dump path, the data compared with golden data",
|
|
61
|
+
required=True
|
|
62
|
+
)
|
|
63
|
+
parser.add_argument(
|
|
64
|
+
"-g", "--golden_dump_path", dest="golden_dump_path", default=None,
|
|
65
|
+
help="<Required> the golden dump data path",
|
|
66
|
+
required=True
|
|
67
|
+
)
|
|
68
|
+
parser.add_argument(
|
|
69
|
+
"-out", "--output_path", dest="output_path", default=None,
|
|
70
|
+
help="<Optional> the output path",
|
|
71
|
+
required=False
|
|
72
|
+
)
|
|
73
|
+
parser.add_argument(
|
|
74
|
+
"-cmp_path", "--msaccucmp_path", dest="msaccucmp_path", default=None,
|
|
75
|
+
help="<Optional> the msaccucmp.py file path",
|
|
76
|
+
required=False
|
|
77
|
+
)
|
|
78
|
+
args = parser.parse_args(self._parse_argv(line))
|
|
79
|
+
self.util.check_path_valid(args.my_dump_path)
|
|
80
|
+
self.util.check_path_valid(args.golden_dump_path)
|
|
81
|
+
self.util.check_files_in_path(args.my_dump_path)
|
|
82
|
+
self.util.check_files_in_path(args.golden_dump_path)
|
|
83
|
+
if self.util.dir_contains_only(args.my_dump_path, ".npy") and \
|
|
84
|
+
self.util.dir_contains_only(args.golden_dump_path, ".npy"):
|
|
85
|
+
self.parse_tool.do_compare_converted_dir(args)
|
|
86
|
+
else:
|
|
87
|
+
self.parse_tool.do_vector_compare(args)
|
|
88
|
+
|
|
89
|
+
def do_dc(self, line=""):
|
|
90
|
+
self.parse_tool.do_convert_dump(self._parse_argv(line))
|
|
91
|
+
|
|
92
|
+
def do_pt(self, line=""):
|
|
93
|
+
self.parse_tool.do_print_data(self._parse_argv(line))
|
|
94
|
+
|
|
95
|
+
def do_pk(self, line=""):
|
|
96
|
+
self.parse_tool.do_parse_pkl(self._parse_argv(line))
|
|
97
|
+
|
|
98
|
+
def do_cn(self, line=''):
|
|
99
|
+
self.parse_tool.do_compare_data(self._parse_argv(line))
|
|
100
|
+
|
|
101
|
+
def do_cad(self, line=''):
|
|
102
|
+
self.parse_tool.do_convert_api_dir(self._parse_argv(line))
|