mindspore 2.3.0__cp310-cp310-win_amd64.whl → 2.4.1__cp310-cp310-win_amd64.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.

Potentially problematic release.


This version of mindspore might be problematic. Click here for more details.

Files changed (275) hide show
  1. mindspore/.commit_id +1 -1
  2. mindspore/__init__.py +3 -1
  3. mindspore/_c_dataengine.cp310-win_amd64.pyd +0 -0
  4. mindspore/_c_expression.cp310-win_amd64.pyd +0 -0
  5. mindspore/_c_mindrecord.cp310-win_amd64.pyd +0 -0
  6. mindspore/_checkparam.py +50 -9
  7. mindspore/_extends/parse/compile_config.py +41 -0
  8. mindspore/_extends/parse/parser.py +9 -7
  9. mindspore/_extends/parse/standard_method.py +52 -14
  10. mindspore/_extends/pijit/pijit_func_white_list.py +350 -24
  11. mindspore/amp.py +24 -10
  12. mindspore/common/__init__.py +6 -4
  13. mindspore/common/_pijit_context.py +190 -0
  14. mindspore/common/_register_for_tensor.py +2 -1
  15. mindspore/common/_tensor_overload.py +139 -0
  16. mindspore/common/api.py +102 -87
  17. mindspore/common/dump.py +5 -6
  18. mindspore/common/generator.py +1 -7
  19. mindspore/common/hook_handle.py +14 -26
  20. mindspore/common/initializer.py +51 -15
  21. mindspore/common/mindir_util.py +2 -2
  22. mindspore/common/parameter.py +62 -15
  23. mindspore/common/recompute.py +39 -9
  24. mindspore/common/sparse_tensor.py +7 -3
  25. mindspore/common/tensor.py +183 -37
  26. mindspore/communication/__init__.py +1 -1
  27. mindspore/communication/_comm_helper.py +38 -3
  28. mindspore/communication/comm_func.py +315 -60
  29. mindspore/communication/management.py +14 -14
  30. mindspore/context.py +132 -22
  31. mindspore/dataset/__init__.py +1 -1
  32. mindspore/dataset/audio/__init__.py +1 -1
  33. mindspore/dataset/core/config.py +7 -0
  34. mindspore/dataset/core/validator_helpers.py +7 -0
  35. mindspore/dataset/engine/cache_client.py +1 -1
  36. mindspore/dataset/engine/datasets.py +72 -44
  37. mindspore/dataset/engine/datasets_audio.py +7 -7
  38. mindspore/dataset/engine/datasets_standard_format.py +53 -3
  39. mindspore/dataset/engine/datasets_text.py +20 -20
  40. mindspore/dataset/engine/datasets_user_defined.py +174 -104
  41. mindspore/dataset/engine/datasets_vision.py +33 -33
  42. mindspore/dataset/engine/iterators.py +29 -0
  43. mindspore/dataset/engine/obs/util.py +7 -0
  44. mindspore/dataset/engine/queue.py +114 -60
  45. mindspore/dataset/engine/serializer_deserializer.py +2 -2
  46. mindspore/dataset/engine/validators.py +34 -14
  47. mindspore/dataset/text/__init__.py +1 -4
  48. mindspore/dataset/transforms/__init__.py +0 -3
  49. mindspore/dataset/utils/line_reader.py +2 -0
  50. mindspore/dataset/vision/__init__.py +1 -4
  51. mindspore/dataset/vision/utils.py +1 -1
  52. mindspore/dataset/vision/validators.py +2 -1
  53. mindspore/{nn/extend → experimental/es}/__init__.py +4 -11
  54. mindspore/experimental/es/embedding_service.py +883 -0
  55. mindspore/{nn/layer → experimental/es}/embedding_service_layer.py +218 -30
  56. mindspore/experimental/llm_boost/__init__.py +21 -0
  57. mindspore/{nn/extend/layer → experimental/llm_boost/atb}/__init__.py +4 -8
  58. mindspore/experimental/llm_boost/atb/boost_base.py +211 -0
  59. mindspore/experimental/llm_boost/atb/llama_boost.py +115 -0
  60. mindspore/experimental/llm_boost/atb/qwen_boost.py +101 -0
  61. mindspore/experimental/llm_boost/register.py +129 -0
  62. mindspore/experimental/llm_boost/utils.py +31 -0
  63. mindspore/experimental/optim/adamw.py +85 -0
  64. mindspore/experimental/optim/optimizer.py +3 -0
  65. mindspore/hal/__init__.py +3 -3
  66. mindspore/hal/contiguous_tensors_handle.py +175 -0
  67. mindspore/hal/stream.py +18 -0
  68. mindspore/include/api/model_group.h +13 -1
  69. mindspore/include/api/types.h +10 -10
  70. mindspore/include/dataset/config.h +2 -2
  71. mindspore/include/dataset/constants.h +2 -2
  72. mindspore/include/dataset/execute.h +2 -2
  73. mindspore/include/dataset/vision.h +4 -0
  74. mindspore/log.py +1 -1
  75. mindspore/mindrecord/filewriter.py +68 -51
  76. mindspore/mindspore_backend.dll +0 -0
  77. mindspore/mindspore_common.dll +0 -0
  78. mindspore/mindspore_core.dll +0 -0
  79. mindspore/mindspore_np_dtype.dll +0 -0
  80. mindspore/mindspore_ops.dll +0 -0
  81. mindspore/mint/__init__.py +983 -46
  82. mindspore/mint/distributed/__init__.py +31 -0
  83. mindspore/mint/distributed/distributed.py +254 -0
  84. mindspore/mint/nn/__init__.py +268 -23
  85. mindspore/mint/nn/functional.py +125 -19
  86. mindspore/mint/nn/layer/__init__.py +39 -0
  87. mindspore/mint/nn/layer/activation.py +133 -0
  88. mindspore/mint/nn/layer/normalization.py +477 -0
  89. mindspore/mint/nn/layer/pooling.py +110 -0
  90. mindspore/mint/optim/adamw.py +26 -13
  91. mindspore/mint/special/__init__.py +63 -0
  92. mindspore/multiprocessing/__init__.py +2 -1
  93. mindspore/nn/__init__.py +0 -1
  94. mindspore/nn/cell.py +276 -96
  95. mindspore/nn/layer/activation.py +211 -44
  96. mindspore/nn/layer/basic.py +137 -10
  97. mindspore/nn/layer/embedding.py +137 -2
  98. mindspore/nn/layer/normalization.py +101 -5
  99. mindspore/nn/layer/padding.py +34 -48
  100. mindspore/nn/layer/pooling.py +161 -7
  101. mindspore/nn/layer/transformer.py +3 -3
  102. mindspore/nn/loss/__init__.py +2 -2
  103. mindspore/nn/loss/loss.py +84 -6
  104. mindspore/nn/optim/__init__.py +2 -1
  105. mindspore/nn/optim/adadelta.py +1 -1
  106. mindspore/nn/optim/adam.py +1 -1
  107. mindspore/nn/optim/lamb.py +1 -1
  108. mindspore/nn/optim/tft_wrapper.py +124 -0
  109. mindspore/nn/wrap/cell_wrapper.py +12 -23
  110. mindspore/nn/wrap/grad_reducer.py +5 -5
  111. mindspore/nn/wrap/loss_scale.py +17 -3
  112. mindspore/numpy/__init__.py +1 -1
  113. mindspore/numpy/array_creations.py +65 -68
  114. mindspore/numpy/array_ops.py +64 -60
  115. mindspore/numpy/fft.py +610 -75
  116. mindspore/numpy/logic_ops.py +11 -10
  117. mindspore/numpy/math_ops.py +85 -84
  118. mindspore/numpy/utils_const.py +4 -4
  119. mindspore/opencv_core452.dll +0 -0
  120. mindspore/opencv_imgcodecs452.dll +0 -0
  121. mindspore/opencv_imgproc452.dll +0 -0
  122. mindspore/ops/__init__.py +6 -4
  123. mindspore/ops/_grad_experimental/grad_array_ops.py +0 -11
  124. mindspore/ops/_grad_experimental/grad_comm_ops.py +67 -4
  125. mindspore/ops/_grad_experimental/grad_math_ops.py +0 -22
  126. mindspore/ops/_vmap/vmap_array_ops.py +2 -4
  127. mindspore/ops/_vmap/vmap_math_ops.py +17 -1
  128. mindspore/ops/_vmap/vmap_nn_ops.py +43 -2
  129. mindspore/ops/auto_generate/cpp_create_prim_instance_helper.py +91 -7
  130. mindspore/ops/auto_generate/gen_arg_dtype_cast.py +2 -0
  131. mindspore/ops/auto_generate/gen_extend_func.py +767 -13
  132. mindspore/ops/auto_generate/gen_ops_def.py +2452 -364
  133. mindspore/ops/auto_generate/gen_ops_prim.py +5442 -1756
  134. mindspore/ops/auto_generate/pyboost_inner_prim.py +176 -56
  135. mindspore/ops/composite/base.py +85 -48
  136. mindspore/ops/composite/multitype_ops/_compile_utils.py +1 -0
  137. mindspore/ops/composite/multitype_ops/not_in_impl.py +2 -2
  138. mindspore/ops/function/__init__.py +22 -0
  139. mindspore/ops/function/array_func.py +492 -153
  140. mindspore/ops/function/debug_func.py +113 -1
  141. mindspore/ops/function/fft_func.py +15 -2
  142. mindspore/ops/function/grad/grad_func.py +3 -2
  143. mindspore/ops/function/math_func.py +564 -207
  144. mindspore/ops/function/nn_func.py +817 -383
  145. mindspore/ops/function/other_func.py +3 -2
  146. mindspore/ops/function/random_func.py +402 -12
  147. mindspore/ops/function/reshard_func.py +13 -11
  148. mindspore/ops/function/sparse_unary_func.py +1 -1
  149. mindspore/ops/function/vmap_func.py +3 -2
  150. mindspore/ops/functional.py +24 -14
  151. mindspore/ops/op_info_register.py +3 -3
  152. mindspore/ops/operations/__init__.py +7 -2
  153. mindspore/ops/operations/_grad_ops.py +2 -76
  154. mindspore/ops/operations/_infer_ops.py +1 -1
  155. mindspore/ops/operations/_inner_ops.py +71 -94
  156. mindspore/ops/operations/array_ops.py +14 -146
  157. mindspore/ops/operations/comm_ops.py +63 -53
  158. mindspore/ops/operations/custom_ops.py +83 -19
  159. mindspore/ops/operations/debug_ops.py +42 -10
  160. mindspore/ops/operations/manually_defined/_inner.py +12 -0
  161. mindspore/ops/operations/manually_defined/ops_def.py +273 -20
  162. mindspore/ops/operations/math_ops.py +12 -223
  163. mindspore/ops/operations/nn_ops.py +20 -114
  164. mindspore/ops/operations/other_ops.py +7 -4
  165. mindspore/ops/operations/random_ops.py +46 -1
  166. mindspore/ops/primitive.py +18 -6
  167. mindspore/ops_generate/arg_dtype_cast.py +2 -0
  168. mindspore/ops_generate/gen_aclnn_implement.py +11 -11
  169. mindspore/ops_generate/gen_constants.py +36 -0
  170. mindspore/ops_generate/gen_ops.py +67 -52
  171. mindspore/ops_generate/gen_ops_inner_prim.py +1 -1
  172. mindspore/ops_generate/gen_pyboost_func.py +131 -47
  173. mindspore/ops_generate/op_proto.py +10 -3
  174. mindspore/ops_generate/pyboost_utils.py +14 -1
  175. mindspore/ops_generate/template.py +43 -21
  176. mindspore/parallel/__init__.py +3 -1
  177. mindspore/parallel/_auto_parallel_context.py +31 -9
  178. mindspore/parallel/_cell_wrapper.py +85 -0
  179. mindspore/parallel/_parallel_serialization.py +47 -19
  180. mindspore/parallel/_tensor.py +127 -13
  181. mindspore/parallel/_utils.py +53 -22
  182. mindspore/parallel/algo_parameter_config.py +5 -5
  183. mindspore/parallel/checkpoint_transform.py +46 -39
  184. mindspore/parallel/cluster/process_entity/__init__.py +1 -1
  185. mindspore/parallel/cluster/process_entity/_api.py +31 -23
  186. mindspore/parallel/cluster/process_entity/_utils.py +2 -27
  187. mindspore/parallel/parameter_broadcast.py +3 -4
  188. mindspore/parallel/shard.py +162 -31
  189. mindspore/parallel/transform_safetensors.py +1146 -0
  190. mindspore/profiler/__init__.py +2 -1
  191. mindspore/profiler/common/constant.py +29 -0
  192. mindspore/profiler/common/registry.py +47 -0
  193. mindspore/profiler/common/util.py +28 -0
  194. mindspore/profiler/dynamic_profiler.py +694 -0
  195. mindspore/profiler/envprofiling.py +17 -19
  196. mindspore/profiler/parser/ascend_analysis/constant.py +18 -0
  197. mindspore/profiler/parser/ascend_analysis/file_manager.py +25 -4
  198. mindspore/profiler/parser/ascend_analysis/function_event.py +43 -19
  199. mindspore/profiler/parser/ascend_analysis/fwk_cann_parser.py +31 -26
  200. mindspore/profiler/parser/ascend_analysis/fwk_file_parser.py +56 -10
  201. mindspore/profiler/parser/ascend_analysis/msprof_timeline_parser.py +55 -8
  202. mindspore/profiler/parser/ascend_analysis/path_manager.py +313 -0
  203. mindspore/profiler/parser/ascend_analysis/profiler_info_parser.py +27 -20
  204. mindspore/profiler/parser/ascend_analysis/trace_event_manager.py +9 -2
  205. mindspore/profiler/parser/ascend_msprof_exporter.py +5 -4
  206. mindspore/profiler/parser/ascend_timeline_generator.py +27 -25
  207. mindspore/profiler/parser/base_timeline_generator.py +19 -25
  208. mindspore/profiler/parser/cpu_gpu_timeline_generator.py +25 -12
  209. mindspore/profiler/parser/framework_parser.py +1 -391
  210. mindspore/profiler/parser/gpu_analysis/__init__.py +14 -0
  211. mindspore/profiler/parser/gpu_analysis/function_event.py +44 -0
  212. mindspore/profiler/parser/gpu_analysis/fwk_file_parser.py +89 -0
  213. mindspore/profiler/parser/gpu_analysis/profiler_info_parser.py +72 -0
  214. mindspore/profiler/parser/memory_usage_parser.py +0 -154
  215. mindspore/profiler/parser/profiler_info.py +78 -6
  216. mindspore/profiler/profiler.py +153 -0
  217. mindspore/profiler/profiling.py +285 -413
  218. mindspore/rewrite/__init__.py +1 -2
  219. mindspore/rewrite/common/namespace.py +4 -4
  220. mindspore/rewrite/symbol_tree/symbol_tree.py +3 -3
  221. mindspore/run_check/_check_version.py +39 -104
  222. mindspore/safeguard/rewrite_obfuscation.py +591 -247
  223. mindspore/train/__init__.py +4 -3
  224. mindspore/train/_utils.py +105 -19
  225. mindspore/train/amp.py +171 -53
  226. mindspore/train/callback/__init__.py +2 -2
  227. mindspore/train/callback/_callback.py +4 -4
  228. mindspore/train/callback/_checkpoint.py +97 -31
  229. mindspore/train/callback/_cluster_monitor.py +1 -1
  230. mindspore/train/callback/_flops_collector.py +1 -0
  231. mindspore/train/callback/_loss_monitor.py +3 -3
  232. mindspore/train/callback/_on_request_exit.py +145 -31
  233. mindspore/train/callback/_summary_collector.py +5 -5
  234. mindspore/train/callback/_tft_register.py +375 -0
  235. mindspore/train/dataset_helper.py +15 -3
  236. mindspore/train/metrics/metric.py +3 -3
  237. mindspore/train/metrics/roc.py +4 -4
  238. mindspore/train/mind_ir_pb2.py +44 -39
  239. mindspore/train/model.py +154 -58
  240. mindspore/train/serialization.py +342 -128
  241. mindspore/utils/__init__.py +21 -0
  242. mindspore/utils/utils.py +60 -0
  243. mindspore/version.py +1 -1
  244. {mindspore-2.3.0.dist-info → mindspore-2.4.1.dist-info}/METADATA +13 -7
  245. {mindspore-2.3.0.dist-info → mindspore-2.4.1.dist-info}/RECORD +248 -242
  246. mindspore/include/c_api/ms/abstract.h +0 -67
  247. mindspore/include/c_api/ms/attribute.h +0 -197
  248. mindspore/include/c_api/ms/base/handle_types.h +0 -43
  249. mindspore/include/c_api/ms/base/macros.h +0 -32
  250. mindspore/include/c_api/ms/base/status.h +0 -33
  251. mindspore/include/c_api/ms/base/types.h +0 -283
  252. mindspore/include/c_api/ms/context.h +0 -102
  253. mindspore/include/c_api/ms/graph.h +0 -160
  254. mindspore/include/c_api/ms/node.h +0 -606
  255. mindspore/include/c_api/ms/tensor.h +0 -161
  256. mindspore/include/c_api/ms/value.h +0 -84
  257. mindspore/mindspore_shared_lib.dll +0 -0
  258. mindspore/nn/extend/basic.py +0 -140
  259. mindspore/nn/extend/embedding.py +0 -143
  260. mindspore/nn/extend/layer/normalization.py +0 -109
  261. mindspore/nn/extend/pooling.py +0 -117
  262. mindspore/nn/layer/embedding_service.py +0 -531
  263. mindspore/ops/_op_impl/aicpu/strided_slice_v2.py +0 -93
  264. mindspore/ops/_op_impl/aicpu/strided_slice_v2_grad.py +0 -66
  265. mindspore/ops/extend/__init__.py +0 -53
  266. mindspore/ops/extend/array_func.py +0 -218
  267. mindspore/ops/extend/math_func.py +0 -76
  268. mindspore/ops/extend/nn_func.py +0 -308
  269. mindspore/ops/silent_check.py +0 -162
  270. mindspore/profiler/parser/msadvisor_analyzer.py +0 -82
  271. mindspore/profiler/parser/msadvisor_parser.py +0 -240
  272. mindspore/train/callback/_mindio_ttp.py +0 -443
  273. {mindspore-2.3.0.dist-info → mindspore-2.4.1.dist-info}/WHEEL +0 -0
  274. {mindspore-2.3.0.dist-info → mindspore-2.4.1.dist-info}/entry_points.txt +0 -0
  275. {mindspore-2.3.0.dist-info → mindspore-2.4.1.dist-info}/top_level.txt +0 -0
