|
- #!/usr/bin/env python3
- # coding: utf-8
- # Copyright 2019 Huawei Technologies Co., Ltd
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
-
- """parsing_profiling_data"""
- import os
- import subprocess
- import struct
- import re
- from tabulate import tabulate
-
- OUTPUT_FORMAT_DATA = "./output_format_data_hwts.txt"
- BLOCK_LEN = 32
- max_time_consume = 9999999999
- def get_log_slice_id(file_name):
- pattern = re.compile(r'(?<=slice_)\d+')
- slice_ = pattern.findall(file_name)
- index = re.findall(r'\d+', slice_[0])
- return int(index[0])
-
-
- def get_file_join_name(input_path=None, file_name=None):
- """Function for getting join name from input path."""
- name_list = []
- file_join_name = ''
- if os.path.exists(input_path):
- files = os.listdir(input_path)
- for f in files:
- if file_name in f and not f.endswith('.done') and not f.endswith('.join'):
- name_list.append(f)
- # resort name_list
- name_list.sort(key=get_log_slice_id)
-
- if len(name_list) == 1:
- file_join_name = input_path + os.sep + name_list[0]
- elif len(name_list) > 1:
- file_join_name = input_path + os.sep + '%s.join' % file_name
- if os.path.exists(file_join_name):
- os.remove(file_join_name)
- with open(file_join_name, 'ab') as bin_data:
- for i in name_list:
- file = input_path + os.sep + i
- with open(file, 'rb') as txt:
- bin_data.write(txt.read())
- return file_join_name
-
-
- def get_first_runtime_task_trace(input_file=None):
- """Function for getting first task trace from runtime."""
- result_data = []
- format_ = "BBHIQHHHHII"
- format_last = "B"
- with open(input_file, 'rb') as bin_data:
- while True:
- line_ = bin_data.read(96)
- if line_:
- if not line_.strip():
- continue
- else:
- break
- if len(line_) == 96:
- unpack_tuple = struct.unpack(format_, line_[0:32])
- char_string = line_[32:95].decode().strip(b'\x00'.decode())
- result_last = [hex(i) for i in struct.unpack(format_last, line_[95:96])]
- byte01 = bin(int(result_last[0].replace('0x', ''), 16)).replace('0b', '').zfill(8)
- persistant_1bit = byte01[-1]
- reserved_7bit = byte01[0:7]
- kernelname = char_string
- result_data.append((unpack_tuple[0], unpack_tuple[1], unpack_tuple[2], unpack_tuple[3],
- unpack_tuple[4], unpack_tuple[5], unpack_tuple[6], unpack_tuple[7],
- unpack_tuple[8], unpack_tuple[9], unpack_tuple[10],
- kernelname, persistant_1bit, reserved_7bit))
- return result_data
-
-
- def get_44_tsch_fw_timeline(input_file=None):
- """Function for getting tsch_fw_timeline from input file."""
- result_data = []
- format_ = "BBHIHHHHQII"
- with open(input_file, 'rb') as bin_data:
- while True:
- line_ = bin_data.read(32)
- if line_:
- if not line_.strip():
- continue
- else:
- break
- if len(line_) == 32:
- result_ = struct.unpack(format_, line_)
- result_data.append((result_[0], result_[1], result_[2], result_[3], result_[4], result_[5], result_[6],
- result_[7], result_[8], result_[9], result_[10]))
- return result_data
-
-
- def get_43_ai_core_data(input_file=None):
- """Function for getting datas from aicore: ov/cnt/total_cyc/ov_cyc/pmu_cnt/stream_id."""
- result_data = []
- with open(input_file, 'rb') as ai_core_file:
- while True:
- line_ = ai_core_file.read(128)
- if line_:
- if not line_.strip():
- continue
- else:
- break
- format_ = "BBHHHIIqqqqqqqqqqIIIIIIII"
- result_ = [hex(i) for i in struct.unpack(format_, line_)]
- byte01 = bin(int(result_[0].replace('0x', ''), 16)).replace('0b', '').zfill(8)
- ov = byte01[-4]
- cnt = byte01[0:4]
- total_cyc = int(result_[7].replace('0x', ''), 16)
- ov_cyc = int(result_[8].replace('0x', ''), 16)
- pmu_cnt = tuple(int(i.replace('0x', ''), 16) for i in result_[9:17])
- stream_id = int(result_[17].replace('0x', ''), 16)
- result_data.append((ov, cnt, total_cyc, ov_cyc, stream_id, pmu_cnt))
- return result_data
-
-
- def get_last_tsch_training_trace(input_file=None):
- """Function for getting last tsch training trace from input file."""
- result_data = []
- format_ = "LLHHLL"
- with open(input_file, 'rb') as bin_data:
- while True:
- line_ = bin_data.read(20)
- if line_:
- if not line_.strip():
- continue
- else:
- break
- if len(line_) == 20:
- result_ = struct.unpack(format_, line_)
- result_data.append((result_[0], result_[1], result_[3], result_[2], result_[4], result_[5]))
- return result_data
-
-
- def get_45_hwts_log(input_file=None):
- """Function for getting hwts log from input file."""
- format_ = ['QIIIIIIIIIIII', 'QIIQIIIIIIII', 'IIIIQIIIIIIII']
- log_type = ['Start of task', 'End of task', 'Start of block', 'End of block', 'Block PMU']
- type1, type2, type3 = [], [], []
- with open(input_file, 'rb') as hwts_data:
- while True:
- line_ = hwts_data.read(64)
- if line_:
- if not line_.strip():
- continue
- else:
- break
- byte_first_four = struct.unpack('BBHHH', line_[0:8])
- byte_first = bin(byte_first_four[0]).replace('0b', '').zfill(8)
- type_ = byte_first[-3:]
- is_warn_res0_ov = byte_first[4]
- cnt = int(byte_first[0:4], 2)
- core_id = byte_first_four[1]
- blk_id, task_id = byte_first_four[3], byte_first_four[4]
- if type_ in ['000', '001', '010']: # log type 0,1,2
- result_ = struct.unpack(format_[0], line_[8:])
- syscnt = result_[0]
- stream_id = result_[1]
- type1.append((log_type[int(type_, 2)], cnt, core_id, blk_id, task_id, syscnt, stream_id))
-
- elif type_ == '011': # log type 3
- result_ = struct.unpack(format_[1], line_[8:])
- syscnt = result_[0]
- stream_id = result_[1]
- if is_warn_res0_ov == '1':
- warn_status = result_[3]
- else:
- warn_status = None
- type2.append(
- (log_type[int(type_, 2)], cnt, is_warn_res0_ov, core_id, blk_id, task_id, syscnt, stream_id,
- warn_status))
- type1.append((log_type[int(type_, 2)], cnt, core_id, blk_id, task_id, syscnt, stream_id))
- elif type_ == '100': # log type 4
- result_ = struct.unpack(format_[2], line_[8:])
- stream_id = result_[2]
- if is_warn_res0_ov == '0':
- total_cyc = result_[4]
- ov_cyc = None
- else:
- total_cyc = None
- ov_cyc = result_[4]
- pmu_events = result_[-8:]
- type3.append((log_type[int(type_, 2)], cnt, is_warn_res0_ov, core_id, blk_id, task_id, stream_id,
- total_cyc, ov_cyc, pmu_events))
- type1.append((log_type[int(type_, 2)], cnt, core_id, blk_id, task_id, total_cyc, stream_id))
-
- return type1, type2, type3
-
-
- def fwrite_format(output_data_path=OUTPUT_FORMAT_DATA, data_source=None, is_start=False):
- if is_start and os.path.exists(OUTPUT_FORMAT_DATA):
- os.remove(OUTPUT_FORMAT_DATA)
- with open(output_data_path, 'a+') as f:
- f.write(data_source)
- f.write("\n")
-
-
- def parsing(source_path):
- """Function for parsing aicore data/tsch fw timeline data/HWTS data/last tsch training trace data."""
- # subprocess.run("cp -r %s ./jobs/" % source_path, shell=True)
- job_name = source_path.split('/')[-1]
- job_path = "/var/log/npu/profiling/" + job_name
- fwrite_format(data_source='====================starting parse task ==================', is_start=True)
- result = get_file_join_name(input_path=job_path, file_name='runtime.host.runtime')
- if result:
- runtime_task_trace_data = get_first_runtime_task_trace(input_file=result)
- fwrite_format(data_source='====================first runtime task trace data==================')
- fwrite_format(data_source=tabulate(runtime_task_trace_data,
- ['mode', 'rpttype', 'bufsize', 'reserved', 'timestamp', 'eventname',
- 'tasktype', 'streamid',
- 'task_id', 'thread', 'device_id', 'kernelname', 'persistant_1bit',
- 'reserved_7bit'],
- tablefmt='simple'))
- result = get_file_join_name(input_path=job_path, file_name='aicore.data.43.dev.profiler_default_tag')
- if result:
- ai_core_data = get_43_ai_core_data(input_file=result)
- fwrite_format(data_source='============================43 AI core data =========================')
- fwrite_format(data_source=tabulate(ai_core_data,
- ['Overflow', 'cnt', 'Total cycles', 'overflowed cycles', 'Stream ID',
- 'PMU events'],
- tablefmt='simple'))
- result = get_file_join_name(input_path=job_path, file_name='ts_track.data.44.dev.profiler_default_tag')
- if result:
- tsch_fw_timeline_data = get_44_tsch_fw_timeline(input_file=result)
- fwrite_format(data_source='============================44 tsch fw timeline data =========================')
- fwrite_format(data_source=tabulate(tsch_fw_timeline_data,
- ['mode', 'rptType', 'bufSize', 'reserved', 'task_type', 'task_state',
- 'stream_id',
- 'task_id', 'timestamp', 'thread', 'device_id'], tablefmt='simple'))
- result = get_file_join_name(input_path=job_path, file_name='hwts.log.data.45.dev.profiler_default_tag')
- start_time = 0
- end_time = 0
- if result:
- data_1, data_2, data_3 = get_45_hwts_log(input_file=result)
- fwrite_format(data_source='============================45 HWTS data ============================')
- for i in data_1:
- if i[0] == 'Start of task' and i[4] == 60000 and start_time == 0:
- start_time = i[5]
- if i[0] == 'End of task' and i[4] == 60000 and end_time == 0:
- end_time = i[5]
-
- fwrite_format(data_source=tabulate(data_1,
- ['Type', 'cnt', 'Core ID', 'Block ID', 'Task ID', 'Cycle counter',
- 'Stream ID'],
- tablefmt='simple'))
- fwrite_format(data_source=tabulate(data_2,
- ['Type', 'cnt', 'WARN', 'Core ID', 'Block ID', 'Task ID', 'Cycle counter',
- 'Stream ID', 'WARN Status'],
- tablefmt='simple'))
- fwrite_format(data_source=tabulate(data_3,
- ['Type', 'cnt', 'Overflow', 'Core ID', 'Block ID', 'Task ID', 'Stream ID',
- 'Total cycles',
- 'Overflowed cycles',
- 'PMU events'], tablefmt='simple'))
-
- result = get_file_join_name(input_path=job_path, file_name='training_trace.dev.profiler_default_tag')
- if result:
- tsch_training_trace_data = get_last_tsch_training_trace(input_file=result)
- fwrite_format(data_source='============================last tsch training_trace data=========================')
- fwrite_format(data_source=tabulate(tsch_training_trace_data,
- ['id_lo', 'id_hi', 'stream_id', 'task_id', 'syscnt_lo', 'syscnt_hi'],
- tablefmt='simple'))
-
- try:
- time_consume = abs(int(start_time) - int(end_time))
- return time_consume if time_consume != 0 else max_time_consume
- except SyntaxError:
- return max_time_consume
|