forked from andikleen/pmu-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
interval-plot.py
executable file
·124 lines (112 loc) · 3.47 KB
/
interval-plot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/usr/bin/env python
# plot interval CSV output from perf/toplev
# perf stat -I1000 -x, -o file ...
# toplev -I1000 -x, -o file ...
# interval-plot.py file (or stdin)
# delimeter must be ,
# this is for data that is not normalized
# TODO: move legend somewhere else where it doesn't overlap?
from __future__ import print_function
import os
import csv
import sys
import collections
import argparse
import re
import matplotlib
if os.getenv("DISPLAY") is None:
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import csv_formats
import gen_level
p = argparse.ArgumentParser(
usage='plot interval CSV output from perf stat/toplev',
description='''
perf stat -I1000 -x, -o file ...
toplev -I1000 -x, -o file ...
interval-plot.py file (or stdin)
delimeter must be ,
this is for data that is not normalized.''')
p.add_argument('--xkcd', action='store_true', help='enable xkcd mode')
p.add_argument('--style', help='set mpltools style (e.g. ggplot)')
p.add_argument('file', help='CSV file to plot (or stdin)', nargs='?')
p.add_argument('--output', '-o', help='Output to file. Otherwise show.',
nargs='?')
args = p.parse_args()
if args.style:
try:
from mpltools import style
style.use(args.style)
except ImportError:
print("Need mpltools for setting styles (pip install mpltools)")
try:
import brewer2mpl
all_colors = brewer2mpl.get_map('Paired', 'Qualitative', 12).hex_colors
except ImportError:
print("Install brewer2mpl for better colors (pip install brewer2mpl)")
all_colors = ('green','orange','red','blue',
'black','olive','purple','#6960EC', '#F0FFFF',
'#728C00', '#827B60', '#F87217', '#E55451', # 16
'#F88017', '#C11B17', '#17BFC2', '#C48793') # 20
cur_colors = collections.defaultdict(lambda: all_colors)
assigned = dict()
if args.file:
inf = open(args.file, "r")
else:
inf = sys.stdin
rc = csv.reader(inf)
timestamps = dict()
value = dict()
def isnum(x):
return re.match(r'[0-9.]+', x)
val = ""
for row in rc:
r = csv_formats.parse_csv_row(row)
if r is None:
continue
ts, cpu, event, val = r.ts, r.cpu, r.ev, r.val
if event not in assigned:
level = gen_level.get_level(event)
assigned[event] = cur_colors[level][0]
cur_colors[level] = cur_colors[level][1:]
if len(cur_colors[level]) == 0:
cur_colors[level] = all_colors
value[event] = []
timestamps[event] = []
timestamps[event].append(float(ts))
try:
value[event].append(float(val.replace("%","")))
except ValueError:
value[event].append(0.0)
levels = set(map(gen_level.get_level, assigned.keys()))
if args.xkcd:
try:
plt.xkcd()
except NameError:
print("Please update matplotlib. Cannot enable xkcd mode.")
n = 1
for l in levels:
ax = plt.subplot(len(levels), 1, n)
if val.find('%') >= 0:
ax.set_ylim(0, 100)
t = []
for j in assigned.keys():
print(j, gen_level.get_level(j), l)
if gen_level.get_level(j) == l:
t.append(j)
if 'style' not in globals():
ax.plot(timestamps[j], value[j], assigned[j])
else:
ax.plot(timestamps[j], value[j])
leg = ax.legend(t, loc='upper left')
leg.get_frame().set_alpha(0.5)
n += 1
plt.xlabel('Time')
if val.find('%') >= 0:
plt.ylabel('Bottleneck %')
else:
plt.ylabel("Counter value")
if args.output:
plt.savefig(args.output)
else:
plt.show()