@@ -17,6 +17,7 @@ import json
17
17
  import os
18
18
  import time
19
19
  from mindspore.profiler import Profiler
20
+ from mindspore.profiler.parser.ascend_analysis.file_manager import FileManager
20
21
  from mindspore.profiler.profiling import AICORE_METRICS_DICT, DeviceSupportParam, ALWAYS_VALID_PARAM
21
22
  from mindspore.profiler.common.validator.validate_path import validate_and_normalize_path
22
23
  from mindspore.profiler.parser.integrator import DeviceTarget
@@ -65,11 +66,7 @@ def construct_profiling_options():
65
66
  if os.getenv("MS_PROFILER_RUN_CONFIG"):
66
67
  return error_config
67
68
  os.environ["MS_PROFILER_RUN_CONFIG"] = json.dumps(error_config)
68
- logger.error(
69
- "The format of MS_PROFILER_OPTIONS is incorrect. "
70
- "The MS_PROFILER_OPTIONS parameter configuration may refer to "
71
- "'https://www.mindspore.cn/mindinsight/docs/zh-CN/master/performance_profiling_ascend.html'."
72
- )
69
+ logger.error("The format of MS_PROFILER_OPTIONS is incorrect.")
73
70
  return error_config
74
71
  conbine_options = combine_profile_options(profiling_options)
