From 29e34a739b991af8d8e1eafe75ecb0904c324dc8 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Fri, 9 Jun 2006 23:01:31 -0400 Subject: Move main control from C++ into Python. User script now invokes initialization and simulation loop after building configuration. These functions are exported from C++ to Python using SWIG. SConstruct: Set up SWIG builder & scanner. Set up symlinking of source files into build directory (by not disabling the default behavior). configs/test/test.py: Rewrite to use new script-driven interface. Include a sample option. src/SConscript: Set up symlinking of source files into build directory (by not disabling the default behavior). Add SWIG-generated main_wrap.cc to source list. src/arch/SConscript: Set up symlinking of source files into build directory (by not disabling the default behavior). src/arch/alpha/ev5.cc: src/arch/alpha/isa/decoder.isa: src/cpu/o3/alpha_cpu_impl.hh: src/cpu/trace/opt_cpu.cc: src/cpu/trace/trace_cpu.cc: src/sim/pseudo_inst.cc: src/sim/root.cc: src/sim/serialize.cc: src/sim/syscall_emul.cc: SimExit() is now exitSimLoop(). src/cpu/base.cc: SimExitEvent is now SimLoopExitEvent src/python/SConscript: Add SWIG build command for main.i. Use python/m5 in build dir as source for zip archive... easy now with file duplication enabled. src/python/m5/__init__.py: - Move copyright notice back to C++ so we can print it right away, even for interactive sessions. - Get rid of argument parsing code; just provide default option descriptors for user script to call optparse with. - Don't clutter m5 namespace by sucking in all of m5.config and m5.objects. - Move instantiate() function here from config.py. src/python/m5/config.py: - Move instantiate() function to __init__.py. - Param.Foo deferred type lookups must use m5.objects namespace now (not m5). src/python/m5/objects/AlphaConsole.py: src/python/m5/objects/AlphaFullCPU.py: src/python/m5/objects/AlphaTLB.py: src/python/m5/objects/BadDevice.py: src/python/m5/objects/BaseCPU.py: src/python/m5/objects/BaseCache.py: src/python/m5/objects/Bridge.py: src/python/m5/objects/Bus.py: src/python/m5/objects/CoherenceProtocol.py: src/python/m5/objects/Device.py: src/python/m5/objects/DiskImage.py: src/python/m5/objects/Ethernet.py: src/python/m5/objects/Ide.py: src/python/m5/objects/IntrControl.py: src/python/m5/objects/MemObject.py: src/python/m5/objects/MemTest.py: src/python/m5/objects/Pci.py: src/python/m5/objects/PhysicalMemory.py: src/python/m5/objects/Platform.py: src/python/m5/objects/Process.py: src/python/m5/objects/Repl.py: src/python/m5/objects/Root.py: src/python/m5/objects/SimConsole.py: src/python/m5/objects/SimpleDisk.py: src/python/m5/objects/System.py: src/python/m5/objects/Tsunami.py: src/python/m5/objects/Uart.py: Fix up imports (m5 namespace no longer includes m5.config). src/sim/eventq.cc: src/sim/eventq.hh: Support for Python-called simulate() function: - Use IsExitEvent flag to signal events that want to exit the simulation loop gracefully (instead of calling exit() to terminate the process). - Modify interface to hand exit event object back to caller so it can be inspected for cause. src/sim/host.hh: Add MaxTick constant. src/sim/main.cc: Move copyright notice back to C++ so we can print it right away, even for interactive sessions. Use PYTHONPATH environment var to set module path (instead of clunky code injection method). Move main control from here into Python: - Separate initialization code and simulation loop into separate functions callable from Python. - Make Python interpreter invocation more pure (more like directly invoking interpreter). Add -i and -p flags (only options on binary itself; other options processed by Python). Import readline package when using interactive mode. src/sim/sim_events.cc: SimExitEvent is now SimLoopExitEvent, and uses IsSimExit flag to terminate loop (instead of exiting simulator process). src/sim/sim_events.hh: SimExitEvent is now SimLoopExitEvent, and uses IsSimExit flag to terminate loop (instead of exiting simulator process). Get rid of a few unused constructors. src/sim/sim_exit.hh: SimExit() is now exitSimLoop(). Get rid of unused functions. Add comments. --HG-- extra : convert_revision : 280b0d671516b25545a6f24cefa64a68319ff3d4 --- src/python/m5/__init__.py | 183 +++++++++++++++------------------------------- 1 file changed, 57 insertions(+), 126 deletions(-) (limited to 'src/python/m5/__init__.py') diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py index c44a9ad1f..60a61d66e 100644 --- a/src/python/m5/__init__.py +++ b/src/python/m5/__init__.py @@ -27,69 +27,26 @@ # Authors: Nathan Binkert # Steve Reinhardt -import sys, os, time +import sys, os, time, atexit, optparse -import __main__ +# import the SWIG-wrapped main C++ functions +import main +# import a few SWIG-wrapped items (those that are likely to be used +# directly by user scripts) completely into this module for +# convenience +from main import simulate, SimLoopExitEvent -briefCopyright = ''' -Copyright (c) 2001-2006 -The Regents of The University of Michigan -All Rights Reserved -''' - -fullCopyright = ''' -Copyright (c) 2001-2006 -The Regents of The University of Michigan -All Rights Reserved - -Permission is granted to use, copy, create derivative works and -redistribute this software and such derivative works for any purpose, -so long as the copyright notice above, this grant of permission, and -the disclaimer below appear in all copies made; and so long as the -name of The University of Michigan is not used in any advertising or -publicity pertaining to the use or distribution of this software -without specific, written prior authorization. - -THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE -UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT -WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR -IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF -THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES, -INCLUDING DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION -WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER -ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -''' - -def sayHello(f): - print >> f, "M5 Simulator System" - print >> f, briefCopyright - print >> f, "M5 compiled on", __main__.compileDate - hostname = os.environ.get('HOSTNAME') - if not hostname: - hostname = os.environ.get('HOST') - if hostname: - print >> f, "M5 executing on", hostname - print >> f, "M5 simulation started", time.ctime() - -sayHello(sys.stderr) +# import the m5 compile options +import defines # define this here so we can use it right away if necessary def panic(string): print >>sys.stderr, 'panic:', string sys.exit(1) -def m5execfile(f, global_dict): - # copy current sys.path - oldpath = sys.path[:] - # push file's directory onto front of path - sys.path.insert(0, os.path.abspath(os.path.dirname(f))) - execfile(f, global_dict) - # restore original path - sys.path = oldpath - -# Prepend given directory to system module search path. +# Prepend given directory to system module search path. We may not +# need this anymore if we can structure our config library more like a +# Python package. def AddToPath(path): # if it's a relative path and we know what directory the current # python script is in, make the path relative to that directory. @@ -100,84 +57,58 @@ def AddToPath(path): # so place the new dir right after that. sys.path.insert(1, path) -# find the m5 compile options: must be specified as a dict in -# __main__.m5_build_env. -import __main__ -if not hasattr(__main__, 'm5_build_env'): - panic("__main__ must define m5_build_env") + +# Callback to set trace flags. Not necessarily the best way to do +# things in the long run (particularly if we change how these global +# options are handled). +def setTraceFlags(option, opt_str, value, parser): + objects.Trace.flags = value + +# Standard optparse options. Need to be explicitly included by the +# user script when it calls optparse.OptionParser(). +standardOptions = [ + optparse.make_option("--traceflags", type="string", action="callback", + callback=setTraceFlags) + ] # make a SmartDict out of the build options for our local use import smartdict build_env = smartdict.SmartDict() -build_env.update(__main__.m5_build_env) +build_env.update(defines.m5_build_env) # make a SmartDict out of the OS environment too env = smartdict.SmartDict() env.update(os.environ) -# import the main m5 config code -from config import * - -# import the built-in object definitions -from objects import * - - -args_left = sys.argv[1:] -configfile_found = False - -while args_left: - arg = args_left.pop(0) - if arg.startswith('--'): - # if arg starts with '--', parse as a special python option - # of the format --= - try: - (var, val) = arg.split('=', 1) - except ValueError: - panic("Could not parse configuration argument '%s'\n" - "Expecting --=\n" % arg); - eval("%s = %s" % (var, repr(val))) - elif arg.startswith('-'): - # if the arg starts with '-', it should be a simulator option - # with a format similar to getopt. - optchar = arg[1] - if len(arg) > 2: - args_left.insert(0, arg[2:]) - if optchar == 'd': - outdir = args_left.pop(0) - elif optchar == 'h': - showBriefHelp(sys.stderr) - sys.exit(1) - elif optchar == 'E': - env_str = args_left.pop(0) - split_result = env_str.split('=', 1) - var = split_result[0] - if len(split_result == 2): - val = split_result[1] - else: - val = True - env[var] = val - elif optchar == 'I': - AddToPath(args_left.pop(0)) - elif optchar == 'P': - eval(args_left.pop(0)) - else: - showBriefHelp(sys.stderr) - panic("invalid argument '%s'\n" % arg_str) - else: - # In any other case, treat the option as a configuration file - # name and load it. - if not arg.endswith('.py'): - panic("Config file '%s' must end in '.py'\n" % arg) - configfile_found = True - m5execfile(arg, globals()) - - -if not configfile_found: - panic("no configuration file specified!") - -if globals().has_key('root') and isinstance(root, Root): +# The final hook to generate .ini files. Called from the user script +# once the config is built. +def instantiate(root): + config.ticks_per_sec = float(root.clock.frequency) + # ugly temporary hack to get output to config.ini sys.stdout = file('config.ini', 'w') - instantiate(root) -else: - print 'Instantiation skipped: no root object found.' - + root.print_ini() + sys.stdout.close() # close config.ini + sys.stdout = sys.__stdout__ # restore to original + main.initialize() # load config.ini into C++ and process it + noDot = True # temporary until we fix dot + if not noDot: + dot = pydot.Dot() + instance.outputDot(dot) + dot.orientation = "portrait" + dot.size = "8.5,11" + dot.ranksep="equally" + dot.rank="samerank" + dot.write("config.dot") + dot.write_ps("config.ps") + +# Export curTick to user script. +def curTick(): + return main.cvar.curTick + +# register our C++ exit callback function with Python +atexit.register(main.doExitCleanup) + +# This import allows user scripts to reference 'm5.objects.Foo' after +# just doing an 'import m5' (without an 'import m5.objects'). May not +# matter since most scripts will probably 'from m5.objects import *'. +import objects -- cgit v1.2.3