sim: move iterating over SimObjects into Python.
This commit is contained in:
parent
c2cce96a0b
commit
5ea906ba16
9 changed files with 42 additions and 167 deletions
|
@ -530,7 +530,8 @@ class SimObject(object):
|
||||||
# If the attribute exists on the C++ object, transparently
|
# If the attribute exists on the C++ object, transparently
|
||||||
# forward the reference there. This is typically used for
|
# forward the reference there. This is typically used for
|
||||||
# SWIG-wrapped methods such as init(), regStats(),
|
# 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):
|
if self._ccObject and hasattr(self._ccObject, attr):
|
||||||
return getattr(self._ccObject, attr)
|
return getattr(self._ccObject, attr)
|
||||||
|
|
||||||
|
@ -660,7 +661,7 @@ class SimObject(object):
|
||||||
def unproxy(self, base):
|
def unproxy(self, base):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def unproxy_all(self):
|
def unproxyParams(self):
|
||||||
for param in self._params.iterkeys():
|
for param in self._params.iterkeys():
|
||||||
value = self._values.get(param)
|
value = self._values.get(param)
|
||||||
if value != None and isproxy(value):
|
if value != None and isproxy(value):
|
||||||
|
@ -681,12 +682,6 @@ class SimObject(object):
|
||||||
if port != None:
|
if port != None:
|
||||||
port.unproxy(self)
|
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):
|
def print_ini(self, ini_file):
|
||||||
print >>ini_file, '[' + self.path() + ']' # .ini section header
|
print >>ini_file, '[' + self.path() + ']' # .ini section header
|
||||||
|
|
||||||
|
@ -717,9 +712,6 @@ class SimObject(object):
|
||||||
|
|
||||||
print >>ini_file # blank line between objects
|
print >>ini_file # blank line between objects
|
||||||
|
|
||||||
for child in child_names:
|
|
||||||
self._children[child].print_ini(ini_file)
|
|
||||||
|
|
||||||
def getCCParams(self):
|
def getCCParams(self):
|
||||||
if self._ccParams:
|
if self._ccParams:
|
||||||
return self._ccParams
|
return self._ccParams
|
||||||
|
@ -774,39 +766,25 @@ class SimObject(object):
|
||||||
% self.path()
|
% self.path()
|
||||||
return self._ccObject
|
return self._ccObject
|
||||||
|
|
||||||
# Call C++ to create C++ object corresponding to this object and
|
def descendants(self):
|
||||||
# (recursively) all its children
|
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):
|
def createCCObject(self):
|
||||||
self.getCCParams()
|
self.getCCParams()
|
||||||
self.getCCObject() # force creation
|
self.getCCObject() # force creation
|
||||||
for child in self._children.itervalues():
|
|
||||||
child.createCCObject()
|
|
||||||
|
|
||||||
def getValue(self):
|
def getValue(self):
|
||||||
return self.getCCObject()
|
return self.getCCObject()
|
||||||
|
|
||||||
# Create C++ port connections corresponding to the connections in
|
# Create C++ port connections corresponding to the connections in
|
||||||
# _port_refs (& recursively for all children)
|
# _port_refs
|
||||||
def connectPorts(self):
|
def connectPorts(self):
|
||||||
for portRef in self._port_refs.itervalues():
|
for portRef in self._port_refs.itervalues():
|
||||||
portRef.ccConnect()
|
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):
|
def getMemoryMode(self):
|
||||||
if not isinstance(self, m5.objects.System):
|
if not isinstance(self, m5.objects.System):
|
||||||
|
@ -820,8 +798,6 @@ class SimObject(object):
|
||||||
# setMemoryMode directly from self._ccObject results in calling
|
# setMemoryMode directly from self._ccObject results in calling
|
||||||
# SimObject::setMemoryMode, not the System::setMemoryMode
|
# SimObject::setMemoryMode, not the System::setMemoryMode
|
||||||
self._ccObject.setMemoryMode(mode)
|
self._ccObject.setMemoryMode(mode)
|
||||||
for child in self._children.itervalues():
|
|
||||||
child.changeTiming(mode)
|
|
||||||
|
|
||||||
def takeOverFrom(self, old_cpu):
|
def takeOverFrom(self, old_cpu):
|
||||||
self._ccObject.takeOverFrom(old_cpu._ccObject)
|
self._ccObject.takeOverFrom(old_cpu._ccObject)
|
||||||
|
|
|
@ -27,14 +27,6 @@
|
||||||
# Authors: Nathan Binkert
|
# Authors: Nathan Binkert
|
||||||
|
|
||||||
import internal
|
import internal
|
||||||
from internal.core import initAll, regAllStats
|
|
||||||
|
|
||||||
def setOutputDir(dir):
|
def setOutputDir(dir):
|
||||||
internal.core.setOutputDir(dir)
|
internal.core.setOutputDir(dir)
|
||||||
|
|
||||||
def initAll():
|
|
||||||
internal.core.initAll()
|
|
||||||
|
|
||||||
def regAllStats():
|
|
||||||
internal.core.regAllStats()
|
|
||||||
|
|
||||||
|
|
|
@ -55,25 +55,29 @@ def instantiate():
|
||||||
# we need to fix the global frequency
|
# we need to fix the global frequency
|
||||||
ticks.fixGlobalFrequency()
|
ticks.fixGlobalFrequency()
|
||||||
|
|
||||||
root.unproxy_all()
|
# Unproxy in sorted order for determinism
|
||||||
|
for obj in root.descendants(): obj.unproxyParams()
|
||||||
|
|
||||||
if options.dump_config:
|
if options.dump_config:
|
||||||
ini_file = file(os.path.join(options.outdir, options.dump_config), 'w')
|
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()
|
ini_file.close()
|
||||||
|
|
||||||
# Initialize the global statistics
|
# Initialize the global statistics
|
||||||
stats.initSimStats()
|
stats.initSimStats()
|
||||||
|
|
||||||
# Create the C++ sim objects and connect ports
|
# Create the C++ sim objects and connect ports
|
||||||
root.createCCObject()
|
for obj in root.descendants(): obj.createCCObject()
|
||||||
root.connectPorts()
|
for obj in root.descendants(): obj.connectPorts()
|
||||||
|
|
||||||
# Do a second pass to finish initializing the sim objects
|
# 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
|
# 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.
|
# We're done registering statistics. Enable the stats package now.
|
||||||
stats.enable()
|
stats.enable()
|
||||||
|
@ -97,7 +101,8 @@ def simulate(*args, **kwargs):
|
||||||
global need_resume, need_startup
|
global need_resume, need_startup
|
||||||
|
|
||||||
if need_startup:
|
if need_startup:
|
||||||
internal.core.startupAll()
|
root = objects.Root.getInstance()
|
||||||
|
for obj in root.descendants(): obj.startup()
|
||||||
need_startup = False
|
need_startup = False
|
||||||
|
|
||||||
for root in need_resume:
|
for root in need_resume:
|
||||||
|
@ -129,10 +134,10 @@ def doDrain(root):
|
||||||
def drain(root):
|
def drain(root):
|
||||||
all_drained = False
|
all_drained = False
|
||||||
drain_event = internal.event.createCountedDrain()
|
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 we've got some objects that can't drain immediately, then simulate
|
||||||
if unready_objects > 0:
|
if unready_objs > 0:
|
||||||
drain_event.setCount(unready_objects)
|
drain_event.setCount(unready_objs)
|
||||||
simulate()
|
simulate()
|
||||||
else:
|
else:
|
||||||
all_drained = True
|
all_drained = True
|
||||||
|
@ -140,7 +145,7 @@ def drain(root):
|
||||||
return all_drained
|
return all_drained
|
||||||
|
|
||||||
def resume(root):
|
def resume(root):
|
||||||
root.resume()
|
for obj in root.descendants(): obj.resume()
|
||||||
|
|
||||||
def checkpoint(dir):
|
def checkpoint(dir):
|
||||||
root = objects.Root.getInstance()
|
root = objects.Root.getInstance()
|
||||||
|
@ -165,7 +170,8 @@ def changeToAtomic(system):
|
||||||
if system.getMemoryMode() != objects.params.atomic:
|
if system.getMemoryMode() != objects.params.atomic:
|
||||||
doDrain(system)
|
doDrain(system)
|
||||||
print "Changing memory mode to atomic"
|
print "Changing memory mode to atomic"
|
||||||
system.changeTiming(objects.params.atomic)
|
for obj in system.descendants():
|
||||||
|
obj.changeTiming(objects.params.atomic)
|
||||||
|
|
||||||
def changeToTiming(system):
|
def changeToTiming(system):
|
||||||
if not isinstance(system, (objects.Root, objects.System)):
|
if not isinstance(system, (objects.Root, objects.System)):
|
||||||
|
@ -175,7 +181,8 @@ def changeToTiming(system):
|
||||||
if system.getMemoryMode() != objects.params.timing:
|
if system.getMemoryMode() != objects.params.timing:
|
||||||
doDrain(system)
|
doDrain(system)
|
||||||
print "Changing memory mode to timing"
|
print "Changing memory mode to timing"
|
||||||
system.changeTiming(objects.params.timing)
|
for obj in system.descendants():
|
||||||
|
obj.changeTiming(objects.params.timing)
|
||||||
|
|
||||||
def switchCpus(cpuList):
|
def switchCpus(cpuList):
|
||||||
print "switching cpus"
|
print "switching cpus"
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
import internal
|
import internal
|
||||||
|
|
||||||
from internal.stats import StatEvent as event
|
from internal.stats import StatEvent as event
|
||||||
|
from objects import Root
|
||||||
|
|
||||||
def initText(filename, desc=True):
|
def initText(filename, desc=True):
|
||||||
internal.stats.initText(filename, desc)
|
internal.stats.initText(filename, desc)
|
||||||
|
@ -56,4 +57,8 @@ def dump():
|
||||||
internal.stats.dump()
|
internal.stats.dump()
|
||||||
|
|
||||||
def reset():
|
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()
|
internal.stats.reset()
|
||||||
|
|
|
@ -78,10 +78,6 @@ Tick curTick;
|
||||||
void serializeAll(const std::string &cpt_dir);
|
void serializeAll(const std::string &cpt_dir);
|
||||||
void unserializeAll(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_warn, warn_verbose;
|
||||||
bool want_info, info_verbose;
|
bool want_info, info_verbose;
|
||||||
bool want_hack, hack_verbose;
|
bool want_hack, hack_verbose;
|
||||||
|
|
|
@ -45,17 +45,6 @@ SimObject *resolveSimObject(const std::string &name);
|
||||||
int connectPorts(SimObject *o1, const std::string &name1, int i1,
|
int connectPorts(SimObject *o1, const std::string &name1, int i1,
|
||||||
SimObject *o2, const std::string &name2, int i2);
|
SimObject *o2, const std::string &name2, int i2);
|
||||||
|
|
||||||
inline void
|
|
||||||
initAll()
|
|
||||||
{
|
|
||||||
SimObject::initAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
regAllStats()
|
|
||||||
{
|
|
||||||
SimObject::regAllStats();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
serializeAll(const std::string &cpt_dir)
|
serializeAll(const std::string &cpt_dir)
|
||||||
|
@ -68,9 +57,3 @@ unserializeAll(const std::string &cpt_dir)
|
||||||
{
|
{
|
||||||
Serializable::unserializeAll(cpt_dir);
|
Serializable::unserializeAll(cpt_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
|
||||||
startupAll()
|
|
||||||
{
|
|
||||||
SimObject::startupAll();
|
|
||||||
}
|
|
||||||
|
|
|
@ -50,6 +50,12 @@ class SimObject {
|
||||||
Drained
|
Drained
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void regStats();
|
||||||
|
void regFormulas();
|
||||||
|
void resetStats();
|
||||||
|
void startup();
|
||||||
|
|
||||||
unsigned int drain(Event *drain_event);
|
unsigned int drain(Event *drain_event);
|
||||||
void resume();
|
void resume();
|
||||||
void switchOut();
|
void switchOut();
|
||||||
|
|
|
@ -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.
|
// 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
|
#ifdef DEBUG
|
||||||
//
|
//
|
||||||
|
|
|
@ -94,7 +94,6 @@ class SimObject : public EventManager, public Serializable
|
||||||
// initialization pass of all objects.
|
// initialization pass of all objects.
|
||||||
// Gets invoked after construction, before unserialize.
|
// Gets invoked after construction, before unserialize.
|
||||||
virtual void init();
|
virtual void init();
|
||||||
static void initAll();
|
|
||||||
|
|
||||||
// register statistics for this object
|
// register statistics for this object
|
||||||
virtual void regStats();
|
virtual void regStats();
|
||||||
|
@ -104,13 +103,6 @@ class SimObject : public EventManager, public Serializable
|
||||||
// final initialization before simulation
|
// final initialization before simulation
|
||||||
// all state is unserialized so
|
// all state is unserialized so
|
||||||
virtual void startup();
|
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: call nameOut() & serialize() on all SimObjects
|
||||||
static void serializeAll(std::ostream &);
|
static void serializeAll(std::ostream &);
|
||||||
|
|
Loading…
Reference in a new issue