75
72
  if conbine_options.get("start"):
@@ -77,8 +74,7 @@ def construct_profiling_options():
77
74
  if not output_path:
78
75
  output_path = os.path.join(os.getcwd(), "data")
79
76
  conbine_options["output_path"] = validate_and_normalize_path(output_path)
80
- if not os.path.exists(output_path):
81
- os.makedirs(output_path, exist_ok=True)
77
+ FileManager.make_dir_safety(output_path)
82
78
  conbine_options["file_output_path"] = os.path.join(output_path, "profiler")
83
79
  return conbine_options
84
80
 
@@ -95,8 +91,8 @@ def parse_pubilc_args(options):
95
91
  if not isinstance(options.get("data_process"), bool):
96
92
  logger.warning(
97
93
  "The 'data_process' parameter of the environment variable MS_PROFILE_OPTIONS must be bool,"
98
- f" but got type {type(options.get('data_process'))}, it will be set to true.")
99
- options["data_process"] = True
94
+ f" but got type {type(options.get('data_process'))}, it will be set to False.")
95
+ options["data_process"] = False
100
96
  if not isinstance(options.get("op_time"), bool):
101
97
  logger.warning(
102
98
  "The 'op_time' parameter of the environment variable MS_PROFILE_OPTIONS must be bool,"
@@ -122,11 +118,11 @@ def parse_pubilc_args(options):
122
118
  "The 'output_path' parameter of the environment variable MS_PROFILE_OPTIONS only supports absolute path, "
123
119
  f"it will be set to '{absolute_path}'.")
