aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-05-02 15:49:11 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2013-05-02 15:49:11 -0400
commite01b51b677e925bc2cd8d55afa89f29674b6f356 (patch)
treee3f957016035b3b23f31b44ad52925913bc30f95
parent219e9595520c5069f4d7a41cd42db8ca50ac8005 (diff)
Added --collapse option to parse_exps.py for creating simpler graphs.
This creates csvs which have merged the lines which only differ by variables whose values are numbers (e.g. 'wss', 'number of tasks', or 'duration', but not 'scheduler'). For example, consider a csv which is tracking the change in working set sizes. There are 3 different experiment configurations per WSS, one with 12 tasks, one for 14, and another for 16. Without --collapse, a seperate csv (and line to plot in plot_exps.py) will be created for each of the 12, 14, and 16 configurations. With --collapse, a single csv (and a single line plotted by plot_exps.py) will be created which averages the values of 12, 14, and 16 tasks for each WSS. This is very useful for noticing trends or presenting overhead bar charts or other examples in papers.
-rwxr-xr-xparse_exps.py82
-rwxr-xr-xplot_exps.py6
2 files changed, 71 insertions, 17 deletions
diff --git a/parse_exps.py b/parse_exps.py
index 37667aa..82febfc 100755
--- a/parse_exps.py
+++ b/parse_exps.py
@@ -43,6 +43,10 @@ def parse_args():
43 parser.add_option('-s', '--scale-against', dest='scale_against', 43 parser.add_option('-s', '--scale-against', dest='scale_against',
44 metavar='PARAM=VALUE', default="type=unmanaged", 44 metavar='PARAM=VALUE', default="type=unmanaged",
45 help='calculate task scaling factors against these configs') 45 help='calculate task scaling factors against these configs')
46 parser.add_option('-c', '--collapse', dest='collapse',
47 action='store_true', default=False,
48 help=('simplify graphs where possible by averaging ' +
49 'parameter values which are numbers (dangerous)'))
46 50
47 return parser.parse_args() 51 return parser.parse_args()
48 52
@@ -226,30 +230,80 @@ def fill_table(table, builder, exps, opts):
226 sys.stderr.write('\n') 230 sys.stderr.write('\n')
227 231
228 232
229def write_output(table, opts): 233def write_csvs(table, out, print_empty=False):
230 reduced_table = table.reduce() 234 reduced_table = table.reduce()
231 235
236 # Write out csv directories for all variable params
237 dir_map = reduced_table.to_dir_map()
238
239 # No csvs to write, assume user meant to print out data
240 if dir_map.is_empty():
241 if print_empty:
242 sys.stderr.write("Too little data to make csv files, " +
243 "printing results.\n")
244 for key, exp in table:
245 for e in exp:
246 print(e)
247 else:
248 dir_map.write(out)
249
250
251def write_collapsed_csvs(table, opts):
252 sys.stderr.write("Collapse option specified. "
253 "Only one numeric column at a time will be plotted.\n"
254 "The values of others will be averaged. "
255 "This is dangerous and can hide important trends!\n")
256
257 original_map = table.get_col_map()
258
259 builder = ColMapBuilder()
260 numeric_cols = []
261
262 # Add only nonnumeric fields to builder
263 for column in original_map.columns():
264 numeric = True
265 for v in original_map.get_values()[column]:
266 try:
267 float(v)
268 except ValueError:
269 numeric = False
270 builder.try_add(column, v)
271 if numeric:
272 numeric_cols += [column]
273
274 for num_column in numeric_cols:
275 # Only going to consider a single number column at a time
276 for num_value in original_map.get_values()[column]:
277 builder.try_add(num_column, num_value)
278
279 next_map = builder.build()
280 next_table = TupleTable(next_map)
281
282 # Re-sort data into new table using this new key
283 for mapped_key, points in table:
284 kv = original_map.get_kv(mapped_key)
285 next_table[kv] += points
286
287 write_csvs(next_table, opts.out)
288
289 builder.try_remove(num_column)
290
291
292def write_output(table, opts):
232 if opts.write_map: 293 if opts.write_map:
233 sys.stderr.write("Writing python map into %s...\n" % opts.out) 294 sys.stderr.write("Writing python map into %s...\n" % opts.out)
295 reduced_table = table.reduce()
234 reduced_table.write_map(opts.out) 296 reduced_table.write_map(opts.out)
235 else: 297 else:
236 if opts.force and os.path.exists(opts.out): 298 if opts.force and os.path.exists(opts.out):
237 sh.rmtree(opts.out) 299 sh.rmtree(opts.out)
238 300
239 # Write out csv directories for all variable params 301 sys.stderr.write("Writing csvs into %s...\n" % opts.out)
240 dir_map = reduced_table.to_dir_map() 302
241 303 if opts.collapse:
242 # No csvs to write, assume user meant to print out data 304 write_collapsed_csvs(table, opts)
243 if dir_map.is_empty():
244 if not opts.verbose:
245 sys.stderr.write("Too little data to make csv files, " +
246 "printing results.\n")
247 for key, exp in table:
248 for e in exp:
249 print(e)
250 else: 305 else:
251 sys.stderr.write("Writing csvs into %s...\n" % opts.out) 306 write_csvs(table, opts.out, not opts.verbose)
252 dir_map.write(opts.out)
253 307
254 308
255def main(): 309def main():
diff --git a/plot_exps.py b/plot_exps.py
index 15c54d0..2d6f06b 100755
--- a/plot_exps.py
+++ b/plot_exps.py
@@ -85,12 +85,12 @@ def plot_by_variable(details):
85 axes.set_title(details.title) 85 axes.set_title(details.title)
86 86
87 lines, labels = zip(*style_map.get_key()) 87 lines, labels = zip(*style_map.get_key())
88 axes.legend(tuple(lines), tuple(labels), prop={'size':10}) 88 axes.legend(tuple(lines), tuple(labels), prop={'size':10}, loc=2)
89 89
90 axes.set_ylabel(details.value) 90 axes.set_ylabel(details.value)
91 axes.set_xlabel(details.variable) 91 axes.set_xlabel(details.variable)
92 axes.set_xlim(0, axes.get_xlim()[1] + 1) 92 axes.set_xlim(0, axes.get_xlim()[1])
93 axes.set_ylim(0, axes.get_ylim()[1] + 1) 93 axes.set_ylim(0, axes.get_ylim()[1])
94 94
95 plot.savefig(details.out, format=OUT_FORMAT) 95 plot.savefig(details.out, format=OUT_FORMAT)
96 96