#!/usr/bin/env python import defapp from os.path import splitext, basename from optparse import make_option as o from tempfile import NamedTemporaryFile as Tmp from plot import decode, scenario_heading, get_data_tmpfile from gnuplot import gnuplot, FORMATS options = [ o(None, '--shared-l3', action='store_true', dest='sharedL3'), o(None, '--name', action='store', dest='name', help='where to store the \ output'), o(None, '--type', action='store', dest='type', type='choice', choices=['hard','soft'], help='type of plot'), o('-f', '--format', action='store', dest='format', type='choice', choices=FORMATS, help='output format'), o(None, '--paper', action='store_true', dest='paper'), o(None, '--wide', action='store_true', dest='wide'), ] defaults = { 'sharedL3' : False, 'name' : 'test', 'type' : 'hard', 'format' : 'show', 'xrange' : (74.5, 250.5), 'yrange' : (100, 1700), 'xticks' : (0, 25), 'yticks' : (0, 250), 'title' : None, 'xlabel' : 'number of tasks', 'ylabel' : 'overhead (us)', 'paper' : False, 'split' : False, 'wide' : False, } JOB_TYPE = { 'NP' : 'Non Preemptive jobs', 'P' : 'Preemptive jobs' } BWORK = { 'bg' : 'with background work', 'idle' : 'without background work' } def overhead_heading(conf, sharedL3=False): ovd_type = 'unknowkn overhead' if 'ovd' in conf: if conf['ovd'] == 'preemption': ovd_type = 'Preemption' elif conf['ovd'] == 'onchip': if sharedL3: ovd_type = 'Shared L3' else: ovd_type = 'Shared L2' elif conf['ovd'] == 'l2cache': ovd_type = 'Shared L2' elif conf['ovd'] == 'offchip': ovd_type = 'Diff. Socket' return ovd_type class PmPlotter(defapp.App): def __init__(self): defapp.App.__init__(self, options, defaults, no_std_opts=True) self.graphs_list = [] self.title = '' self.fname = {'ovd':set([]), 'wss':set([])} self.tmpfile_list = [] self.conf = [] def compose_name(self, conf): name = 'pm_' name += ('avg' if 'soft' in conf else 'wc') name += '_wss=' wsses = [] for i in self.fname['wss']: wsses.append(i) for i in sorted(wsses, key=int): name += str(i) + ',' name = name[0:-1] name += '_ovd=' for i in self.fname['ovd']: name += str(i) + ',' name = name[0:-1] return name def plot(self, graphs, title, name, conf, **xtra): name = self.compose_name(conf) print name gnuplot(graphs, title=title, xlabel=self.options.xlabel, ylabel=self.options.ylabel + (' [avg]' if 'soft' in conf else ' [max]'), #xrange=self.options.xrange, #yrange=self.options.yrange, #xticks=self.options.xticks, #yticks=self.options.yticks, format=self.options.format, style=('yerrorlines' if 'soft' in conf else 'linespoints'), fname=name, **xtra) def compose_title(self, conf): if self.title == '': if 'soft' in conf: self.title = 'measured average overhead to 2nd hot access' else: self.title = 'measured maximum overhead to 2nd hot access' def add_to_graph_list(self, tmpfile, name, conf): self.compose_title(conf) wsslist = conf['wss'].split(',') self.fname['ovd'].add(conf['ovd']) wsspos = 2 if 'soft' in conf: wsspos += 1 for i in wsslist: self.fname['wss'].add(i) label = conf['ovd'] + ' WSS=' + i if 'soft' in conf: self.graphs_list.append((tmpfile, 1, wsspos, wsspos+1, \ wsspos+2, label)) else: self.graphs_list.append((tmpfile, 1, wsspos, label)) wsspos += 4 def plot_graph_list(self, type, name): self.plot(self.graphs_list, self.title, name, type) # delete temporary data files for tmp in self.tmpfile_list: del tmp def plot_file(self, datafile): bname = basename(datafile) name, ext = splitext(bname) if ext != '.csv': self.err("Warning: '%s' doesn't look like a CSV file. Skipping..." % bname) return None conf = decode(name) tmpfile = get_data_tmpfile(datafile) if tmpfile: if 'pm' in conf: conf[self.options.type] = None self.add_to_graph_list(tmpfile.name, name, conf) else: self.err("Skipped '%s'; unknown experiment type." % bname) # keep a list of temporary data files self.tmpfile_list.append(tmpfile) else: self.err("Skipped '%s'; it dosn't appear to contain data." % bname) def default(self, _): for datafile in self.args: self.plot_file(datafile) # also clean up tmp data files self.plot_graph_list(self.options.type, self.options.name) if __name__ == "__main__": PmPlotter().launch()