output.py revision 2006
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
292006Sbinkertn@umich.edufrom chart import ChartOptions
302006Sbinkertn@umich.edu
312006Sbinkertn@umich.educlass StatOutput(ChartOptions):
322006Sbinkertn@umich.edu    def __init__(self, jobfile, info, stat=None, binstats=None):
332006Sbinkertn@umich.edu        super(StatOutput, self).__init__()
341881Sbinkertn@umich.edu        self.jobfile = jobfile
351881Sbinkertn@umich.edu        self.stat = stat
361881Sbinkertn@umich.edu        self.binstats = None
371881Sbinkertn@umich.edu        self.invert = False
381881Sbinkertn@umich.edu        self.info = info
391881Sbinkertn@umich.edu
402006Sbinkertn@umich.edu    def printdata(self, name, bin = None, printmode = 'G'):
411881Sbinkertn@umich.edu        import info
421881Sbinkertn@umich.edu
431881Sbinkertn@umich.edu        if bin:
442006Sbinkertn@umich.edu            print '%s %s stats' % (name, bin)
451881Sbinkertn@umich.edu
461881Sbinkertn@umich.edu        if self.binstats:
471881Sbinkertn@umich.edu            for stat in self.binstats:
481881Sbinkertn@umich.edu                stat.bins = bin
491881Sbinkertn@umich.edu
501881Sbinkertn@umich.edu        if printmode == 'G':
511881Sbinkertn@umich.edu            valformat = '%g'
521881Sbinkertn@umich.edu        elif printmode != 'F' and value > 1e6:
531881Sbinkertn@umich.edu            valformat = '%0.5e'
541881Sbinkertn@umich.edu        else:
551881Sbinkertn@umich.edu            valformat = '%f'
561881Sbinkertn@umich.edu
571881Sbinkertn@umich.edu        for job in self.jobfile.jobs():
581881Sbinkertn@umich.edu            value = self.info.get(job, self.stat)
591881Sbinkertn@umich.edu            if value is None:
601881Sbinkertn@umich.edu                return
611881Sbinkertn@umich.edu
621881Sbinkertn@umich.edu            if not isinstance(value, list):
631881Sbinkertn@umich.edu                value = [ value ]
641881Sbinkertn@umich.edu
651881Sbinkertn@umich.edu            if self.invert:
661881Sbinkertn@umich.edu                for i,val in enumerate(value):
671881Sbinkertn@umich.edu                    if val != 0.0:
681881Sbinkertn@umich.edu                        value[i] = 1 / val
691881Sbinkertn@umich.edu
701881Sbinkertn@umich.edu            valstring = ', '.join([ valformat % val for val in value ])
711881Sbinkertn@umich.edu            print '%-50s    %s' % (job.name + ':', valstring)
721881Sbinkertn@umich.edu
732006Sbinkertn@umich.edu    def display(self, name, binned = False, printmode = 'G'):
741881Sbinkertn@umich.edu        if binned and self.binstats:
752006Sbinkertn@umich.edu            self.printdata(name, 'kernel', printmode)
762006Sbinkertn@umich.edu            self.printdata(name, 'idle', printmode)
772006Sbinkertn@umich.edu            self.printdata(name, 'user', printmode)
782006Sbinkertn@umich.edu            self.printdata(name, 'interrupt', printmode)
791881Sbinkertn@umich.edu
802006Sbinkertn@umich.edu            print '%s total stats' % name
812006Sbinkertn@umich.edu        self.printdata(name, printmode=printmode)
821881Sbinkertn@umich.edu
832006Sbinkertn@umich.edu    def graph(self, name, graphdir, proxy=None):
841915Sbinkertn@umich.edu        from os.path import expanduser, isdir, join as joinpath
851881Sbinkertn@umich.edu        from barchart import BarChart
861915Sbinkertn@umich.edu        from matplotlib.numerix import Float, array, zeros
872006Sbinkertn@umich.edu        import os, re, urllib
882006Sbinkertn@umich.edu        from jobfile import crossproduct
891881Sbinkertn@umich.edu
901881Sbinkertn@umich.edu        confgroups = self.jobfile.groups()
911881Sbinkertn@umich.edu        ngroups = len(confgroups)
921881Sbinkertn@umich.edu        skiplist = [ False ] * ngroups
932006Sbinkertn@umich.edu        groupopts = []
942006Sbinkertn@umich.edu        baropts = []
951881Sbinkertn@umich.edu        groups = []
961881Sbinkertn@umich.edu        for i,group in enumerate(confgroups):
971881Sbinkertn@umich.edu            if group.flags.graph_group:
982006Sbinkertn@umich.edu                groupopts.append(group.subopts())
991881Sbinkertn@umich.edu                skiplist[i] = True
1001881Sbinkertn@umich.edu            elif group.flags.graph_bars:
1012006Sbinkertn@umich.edu                baropts.append(group.subopts())
1021881Sbinkertn@umich.edu                skiplist[i] = True
1031881Sbinkertn@umich.edu            else:
1041881Sbinkertn@umich.edu                groups.append(group)
1051881Sbinkertn@umich.edu
1062006Sbinkertn@umich.edu        if not groupopts:
1071881Sbinkertn@umich.edu            raise AttributeError, 'No group selected for graph group'
1081881Sbinkertn@umich.edu
1092006Sbinkertn@umich.edu        if not baropts:
1101881Sbinkertn@umich.edu            raise AttributeError, 'No group selected for graph bars'
1111881Sbinkertn@umich.edu
1122006Sbinkertn@umich.edu        groupopts = [ group for group in crossproduct(groupopts) ]
1132006Sbinkertn@umich.edu        baropts = [ bar for bar in crossproduct(baropts) ]
1142006Sbinkertn@umich.edu
1151881Sbinkertn@umich.edu        directory = expanduser(graphdir)
1161915Sbinkertn@umich.edu        if not isdir(directory):
1171915Sbinkertn@umich.edu            os.mkdir(directory)
1182006Sbinkertn@umich.edu        html = file(joinpath(directory, '%s.html' % name), 'w')
1191881Sbinkertn@umich.edu        print >>html, '<html>'
1202006Sbinkertn@umich.edu        print >>html, '<title>Graphs for %s</title>' % name
1211881Sbinkertn@umich.edu        print >>html, '<body>'
1222006Sbinkertn@umich.edu        html.flush()
1231881Sbinkertn@umich.edu
1241881Sbinkertn@umich.edu        for options in self.jobfile.options(groups):
1252006Sbinkertn@umich.edu            chart = BarChart(self)
1262006Sbinkertn@umich.edu
1271881Sbinkertn@umich.edu            data = zeros((len(groupopts), len(baropts)), Float)
1281881Sbinkertn@umich.edu            data = [ [ None ] * len(baropts) for i in xrange(len(groupopts)) ]
1291881Sbinkertn@umich.edu            enabled = False
1301929Sbinkertn@umich.edu            stacked = 0
1311881Sbinkertn@umich.edu            for g,gopt in enumerate(groupopts):
1321881Sbinkertn@umich.edu                for b,bopt in enumerate(baropts):
1332006Sbinkertn@umich.edu                    job = self.jobfile.job(options + gopt + bopt)
1341915Sbinkertn@umich.edu                    if not job:
1351915Sbinkertn@umich.edu                        continue
1361881Sbinkertn@umich.edu
1372006Sbinkertn@umich.edu                    if proxy:
1382006Sbinkertn@umich.edu                        import db
1392006Sbinkertn@umich.edu                        proxy.dict['system'] = self.info[job.system]
1401881Sbinkertn@umich.edu                    val = self.info.get(job, self.stat)
1412006Sbinkertn@umich.edu                    if val is None:
1422006Sbinkertn@umich.edu                        print 'stat "%s" for job "%s" not found' % \
1432006Sbinkertn@umich.edu                              (self.stat, job)
1442006Sbinkertn@umich.edu
1451929Sbinkertn@umich.edu                    if isinstance(val, (list, tuple)):
1461929Sbinkertn@umich.edu                        if len(val) == 1:
1471929Sbinkertn@umich.edu                            val = val[0]
1481929Sbinkertn@umich.edu                        else:
1491929Sbinkertn@umich.edu                            stacked = len(val)
1501881Sbinkertn@umich.edu
1511881Sbinkertn@umich.edu                    data[g][b] = val
1521881Sbinkertn@umich.edu
1531929Sbinkertn@umich.edu            if stacked == 0:
1541929Sbinkertn@umich.edu                for i in xrange(len(groupopts)):
1551929Sbinkertn@umich.edu                    for j in xrange(len(baropts)):
1561929Sbinkertn@umich.edu                        if data[i][j] is None:
1571929Sbinkertn@umich.edu                            data[i][j] = 0.0
1581929Sbinkertn@umich.edu            else:
1591929Sbinkertn@umich.edu                for i in xrange(len(groupopts)):
1601929Sbinkertn@umich.edu                    for j in xrange(len(baropts)):
1611929Sbinkertn@umich.edu                        val = data[i][j]
1621929Sbinkertn@umich.edu                        if val is None:
1632006Sbinkertn@umich.edu                            data[i][j] = [ 0.0 ] * stacked
1641929Sbinkertn@umich.edu                        elif len(val) != stacked:
1651929Sbinkertn@umich.edu                            raise ValueError, "some stats stacked, some not"
1661929Sbinkertn@umich.edu
1671915Sbinkertn@umich.edu            data = array(data)
1681915Sbinkertn@umich.edu            if data.sum() == 0:
1691915Sbinkertn@umich.edu                continue
1701915Sbinkertn@umich.edu
1712006Sbinkertn@umich.edu            x = data.shape[0]
1722006Sbinkertn@umich.edu            y = data.shape[1]
1732006Sbinkertn@umich.edu            xkeep = [ i for i in xrange(x) if data[i].sum() != 0 ]
1742006Sbinkertn@umich.edu            ykeep = [ i for i in xrange(y) if data[:,i].sum() != 0 ]
1752006Sbinkertn@umich.edu            data = data.take(xkeep, axis=0)
1762006Sbinkertn@umich.edu            data = data.take(ykeep, axis=1)
1772006Sbinkertn@umich.edu            chart.data = data
1781881Sbinkertn@umich.edu
1792006Sbinkertn@umich.edu            gopts = [ groupopts[i] for i in xkeep ]
1802006Sbinkertn@umich.edu            bopts = [ baropts[i] for i in ykeep ]
1812006Sbinkertn@umich.edu
1822006Sbinkertn@umich.edu            bdescs = [ ' '.join([o.desc for o in opt]) for opt in bopts]
1832006Sbinkertn@umich.edu            gdescs = [ ' '.join([o.desc for o in opt]) for opt in gopts]
1842006Sbinkertn@umich.edu
1852006Sbinkertn@umich.edu            if chart.legend is None:
1862006Sbinkertn@umich.edu                if stacked:
1872006Sbinkertn@umich.edu                    try:
1882006Sbinkertn@umich.edu                        chart.legend = self.info.rcategories
1892006Sbinkertn@umich.edu                    except:
1902006Sbinkertn@umich.edu                        chart.legend = [ str(i) for i in xrange(stacked) ]
1912006Sbinkertn@umich.edu                else:
1922006Sbinkertn@umich.edu                    chart.legend = bdescs
1932006Sbinkertn@umich.edu
1942006Sbinkertn@umich.edu            if chart.xticks is None:
1952006Sbinkertn@umich.edu                chart.xticks = gdescs
1961881Sbinkertn@umich.edu            chart.graph()
1971881Sbinkertn@umich.edu
1981881Sbinkertn@umich.edu            names = [ opt.name for opt in options ]
1991881Sbinkertn@umich.edu            descs = [ opt.desc for opt in options ]
2001881Sbinkertn@umich.edu
2012006Sbinkertn@umich.edu            if names[0] == 'run':
2022006Sbinkertn@umich.edu                names = names[1:]
2032006Sbinkertn@umich.edu                descs = descs[1:]
2042006Sbinkertn@umich.edu
2052006Sbinkertn@umich.edu            basename = '%s-%s' % (name, ':'.join(names))
2061881Sbinkertn@umich.edu            desc = ' '.join(descs)
2072006Sbinkertn@umich.edu
2082006Sbinkertn@umich.edu            pngname = '%s.png' % basename
2092006Sbinkertn@umich.edu            psname = '%s.eps' % re.sub(':', '-', basename)
2102006Sbinkertn@umich.edu            epsname = '%s.ps' % re.sub(':', '-', basename)
2112006Sbinkertn@umich.edu            chart.savefig(joinpath(directory, pngname))
2122006Sbinkertn@umich.edu            chart.savefig(joinpath(directory, epsname))
2132006Sbinkertn@umich.edu            chart.savefig(joinpath(directory, psname))
2142006Sbinkertn@umich.edu            html_name = urllib.quote(pngname)
2152006Sbinkertn@umich.edu            print >>html, '''%s<br><img src="%s"><br>''' % (desc, html_name)
2162006Sbinkertn@umich.edu            html.flush()
2171881Sbinkertn@umich.edu
2181881Sbinkertn@umich.edu        print >>html, '</body>'
2191881Sbinkertn@umich.edu        print >>html, '</html>'
2201881Sbinkertn@umich.edu        html.close()
221