Lava: Add standard deviation the benchmark plots
[lttng-ci.git] / scripts / lttng-baremetal-tests / generate-plots.py
1 # Copyright (C) 2017 - Francis Deslauriers <francis.deslauriers@efficios.com>
2 #
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation, either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16
17 import os, sys
18 import numpy as np
19 import pandas as pd
20
21 #Set Matplotlib to use the PNG non interactive backend
22 import matplotlib as mpl
23 mpl.use('Agg')
24
25 import matplotlib.pyplot as plt
26 from matplotlib.ticker import MaxNLocator
27 from cycler import cycler
28
29 def rename_cols(df):
30 new_cols = {'baseline_1thr_peritermean': 'basel_1thr',
31 'baseline_2thr_peritermean': 'basel_2thr',
32 'baseline_4thr_peritermean': 'basel_4thr',
33 'baseline_8thr_peritermean': 'basel_8thr',
34 'baseline_16thr_peritermean': 'basel_16thr',
35 'lttng_1thr_peritermean': 'lttng_1thr',
36 'lttng_2thr_peritermean': 'lttng_2thr',
37 'lttng_4thr_peritermean': 'lttng_4thr',
38 'lttng_8thr_peritermean': 'lttng_8thr',
39 'lttng_16thr_peritermean': 'lttng_16thr',
40 'baseline_1thr_periterstdev': 'basel_1thr_stdev',
41 'baseline_2thr_periterstdev': 'basel_2thr_stdev',
42 'baseline_4thr_periterstdev': 'basel_4thr_stdev',
43 'baseline_8thr_periterstdev': 'basel_8thr_stdev',
44 'baseline_16thr_periterstdev': 'basel_16thr_stdev',
45 'lttng_1thr_periterstdev': 'lttng_1thr_stdev',
46 'lttng_2thr_periterstdev': 'lttng_2thr_stdev',
47 'lttng_4thr_periterstdev': 'lttng_4thr_stdev',
48 'lttng_8thr_periterstdev': 'lttng_8thr_stdev',
49 'lttng_16thr_periterstdev': 'lttng_16thr_stdev'
50 }
51 df.rename(columns=new_cols, inplace=True)
52 return df
53
54 def convert_us_to_ns(df):
55 cols = [col for col in df.columns if 'periter' in col]
56 df[cols] = df[cols].apply(lambda x: x*1000)
57 return df
58
59 def create_plot(df, graph_type):
60 # We split the data into two plots so it's easier to read
61 lower = ['basel_{}thr'.format(s) for s in [1,2,4]]
62 lower += ['lttng_{}thr'.format(s) for s in [1,2,4]]
63
64 upper = ['basel_{}thr'.format(s) for s in [8, 16]]
65 upper += ['lttng_{}thr'.format(s) for s in [8, 16]]
66
67 lower_stdev = ['{}_stdev'.format(s) for s in lower]
68 upper_stdev = ['{}_stdev'.format(s) for s in upper]
69
70 lower_color = ['lightcoral', 'gray', 'chartreuse', 'red', 'black', 'forestgreen']
71 upper_color = ['deepskyblue', 'orange', 'mediumblue', 'saddlebrown']
72
73 title='Meantime per syscalls for {} testcase'.format(graph_type)
74
75 # Create a plot with 2 sub-plots
76 f, arrax = plt.subplots(2, sharex=True, figsize=(12, 14))
77
78 f.suptitle(title, fontsize=18)
79
80 for (ax, data_cols, stdev_cols, colors) in zip(arrax, [lower, upper], [lower_stdev, upper_stdev], [lower_color,upper_color]):
81 curr_df = df[data_cols]
82
83 # set the color cycler for this plot
84 ax.set_prop_cycle(cycler('color', colors))
85
86 # Plot each line and its errorbars
87 for (data, stdev) in zip(data_cols, stdev_cols):
88 ax.errorbar(x=df.index.values, y=df[data], yerr=df[stdev], marker='o')
89
90 ax.set_ylim(0)
91 ax.grid()
92 ax.set_xlabel('Jenkins Build ID')
93 ax.set_ylabel('Meantime per syscall [us]')
94 ax.legend(labels=curr_df.columns.values, bbox_to_anchor=(1.2,1))
95 ax.xaxis.set_major_locator(MaxNLocator(integer=True))
96
97 plt.savefig('{}.png'.format(graph_type), bbox_inches='tight')
98
99 # Writes a file that contains commit id of all configurations shown in the
100 # plots
101 def create_metadata_file(res_dir):
102 list_ = []
103 for dirname, dirnames, res_files in os.walk('./'+res_dir):
104 if len(dirnames) > 0:
105 continue
106 metadata = pd.read_csv(os.path.join(dirname, 'metadata.csv'))
107 list_.append(metadata)
108
109 df = pd.concat(list_)
110 df.index=df.build_id
111 df.sort_index(inplace=True)
112 df.to_csv('metadata.csv', index=False)
113
114 #Iterates over a result directory and creates the plots for the different
115 #testcases
116 def create_plots(res_dir):
117 df = pd.DataFrame()
118 metadata_df = pd.DataFrame()
119 list_ = []
120 for dirname, dirnames, res_files in os.walk('./'+res_dir):
121 if len(dirnames) > 0:
122 continue
123 metadata = pd.read_csv(os.path.join(dirname, 'metadata.csv'))
124
125 for res in res_files:
126 if res in 'metadata.csv':
127 continue
128 tmp = pd.read_csv(os.path.join(dirname, res))
129 #Use the build id as the index for the dataframe for filtering
130 tmp.index = metadata.build_id
131 #Add the testcase name to the row for later filtering
132 tmp['testcase'] = res.split('.')[0]
133 list_.append(tmp)
134
135 df = pd.concat(list_)
136 df = convert_us_to_ns(df)
137 df = rename_cols(df)
138 df.sort_index(inplace=True)
139
140 #Go over the entire dataframe by testcase and create a plot for each type
141 for testcase in df.testcase.unique():
142 df_testcase = df.loc[df['testcase'] == testcase]
143 create_plot(df=df_testcase, graph_type=testcase)
144
145 def main():
146 res_path = sys.argv[1]
147 create_plots(os.path.join(res_path))
148 create_metadata_file(os.path.join(res_path))
149
150 if __name__ == '__main__':
151 main()
This page took 0.032954 seconds and 4 git commands to generate.