output.py revision 1881
11881Sbinkertn@umich.edu# Copyright (c) 2005 The Regents of The University of Michigan 21881Sbinkertn@umich.edu# All rights reserved. 31881Sbinkertn@umich.edu# 41881Sbinkertn@umich.edu# Redistribution and use in source and binary forms, with or without 51881Sbinkertn@umich.edu# modification, are permitted provided that the following conditions are 61881Sbinkertn@umich.edu# met: redistributions of source code must retain the above copyright 71881Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer; 81881Sbinkertn@umich.edu# redistributions in binary form must reproduce the above copyright 91881Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer in the 101881Sbinkertn@umich.edu# documentation and/or other materials provided with the distribution; 111881Sbinkertn@umich.edu# neither the name of the copyright holders nor the names of its 121881Sbinkertn@umich.edu# contributors may be used to endorse or promote products derived from 131881Sbinkertn@umich.edu# this software without specific prior written permission. 141881Sbinkertn@umich.edu# 151881Sbinkertn@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 161881Sbinkertn@umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 171881Sbinkertn@umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 181881Sbinkertn@umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 191881Sbinkertn@umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 201881Sbinkertn@umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 211881Sbinkertn@umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 221881Sbinkertn@umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 231881Sbinkertn@umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 241881Sbinkertn@umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 251881Sbinkertn@umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 261881Sbinkertn@umich.edu# 271881Sbinkertn@umich.edu# Authors: Nathan Binkert 281881Sbinkertn@umich.edu 291881Sbinkertn@umich.educlass dbinfo(object): 301881Sbinkertn@umich.edu def get(self, job, stat): 311881Sbinkertn@umich.edu import info 321881Sbinkertn@umich.edu 331881Sbinkertn@umich.edu run = info.source.allRunNames.get(job.name, None) 341881Sbinkertn@umich.edu if run is None: 351881Sbinkertn@umich.edu print 'run "%s" not found' % job 361881Sbinkertn@umich.edu return None 371881Sbinkertn@umich.edu 381881Sbinkertn@umich.edu stat.system = info.source[job.system] 391881Sbinkertn@umich.edu info.display_run = run.run; 401881Sbinkertn@umich.edu val = float(stat) 411881Sbinkertn@umich.edu if val == 1e300*1e300: 421881Sbinkertn@umich.edu return None 431881Sbinkertn@umich.edu return val 441881Sbinkertn@umich.edu 451881Sbinkertn@umich.educlass StatOutput(object): 461881Sbinkertn@umich.edu def __init__(self, name, jobfile, stat=None, info=dbinfo(), binstats=None): 471881Sbinkertn@umich.edu self.name = name 481881Sbinkertn@umich.edu self.jobfile = jobfile 491881Sbinkertn@umich.edu self.stat = stat 501881Sbinkertn@umich.edu self.binstats = None 511881Sbinkertn@umich.edu self.label = self.name 521881Sbinkertn@umich.edu self.invert = False 531881Sbinkertn@umich.edu self.info = info 541881Sbinkertn@umich.edu 551881Sbinkertn@umich.edu def printdata(self, bin = None, printmode = 'G'): 561881Sbinkertn@umich.edu import info 571881Sbinkertn@umich.edu 581881Sbinkertn@umich.edu if bin: 591881Sbinkertn@umich.edu print '%s %s stats' % (self.name, bin) 601881Sbinkertn@umich.edu 611881Sbinkertn@umich.edu if self.binstats: 621881Sbinkertn@umich.edu for stat in self.binstats: 631881Sbinkertn@umich.edu stat.bins = bin 641881Sbinkertn@umich.edu 651881Sbinkertn@umich.edu if printmode == 'G': 661881Sbinkertn@umich.edu valformat = '%g' 671881Sbinkertn@umich.edu elif printmode != 'F' and value > 1e6: 681881Sbinkertn@umich.edu valformat = '%0.5e' 691881Sbinkertn@umich.edu else: 701881Sbinkertn@umich.edu valformat = '%f' 711881Sbinkertn@umich.edu 721881Sbinkertn@umich.edu for job in self.jobfile.jobs(): 731881Sbinkertn@umich.edu value = self.info.get(job, self.stat) 741881Sbinkertn@umich.edu if value is None: 751881Sbinkertn@umich.edu return 761881Sbinkertn@umich.edu 771881Sbinkertn@umich.edu if not isinstance(value, list): 781881Sbinkertn@umich.edu value = [ value ] 791881Sbinkertn@umich.edu 801881Sbinkertn@umich.edu if self.invert: 811881Sbinkertn@umich.edu for i,val in enumerate(value): 821881Sbinkertn@umich.edu if val != 0.0: 831881Sbinkertn@umich.edu value[i] = 1 / val 841881Sbinkertn@umich.edu 851881Sbinkertn@umich.edu valstring = ', '.join([ valformat % val for val in value ]) 861881Sbinkertn@umich.edu print '%-50s %s' % (job.name + ':', valstring) 871881Sbinkertn@umich.edu 881881Sbinkertn@umich.edu def display(self, binned = False, printmode = 'G'): 891881Sbinkertn@umich.edu if binned and self.binstats: 901881Sbinkertn@umich.edu self.printdata('kernel', printmode) 911881Sbinkertn@umich.edu self.printdata('idle', printmode) 921881Sbinkertn@umich.edu self.printdata('user', printmode) 931881Sbinkertn@umich.edu self.printdata('interrupt', printmode) 941881Sbinkertn@umich.edu 951881Sbinkertn@umich.edu print '%s total stats' % self.name 961881Sbinkertn@umich.edu self.printdata(printmode=printmode) 971881Sbinkertn@umich.edu 981881Sbinkertn@umich.edu def graph(self, graphdir): 991881Sbinkertn@umich.edu from os.path import expanduser, join as joinpath 1001881Sbinkertn@umich.edu from barchart import BarChart 1011881Sbinkertn@umich.edu from matplotlib.numerix import Float, zeros 1021881Sbinkertn@umich.edu import re 1031881Sbinkertn@umich.edu 1041881Sbinkertn@umich.edu confgroups = self.jobfile.groups() 1051881Sbinkertn@umich.edu ngroups = len(confgroups) 1061881Sbinkertn@umich.edu skiplist = [ False ] * ngroups 1071881Sbinkertn@umich.edu groupopts = None 1081881Sbinkertn@umich.edu baropts = None 1091881Sbinkertn@umich.edu groups = [] 1101881Sbinkertn@umich.edu for i,group in enumerate(confgroups): 1111881Sbinkertn@umich.edu if group.flags.graph_group: 1121881Sbinkertn@umich.edu if groupopts is not None: 1131881Sbinkertn@umich.edu raise AttributeError, \ 1141881Sbinkertn@umich.edu 'Two groups selected for graph group' 1151881Sbinkertn@umich.edu groupopts = group.subopts() 1161881Sbinkertn@umich.edu skiplist[i] = True 1171881Sbinkertn@umich.edu elif group.flags.graph_bars: 1181881Sbinkertn@umich.edu if baropts is not None: 1191881Sbinkertn@umich.edu raise AttributeError, \ 1201881Sbinkertn@umich.edu 'Two groups selected for graph bars' 1211881Sbinkertn@umich.edu baropts = group.subopts() 1221881Sbinkertn@umich.edu skiplist[i] = True 1231881Sbinkertn@umich.edu else: 1241881Sbinkertn@umich.edu groups.append(group) 1251881Sbinkertn@umich.edu 1261881Sbinkertn@umich.edu if groupopts is None: 1271881Sbinkertn@umich.edu raise AttributeError, 'No group selected for graph group' 1281881Sbinkertn@umich.edu 1291881Sbinkertn@umich.edu if baropts is None: 1301881Sbinkertn@umich.edu raise AttributeError, 'No group selected for graph bars' 1311881Sbinkertn@umich.edu 1321881Sbinkertn@umich.edu directory = expanduser(graphdir) 1331881Sbinkertn@umich.edu html = file(joinpath(directory, '%s.html' % self.name), 'w') 1341881Sbinkertn@umich.edu print >>html, '<html>' 1351881Sbinkertn@umich.edu print >>html, '<title>Graphs for %s</title>' % self.name 1361881Sbinkertn@umich.edu print >>html, '<body>' 1371881Sbinkertn@umich.edu 1381881Sbinkertn@umich.edu for options in self.jobfile.options(groups): 1391881Sbinkertn@umich.edu data = zeros((len(groupopts), len(baropts)), Float) 1401881Sbinkertn@umich.edu data = [ [ None ] * len(baropts) for i in xrange(len(groupopts)) ] 1411881Sbinkertn@umich.edu enabled = False 1421881Sbinkertn@umich.edu stacked = None 1431881Sbinkertn@umich.edu for g,gopt in enumerate(groupopts): 1441881Sbinkertn@umich.edu for b,bopt in enumerate(baropts): 1451881Sbinkertn@umich.edu job = self.jobfile.job(options + [ gopt, bopt ]) 1461881Sbinkertn@umich.edu 1471881Sbinkertn@umich.edu val = self.info.get(job, self.stat) 1481881Sbinkertn@umich.edu if val is None: 1491881Sbinkertn@umich.edu val = 0.0 1501881Sbinkertn@umich.edu curstacked = isinstance(val, (list, tuple)) 1511881Sbinkertn@umich.edu if stacked is None: 1521881Sbinkertn@umich.edu stacked = curstacked 1531881Sbinkertn@umich.edu else: 1541881Sbinkertn@umich.edu if stacked != curstacked: 1551881Sbinkertn@umich.edu raise ValueError, "some stats stacked, some not" 1561881Sbinkertn@umich.edu 1571881Sbinkertn@umich.edu data[g][b] = val 1581881Sbinkertn@umich.edu 1591881Sbinkertn@umich.edu bar_descs = [ opt.desc for opt in baropts ] 1601881Sbinkertn@umich.edu group_descs = [ opt.desc for opt in groupopts ] 1611881Sbinkertn@umich.edu if stacked: 1621881Sbinkertn@umich.edu legend = self.info.rcategories 1631881Sbinkertn@umich.edu else: 1641881Sbinkertn@umich.edu legend = bar_descs 1651881Sbinkertn@umich.edu 1661881Sbinkertn@umich.edu chart = BarChart(data=data, xlabel='Benchmark', ylabel=self.label, 1671881Sbinkertn@umich.edu legend=legend, xticks=group_descs) 1681881Sbinkertn@umich.edu chart.graph() 1691881Sbinkertn@umich.edu 1701881Sbinkertn@umich.edu names = [ opt.name for opt in options ] 1711881Sbinkertn@umich.edu descs = [ opt.desc for opt in options ] 1721881Sbinkertn@umich.edu 1731881Sbinkertn@umich.edu filename = '%s-%s.png' % (self.name, ':'.join(names)) 1741881Sbinkertn@umich.edu desc = ' '.join(descs) 1751881Sbinkertn@umich.edu filepath = joinpath(directory, filename) 1761881Sbinkertn@umich.edu chart.savefig(filepath) 1771881Sbinkertn@umich.edu filename = re.sub(':', '%3A', filename) 1781881Sbinkertn@umich.edu print >>html, '''%s<br><img src="%s"><br>''' % (desc, filename) 1791881Sbinkertn@umich.edu 1801881Sbinkertn@umich.edu print >>html, '</body>' 1811881Sbinkertn@umich.edu print >>html, '</html>' 1821881Sbinkertn@umich.edu html.close() 183