124
120
  options["output_path"] = absolute_path
125
- if options.get("profile_framework") not in ["memory", "time", "all", None]:
121
+ if options.get("profile_framework") not in ["time", "all", None]:
126
122
  logger.warning(
127
- "The 'profile_framework' parameter of the environment variable MS_PROFILE_OPTIONS must be one of ['memory',"
128
- " 'time', 'all', null], but got %s, it will be set to 'all'.", options.get("profile_framework"))
129
- options['profile_framework'] = "all"
123
+ "The 'profile_framework' parameter of the environment variable MS_PROFILE_OPTIONS must be one of ["
124
+ " 'time', 'all', null], but got %s, it will be set to None.", options.get("profile_framework"))
125
+ options['profile_framework'] = None
130
126
  return options
131
127
 
132
128
 
@@ -150,8 +146,8 @@ def parse_ascend_args(options):
150
146
  if not isinstance(options.get("parallel_strategy"), bool):
151
147
  logger.warning(
152
148
  "The 'parallel_strategy' parameter of the environment variable MS_PROFILE_OPTIONS must be bool,"
153
- f" but got type {type(options.get('parallel_strategy'))}, it will be set to true.")
154
- options["parallel_strategy"] = True
149
+ f" but got type {type(options.get('parallel_strategy'))}, it will be set to false.")
150
+ options["parallel_strategy"] = False
155
151
  if not isinstance(options.get("profile_communication"), bool):
156
152
  logger.warning(
157
153
  "The 'profile_communication' parameter of the environment variable MS_PROFILE_OPTIONS must be bool,"
@@ -193,11 +189,12 @@ def combine_profile_options(profiling_options):
193
189
  "aicore_metrics": profiling_options.get("aicore_metrics", 0),
194
190
  "l2_cache": profiling_options.get("l2_cache", False),
195
191
  "sync_enable": profiling_options.get("sync_enable", True),
196
- "data_process": profiling_options.get("data_process", True),
192
+ "data_process": profiling_options.get("data_process", False),
197
193
  "timeline_limit": profiling_options.get("timeline_limit", 500),
198
- "parallel_strategy": profiling_options.get("parallel_strategy", True),
194
+ "parallel_strategy": profiling_options.get("parallel_strategy", False),
199
195
  'op_time': profiling_options.get("op_time", True),
200
- 'profile_framework': profiling_options.get("profile_framework", "all")
196
+ 'profile_framework': profiling_options.get("profile_framework", None),
197
+ 'with_stack': profiling_options.get("with_stack", False)
201
198
  }
202
199
  combine_options = parse_profiling_args(config_options)
203
200
  if combine_options.get("start"):
@@ -250,7 +247,8 @@ def profiler_check_env():
250
247
  sync_enable=config.get("sync_enable", False),
251
248
  op_time=config.get("op_time", False),
252
249
  timeline_limit=config.get("timeline_limit", 500),
253
- profile_framework=config.get("profile_framework", "all"))
250
+ profile_framework=config.get("profile_framework", None),
251
+ with_stack=config.get("with_stack", False))
254
252
 
255
253
 
256
254
  profiler_check_env()
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
  # ============================================================================
15
15
  """Constant value for ascend profiling parser."""
16
+ import os
16
17
 
17
18
 
18
19
  class Constant:
@@ -25,6 +26,7 @@ class Constant:
25
26
  COMPLETE_EVENT = 'X'
26
27
  FLOW_OP = "flow"
27
28
  INVALID_FLOW_ID = 18446744073709551615
29
+ DEFAULT_PROCESS_NUMBER = os.cpu_count() // 2
28
30
 
29
31
  # file authority
30
32
  MAX_FILE_SIZE = 1024 * 1024 * 1024 * 10
@@ -44,6 +46,7 @@ class Constant:
44
46
  MODULE_HIERARCHY = "Module Hierarchy"
45
47
  FLOPS = "flops"
46
48
  NAME = "name"
49
+ CUSTOM_INFO = "custom_info"
47
50
 
48
51
  # trace constant
49
52
  PROCESS_NAME = "process_name"
@@ -51,3 +54,18 @@ class Constant:
51
54
  PROCESS_SORT = "process_sort_index"
52
55
  THREAD_NAME = "thread_name"
53
56
  THREAD_SORT = "thread_sort_index"
57
+
58
+ # dir name
59
+ FRAMEWORK_DIR = "FRAMEWORK"
60
+ PROFILER_DIR = "profiler"
61
+ TOP_SCOPE_NAMES = ('Default', 'Gradients', 'recompute_Default')
62
+
63
+ # the index of modules of timeline
64
+ MINDSPORE = 1
65
+ CPU_OP = 2
66
+ CANN = 3
67
+ SCOPE_LAYLER = 4
68
+ ASCEND_HARDWARE = 5
69
+ HCCL = 6
70
+ OVERLAP = 7
71
+ OTHERWISE = 8
@@ -16,11 +16,12 @@
16
16
  import csv
17
17
  import json
18
18
  import os.path
19
- from typing import List
19
+ from typing import List, Dict, Optional
20
20
 
21
21
  from mindspore import log as logger
22
22
  from mindspore.profiler.common.validator.validate_path import validate_and_normalize_path
23
23
  from mindspore.profiler.parser.ascend_analysis.constant import Constant
