diff -r bfac87aa5771 -r c874d053e378 src/python/m5/stats/info.py --- a/src/python/m5/stats/info.py Wed Apr 24 11:26:04 2013 +0100 +++ b/src/python/m5/stats/info.py Wed Apr 24 11:27:04 2013 +0100 @@ -91,11 +91,14 @@ ## @brief Sum all of the values for a stat. # @return The sum. def total(stat): - val = values(stat) try: + val = values(stat) return sum(val) - except TypeError: - return val + except AttributeError: + if type(stat) is float: + return stat + else: + return value(stat) ## @brief Get the length of a stat. # @return The length. @@ -219,7 +222,7 @@ ## @brief Get the value of the constant. # @return The value of the constant. - def __value__(self): + def __value__(self, *args): return self.constant ## @brief Get the length of the stat. @@ -580,9 +583,58 @@ g = dict(total=total, ScalarConstant=ScalarConstant, VectorConstant=VectorConstant) - self._the_value = eval(self.formula, g, self.context) + + try: + self._the_value = eval(self.formula, g, self.context) + except (ZeroDivisionError, ValueError): + print "Warning: unable to evaluate: " + self.name + print "Supplied formula is: " + self.formula + + # If we failed to evaluate the formula, then we return + # NaN. We need to wrap the value to make sure that the + # stats system gets a statistic, rather than a float. + self._the_value = WrapValue(float('NaN')) + return self._the_value + # If we want to get the total,evaluate it and return the result. + if attr == 'total': + import ast + + ## @brief Class which vists every node in an AST and adds in the + # total calculation + class AddTotal(ast.NodeTransformer): + def visit_BinOp(self, node): + if isinstance(node.op, ast.Div): + leftTemp = node.left + rightTemp = node.right + node.left = ast.Call(func=ast.Name(id='total', + ctx=ast.Load()), args=[leftTemp], + keywords = [], starargs=None, + kwargs=None ) + node.right = ast.Call(func=ast.Name(id='total', + ctx=ast.Load()), args=[rightTemp], + keywords = [], starargs=None, + kwargs=None ) + return node + + g = dict(total=total, + ScalarConstant=ScalarConstant, + VectorConstant=VectorConstant) + + parsedFormula = ast.parse("total(" + self.formula + ")", + mode='eval') + AddTotal().visit(parsedFormula) + parsedFormula = ast.fix_missing_locations(parsedFormula) + + try: + self.total = eval(compile(parsedFormula, '', 'eval'), g, + self.context) + except (ZeroDivisionError, ValueError): + self.total = float('nan') + + return self.total + # Return the properties of the value. if attr in ('__scalar__', '__vector__', '__value__', '__len__'): return getattr(self._the_value, attr)