import sys
import re
-
import numpy as np
import numpy.linalg as nplag
+import matplotlib.pyplot as plt
+import matplotlib
+
import collections
import psycopg2
import psycopg2.extras
import subprocess
import json
+import pickle
import utils
+#matplotlib.rcParams['font.size'] = 8
+matplotlib.rcParams['savefig.bbox'] = 'tight'
conn = psycopg2.connect(dbname="linux-conf-perf", connection_factory=psycopg2.extras.NamedTupleConnection)
cur = conn.cursor()
for k in self:
print("%-40s %s" % (k, self[k]))
-configs = {}
+def load_configs(measurements, options):
+ try:
+ configs = pickle.load(open('configs.pickle', 'rb'))
+ except:
+ configs = {}
+ for i in range(len(measurements)):
+ config = Config(measurements[i].conf)
+ keys = config.copy().keys()
+ for k in keys:
+ if not k in options:
+ del config[k]
+ configs[measurements[i].conf] = config
+ pickle.dump(configs, open('configs.pickle', 'wb'))
+ return configs
-def construct_ab(options, measurements):
- A = np.zeros((len(measurements), len(options) + 1))
- B = np.zeros((len(measurements), 1))
+def construct_ab(options, measurements, configs):
+ A = np.mat(np.zeros((len(measurements), len(options) + 1)))
+ B = np.mat(np.zeros((len(measurements), 1)))
for i in range(len(measurements)):
- try:
- config = configs[measurements[i].conf]
- except KeyError:
- config = Config(measurements[i].conf)
- configs[measurements[i].conf] = config
+ config = configs[measurements[i].conf]
A[i, len(options)] = 1
B[i] = measurements[i].value
for j in range(len(options)):
A[i,j] = 1 if config[options.name_by_index(j)] == 'y' else 0
return (A, B)
+def plot_values(measurements, configs, measurements_est, highlight_options):
+ print(measurements_est.__class__, measurements_est.shape)
+ B = np.mat(np.zeros((len(measurements),1)))
+ for i in range(len(measurements)):
+ B[i] = measurements[i].value
+
+ idx = np.argsort(B, 0)
+ B = B[idx,0]
+ measurements = sorted(measurements, key=lambda x: x.value)
+ measurements_est = measurements_est[idx, 0]
-def evaluate():
- cur.execute("SELECT conf, value FROM measure WHERE result='nominal' AND toolgit IN (1, 11);")
- measurements = cur.fetchall()
+ plt.plot(measurements_est, 'x', color='#aaaaaa')
+ plt.hold(True)
+ plt.gcf().set_size_inches(8,4)
+ plt.plot(B, color='b')
+ plt.xlabel('Configuration')
+ plt.ylabel('cyclictest result [µs]')
+ yy = 0
+ for o in highlight_options if 0 else []:
+ yy += 1
+ x = []
+ y = []
+ for i in range(len(measurements)):
+ if configs[measurements[i].conf][o] == 'y':
+ x.append(i)
+ y.append(measurements[i].value)
+ plt.plot(x, (yy*5-150)*np.ones(len(x)), '+')
+
+ plt.legend(['Model', 'Measured'] + [o[7:] for o in highlight_options], loc = 'upper left')
+ plt.grid(True)
+ plt.xlim(0,len(measurements))
+ plt.savefig('measurements.pdf')
+ #plt.show()
+
+def save_options(options):
+ json.dump(options, open('options.json', 'w'), indent=' ', sort_keys=True)
+def load_variable_options(measurements):
if os.path.exists('options.json'):
options = VariableOptions([])
options.update(json.load(open('options.json', 'r')))
options.update_order()
else:
options = VariableOptions(measurements)
- json.dump(options, open('options.json', 'w'), indent=' ', sort_keys=True)
+ save_options(options)
#options.print()
+ return options
- (A,B) = construct_ab(options, measurements)
+def remove_linerly_dependent_options(options, measurements, configs):
+ (A,B) = construct_ab(options, measurements, configs)
rank = nplag.matrix_rank(A)
+ if rank == A.shape[1]:
+ return options
+
o = options.copy()
for k in sorted(o.keys()):
del options[k]
options.update_order()
- (A,B) = construct_ab(options, measurements)
+ (A,B) = construct_ab(options, measurements, configs)
if nplag.matrix_rank(A) != rank:
options[k]=None
options.update_order()
else:
print("Removed", k)
+ return options
+
+class OptionResult:
+ def __init__(self, option_name, regression=None, yes_count=None):
+ self.option_name = option_name
+ self.regression = regression
+ self.yes_count = int(yes_count)
+ self.measure_diff = []
+
+ def calc_measure_diff(self, A, B, options):
+ oidx = options[self.option_name]
+ for m1 in range(A.shape[0]):
+ if A[m1,oidx] == 1:
+ row = A[m1].copy()
+ row[0,oidx] = 0
+ for m2 in range(A.shape[0]):
+ if A[m2,oidx] == 0 and (row == A[m2]).all():
+ self.measure_diff.append(B[m1] - B[m2])
+ break
+
+def plot_bars(results):
+ y_pos = np.arange(len(results), 0, -1)
+ regr = np.array([r.regression for r in results])
+ diff = np.array([np.array(r.measure_diff).mean() for r in results])
+
+ fig, ax = plt.subplots()
+ fig.set_size_inches(8,12)
+
+ ax.set_yticks(y_pos)
+ ax.set_yticklabels([r.option_name[7:] for r in results], fontsize=12)
+ rects1 = ax.barh(y_pos, regr, height=0.35, color='b')
+ rects2 = ax.barh(y_pos+0.35, diff, height=0.35, color='w', hatch='//')
+ ax.legend(['regression', 'two measurement diff'])
+ ax.grid(True)
+ ax.set_xlabel("Config option influence [µs]")
+ plt.savefig('option_res.pdf')
+ #plt.show()
+
+def evaluate():
+ cur.execute("SELECT conf, value FROM measure WHERE result='nominal' AND toolgit IN (1, 11);")
+ measurements = cur.fetchall()
+
+ options = load_variable_options(measurements)
+ configs = load_configs(measurements, options)
- (A,B) = construct_ab(options, measurements)
+ options = remove_linerly_dependent_options(options, measurements, configs)
+ save_options(options)
+
+ (A,B) = construct_ab(options, measurements, configs)
#np.set_printoptions(threshold = float('nan'), linewidth = 300)
np.set_printoptions(edgeitems = 9, linewidth = 80)
# print(A)
# print(B)
result = nplag.lstsq(A, B)
- print(result)
- x=result[0]
+ x=np.mat(result[0])
+ try:
+ results = pickle.load(open('results.pickle', 'rb'))
+ except:
+ results = []
+ for k in options:
+ print(k)
+ idx = options[k]
+ r = OptionResult(k, regression=x.item(idx), yes_count=A[:,idx].sum())
+ r.calc_measure_diff(A, B, options)
+
+ results.append(r)
+ results.sort(key=lambda r: r.regression)
+ pickle.dump(results, open('results.pickle', 'wb'))
- results = []
- for k in options:
- idx = options[k]
- results.append((k, x[idx], A[:,idx].sum(), A[:,idx].sum()/A.shape[0]*100))
- results.sort(key=lambda r: r[1])
for r in results:
- print("%-40s %7.4g %8d %3d%%" % r)
- print("%-40s %g" % ("common", x[len(options)]))
+ print("{option_name:<40} {regression:7.2f} {yes_count:4d} {percent:2}%".format(percent=10, **r.__dict__))
+ print("%-40s %6.2f" % ("common", x[len(options)]))
print(A.shape)
+ plot_values(measurements, configs, A*x, [r.option_name for r in results])
+ plot_bars(results)
+
if __name__ == '__main__':
evaluate()