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 | |
koder aka kdanilov | 4e9f3ed | 2015-04-14 11:26:12 +0300 | [diff] [blame^] | 12 | key_pos = {'blocksize': 0, 'direct': 1, 'name': 2} |
Ved-vampir | 0d0740c | 2015-04-06 15:39:33 +0300 | [diff] [blame] | 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 | |