119 lines
3.3 KiB
Python
119 lines
3.3 KiB
Python
# Copyright (c) OpenMMLab. All rights reserved.
|
|
import argparse
|
|
|
|
import numpy as np
|
|
from texttable import Texttable
|
|
|
|
|
|
def parse_args():
|
|
parser = argparse.ArgumentParser(
|
|
description='Analyze sdk profiler file tool.')
|
|
parser.add_argument('profile_file', help='SDK profile file path')
|
|
args = parser.parse_args()
|
|
return args
|
|
|
|
|
|
def get_name(addr, prev, addr2name, used_addr, depth, skip):
|
|
node_name = addr2name[addr] if not skip else ''
|
|
if addr not in prev:
|
|
return ' ' * depth * 4 + node_name
|
|
prev_addr = prev[addr]
|
|
if prev_addr in used_addr:
|
|
depth += 1
|
|
skip = True
|
|
prev_name = get_name(prev[addr], prev, addr2name, used_addr, depth, skip)
|
|
if len(prev_name.split()) == 0:
|
|
return prev_name + node_name
|
|
return prev_name + '/' + node_name
|
|
|
|
|
|
def main():
|
|
args = parse_args()
|
|
with open(args.profile_file) as f:
|
|
data = f.read()
|
|
graph, events = data.split('----\n')
|
|
graph = graph.strip().split('\n')
|
|
events = events.strip().split('\n')
|
|
|
|
addr2name = {}
|
|
addr2id = {}
|
|
id2addr = {}
|
|
next = {}
|
|
prev = {}
|
|
for i, line in enumerate(graph):
|
|
info = line.split()
|
|
name, addr = info[:2]
|
|
addr2name[addr] = name
|
|
addr2id[addr] = i
|
|
id2addr[i] = addr
|
|
next[addr] = []
|
|
for child in info[2:]:
|
|
next[addr].append(child)
|
|
prev[child] = addr
|
|
|
|
n_active = {i: 0 for i in range(len(addr2id))}
|
|
n_call = {i: 0 for i in range(len(addr2id))}
|
|
t_occupy = {i: 0 for i in range(len(addr2id))}
|
|
t_usage = {i: 0 for i in range(len(addr2id))}
|
|
t_time = {i: [] for i in range(len(addr2id))}
|
|
used_id = set()
|
|
used_addr = set()
|
|
event_start = {}
|
|
now = 0
|
|
first_id = None
|
|
|
|
for event in events:
|
|
words = event.split()
|
|
addr = words[0]
|
|
id = addr2id[addr]
|
|
used_addr.add(addr)
|
|
used_id.add(id)
|
|
kind, index, ts = map(int, words[1:])
|
|
|
|
if first_id is None:
|
|
first_id = id
|
|
|
|
if id == first_id and kind == 0 and n_active[id] == 0:
|
|
now = ts
|
|
|
|
key = (id, index)
|
|
delta = ts - now
|
|
now = ts
|
|
|
|
for i, n_act in n_active.items():
|
|
if n_act > 0:
|
|
t_occupy[i] += delta
|
|
t_usage[i] += delta * n_act
|
|
|
|
if kind == 0:
|
|
event_start[key] = ts
|
|
n_active[id] += 1
|
|
n_call[id] += 1
|
|
else:
|
|
dt = ts - event_start[key]
|
|
t_time[id].append(dt)
|
|
event_start.pop(key)
|
|
n_active[id] -= 1
|
|
|
|
table = Texttable(max_width=0)
|
|
table.header(
|
|
['name', 'occupy', 'usage', 'n_call', 't_mean', 't_50%', 't_90%'])
|
|
|
|
for id in sorted(list(used_id)):
|
|
occupy = t_occupy[id] / (t_occupy[first_id])
|
|
usage = t_usage[id] / (t_occupy[first_id])
|
|
times = sorted(t_time[id])
|
|
t_mean = np.mean(times) / 1000
|
|
t_50 = times[int(len(times) * 0.5)] / 1000
|
|
t_90 = times[int(len(times) * 0.9)] / 1000
|
|
name = get_name(id2addr[id], prev, addr2name, used_addr, 0, False)
|
|
if len(next[id2addr[id]]) != 0:
|
|
occupy = '-'
|
|
usage = '-'
|
|
table.add_row([name, occupy, usage, n_call[id], t_mean, t_50, t_90])
|
|
print(table.draw())
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|