24
+ from mindspore.profiler.parser.ascend_analysis.path_manager import PathManager
24
25
 
25
26
 
26
27
  class FileManager:
@@ -67,15 +68,35 @@ class FileManager:
67
68
  raise RuntimeError(msg) from err
68
69
 
69
70
  @classmethod
70
- def create_json_file(cls, output_path: str, json_data: List, file_name: str) -> None:
71
+ def read_json_file(cls, file_path: str) -> Optional[Dict]:
72
+ """Read json file and return dict data"""
73
+ if not os.path.isfile(file_path):
74
+ return {}
75
+ file_size = os.path.getsize(file_path)
76
+ if file_size <= 0:
77
+ return {}
78
+ if file_size > Constant.MAX_FILE_SIZE:
79
+ msg = f"The file size exceeds the preset value, please check the file: {file_path}"
80
+ logger.warning(msg)
81
+ return {}
82
+ try:
83
+ PathManager.check_directory_path_readable(file_path)
84
+ with open(file_path, 'r', encoding='utf-8') as json_file:
85
+ data = json.load(json_file)
86
+ return data
87
+ except Exception as err:
88
+ raise RuntimeError(f"Failed to read the file: {file_path}") from err
89
+
90
+ @classmethod
91
+ def create_json_file(cls, output_path: str, json_data: List, file_name: str, indent: int = None) -> None:
71
92
  """Create json file with least authority"""
72
93
  if not json_data:
73
94
  return
74
95
  cls.make_dir_safety(output_path)
75
96
  file_path = os.path.join(output_path, file_name)
76
- flags = os.O_WRONLY | os.O_CREAT
97
+ flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
77
98
  with os.fdopen(os.open(file_path, flags, cls.DATA_FILE_AUTHORITY), 'w') as fp:
78
- json.dump(json_data, fp, ensure_ascii=False)
99
+ json.dump(json_data, fp, ensure_ascii=False, indent=indent)
79
100
 
80
101
  @classmethod
81
102
  def read_csv_file(cls, file_path: str) -> list:
@@ -35,7 +35,7 @@ class BaseEvent(ABC):
35
35
  self.pid: int = 0
36
36
  self.tid: int = 0
37
37
  self.ts: Decimal = Decimal(0)
38
- self.end_us: Decimal = Decimal(0)
38
+ self.te: Decimal = Decimal(0)
39
39
  self.dur: float = 0.0
40
40
  self.args: Dict = {}
41
41
  self.parent: Optional[BaseEvent] = None
@@ -56,7 +56,7 @@ class CANNEvent(BaseEvent):
56
56
  self.pid = self._orig_data.get("pid", 0)
57
57
  self.tid = self._orig_data.get("tid", 0)
58
58
  self.dur = self._orig_data.get("dur", 0.0)
59
- self.end_us = self.ts + Decimal(str(self.dur))
59
+ self.te = self.ts + Decimal(str(self.dur))
60
60
  self.name = self._orig_data.get("name", "")
61
61
  self.id = self._orig_data.get("id", 0)
62
62
  self.args = self._orig_data.get("args", {})
@@ -75,16 +75,32 @@ class CANNEvent(BaseEvent):
75
75
 
76
76
  def is_x_event(self) -> bool:
77
77
  """Determine whether the event x event or not."""
78
- return self._orig_data.get("ph") == "X"
78
+ return self._orig_data.get("ph") == Constant.COMPLETE_EVENT
79
+
80
+ def get_sort_index(self):
81
+ """get the process sort index"""
82
+ if self.args.get('name', '') == 'Ascend Hardware':
83
+ return Constant.ASCEND_HARDWARE
84
+ if self.args.get('name', '') == 'CANN':
85
+ return Constant.CANN
86
+ if self.args.get('name', '') == 'HCCL':
87
+ return Constant.HCCL
88
+ if self.args.get('name', '') == 'Overlap Analysis':
89
+ return Constant.OVERLAP
90
+ return Constant.OTHERWISE
79
91
 
80
92
  def to_json(self):
81
93
  """Cast to trace event."""
82
94
  if self.ph == Constant.META_EVENT:
83
- res = {'name': self.name, 'pid': self.pid, 'tid': self.tid,
84
- 'args': self.args, 'ph': self.ph}
85
- if self.cat:
86
- res.update({'cat': self.cat})
87
- return res
95
+ if self.name == Constant.PROCESS_NAME:
96
+ return [{'name': self.name, 'pid': self.pid, 'tid': self.tid,
97
+ 'args': self.args, 'ph': self.ph},
98
+ {'name': Constant.PROCESS_SORT, 'pid': self.pid, 'tid': self.tid,
99
+ 'args': {'sort_index': self.get_sort_index()}, 'ph': self.ph}]
100
+ if self.name == Constant.PROCESS_SORT:
101
+ return None
102
+ return {'name': self.name, 'pid': self.pid, 'tid': self.tid,
103
+ 'args': self.args, 'ph': self.ph}
88
104
 
89
105
  if self.ph == Constant.COMPLETE_EVENT:
90
106
  if self.parent is not None:
@@ -102,8 +118,7 @@ class CANNEvent(BaseEvent):
102
118
  if self.ph == Constant.END_FLOW:
103
119
  return {"ph": self.ph, "name": self.name, "id": self.id, "pid": self.pid,
104
120
  "tid": self.tid, "ts": str(self.ts), "cat": self.cat, 'bp': "e"}
105
- return {'name': self.name, 'pid': self.pid, 'tid': self.tid,
106
- 'ts': str(self.ts), 'args': self.args, 'ph': self.ph}
121
+ return None
107
122
 
108
123
 
109
124
  class MindSporeOpEnum(Enum):
@@ -117,7 +132,8 @@ class MindSporeOpEnum(Enum):
117
132
  FORWORD_THREAD_ID = 6
118
133
  FLOW_ID = 7
119
134
  STEP_ID = 8
120
- IS_ASYNC = 9
135
+ LEVEL = 9
136
+ IS_ASYNC = 10
121
137
 
122
138
 
123
139
  class MindSporeOpEvent(BaseEvent):
