__init__.py revision 7459
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 425873Snate@binkert.org 436654Snate@binkert.org# define this here so we can use it right away if necessary 446654Snate@binkert.orgdef errorURL(prefix, s): 456654Snate@binkert.org try: 466654Snate@binkert.org import zlib 476654Snate@binkert.org hashstr = "%x" % zlib.crc32(s) 486654Snate@binkert.org except: 496654Snate@binkert.org hashstr = "UnableToHash" 506654Snate@binkert.org return "For more information see: http://www.m5sim.org/%s/%s" % \ 516654Snate@binkert.org (prefix, hashstr) 526654Snate@binkert.org 536654Snate@binkert.org# panic() should be called when something happens that should never 546654Snate@binkert.org# ever happen regardless of what the user does (i.e., an acutal m5 556654Snate@binkert.org# bug). 566654Snate@binkert.orgdef panic(fmt, *args): 576654Snate@binkert.org print >>sys.stderr, 'panic:', fmt % args 586654Snate@binkert.org print >>sys.stderr, errorURL('panic',fmt) 596654Snate@binkert.org sys.exit(1) 606654Snate@binkert.org 616654Snate@binkert.org# fatal() should be called when the simulation cannot continue due to 626654Snate@binkert.org# some condition that is the user's fault (bad configuration, invalid 636654Snate@binkert.org# arguments, etc.) and not a simulator bug. 646654Snate@binkert.orgdef fatal(fmt, *args): 656654Snate@binkert.org print >>sys.stderr, 'fatal:', fmt % args 666654Snate@binkert.org print >>sys.stderr, errorURL('fatal',fmt) 676654Snate@binkert.org sys.exit(1) 686654Snate@binkert.org 696654Snate@binkert.orgclass Singleton(type): 706654Snate@binkert.org def __call__(cls, *args, **kwargs): 716654Snate@binkert.org if hasattr(cls, '_instance'): 726654Snate@binkert.org return cls._instance 736654Snate@binkert.org 746654Snate@binkert.org cls._instance = super(Singleton, cls).__call__(*args, **kwargs) 756654Snate@binkert.org return cls._instance 766654Snate@binkert.org 776654Snate@binkert.orgdef addToPath(path): 786654Snate@binkert.org """Prepend given directory to system module search path. We may not 796654Snate@binkert.org need this anymore if we can structure our config library more like a 806654Snate@binkert.org Python package.""" 816654Snate@binkert.org 826654Snate@binkert.org # if it's a relative path and we know what directory the current 836654Snate@binkert.org # python script is in, make the path relative to that directory. 846654Snate@binkert.org if not os.path.isabs(path) and sys.path[0]: 856654Snate@binkert.org path = os.path.join(sys.path[0], path) 866654Snate@binkert.org path = os.path.realpath(path) 876654Snate@binkert.org # sys.path[0] should always refer to the current script's directory, 886654Snate@binkert.org # so place the new dir right after that. 896654Snate@binkert.org sys.path.insert(1, path) 906654Snate@binkert.org 916654Snate@binkert.org# Apply method to object. 926654Snate@binkert.org# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>) 936654Snate@binkert.orgdef applyMethod(obj, meth, *args, **kwargs): 946654Snate@binkert.org return getattr(obj, meth)(*args, **kwargs) 956654Snate@binkert.org 966654Snate@binkert.org# If the first argument is an (non-sequence) object, apply the named 976654Snate@binkert.org# method with the given arguments. If the first argument is a 986654Snate@binkert.org# sequence, apply the method to each element of the sequence (a la 996654Snate@binkert.org# 'map'). 1006654Snate@binkert.orgdef applyOrMap(objOrSeq, meth, *args, **kwargs): 1016654Snate@binkert.org if not isinstance(objOrSeq, (list, tuple)): 1026654Snate@binkert.org return applyMethod(objOrSeq, meth, *args, **kwargs) 1036654Snate@binkert.org else: 1046654Snate@binkert.org return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq] 1056654Snate@binkert.org 1066654Snate@binkert.orgdef compareVersions(v1, v2): 1076654Snate@binkert.org """helper function: compare arrays or strings of version numbers. 1086654Snate@binkert.org E.g., compare_version((1,3,25), (1,4,1)') 1096654Snate@binkert.org returns -1, 0, 1 if v1 is <, ==, > v2 1106654Snate@binkert.org """ 1116654Snate@binkert.org def make_version_list(v): 1126654Snate@binkert.org if isinstance(v, (list,tuple)): 1136654Snate@binkert.org return v 1146654Snate@binkert.org elif isinstance(v, str): 1156654Snate@binkert.org return map(lambda x: int(re.match('\d+', x).group()), v.split('.')) 1166654Snate@binkert.org else: 1176654Snate@binkert.org raise TypeError 1186654Snate@binkert.org 1196654Snate@binkert.org v1 = make_version_list(v1) 1206654Snate@binkert.org v2 = make_version_list(v2) 1216654Snate@binkert.org # Compare corresponding elements of lists 1226654Snate@binkert.org for n1,n2 in zip(v1, v2): 1236654Snate@binkert.org if n1 < n2: return -1 1246654Snate@binkert.org if n1 > n2: return 1 1256654Snate@binkert.org # all corresponding values are equal... see if one has extra values 1266654Snate@binkert.org if len(v1) < len(v2): return -1 1276654Snate@binkert.org if len(v1) > len(v2): return 1 1286654Snate@binkert.org return 0 1296654Snate@binkert.org 1306654Snate@binkert.orgdef crossproduct(items): 1316654Snate@binkert.org if len(items) == 1: 1326654Snate@binkert.org for i in items[0]: 1336654Snate@binkert.org yield (i,) 1346654Snate@binkert.org else: 1356654Snate@binkert.org for i in items[0]: 1366654Snate@binkert.org for j in crossproduct(items[1:]): 1376654Snate@binkert.org yield (i,) + j 1386654Snate@binkert.org 1396654Snate@binkert.orgdef flatten(items): 1406654Snate@binkert.org while items: 1416654Snate@binkert.org item = items.pop(0) 1426654Snate@binkert.org if isinstance(item, (list, tuple)): 1436654Snate@binkert.org items[0:0] = item 1446654Snate@binkert.org else: 1456654Snate@binkert.org yield item 1466654Snate@binkert.org 1476654Snate@binkert.org# force scalars to one-element lists for uniformity 1486654Snate@binkert.orgdef makeList(objOrList): 1496654Snate@binkert.org if isinstance(objOrList, list): 1506654Snate@binkert.org return objOrList 1516654Snate@binkert.org return [objOrList] 1526654Snate@binkert.org 1536654Snate@binkert.orgdef printList(items, indent=4): 1545873Snate@binkert.org line = ' ' * indent 1555873Snate@binkert.org for i,item in enumerate(items): 1565873Snate@binkert.org if len(line) + len(item) > 76: 1575873Snate@binkert.org print line 1585873Snate@binkert.org line = ' ' * indent 1595873Snate@binkert.org 1605873Snate@binkert.org if i < len(items) - 1: 1615873Snate@binkert.org line += '%s, ' % item 1625873Snate@binkert.org else: 1635873Snate@binkert.org line += item 1645873Snate@binkert.org print line 1656654Snate@binkert.org 1666654Snate@binkert.orgdef readCommand(cmd, **kwargs): 1676654Snate@binkert.org """run the command cmd, read the results and return them 1686654Snate@binkert.org this is sorta like `cmd` in shell""" 1696654Snate@binkert.org from subprocess import Popen, PIPE, STDOUT 1706654Snate@binkert.org 1716654Snate@binkert.org if isinstance(cmd, str): 1726654Snate@binkert.org cmd = cmd.split() 1736654Snate@binkert.org 1746654Snate@binkert.org no_exception = 'exception' in kwargs 1756654Snate@binkert.org exception = kwargs.pop('exception', None) 1766654Snate@binkert.org 1776654Snate@binkert.org kwargs.setdefault('shell', False) 1786654Snate@binkert.org kwargs.setdefault('stdout', PIPE) 1796654Snate@binkert.org kwargs.setdefault('stderr', STDOUT) 1806654Snate@binkert.org kwargs.setdefault('close_fds', True) 1816654Snate@binkert.org try: 1826654Snate@binkert.org subp = Popen(cmd, **kwargs) 1836654Snate@binkert.org except Exception, e: 1846654Snate@binkert.org if no_exception: 1856654Snate@binkert.org return exception 1866654Snate@binkert.org raise 1876654Snate@binkert.org 1886654Snate@binkert.org return subp.communicate()[0] 189