__init__.py revision 8453
16654Snate@binkert.org# Copyright (c) 2008-2009 The Hewlett-Packard Development Company 26654Snate@binkert.org# Copyright (c) 2004-2006 The Regents of The University of Michigan 35467Snate@binkert.org# All rights reserved. 45467Snate@binkert.org# 55467Snate@binkert.org# Redistribution and use in source and binary forms, with or without 65467Snate@binkert.org# modification, are permitted provided that the following conditions are 75467Snate@binkert.org# met: redistributions of source code must retain the above copyright 85467Snate@binkert.org# notice, this list of conditions and the following disclaimer; 95467Snate@binkert.org# redistributions in binary form must reproduce the above copyright 105467Snate@binkert.org# notice, this list of conditions and the following disclaimer in the 115467Snate@binkert.org# documentation and/or other materials provided with the distribution; 125467Snate@binkert.org# neither the name of the copyright holders nor the names of its 135467Snate@binkert.org# contributors may be used to endorse or promote products derived from 145467Snate@binkert.org# this software without specific prior written permission. 155467Snate@binkert.org# 165467Snate@binkert.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175467Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185467Snate@binkert.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195467Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205467Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215467Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225467Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235467Snate@binkert.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245467Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255467Snate@binkert.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265467Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275467Snate@binkert.org# 285467Snate@binkert.org# Authors: Nathan Binkert 295467Snate@binkert.org 306654Snate@binkert.orgimport os 316654Snate@binkert.orgimport re 326654Snate@binkert.orgimport sys 336654Snate@binkert.org 346654Snate@binkert.orgimport convert 356654Snate@binkert.orgimport jobfile 366654Snate@binkert.org 377459Snate@binkert.orgfrom attrdict import attrdict, multiattrdict, optiondict 386502Snate@binkert.orgfrom code_formatter import code_formatter 395467Snate@binkert.orgfrom multidict import multidict 406500Snate@binkert.orgfrom orderdict import orderdict 416654Snate@binkert.orgfrom smartdict import SmartDict 427503Snate@binkert.orgfrom sorteddict import SortedDict 438224Snate@binkert.orgfrom region import neg_inf, pos_inf, Region, Regions 445873Snate@binkert.org 456654Snate@binkert.org# panic() should be called when something happens that should never 466654Snate@binkert.org# ever happen regardless of what the user does (i.e., an acutal m5 476654Snate@binkert.org# bug). 486654Snate@binkert.orgdef panic(fmt, *args): 496654Snate@binkert.org print >>sys.stderr, 'panic:', fmt % args 506654Snate@binkert.org sys.exit(1) 516654Snate@binkert.org 526654Snate@binkert.org# fatal() should be called when the simulation cannot continue due to 536654Snate@binkert.org# some condition that is the user's fault (bad configuration, invalid 546654Snate@binkert.org# arguments, etc.) and not a simulator bug. 556654Snate@binkert.orgdef fatal(fmt, *args): 566654Snate@binkert.org print >>sys.stderr, 'fatal:', fmt % args 576654Snate@binkert.org sys.exit(1) 586654Snate@binkert.org 596654Snate@binkert.orgclass Singleton(type): 606654Snate@binkert.org def __call__(cls, *args, **kwargs): 616654Snate@binkert.org if hasattr(cls, '_instance'): 626654Snate@binkert.org return cls._instance 636654Snate@binkert.org 646654Snate@binkert.org cls._instance = super(Singleton, cls).__call__(*args, **kwargs) 656654Snate@binkert.org return cls._instance 666654Snate@binkert.org 676654Snate@binkert.orgdef addToPath(path): 686654Snate@binkert.org """Prepend given directory to system module search path. We may not 696654Snate@binkert.org need this anymore if we can structure our config library more like a 706654Snate@binkert.org Python package.""" 716654Snate@binkert.org 726654Snate@binkert.org # if it's a relative path and we know what directory the current 736654Snate@binkert.org # python script is in, make the path relative to that directory. 746654Snate@binkert.org if not os.path.isabs(path) and sys.path[0]: 756654Snate@binkert.org path = os.path.join(sys.path[0], path) 766654Snate@binkert.org path = os.path.realpath(path) 776654Snate@binkert.org # sys.path[0] should always refer to the current script's directory, 786654Snate@binkert.org # so place the new dir right after that. 796654Snate@binkert.org sys.path.insert(1, path) 806654Snate@binkert.org 816654Snate@binkert.org# Apply method to object. 826654Snate@binkert.org# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>) 836654Snate@binkert.orgdef applyMethod(obj, meth, *args, **kwargs): 846654Snate@binkert.org return getattr(obj, meth)(*args, **kwargs) 856654Snate@binkert.org 866654Snate@binkert.org# If the first argument is an (non-sequence) object, apply the named 876654Snate@binkert.org# method with the given arguments. If the first argument is a 886654Snate@binkert.org# sequence, apply the method to each element of the sequence (a la 896654Snate@binkert.org# 'map'). 906654Snate@binkert.orgdef applyOrMap(objOrSeq, meth, *args, **kwargs): 916654Snate@binkert.org if not isinstance(objOrSeq, (list, tuple)): 926654Snate@binkert.org return applyMethod(objOrSeq, meth, *args, **kwargs) 936654Snate@binkert.org else: 946654Snate@binkert.org return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq] 956654Snate@binkert.org 966654Snate@binkert.orgdef compareVersions(v1, v2): 976654Snate@binkert.org """helper function: compare arrays or strings of version numbers. 986654Snate@binkert.org E.g., compare_version((1,3,25), (1,4,1)') 996654Snate@binkert.org returns -1, 0, 1 if v1 is <, ==, > v2 1006654Snate@binkert.org """ 1016654Snate@binkert.org def make_version_list(v): 1026654Snate@binkert.org if isinstance(v, (list,tuple)): 1036654Snate@binkert.org return v 1046654Snate@binkert.org elif isinstance(v, str): 1056654Snate@binkert.org return map(lambda x: int(re.match('\d+', x).group()), v.split('.')) 1066654Snate@binkert.org else: 1076654Snate@binkert.org raise TypeError 1086654Snate@binkert.org 1096654Snate@binkert.org v1 = make_version_list(v1) 1106654Snate@binkert.org v2 = make_version_list(v2) 1116654Snate@binkert.org # Compare corresponding elements of lists 1126654Snate@binkert.org for n1,n2 in zip(v1, v2): 1136654Snate@binkert.org if n1 < n2: return -1 1146654Snate@binkert.org if n1 > n2: return 1 1156654Snate@binkert.org # all corresponding values are equal... see if one has extra values 1166654Snate@binkert.org if len(v1) < len(v2): return -1 1176654Snate@binkert.org if len(v1) > len(v2): return 1 1186654Snate@binkert.org return 0 1196654Snate@binkert.org 1206654Snate@binkert.orgdef crossproduct(items): 1216654Snate@binkert.org if len(items) == 1: 1226654Snate@binkert.org for i in items[0]: 1236654Snate@binkert.org yield (i,) 1246654Snate@binkert.org else: 1256654Snate@binkert.org for i in items[0]: 1266654Snate@binkert.org for j in crossproduct(items[1:]): 1276654Snate@binkert.org yield (i,) + j 1286654Snate@binkert.org 1296654Snate@binkert.orgdef flatten(items): 1306654Snate@binkert.org while items: 1316654Snate@binkert.org item = items.pop(0) 1326654Snate@binkert.org if isinstance(item, (list, tuple)): 1336654Snate@binkert.org items[0:0] = item 1346654Snate@binkert.org else: 1356654Snate@binkert.org yield item 1366654Snate@binkert.org 1376654Snate@binkert.org# force scalars to one-element lists for uniformity 1386654Snate@binkert.orgdef makeList(objOrList): 1396654Snate@binkert.org if isinstance(objOrList, list): 1406654Snate@binkert.org return objOrList 1416654Snate@binkert.org return [objOrList] 1426654Snate@binkert.org 1436654Snate@binkert.orgdef printList(items, indent=4): 1445873Snate@binkert.org line = ' ' * indent 1455873Snate@binkert.org for i,item in enumerate(items): 1465873Snate@binkert.org if len(line) + len(item) > 76: 1475873Snate@binkert.org print line 1485873Snate@binkert.org line = ' ' * indent 1495873Snate@binkert.org 1505873Snate@binkert.org if i < len(items) - 1: 1515873Snate@binkert.org line += '%s, ' % item 1525873Snate@binkert.org else: 1535873Snate@binkert.org line += item 1545873Snate@binkert.org print line 1556654Snate@binkert.org 1566654Snate@binkert.orgdef readCommand(cmd, **kwargs): 1576654Snate@binkert.org """run the command cmd, read the results and return them 1586654Snate@binkert.org this is sorta like `cmd` in shell""" 1596654Snate@binkert.org from subprocess import Popen, PIPE, STDOUT 1606654Snate@binkert.org 1616654Snate@binkert.org if isinstance(cmd, str): 1626654Snate@binkert.org cmd = cmd.split() 1636654Snate@binkert.org 1646654Snate@binkert.org no_exception = 'exception' in kwargs 1656654Snate@binkert.org exception = kwargs.pop('exception', None) 1666654Snate@binkert.org 1676654Snate@binkert.org kwargs.setdefault('shell', False) 1686654Snate@binkert.org kwargs.setdefault('stdout', PIPE) 1696654Snate@binkert.org kwargs.setdefault('stderr', STDOUT) 1706654Snate@binkert.org kwargs.setdefault('close_fds', True) 1716654Snate@binkert.org try: 1726654Snate@binkert.org subp = Popen(cmd, **kwargs) 1736654Snate@binkert.org except Exception, e: 1746654Snate@binkert.org if no_exception: 1756654Snate@binkert.org return exception 1766654Snate@binkert.org raise 1776654Snate@binkert.org 1786654Snate@binkert.org return subp.communicate()[0] 1798453Snate@binkert.org 1808453Snate@binkert.orgdef makeDir(path): 1818453Snate@binkert.org """Make a directory if it doesn't exist. If the path does exist, 1828453Snate@binkert.org ensure that it is a directory""" 1838453Snate@binkert.org if os.path.exists(path): 1848453Snate@binkert.org if not os.path.isdir(path): 1858453Snate@binkert.org raise AttributeError, "%s exists but is not directory" % path 1868453Snate@binkert.org else: 1878453Snate@binkert.org os.mkdir(path) 188