@@ -129,24 +145,27 @@ class MindSporeOpEvent(BaseEvent):
129
145
  """
130
146
  _tlv_type_dict = {
131
147
  Constant.OP_NAME: 3, Constant.INPUT_SHAPES: 5, Constant.INPUT_DTYPES: 4,
132
- Constant.CALL_STACK: 6, Constant.MODULE_HIERARCHY: 7, Constant.FLOPS: 8
148
+ Constant.CALL_STACK: 6, Constant.MODULE_HIERARCHY: 7, Constant.FLOPS: 8,
149
+ Constant.CUSTOM_INFO: 9
133
150
  }
134
- _fix_data_format = "<3q6Q?"
151
+ _fix_data_format = "<3q6Qb?"
135
152
 
136
153
  def _init_params(self):
137
154
  """Initialize the attribute value of MindSporeOpEvent."""
138
155
  fix_size_data = struct.unpack(self._fix_data_format, self._orig_data.get(Constant.FIX_SIZE_BYTES))
139
- self.pid = int(fix_size_data[MindSporeOpEnum.PROCESS_ID.value])
156
+ self.pid = Constant.MINDSPORE
140
157
  self.tid = int(fix_size_data[MindSporeOpEnum.START_THREAD_ID.value])
141
158
  self.name = str(self._orig_data.get(self._tlv_type_dict.get(Constant.OP_NAME), ""))
142
- self.ts = ProfilerInfoParser.get_local_time(fix_size_data[MindSporeOpEnum.START_NS.value])
143
- self.end_us = ProfilerInfoParser.get_local_time(fix_size_data[MindSporeOpEnum.END_NS.value])
144
- self.dur = self.end_us - self.ts
159
+ self.ts = ProfilerInfoParser.get_local_time(fix_size_data[MindSporeOpEnum.START_NS.value]) # unit is us
160
+ self.te = ProfilerInfoParser.get_local_time(fix_size_data[MindSporeOpEnum.END_NS.value]) # unit is us
161
+ self.dur = self.te - self.ts
145
162
  self.flow_id = int(fix_size_data[MindSporeOpEnum.FLOW_ID.value])
146
163
  self.step = int(fix_size_data[MindSporeOpEnum.STEP_ID.value])
147
- self.args = self.__get_args(fix_size_data)
164
+ self.level = int(fix_size_data[MindSporeOpEnum.LEVEL.value])
165
+ self.custom_info = ""
166
+ self.args = self._get_args(fix_size_data)
148
167
 
149
- def __get_args(self, fix_size_data) -> Dict:
168
+ def _get_args(self, fix_size_data) -> Dict:
150
169
  """Get the rest information saved in args"""
151
170
  args = {
152
171
  Constant.SEQUENCE_UNMBER: int(fix_size_data[MindSporeOpEnum.SEQUENCE_UNMBER.value]),
@@ -156,6 +175,11 @@ class MindSporeOpEvent(BaseEvent):
156
175
  continue
157
176
  if type_name in set([Constant.INPUT_SHAPES, Constant.INPUT_DTYPES, Constant.CALL_STACK]):
158
177
  args[type_name] = self._orig_data.get(type_id).replace("|", "\r\n")
178
+ elif type_name == Constant.CUSTOM_INFO and self._orig_data.get(type_id):
179
+ pairs = self._orig_data.get(type_id).split(';')
180
+ custom_info = {pair.split(':')[0]: pair.split(':')[1] for pair in pairs}
181
+ args[type_name] = custom_info
182
+ self.custom_info = custom_info.__str__()
159
183
  else:
160
184
  args[type_name] = self._orig_data.get(type_id)
161
185
  return args
@@ -24,23 +24,25 @@ from mindspore.profiler.parser.ascend_analysis.fwk_file_parser import FwkFilePar
24
24
  from mindspore.profiler.parser.ascend_analysis.trace_event_manager import TraceEventManager
25
25
  from mindspore.profiler.parser.ascend_analysis.msprof_timeline_parser import MsprofTimelineParser
26
26
  from mindspore.profiler.parser.ascend_analysis.profiler_info_parser import ProfilerInfoParser
27
- from mindspore.profiler.parser.ascend_analysis.constant import Constant
27
+ from mindspore.profiler.parser.profiler_info import ProfilerInfo
28
28
 
29
29
 
30
30
  class FwkCANNParser:
31
31
  """The top-level trace view parser."""
32
32
 
33
- _time_padding_diff = 1000 # ns
34
-
35
33
  def __init__(self, source_path: str, msprof_data: List, rank_id: int, step_list=None):
36
34
  source_path = validate_and_normalize_path(source_path)
37
35
  ProfilerInfoParser.init_source_path(source_path)
38
36
  ProfilerInfoParser.init_rank_id(rank_id)
37
+
39
38
  fwk_parser = FwkFileParser(source_path, rank_id)
40
- msprof_timeline_parser = MsprofTimelineParser(msprof_data)
41
39
  self._fwk_data = fwk_parser.get_op_range_data(step_list)
42
- self._fwk_json = fwk_parser.get_fwk_trace_data(self._fwk_data)
43
- self._start_flow_to_npu_dict, self._device_most_json = msprof_timeline_parser.get_acl_to_npu_data()
40
+ self._fwk_json, self._link_event_dict, self._fwk_launch_op = fwk_parser.get_fwk_trace_data(self._fwk_data)
41
+
42
+ msprof_timeline_parser = MsprofTimelineParser(msprof_data)
43
+ self._start_flow_to_npu_dict, self._device_mostly_json, self.scope_data_without_flow \
44
+ = msprof_timeline_parser.get_acl_to_npu_data()
45
+ self.scope_data_with_flow = []
44
46
  self.rank_id: int = rank_id
45
47
  self.kernels: List[CANNEvent] = []
46
48
 
@@ -51,18 +53,12 @@ class FwkCANNParser:
51
53
  """
52
54
  fwk_flow_json = self.__link_msop_self()
53
55
  device_flow_and_x_json = self.__link_msop_kernel()
54
- return self._fwk_json + fwk_flow_json + self._device_most_json + device_flow_and_x_json
56
+ return self._fwk_json + fwk_flow_json + self._device_mostly_json + device_flow_and_x_json
55
57
 
56
58
  def __link_msop_self(self):
57
59
  """Create flow between framework-side multi-level pipeline task."""
58
- link_event_dict = defaultdict(list)
59
- for op_data in self._fwk_data:
60
- if op_data.name == Constant.FLOW_OP:
61
- link_event_dict[op_data.flow_id].insert(0, op_data)
62
- elif op_data.flow_id != Constant.INVALID_FLOW_ID:
63
- link_event_dict[op_data.flow_id].append(op_data)
64
60
  flow_json = []
65
- for op_data_list in link_event_dict.values():
61
+ for op_data_list in self._link_event_dict.values():
66
62
  if len(op_data_list) != 2:
67
63
  logger.info('Only alow 2 op_data have the same flow_id. but got %s', len(op_data_list))
68
64
  continue
@@ -70,34 +66,43 @@ class FwkCANNParser:
70
66
  op_data_list[1]))
71
67
  return flow_json
72
68
 
73
- def __link_msop_kernel(self) -> List:
69
+ def __link_msop_kernel(self):
74
70
  """Associate the frame-side operator with the device-side kernel"""
75
71
  trace_data_json = []
76
- op_data_by_tid = defaultdict(list)
77
72
  acl_to_npu_by_tid = {}
