X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=util%2Fstats%2Fdb.py;h=e1198d4380dd40eef6af84448ec472fe45ed0035;hb=c4ba6967a522df3b51a50017d8a5f2c47c382f57;hp=ed5d10bc2c5115ad65ce45b53351f7b8ee15928b;hpb=c389c2e327cc3ee1c988855b05505660c6670172;p=gem5.git diff --git a/util/stats/db.py b/util/stats/db.py index ed5d10bc2..e1198d438 100644 --- a/util/stats/db.py +++ b/util/stats/db.py @@ -1,3 +1,31 @@ +# Copyright (c) 2003-2004 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Nathan Binkert + import MySQLdb, re, string def statcmp(a, b): @@ -75,7 +103,21 @@ class Node(object): def __init__(self, name): self.name = name def __str__(self): - return name + return self.name + +class Result(object): + def __init__(self, x, y): + self.data = {} + self.x = x + self.y = y + + def __contains__(self, run): + return run in self.data + + def __getitem__(self, run): + if run not in self.data: + self.data[run] = [ [ 0.0 ] * self.y for i in xrange(self.x) ] + return self.data[run] class Database(object): def __init__(self): @@ -95,10 +137,6 @@ class Database(object): self.allRunIds = {} self.allRunNames = {} - self.allBins = [] - self.allBinIds = {} - self.allBinNames = {} - self.allFormulas = {} self.stattop = {} @@ -107,9 +145,30 @@ class Database(object): self.mode = 'sum'; self.runs = None - self.bins = None self.ticks = None - self.__dict__['get'] = type(self).sum + self.method = 'sum' + self._method = type(self).sum + + def get(self, job, stat, system=None): + run = self.allRunNames.get(str(job), None) + if run is None: + return None + + from info import ProxyError, scalar, vector, value, values, total, len + if system is None and hasattr(job, 'system'): + system = job.system + + if system is not None: + stat.system = self[system] + try: + if scalar(stat): + return value(stat, run.run) + if vector(stat): + return values(stat, run.run) + except ProxyError: + return None + + return None def query(self, sql): self.cursor.execute(sql) @@ -156,11 +215,6 @@ class Database(object): self.allRunIds[run.run] = run self.allRunNames[run.name] = run - self.query('select * from bins') - for id,name in self.cursor.fetchall(): - self.allBinIds[int(id)] = name - self.allBinNames[name] = int(id) - self.query('select sd_stat,sd_x,sd_y,sd_name,sd_descr from subdata') for result in self.cursor.fetchall(): subdata = SubData(result) @@ -177,24 +231,12 @@ class Database(object): self.query('select * from stats') import info for result in self.cursor.fetchall(): - stat = info.NewStat(StatData(result)) + stat = info.NewStat(self, StatData(result)) self.append(stat) self.allStats.append(stat) self.allStatIds[stat.stat] = stat self.allStatNames[stat.name] = stat - # Name: listbins - # Desc: Prints all bins matching regex argument, if no argument - # is given all bins are returned - def listBins(self, regex='.*'): - print '%-50s %-10s' % ('bin name', 'id') - print '-' * 61 - names = self.allBinNames.keys() - names.sort() - for name in names: - id = self.allBinNames[name] - print '%-50s %-10d' % (name, id) - # Name: listruns # Desc: Prints all runs matching a given user, if no argument # is given all runs are returned @@ -298,39 +340,10 @@ class Database(object): ret.append(stat) return ret - def getBin(self, bins): - if type(bins) is not list: - bins = [ bins ] - - ret = [] - for bin in bins: - if type(bin) is int: - ret.append(bin) - elif type(bin) is str: - ret.append(self.allBinNames[bin]) - else: - for name,id in self.allBinNames.items(): - if bin.match(name): - ret.append(id) - - return ret - - def getNotBin(self, bin): - map = {} - for bin in getBin(bin): - map[bin] = 1 - - ret = [] - for bin in self.allBinIds.keys(): - if not map.has_key(bin): - ret.append(bin) - - return ret - ######################################### # get the data # - def inner(self, op, stat, bins, ticks, group=False): + def query(self, op, stat, ticks, group=False): sql = 'select ' sql += 'dt_stat as stat, ' sql += 'dt_run as run, ' @@ -352,10 +365,6 @@ class Database(object): val = ' or '.join([ 'dt_run=%d' % r for r in self.runs ]) sql += ' and (%s)' % val - if bins != None and len(bins): - val = ' or '.join([ 'dt_bin=%d' % b for b in bins ]) - sql += ' and (%s)' % val - if ticks != None and len(ticks): val = ' or '.join([ 'dt_tick=%d' % s for s in ticks ]) sql += ' and (%s)' % val @@ -365,72 +374,45 @@ class Database(object): sql += ',dt_tick' return sql - def outer(self, op_out, op_in, stat, bins, ticks): - sql = self.inner(op_in, stat, bins, ticks, True) - sql = 'select stat,run,x,y,%s(data) from (%s) as tb ' % (op_out, sql) - sql += 'group by stat,run,x,y' - return sql - # Name: sum - # Desc: given a run, a stat and an array of samples and bins, - # sum all the bins and then get the standard deviation of the - # samples for non-binned runs. This will just return the average - # of samples, however a bin array still must be passed - def sum(self, stat, bins, ticks): - return self.inner('sum', stat, bins, ticks) + # Desc: given a run, a stat and an array of samples, total the samples + def sum(self, *args, **kwargs): + return self.query('sum', *args, **kwargs) # Name: avg - # Desc: given a run, a stat and an array of samples and bins, - # sum all the bins and then average the samples for non-binned - # runs this will just return the average of samples, however - # a bin array still must be passed - def avg(self, stat, bins, ticks): - return self.outer('avg', 'sum', stat, bins, ticks) + # Desc: given a run, a stat and an array of samples, average the samples + def avg(self, stat, ticks): + return self.query('avg', *args, **kwargs) # Name: stdev - # Desc: given a run, a stat and an array of samples and bins, - # sum all the bins and then get the standard deviation of the - # samples for non-binned runs. This will just return the average - # of samples, however a bin array still must be passed - def stdev(self, stat, bins, ticks): - return self.outer('stddev', 'sum', stat, bins, ticks) - - def __getattribute__(self, attr): - if attr != 'get': - return super(Database, self).__getattribute__(attr) - - if self.__dict__['get'] == type(self).sum: - return 'sum' - elif self.__dict__['get'] == type(self).avg: - return 'avg' - elif self.__dict__['get'] == type(self).stdev: - return 'stdev' - else: - return '' + # Desc: given a run, a stat and an array of samples, get the standard + # deviation + def stdev(self, stat, ticks): + return self.query('stddev', *args, **kwargs) def __setattr__(self, attr, value): - if attr != 'get': - super(Database, self).__setattr__(attr, value) + super(Database, self).__setattr__(attr, value) + if attr != 'method': return if value == 'sum': - self.__dict__['get'] = type(self).sum + self._method = self.sum elif value == 'avg': - self.__dict__['get'] = type(self).avg + self._method = self.avg elif value == 'stdev': - self.__dict__['get'] = type(self).stdev + self._method = self.stdev else: raise AttributeError, "can only set get to: sum | avg | stdev" - def data(self, stat, bins=None, ticks=None): - if bins is None: - bins = self.bins + def data(self, stat, ticks=None): if ticks is None: ticks = self.ticks - sql = self.__dict__['get'](self, stat, bins, ticks) + sql = self._method(self, stat, ticks) self.query(sql) runs = {} + xmax = 0 + ymax = 0 for x in self.cursor.fetchall(): data = Data(x) if not runs.has_key(data.run): @@ -438,5 +420,17 @@ class Database(object): if not runs[data.run].has_key(data.x): runs[data.run][data.x] = {} + xmax = max(xmax, data.x) + ymax = max(ymax, data.y) runs[data.run][data.x][data.y] = data.data - return runs + + results = Result(xmax + 1, ymax + 1) + for run,data in runs.iteritems(): + result = results[run] + for x,ydata in data.iteritems(): + for y,data in ydata.iteritems(): + result[x][y] = data + return results + + def __getitem__(self, key): + return self.stattop[key]