From 5ea906ba1625266ee80968d70e0c218adedcce9f Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Tue, 17 Aug 2010 05:08:50 -0700 Subject: [PATCH] sim: move iterating over SimObjects into Python. --- src/python/m5/SimObject.py | 46 +++++--------------- src/python/m5/core.py | 8 ---- src/python/m5/simulate.py | 33 +++++++++------ src/python/m5/stats.py | 5 +++ src/python/swig/core.i | 4 -- src/python/swig/pyobject.hh | 17 -------- src/python/swig/sim_object.i | 6 +++ src/sim/sim_object.cc | 82 ------------------------------------ src/sim/sim_object.hh | 8 ---- 9 files changed, 42 insertions(+), 167 deletions(-) diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 69f79ed61..a3905949a 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -530,7 +530,8 @@ class SimObject(object): # If the attribute exists on the C++ object, transparently # forward the reference there. This is typically used for # SWIG-wrapped methods such as init(), regStats(), - # regFormulas(), resetStats(), and startup(). + # regFormulas(), resetStats(), startup(), drain(), and + # resume(). if self._ccObject and hasattr(self._ccObject, attr): return getattr(self._ccObject, attr) @@ -660,7 +661,7 @@ class SimObject(object): def unproxy(self, base): return self - def unproxy_all(self): + def unproxyParams(self): for param in self._params.iterkeys(): value = self._values.get(param) if value != None and isproxy(value): @@ -681,12 +682,6 @@ class SimObject(object): if port != None: port.unproxy(self) - # Unproxy children in sorted order for determinism also. - child_names = self._children.keys() - child_names.sort() - for child in child_names: - self._children[child].unproxy_all() - def print_ini(self, ini_file): print >>ini_file, '[' + self.path() + ']' # .ini section header @@ -717,9 +712,6 @@ class SimObject(object): print >>ini_file # blank line between objects - for child in child_names: - self._children[child].print_ini(ini_file) - def getCCParams(self): if self._ccParams: return self._ccParams @@ -774,39 +766,25 @@ class SimObject(object): % self.path() return self._ccObject - # Call C++ to create C++ object corresponding to this object and - # (recursively) all its children + def descendants(self): + yield self + for child in self._children.itervalues(): + for obj in child.descendants(): + yield obj + + # Call C++ to create C++ object corresponding to this object def createCCObject(self): self.getCCParams() self.getCCObject() # force creation - for child in self._children.itervalues(): - child.createCCObject() def getValue(self): return self.getCCObject() # Create C++ port connections corresponding to the connections in - # _port_refs (& recursively for all children) + # _port_refs def connectPorts(self): for portRef in self._port_refs.itervalues(): portRef.ccConnect() - for child in self._children.itervalues(): - child.connectPorts() - - def startDrain(self, drain_event, recursive): - count = 0 - if isinstance(self, SimObject): - count += self._ccObject.drain(drain_event) - if recursive: - for child in self._children.itervalues(): - count += child.startDrain(drain_event, True) - return count - - def resume(self): - if isinstance(self, SimObject): - self._ccObject.resume() - for child in self._children.itervalues(): - child.resume() def getMemoryMode(self): if not isinstance(self, m5.objects.System): @@ -820,8 +798,6 @@ class SimObject(object): # setMemoryMode directly from self._ccObject results in calling # SimObject::setMemoryMode, not the System::setMemoryMode self._ccObject.setMemoryMode(mode) - for child in self._children.itervalues(): - child.changeTiming(mode) def takeOverFrom(self, old_cpu): self._ccObject.takeOverFrom(old_cpu._ccObject) diff --git a/src/python/m5/core.py b/src/python/m5/core.py index 1d7985be6..8fa3d6fac 100644 --- a/src/python/m5/core.py +++ b/src/python/m5/core.py @@ -27,14 +27,6 @@ # Authors: Nathan Binkert import internal -from internal.core import initAll, regAllStats def setOutputDir(dir): internal.core.setOutputDir(dir) - -def initAll(): - internal.core.initAll() - -def regAllStats(): - internal.core.regAllStats() - diff --git a/src/python/m5/simulate.py b/src/python/m5/simulate.py index 2db5c6952..54c6a0a2d 100644 --- a/src/python/m5/simulate.py +++ b/src/python/m5/simulate.py @@ -55,25 +55,29 @@ def instantiate(): # we need to fix the global frequency ticks.fixGlobalFrequency() - root.unproxy_all() + # Unproxy in sorted order for determinism + for obj in root.descendants(): obj.unproxyParams() if options.dump_config: ini_file = file(os.path.join(options.outdir, options.dump_config), 'w') - root.print_ini(ini_file) + # Print ini sections in sorted order for easier diffing + for obj in sorted(root.descendants(), key=lambda o: o.path()): + obj.print_ini(ini_file) ini_file.close() # Initialize the global statistics stats.initSimStats() # Create the C++ sim objects and connect ports - root.createCCObject() - root.connectPorts() + for obj in root.descendants(): obj.createCCObject() + for obj in root.descendants(): obj.connectPorts() # Do a second pass to finish initializing the sim objects - core.initAll() + for obj in root.descendants(): obj.init() # Do a third pass to initialize statistics - core.regAllStats() + for obj in root.descendants(): obj.regStats() + for obj in root.descendants(): obj.regFormulas() # We're done registering statistics. Enable the stats package now. stats.enable() @@ -97,7 +101,8 @@ def simulate(*args, **kwargs): global need_resume, need_startup if need_startup: - internal.core.startupAll() + root = objects.Root.getInstance() + for obj in root.descendants(): obj.startup() need_startup = False for root in need_resume: @@ -129,10 +134,10 @@ def doDrain(root): def drain(root): all_drained = False drain_event = internal.event.createCountedDrain() - unready_objects = root.startDrain(drain_event, True) + unready_objs = sum(obj.drain(drain_event) for obj in root.descendants()) # If we've got some objects that can't drain immediately, then simulate - if unready_objects > 0: - drain_event.setCount(unready_objects) + if unready_objs > 0: + drain_event.setCount(unready_objs) simulate() else: all_drained = True @@ -140,7 +145,7 @@ def drain(root): return all_drained def resume(root): - root.resume() + for obj in root.descendants(): obj.resume() def checkpoint(dir): root = objects.Root.getInstance() @@ -165,7 +170,8 @@ def changeToAtomic(system): if system.getMemoryMode() != objects.params.atomic: doDrain(system) print "Changing memory mode to atomic" - system.changeTiming(objects.params.atomic) + for obj in system.descendants(): + obj.changeTiming(objects.params.atomic) def changeToTiming(system): if not isinstance(system, (objects.Root, objects.System)): @@ -175,7 +181,8 @@ def changeToTiming(system): if system.getMemoryMode() != objects.params.timing: doDrain(system) print "Changing memory mode to timing" - system.changeTiming(objects.params.timing) + for obj in system.descendants(): + obj.changeTiming(objects.params.timing) def switchCpus(cpuList): print "switching cpus" diff --git a/src/python/m5/stats.py b/src/python/m5/stats.py index 40a49b001..76729d5ee 100644 --- a/src/python/m5/stats.py +++ b/src/python/m5/stats.py @@ -29,6 +29,7 @@ import internal from internal.stats import StatEvent as event +from objects import Root def initText(filename, desc=True): internal.stats.initText(filename, desc) @@ -56,4 +57,8 @@ def dump(): internal.stats.dump() def reset(): + # call reset stats on all SimObjects + root = Root.getInstance() + for obj in root.descendants(): obj.resetStats() + # call any other registered stats reset callbacks internal.stats.reset() diff --git a/src/python/swig/core.i b/src/python/swig/core.i index f7a075f74..81085dd06 100644 --- a/src/python/swig/core.i +++ b/src/python/swig/core.i @@ -78,10 +78,6 @@ Tick curTick; void serializeAll(const std::string &cpt_dir); void unserializeAll(const std::string &cpt_dir); -void initAll(); -void regAllStats(); -void startupAll(); - bool want_warn, warn_verbose; bool want_info, info_verbose; bool want_hack, hack_verbose; diff --git a/src/python/swig/pyobject.hh b/src/python/swig/pyobject.hh index 01f0fd95e..a27080d08 100644 --- a/src/python/swig/pyobject.hh +++ b/src/python/swig/pyobject.hh @@ -45,17 +45,6 @@ SimObject *resolveSimObject(const std::string &name); int connectPorts(SimObject *o1, const std::string &name1, int i1, SimObject *o2, const std::string &name2, int i2); -inline void -initAll() -{ - SimObject::initAll(); -} - -inline void -regAllStats() -{ - SimObject::regAllStats(); -} inline void serializeAll(const std::string &cpt_dir) @@ -68,9 +57,3 @@ unserializeAll(const std::string &cpt_dir) { Serializable::unserializeAll(cpt_dir); } - -inline void -startupAll() -{ - SimObject::startupAll(); -} diff --git a/src/python/swig/sim_object.i b/src/python/swig/sim_object.i index c98e44ec2..8cd8e8beb 100644 --- a/src/python/swig/sim_object.i +++ b/src/python/swig/sim_object.i @@ -50,6 +50,12 @@ class SimObject { Drained }; + void init(); + void regStats(); + void regFormulas(); + void resetStats(); + void startup(); + unsigned int drain(Event *drain_event); void resume(); void switchOut(); diff --git a/src/sim/sim_object.cc b/src/sim/sim_object.cc index 0b18ff437..157bf1395 100644 --- a/src/sim/sim_object.cc +++ b/src/sim/sim_object.cc @@ -96,76 +96,6 @@ SimObject::resetStats() { } -// -// static function: -// call regStats() on all SimObjects and then regFormulas() on all -// SimObjects. -// -struct SimObjectResetCB : public Callback -{ - virtual void process() { SimObject::resetAllStats(); } -}; - -namespace { - static SimObjectResetCB StatResetCB; -} - -void -SimObject::regAllStats() -{ - SimObjectList::iterator i; - SimObjectList::iterator end = simObjectList.end(); - - /** - * @todo change cprintfs to DPRINTFs - */ - for (i = simObjectList.begin(); i != end; ++i) { -#ifdef STAT_DEBUG - cprintf("registering stats for %s\n", (*i)->name()); -#endif - (*i)->regStats(); - } - - for (i = simObjectList.begin(); i != end; ++i) { -#ifdef STAT_DEBUG - cprintf("registering formulas for %s\n", (*i)->name()); -#endif - (*i)->regFormulas(); - } - - Stats::registerResetCallback(&StatResetCB); -} - -// -// static function: call init() on all SimObjects. -// -void -SimObject::initAll() -{ - SimObjectList::iterator i = simObjectList.begin(); - SimObjectList::iterator end = simObjectList.end(); - - for (; i != end; ++i) { - SimObject *obj = *i; - obj->init(); - } -} - -// -// static function: call resetStats() on all SimObjects. -// -void -SimObject::resetAllStats() -{ - SimObjectList::iterator i = simObjectList.begin(); - SimObjectList::iterator end = simObjectList.end(); - - for (; i != end; ++i) { - SimObject *obj = *i; - obj->resetStats(); - } -} - // // static function: serialize all SimObjects. // @@ -201,18 +131,6 @@ SimObject::unserializeAll(Checkpoint *cp) } -void -SimObject::startupAll() -{ - SimObjectList::iterator i = simObjectList.begin(); - SimObjectList::iterator end = simObjectList.end(); - - while (i != end) { - (*i)->startup(); - ++i; - } -} - #ifdef DEBUG // diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh index 2bea97301..1b22c5825 100644 --- a/src/sim/sim_object.hh +++ b/src/sim/sim_object.hh @@ -94,7 +94,6 @@ class SimObject : public EventManager, public Serializable // initialization pass of all objects. // Gets invoked after construction, before unserialize. virtual void init(); - static void initAll(); // register statistics for this object virtual void regStats(); @@ -104,13 +103,6 @@ class SimObject : public EventManager, public Serializable // final initialization before simulation // all state is unserialized so virtual void startup(); - static void startupAll(); - - // static: call reg_stats on all SimObjects - static void regAllStats(); - - // static: call resetStats on all SimObjects - static void resetAllStats(); // static: call nameOut() & serialize() on all SimObjects static void serializeAll(std::ostream &);