78
- for host_data in self._fwk_data:
79
- if 'KernelLaunch' in host_data.name or 'LaunchTask' in host_data.name:
80
- op_data_by_tid[host_data.tid].append(host_data)
81
73
  for (cann_op_tid, cann_op_ts), event_list in self._start_flow_to_npu_dict.items():
82
74
  acl_to_npu_by_tid.setdefault(cann_op_tid, defaultdict(list))[cann_op_ts].extend(event_list)
83
75
 
84
- if op_data_by_tid.keys() != acl_to_npu_by_tid.keys():
76
+ if self._fwk_launch_op and acl_to_npu_by_tid and self._fwk_launch_op.keys() != acl_to_npu_by_tid.keys():
85
77
  logger.warning("Failed to create link between mindspore operator and kernels.")
86
-
78
+ is_not_O2 = bool(ProfilerInfo.get_profiler_info().get(ProfilerInfo.JIT_LEVEL, "") != "O2")
87
79
  for device_tid in acl_to_npu_by_tid:
88
- host_data_sorted = sorted(op_data_by_tid.get(device_tid, []), key=lambda x: x.ts)
80
+ host_data_sorted = sorted(self._fwk_launch_op.get(device_tid, []), key=lambda x: x.ts)
89
81
  op_idx = 0
90
82
 
91
83
  for ts, device_data_list in sorted(acl_to_npu_by_tid.get(device_tid).items(), key=lambda x: x[0]):
92
84
  op_idx, status = FwkCANNParser.__find_launch_op(ts, host_data_sorted, op_idx)
85
+ if not status and is_not_O2:
86
+ logger.warning("There are %s device ops have no flows were found. The CANN ts is %s.",
87
+ len(device_data_list), ts)
93
88
 
94
89
  for device_data in device_data_list:
95
90
  if status:
96
91
  device_data.parent = host_data_sorted[op_idx]
