blob: c1368e827ccd1d60e03bcb284f19dd6d5b6bd8b6 [file] [log] [blame]
Ved-vampir0d0740c2015-04-06 15:39:33 +03001import sys
2import time
3
4from copy import deepcopy
5
6import numpy
7import scipy.optimize as scp
8import matplotlib.pyplot as plt
9
10import io_py_result_processor as io_test
11
12key_pos = {'blocksize': 0, 'direct_io': 1, 'name': 2}
13actions = ['randwrite', 'randread', 'read', 'write']
14types = ['s', 'd']
15colors = ['red', 'green', 'blue', 'cyan',
16 'magenta', 'black', 'yellow', 'burlywood']
17
koder aka kdanilov2e928022015-04-08 13:47:15 +030018
Ved-vampir0d0740c2015-04-06 15:39:33 +030019def get_key(x, no):
20 """ x = (), no = key_pos key """
21 keys = deepcopy(key_pos)
22 del keys[no]
23 key = [x[n] for n in keys.values()]
24 return tuple(key), x[key_pos[no]]
25
26
27def generate_groups(data, group_id):
28 """ select data for plot by group_id
29 data - processed_series"""
30 grouped = {}
31
32 for key, val in data.items():
33 new_key, group_val = get_key(key, group_id)
34 group = grouped.setdefault(new_key, {})
35 group[group_val] = val
36
37 return grouped
38
39
40def gen_dots(val):
41 """Generate dots from real data
42 val = dict (x:y)
43 return ox, oy lists """
44 oy = []
45 ox = []
46 for x in sorted(val.keys()):
47 ox.append(int(x[:-1]))
48 if val[x][0] != 0:
49 oy.append(1.0/val[x][0])
50 else:
51 oy.append(0)
52 return ox, oy
53
54
55def gen_line_numpy(x, y):
56 A = numpy.vstack([x, numpy.ones(len(x))]).T
57 coef = numpy.linalg.lstsq(A, y)[0]
58 funcLine = lambda tpl, x: tpl[0] * x + tpl[1]
59 print coef
60 return x, funcLine(coef, x)
61
62
63def gen_line_scipy(x, y):
64 funcLine = lambda tpl, x: tpl[0] * x + tpl[1]
65 ErrorFunc = lambda tpl, x, y: 1.0 - y/funcLine(tpl, x)
66 tplInitial = (1.0, 0.0)
67 # print x, y
68 tplFinal, success = scp.leastsq(ErrorFunc, tplInitial[:], args=(x, y),
69 diag=(1./x.mean(), 1./y.mean()))
70 if success not in range(1, 4):
71 raise ValueError("No line for this dots")
72 xx = numpy.linspace(x.min(), x.max(), 50)
73 print tplFinal
74 # print x, ErrorFunc(tplFinal, x, y)
75 return xx, funcLine(tplFinal, xx)
76
77
78def gen_app_plot(key, val, plot, color):
79 """ Plots with fake line and real dots around"""
80 ox, oy = gen_dots(val)
81 name = "_".join(str(k) for k in key)
82 if len(ox) < 2:
83 # skip single dots
84 return False
85 # create approximation
86 x = numpy.array(ox)#numpy.log(ox))
87 y = numpy.array(oy)#numpy.log(oy))
88 print x, y
89 try:
90 print name
91 x1, y1 = gen_line_scipy(x, y)
92 plot.plot(x1, y1, color=color)
93 #
94 #plot.loglog(x1, y1, color=color)
95 except ValueError:
96 # just don't draw it - it's ok
97 # we'll see no appr and bad dots
98 # not return False, because we need see dots
99 pass
100 plot.plot(x, y, '^', label=name, markersize=7, color=color)
101 #plot.loglog(x, y, '^', label=name, markersize=7, color=color)
102 return True
103
104
105def save_plot(key, val):
106 """ one plot from one dict item with value list"""
107 ox, oy = gen_dots(val)
108 name = "_".join(str(k) for k in key)
109 plt.plot(ox, oy, label=name)
110
111
112def plot_generation(fname, group_by):
113 """ plots for value group_by in imgs by actions"""
114 data = list(io_test.load_io_py_file(fname))
115 item = io_test.Data("hdr")
116 for key, vals in io_test.groupby_globally(data, io_test.key_func).items():
117 item.series[key] = [val['iops'] for val in vals]
118 io_test.process_inplace(item)
119
120 pr_data = generate_groups(item.processed_series, group_by)
121 print pr_data
122
123 #fig = plt.figure()
124 plot = plt.subplot(111)
125
126 for action in actions:
127 for tp in types:
128 color = 0
129 hasPlot = False
130 for key, val in pr_data.items():
131 if action in key and tp in key:
132 ok = gen_app_plot(key, val, plot, colors[color])
133 hasPlot = hasPlot or ok
134 color += 1
135 # use it for just connect dots
136 #save_plot(key, val)
137 if hasPlot:
138 # Shrink current axis by 10%
139 box = plot.get_position()
140 plot.set_position([box.x0, box.y0 + box.height * 0.1,
141 box.width, box.height * 0.9])
142
143 # Put a legend to the bottom
144 plot.legend(loc='lower center', bbox_to_anchor=(0.5, -0.25),
145 fancybox=True, shadow=True, ncol=4,
146 fontsize='xx-small')
147 plt.title("Plot for %s on %s" % (group_by, action))
148 plt.ylabel("time")
149 plt.xlabel(group_by)
150 plt.grid()
151 # use it if want scale plot somehow
152 # plt.axis([0.0, 5000.0, 0.0, 64.0])
153 name = "%s__%s_%s.png" % (group_by, action, tp)
154 plt.savefig(name, format='png', dpi=100)
155 plt.clf()
156 plot = plt.subplot(111)
157 color = 0
158
159
160def deviation_on_deviation(groups_list, data):
161 """ calc deviation of data all and by selection groups"""
162 total_dev = io_test.round_deviation(io_test.med_dev(data))
163 grouped_dev = [total_dev]
164 for group in groups_list:
165 beg = 0
166 end = group
167 local_dev = []
168 while end <= len(data):
169 local_dev.append(io_test.round_deviation(io_test.med_dev(data[beg:end]))[0])
170 beg += group
171 end += group
172 grouped_dev.append(io_test.round_deviation(io_test.med_dev(local_dev)))
173 return grouped_dev
174
175
176
177def deviation_generation(fname, groups_list):
178 """ Print deviation by groups for data from fname """
179 CONC_POS = key_pos['concurence']
180 int_list = [int(i) for i in groups_list]
181 data = list(io_test.load_io_py_file(fname))
182 item = io_test.Data("hdr")
183 for key, vals in io_test.groupby_globally(data, io_test.key_func).items():
184 item.series[key] = [val['iops'] * key[CONC_POS] for val in vals]
185 print deviation_on_deviation(int_list, item.series[key])
186
187
188def main(argv):
189 if argv[1] == "plot":
190 plot_generation(argv[2], argv[3])
191 elif argv[1] == "dev":
192 deviation_generation(argv[2], argv[3:])
193
194
195if __name__ == "__main__":
196 exit(main(sys.argv))
197
198
199
200