output.py revision 1881:fc205a7edd58
1# Copyright (c) 2005 The Regents of The University of Michigan 2# All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are 6# met: redistributions of source code must retain the above copyright 7# notice, this list of conditions and the following disclaimer; 8# redistributions in binary form must reproduce the above copyright 9# notice, this list of conditions and the following disclaimer in the 10# documentation and/or other materials provided with the distribution; 11# neither the name of the copyright holders nor the names of its 12# contributors may be used to endorse or promote products derived from 13# this software without specific prior written permission. 14# 15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26# 27# Authors: Nathan Binkert 28 29class dbinfo(object): 30 def get(self, job, stat): 31 import info 32 33 run = info.source.allRunNames.get(job.name, None) 34 if run is None: 35 print 'run "%s" not found' % job 36 return None 37 38 stat.system = info.source[job.system] 39 info.display_run = run.run; 40 val = float(stat) 41 if val == 1e300*1e300: 42 return None 43 return val 44 45class StatOutput(object): 46 def __init__(self, name, jobfile, stat=None, info=dbinfo(), binstats=None): 47 self.name = name 48 self.jobfile = jobfile 49 self.stat = stat 50 self.binstats = None 51 self.label = self.name 52 self.invert = False 53 self.info = info 54 55 def printdata(self, bin = None, printmode = 'G'): 56 import info 57 58 if bin: 59 print '%s %s stats' % (self.name, bin) 60 61 if self.binstats: 62 for stat in self.binstats: 63 stat.bins = bin 64 65 if printmode == 'G': 66 valformat = '%g' 67 elif printmode != 'F' and value > 1e6: 68 valformat = '%0.5e' 69 else: 70 valformat = '%f' 71 72 for job in self.jobfile.jobs(): 73 value = self.info.get(job, self.stat) 74 if value is None: 75 return 76 77 if not isinstance(value, list): 78 value = [ value ] 79 80 if self.invert: 81 for i,val in enumerate(value): 82 if val != 0.0: 83 value[i] = 1 / val 84 85 valstring = ', '.join([ valformat % val for val in value ]) 86 print '%-50s %s' % (job.name + ':', valstring) 87 88 def display(self, binned = False, printmode = 'G'): 89 if binned and self.binstats: 90 self.printdata('kernel', printmode) 91 self.printdata('idle', printmode) 92 self.printdata('user', printmode) 93 self.printdata('interrupt', printmode) 94 95 print '%s total stats' % self.name 96 self.printdata(printmode=printmode) 97 98 def graph(self, graphdir): 99 from os.path import expanduser, join as joinpath 100 from barchart import BarChart 101 from matplotlib.numerix import Float, zeros 102 import re 103 104 confgroups = self.jobfile.groups() 105 ngroups = len(confgroups) 106 skiplist = [ False ] * ngroups 107 groupopts = None 108 baropts = None 109 groups = [] 110 for i,group in enumerate(confgroups): 111 if group.flags.graph_group: 112 if groupopts is not None: 113 raise AttributeError, \ 114 'Two groups selected for graph group' 115 groupopts = group.subopts() 116 skiplist[i] = True 117 elif group.flags.graph_bars: 118 if baropts is not None: 119 raise AttributeError, \ 120 'Two groups selected for graph bars' 121 baropts = group.subopts() 122 skiplist[i] = True 123 else: 124 groups.append(group) 125 126 if groupopts is None: 127 raise AttributeError, 'No group selected for graph group' 128 129 if baropts is None: 130 raise AttributeError, 'No group selected for graph bars' 131 132 directory = expanduser(graphdir) 133 html = file(joinpath(directory, '%s.html' % self.name), 'w') 134 print >>html, '<html>' 135 print >>html, '<title>Graphs for %s</title>' % self.name 136 print >>html, '<body>' 137 138 for options in self.jobfile.options(groups): 139 data = zeros((len(groupopts), len(baropts)), Float) 140 data = [ [ None ] * len(baropts) for i in xrange(len(groupopts)) ] 141 enabled = False 142 stacked = None 143 for g,gopt in enumerate(groupopts): 144 for b,bopt in enumerate(baropts): 145 job = self.jobfile.job(options + [ gopt, bopt ]) 146 147 val = self.info.get(job, self.stat) 148 if val is None: 149 val = 0.0 150 curstacked = isinstance(val, (list, tuple)) 151 if stacked is None: 152 stacked = curstacked 153 else: 154 if stacked != curstacked: 155 raise ValueError, "some stats stacked, some not" 156 157 data[g][b] = val 158 159 bar_descs = [ opt.desc for opt in baropts ] 160 group_descs = [ opt.desc for opt in groupopts ] 161 if stacked: 162 legend = self.info.rcategories 163 else: 164 legend = bar_descs 165 166 chart = BarChart(data=data, xlabel='Benchmark', ylabel=self.label, 167 legend=legend, xticks=group_descs) 168 chart.graph() 169 170 names = [ opt.name for opt in options ] 171 descs = [ opt.desc for opt in options ] 172 173 filename = '%s-%s.png' % (self.name, ':'.join(names)) 174 desc = ' '.join(descs) 175 filepath = joinpath(directory, filename) 176 chart.savefig(filepath) 177 filename = re.sub(':', '%3A', filename) 178 print >>html, '''%s<br><img src="%s"><br>''' % (desc, filename) 179 180 print >>html, '</body>' 181 print >>html, '</html>' 182 html.close() 183