You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

aicpu_data_parser.py 5.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. # Copyright 2020 Huawei Technologies Co., Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ============================================================================
  15. """
  16. The parser for AI CPU preprocess data.
  17. """
  18. import os
  19. from tabulate import tabulate
  20. from mindinsight.profiler.common._utils import fwrite_format, get_file_join_name
  21. from mindinsight.profiler.common.log import logger
  22. class DataPreProcessParser:
  23. """
  24. The Parser for AI CPU preprocess data.
  25. Args:
  26. input_path(str): The profiling job path.
  27. output_filename(str): The output data path and name.
  28. """
  29. _source_file_target = 'DATA_PREPROCESS.dev.AICPU.'
  30. _dst_file_title = 'title:DATA_PREPROCESS AICPU'
  31. _dst_file_column_title = ['serial_number', 'node_type_name', 'total_time(us)',
  32. 'dispatch_time(us)', 'run_start', 'run_end']
  33. def __init__(self, input_path, output_filename):
  34. self._input_path = input_path
  35. self._output_filename = output_filename
  36. self._source_file_name = self._get_source_file()
  37. self._ms_kernel_flag = 3
  38. self._other_kernel_flag = 6
  39. self._thread_flag = 7
  40. self._ms_kernel_run_end_index = 2
  41. self._other_kernel_run_end_index = 5
  42. def _get_source_file(self):
  43. """Get log file name, which was created by ada service."""
  44. file_name = get_file_join_name(self._input_path, self._source_file_target)
  45. if not file_name:
  46. data_path = os.path.join(self._input_path, "data")
  47. file_name = get_file_join_name(data_path, self._source_file_target)
  48. return file_name
  49. def _get_kernel_result(self, number, node_list, thread_list):
  50. """Get the profiling data form different aicpu kernel"""
  51. try:
  52. if len(node_list) == self._ms_kernel_flag and len(thread_list) == self._thread_flag:
  53. node_type_name = node_list[0].split(':')[-1]
  54. run_end_index = self._ms_kernel_run_end_index
  55. elif len(node_list) == self._other_kernel_flag and len(thread_list) == self._thread_flag:
  56. node_type_name = node_list[0].split(':')[-1].split('/')[-1].split('-')[0]
  57. run_end_index = self._other_kernel_run_end_index
  58. else:
  59. logger.warning("the data format can't support 'node_list':%s", str(node_list))
  60. return None
  61. run_start = node_list[1].split(':')[-1].split(' ')[0]
  62. run_end = node_list[run_end_index].split(':')[-1].split(' ')[0]
  63. total_time = thread_list[-1].split('=')[-1].split()[0]
  64. dispatch_time = thread_list[-2].split('=')[-1].split()[0]
  65. return [number, node_type_name, total_time, dispatch_time,
  66. run_start, run_end]
  67. except IndexError as e:
  68. logger.exception(e)
  69. return None
  70. def execute(self):
  71. """Execute the parser, get result data, and write it to the output file."""
  72. if not os.path.exists(self._source_file_name):
  73. logger.info("Did not find the aicpu profiling source file")
  74. return
  75. with open(self._source_file_name, 'rb') as ai_cpu_data:
  76. ai_cpu_str = str(ai_cpu_data.read().replace(b'\n\x00', b' ___ ')
  77. .replace(b'\x00', b' ___ '))[2:-1]
  78. ai_cpu_lines = ai_cpu_str.split(" ___ ")
  79. result_list = list()
  80. ai_cpu_total_time_summary = 0
  81. # Node serial number.
  82. serial_number = 1
  83. for i in range(len(ai_cpu_lines) - 1):
  84. node_line = ai_cpu_lines[i]
  85. thread_line = ai_cpu_lines[i + 1]
  86. result = []
  87. if "Node" in node_line and "Thread" in thread_line:
  88. # Get the node data from node_line
  89. node_list = node_line.split(',')
  90. thread_list = thread_line.split(',')
  91. result = self._get_kernel_result(serial_number, node_list, thread_list)
  92. if result is None:
  93. continue
  94. result_list.append(result)
  95. # Calculate the total time.
  96. total_time = result[2]
  97. ai_cpu_total_time_summary += int(total_time)
  98. # Increase node serial number.
  99. serial_number += 1
  100. elif "Node" in node_line and "Thread" not in thread_line:
  101. node_type_name = node_line.split(',')[0].split(':')[-1]
  102. logger.warning("The node type:%s cannot find thread data", node_type_name)
  103. if result_list:
  104. result_list.append(["AI CPU Total Time(us):", ai_cpu_total_time_summary])
  105. fwrite_format(self._output_filename, data_source=self._dst_file_title, is_print=True,
  106. is_start=True)
  107. fwrite_format(self._output_filename,
  108. data_source=tabulate(result_list, self._dst_file_column_title,
  109. tablefmt='simple'),
  110. is_start=True, is_print=True)