| Ved-vampir | 0d0740c | 2015-04-06 15:39:33 +0300 | [diff] [blame] | 1 | import sys | 
|  | 2 | import time | 
|  | 3 |  | 
|  | 4 | from copy import deepcopy | 
|  | 5 |  | 
|  | 6 | import numpy | 
|  | 7 | import scipy.optimize as scp | 
|  | 8 | import matplotlib.pyplot as plt | 
|  | 9 |  | 
|  | 10 | import io_py_result_processor as io_test | 
|  | 11 |  | 
|  | 12 | key_pos = {'blocksize': 0, 'direct_io': 1, 'name': 2} | 
|  | 13 | actions = ['randwrite', 'randread', 'read', 'write'] | 
|  | 14 | types = ['s', 'd'] | 
|  | 15 | colors = ['red', 'green', 'blue', 'cyan', | 
|  | 16 | 'magenta', 'black', 'yellow', 'burlywood'] | 
|  | 17 |  | 
| koder aka kdanilov | 2e92802 | 2015-04-08 13:47:15 +0300 | [diff] [blame^] | 18 |  | 
| Ved-vampir | 0d0740c | 2015-04-06 15:39:33 +0300 | [diff] [blame] | 19 | def 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 |  | 
|  | 27 | def 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 |  | 
|  | 40 | def 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 |  | 
|  | 55 | def 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 |  | 
|  | 63 | def 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 |  | 
|  | 78 | def 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 |  | 
|  | 105 | def 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 |  | 
|  | 112 | def 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 |  | 
|  | 160 | def 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 |  | 
|  | 177 | def 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 |  | 
|  | 188 | def 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 |  | 
|  | 195 | if __name__ == "__main__": | 
|  | 196 | exit(main(sys.argv)) | 
|  | 197 |  | 
|  | 198 |  | 
|  | 199 |  | 
|  | 200 |  |