mmdeploy/tools/sdk_analyze.py

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()