summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCiro Santilli <ciro.santilli@arm.com>2018-09-13 14:54:34 +0100
committerCiro Santilli <ciro.santilli@arm.com>2018-10-19 17:12:35 +0000
commit3cceef1316f75366ca0ddbbe0f86eb0342529df3 (patch)
tree48fbbc22921bbf384317f2c287fbc0c359df6d0f
parentfcc379674201ea8eb23b2cfc9bf22d7d0925f65c (diff)
downloadgem5-3cceef1316f75366ca0ddbbe0f86eb0342529df3.tar.xz
python: Add utility function to override config parameters
Add a utility method, SimObject.apply_config that can be used to implement SimObject param overrides from the command line. This function provides safe and convenient semantics for CLI assignment: * The override expression is evaluated in a restricted environment. The only global variables are the child objects and params from the root object. * Only params can be overridden. For example, calling methods or setting attributes on SimObjects isn't possible. * Vectors use non-standard list semantics which enable something similar to glob expansion on the shell. For example, setting: root.system.cpu[0:2].numThreads = 2 will override numThreads for cpu 0 and 1 and: root.system.cpus[0,2].numThreads = 2 sets it for cpus 0 and 2. The intention is that the helper method is called to override default values before calling m5.instantiate. Change-Id: I73f99da21d6d8ce1ff2ec8db2bb34338456f6799 Reviewed-on: https://gem5-review.googlesource.com/c/12984 Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Jason Lowe-Power <jason@lowepower.com>
-rw-r--r--src/python/m5/SimObject.py83
1 files changed, 82 insertions, 1 deletions
diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py
index 0a5436f5b..44f26ea9b 100644
--- a/src/python/m5/SimObject.py
+++ b/src/python/m5/SimObject.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2017 ARM Limited
+# Copyright (c) 2017-2018 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
@@ -934,6 +934,63 @@ class ParamInfo(object):
if not "created" in self.__dict__:
self.__dict__[name] = value
+class SimObjectCliWrapperException(Exception):
+ def __init__(self, message):
+ super(Exception, self).__init__(message)
+
+class SimObjectCliWrapper(object):
+ """
+ Wrapper class to restrict operations that may be done
+ from the command line on SimObjects.
+
+ Only parameters may be set, and only children may be accessed.
+
+ Slicing allows for multiple simultaneous assignment of items in
+ one statement.
+ """
+
+ def __init__(self, sim_objects):
+ self.__dict__['_sim_objects'] = list(sim_objects)
+
+ def __getattr__(self, key):
+ return SimObjectCliWrapper(sim_object._children[key]
+ for sim_object in self._sim_objects)
+
+ def __setattr__(self, key, val):
+ for sim_object in self._sim_objects:
+ if key in sim_object._params:
+ if sim_object._params[key].isCmdLineSettable():
+ setattr(sim_object, key, val)
+ else:
+ raise SimObjectCliWrapperException(
+ 'tried to set or unsettable' \
+ 'object parameter: ' + key)
+ else:
+ raise SimObjectCliWrapperException(
+ 'tried to set or access non-existent' \
+ 'object parameter: ' + key)
+
+ def __getitem__(self, idx):
+ """
+ Extends the list() semantics to also allow tuples,
+ for example object[1, 3] selects items 1 and 3.
+ """
+ out = []
+ if isinstance(idx, tuple):
+ for t in idx:
+ out.extend(self[t]._sim_objects)
+ else:
+ if isinstance(idx, int):
+ _range = range(idx, idx + 1)
+ elif not isinstance(idx, slice):
+ raise SimObjectCliWrapperException( \
+ 'invalid index type: ' + repr(idx))
+ for sim_object in self._sim_objects:
+ if isinstance(idx, slice):
+ _range = range(*idx.indices(len(sim_object)))
+ out.extend(sim_object[i] for i in _range)
+ return SimObjectCliWrapper(out)
+
# The SimObject class is the root of the special hierarchy. Most of
# the code in this class deals with the configuration hierarchy itself
# (parent/child node relationships).
@@ -1525,6 +1582,30 @@ class SimObject(object):
for dt in item.generateDeviceTree(state):
yield dt
+ # On a separate method otherwise certain buggy Python versions
+ # would fail with: SyntaxError: unqualified exec is not allowed
+ # in function 'apply_config'
+ def _apply_config_get_dict(self):
+ return {
+ child_name: SimObjectCliWrapper(
+ iter(self._children[child_name]))
+ for child_name in self._children
+ }
+
+ def apply_config(self, params):
+ """
+ exec a list of Python code strings contained in params.
+
+ The only exposed globals to those strings are the child
+ SimObjects of this node.
+
+ This function is intended to allow users to modify SimObject
+ parameters from the command line with Python statements.
+ """
+ d = self._apply_config_get_dict()
+ for param in params:
+ exec(param, d)
+
# Function to provide to C++ so it can look up instances based on paths
def resolveSimObject(name):
obj = instanceDict[name]