output.py revision 1915
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):
991915Sbinkertn@umich.edu        from os.path import expanduser, isdir, join as joinpath
1001881Sbinkertn@umich.edu        from barchart import BarChart
1011915Sbinkertn@umich.edu        from matplotlib.numerix import Float, array, zeros
1021915Sbinkertn@umich.edu        import os, 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)
1331915Sbinkertn@umich.edu        if not isdir(directory):
1341915Sbinkertn@umich.edu            os.mkdir(directory)
1351881Sbinkertn@umich.edu        html = file(joinpath(directory, '%s.html' % self.name), 'w')
1361881Sbinkertn@umich.edu        print >>html, '<html>'
1371881Sbinkertn@umich.edu        print >>html, '<title>Graphs for %s</title>' % self.name
1381881Sbinkertn@umich.edu        print >>html, '<body>'
1391881Sbinkertn@umich.edu
1401881Sbinkertn@umich.edu        for options in self.jobfile.options(groups):
1411881Sbinkertn@umich.edu            data = zeros((len(groupopts), len(baropts)), Float)
1421881Sbinkertn@umich.edu            data = [ [ None ] * len(baropts) for i in xrange(len(groupopts)) ]
1431881Sbinkertn@umich.edu            enabled = False
1441881Sbinkertn@umich.edu            stacked = None
1451881Sbinkertn@umich.edu            for g,gopt in enumerate(groupopts):
1461881Sbinkertn@umich.edu                for b,bopt in enumerate(baropts):
1471881Sbinkertn@umich.edu                    job = self.jobfile.job(options + [ gopt, bopt ])
1481915Sbinkertn@umich.edu                    if not job:
1491915Sbinkertn@umich.edu                        continue
1501881Sbinkertn@umich.edu
1511881Sbinkertn@umich.edu                    val = self.info.get(job, self.stat)
1521881Sbinkertn@umich.edu                    if val is None:
1531881Sbinkertn@umich.edu                        val = 0.0
1541881Sbinkertn@umich.edu                    curstacked = isinstance(val, (list, tuple))
1551881Sbinkertn@umich.edu                    if stacked is None:
1561881Sbinkertn@umich.edu                        stacked = curstacked
1571881Sbinkertn@umich.edu                    else:
1581881Sbinkertn@umich.edu                        if stacked != curstacked:
1591881Sbinkertn@umich.edu                            raise ValueError, "some stats stacked, some not"
1601881Sbinkertn@umich.edu
1611881Sbinkertn@umich.edu                    data[g][b] = val
1621881Sbinkertn@umich.edu
1631915Sbinkertn@umich.edu            data = array(data)
1641915Sbinkertn@umich.edu            if data.sum() == 0:
1651915Sbinkertn@umich.edu                continue
1661915Sbinkertn@umich.edu
1671881Sbinkertn@umich.edu            bar_descs = [ opt.desc for opt in baropts ]
1681881Sbinkertn@umich.edu            group_descs = [ opt.desc for opt in groupopts ]
1691881Sbinkertn@umich.edu            if stacked:
1701881Sbinkertn@umich.edu                legend = self.info.rcategories
1711881Sbinkertn@umich.edu            else:
1721881Sbinkertn@umich.edu                legend = bar_descs
1731881Sbinkertn@umich.edu
1741881Sbinkertn@umich.edu            chart = BarChart(data=data, xlabel='Benchmark', ylabel=self.label,
1751881Sbinkertn@umich.edu                             legend=legend, xticks=group_descs)
1761881Sbinkertn@umich.edu            chart.graph()
1771881Sbinkertn@umich.edu
1781881Sbinkertn@umich.edu            names = [ opt.name for opt in options ]
1791881Sbinkertn@umich.edu            descs = [ opt.desc for opt in options ]
1801881Sbinkertn@umich.edu
1811881Sbinkertn@umich.edu            filename =  '%s-%s.png' % (self.name, ':'.join(names))
1821881Sbinkertn@umich.edu            desc = ' '.join(descs)
1831881Sbinkertn@umich.edu            filepath = joinpath(directory, filename)
1841881Sbinkertn@umich.edu            chart.savefig(filepath)
1851881Sbinkertn@umich.edu            filename = re.sub(':', '%3A', filename)
1861881Sbinkertn@umich.edu            print >>html, '''%s<br><img src="%s"><br>''' % (desc, filename)
1871881Sbinkertn@umich.edu
1881881Sbinkertn@umich.edu        print >>html, '</body>'
1891881Sbinkertn@umich.edu        print >>html, '</html>'
1901881Sbinkertn@umich.edu        html.close()
191