97
- trace_data_json.extend(TraceEventManager.create_mindspore_to_npu_flow(host_data_sorted[op_idx],
92
+ trace_data_json.extend(TraceEventManager.create_mindspore_to_npu_flow(device_data.parent,
98
93
  device_data))
99
94
  self.kernels.append(device_data)
100
- trace_data_json.append(device_data.to_json())
95
+
96
+ scope_layer = MsprofTimelineParser.parse_ascend_hardware_scope(device_data)
97
+
98
+ if scope_layer is not None:
99
+ self.scope_data_with_flow.append(scope_layer)
100
+
101
+ event_json = device_data.to_json()
102
+ if event_json and isinstance(event_json, list):
103
+ trace_data_json.extend(event_json)
104
+ elif event_json and isinstance(event_json, dict):
105
+ trace_data_json.append(event_json)
101
106
 
102
107
  return trace_data_json
103
108
 
@@ -122,9 +127,9 @@ class FwkCANNParser:
122
127
  right = len(op_list) if (right is None or right < 0) else right
123
128
  # The data in range [left, right) is considered.
124
129
  while right > left:
125
- if op_list[left].ts - FwkCANNParser._time_padding_diff > ts:
130
+ if op_list[left].ts > ts:
126
131
  return left, False
127
- if op_list[left].end_us < ts:
132
+ if op_list[left].te < ts:
128
133
  left += 1
129
134
  else:
130
135
  return left, True
@@ -15,6 +15,8 @@
15
15
  """MindSpore framework oprange file parser"""
16
16
 
17
17
  import os
18
+ import stat
19
+ import csv
18
20
  from typing import List
19
21
  from collections import defaultdict
20
22
 
@@ -31,15 +33,16 @@ class FwkFileParser:
31
33
  """Framework-side operator file parser."""
32
34
 
33
35
  _op_range = "FRAMEWORK/op_range_{}"
34
- _op_range_struct_size = 73
36
+ _op_range_struct_size = 74
35
37
 
36
38
  def __init__(self, source_path: str, rank_id: int):
37
39
  """
38
40
  source_path: The path of PROF_* directory
39
41
  """
40
42
  self.rank_id = rank_id
43
+ self._prof_root = None
41
44
  self._op_range_path = None
42
- self.__init_framework_path(source_path)
45
+ self._init_framework_path(source_path)
43
46
 
44
47
  def get_op_range_data(self, step_list=None) -> List[MindSporeOpEvent]:
45
48
  """Read and decode all the mindspore oprange data."""
@@ -48,7 +51,7 @@ class FwkFileParser:
48
51
  op_range_bytes = FileManager.read_file_content(self._op_range_path, "rb")
49
52
  op_range_list = TLVDecoder.decode(op_range_bytes, MindSporeOpEvent, self._op_range_struct_size)
50
53
  else:
51
- logger.error("Failed to find op_range data.")
54
+ logger.warning("Failed to find op_range data. skip parse host profiler data.")
52
55
  if step_list and isinstance(step_list, list):
53
56
  first_step = min(op.step for op in op_range_list)
54
57
  step_list = [step - 1 + first_step for step in step_list]
@@ -61,18 +64,62 @@ class FwkFileParser:
61
64
  mindspore_op_data = self.get_op_range_data()
62
65
  tid_map = defaultdict(set)
63
66
  fwk_x_event_list = []
67
+ link_event_dict = defaultdict(list)
68
+ fwk_launch_op = defaultdict(list)
69
+ dataset_op_data = []
64
70
 
65
71
  for mindspore_op in mindspore_op_data:
66
72
  if mindspore_op.name == Constant.FLOW_OP:
73
+ link_event_dict[mindspore_op.flow_id].insert(0, mindspore_op)
67
74
  continue
75
+ if mindspore_op.flow_id != Constant.INVALID_FLOW_ID:
76
+ link_event_dict[mindspore_op.flow_id].append(mindspore_op)
77
+
78
+ if 'KernelLaunch' in mindspore_op.name or 'LaunchTask' in mindspore_op.name:
79
+ fwk_launch_op[mindspore_op.tid].append(mindspore_op)
80
+
81
+ if mindspore_op.name.split('::')[0] == 'Dataset':
82
+ dataset_op_data.append(mindspore_op)
83
+
68
84
  tid_map[mindspore_op.pid].add(mindspore_op.tid)
69
- fwk_x_event_list.append(TraceEventManager.create_x_event(mindspore_op, "cpu_op"))
85
+ if mindspore_op.dur > 0:
86
+ fwk_x_event_list.append(TraceEventManager.create_x_event(mindspore_op, "cpu_op"))
87
+ else:
88
+ fwk_x_event_list.append(TraceEventManager.create_i_event(mindspore_op))
89
+
70
90
  fwk_m_event_list = []
71
91
  for pid, tid_set in tid_map.items():
72
- fwk_m_event_list.extend(TraceEventManager.create_m_event(pid, tid_set))
73
- return fwk_x_event_list + fwk_m_event_list
92
+ fwk_m_event_list.extend(TraceEventManager.create_m_event(pid, tid_set, pid))
93
+
94
+ self.calculate_dataset_item(dataset_op_data)
95
+
96
+ return fwk_x_event_list + fwk_m_event_list, link_event_dict, fwk_launch_op
97
+
98
+ def calculate_dataset_item(self, dataset_op_data: List[MindSporeOpEvent]):
99
+ """
100
+ Get the summary data of dataset op by parsing the dataset_op_data.
101
+ """
102
+ self._prof_root = validate_and_normalize_path(self._prof_root)
103
+ dataset_file = os.path.join(self._prof_root, f'dataset_{self.rank_id}.csv')
104
+ summary_data = defaultdict(list)
105
+ for op_data in dataset_op_data:
106
+ _, event, stage = op_data.name.split('::')
107
+ key = event + '::' + stage + '::' + op_data.custom_info
108
+ summary_data[key].append(op_data.dur)
109
+
110
+ flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
111
+ modes = stat.S_IWUSR | stat.S_IRUSR
112
+ with os.fdopen(os.open(dataset_file, flags, modes), 'w', newline='') as fw:
113
+ csv_writer = csv.writer(fw)
114
+ csv_writer.writerow(['Operation', 'Stage', 'Occurrences', 'Avg. time (us)', 'Custom Info'])
115
+ for k, v in summary_data.items():
116
+ event, stage, custom_info = k.split('::')
117
+ count = len(v)
118
+ average_execution = round(float(sum(v) / count), 2)
119
+ csv_writer.writerow([event, stage, count, average_execution, custom_info])
120
+ os.chmod(dataset_file, modes)
74
121
 
75
- def __init_framework_path(self, source_path: str):
122
+ def _init_framework_path(self, source_path: str):
76
123
  """Init the oprange data path."""
77
124
  source_path = validate_and_normalize_path(source_path)
78
125
  if not os.path.exists(source_path):
@@ -80,6 +127,5 @@ class FwkFileParser:
80
127
  device_name = os.path.basename(source_path)
81
128
  if not device_name.startswith("device") and not os.path.isdir(source_path):
82
129
  raise RuntimeError("Input source_path is invalid!")
83
- prof_path = os.path.dirname(source_path)
84
- prof_root = os.path.dirname(prof_path)
85
- self._op_range_path = os.path.join(prof_root, self._op_range.format(self.rank_id))
130
+ self._prof_root = os.path.dirname(os.path.dirname(source_path))
131
+ self._op_range_path = os.path.join(self._prof_root, self._op_range.format(self.rank_id))
@@ -16,7 +16,8 @@
16
16
  from collections import defaultdict
17
17
  from typing import List
18
18
 
19
- from mindspore.profiler.parser.ascend_analysis.function_event import CANNEvent
19
+ from mindspore.profiler.parser.ascend_analysis.constant import Constant
20
+ from mindspore.profiler.parser.ascend_analysis.function_event import CANNEvent, MindSporeOpEvent, BaseEvent
20
21
 
21
22
 
22
23
  class MsprofTimelineParser:
@@ -34,24 +35,70 @@ class MsprofTimelineParser:
34
35
  if cann_event.is_x_event():
35
36
  x_event_list.append(cann_event)
36
37
  else:
37
- cann_event_json = cann_event.to_json()
38
- if cann_event_json:
39
- other_event_json.append(cann_event_json)
38
+ event_json = cann_event.to_json()
39
+ if event_json and isinstance(event_json, list):
40
+ other_event_json.extend(event_json)
41
+ elif event_json and isinstance(event_json, dict):
42
+ other_event_json.append(event_json)
40
43
 
41
44
  if cann_event.is_flow_start_event():
42
45
  flow_start_dict[cann_event.id] = (cann_event.tid, cann_event.ts)
43
46
  elif cann_event.is_flow_end_event():
44
47
  flow_end_dict[(cann_event.pid, cann_event.tid, cann_event.ts)] = cann_event.id
48
+
45
49
  start_flow_to_npu_dict = defaultdict(list)
46
50
  device_data_without_flow_json = []
51
+ scope_data_without_flow = []
47
52
  for cann_event in x_event_list:
48
53
  flow_id = flow_end_dict.get((cann_event.pid, cann_event.tid, cann_event.ts))
49
54
  start_flow_info = flow_start_dict.get(flow_id)
50
55
  if flow_id is not None and start_flow_info is not None:
51
56
  start_flow_to_npu_dict[start_flow_info].append(cann_event)
52
57
  else:
53
- cann_event_json = cann_event.to_json()
54
- if cann_event_json:
55
- device_data_without_flow_json.append(cann_event_json)
58
+ event_json = cann_event.to_json()
59
+ if event_json and isinstance(event_json, list):
60
+ device_data_without_flow_json.extend(event_json)
61
+ elif event_json and isinstance(event_json, dict):
62
+ device_data_without_flow_json.append(event_json)
63
+
64
+ scope_layer = self.parse_ascend_hardware_scope(cann_event)
65
+ if scope_layer is not None:
66
+ scope_data_without_flow.append(scope_layer)
67
+
68
+ return start_flow_to_npu_dict, device_data_without_flow_json + other_event_json, scope_data_without_flow
69
+
70
+ @staticmethod
71
+ def parse_ascend_hardware_scope(cann_event: BaseEvent):
72
+ """
73
+ parse ascend hardware scope
74
+ """
75
+ scope_from_flow_start = MsprofTimelineParser.get_scope_layer(cann_event.parent)
76
+ scope = MsprofTimelineParser.get_scope_layer(cann_event)
77
+
78
+ if scope and scope_from_flow_start:
79
+ scope = scope_from_flow_start if len(scope_from_flow_start) > len(scope) else scope
80
+ elif not scope and not scope_from_flow_start:
81
+ return None
82
+ else:
83
+ scope = scope_from_flow_start if scope_from_flow_start else scope
84
+
85
+ return (scope, cann_event.ts, cann_event.te)
86
+
87
+ @staticmethod
88
+ def get_scope_layer(event: BaseEvent):
89
+ """
90
+ get the scope of device op
91
+ """
92
+
93
+ if event is None:
94
+ return None
95
+
96
+ full_scope_name = None
97
+ if isinstance(event, MindSporeOpEvent):
98
+ full_scope_name = event.name.split('::')[-1]
99
+ elif isinstance(event, CANNEvent):
100
+ full_scope_name = event.name
56
101
 
57
- return start_flow_to_npu_dict, device_data_without_flow_json + other_event_json
102
+ if full_scope_name and full_scope_name.startswith(Constant.TOP_SCOPE_NAMES):
103
+ return full_scope_name.split('/')[:-1]
104
+ return None