python: Add support for multiplying proxies to compatible Param
authorNikos Nikoleris <nikos.nikoleris@arm.com>
Fri, 22 Jun 2018 09:54:31 +0000 (10:54 +0100)
committerNikos Nikoleris <nikos.nikoleris@arm.com>
Tue, 26 Jun 2018 07:36:53 +0000 (07:36 +0000)
Previously we allowed multiplications between proxy Param and
compatible constants (int, long, float). This change extends this
functionality and adds support for multiplying with between proxy
Param and compatible proxy Param.

Change-Id: I23a083881ae4d770e818895b893534767cd2472d
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/11510
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>

src/python/m5/proxy.py

index a99d3715c72ca53543c51eca797b73d84d597b86..c0bf84a93d44a0f3304f224709a5f4c89e4401be 100644 (file)
@@ -1,3 +1,15 @@
+# Copyright (c) 2018 ARM Limited
+# All rights reserved.
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder.  You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
 # Copyright (c) 2004-2006 The Regents of The University of Michigan
 # All rights reserved.
 #
 
 import copy
 
+import params
+
 class BaseProxy(object):
     def __init__(self, search_self, search_up):
         self._search_self = search_self
         self._search_up = search_up
-        self._multiplier = None
+        self._multipliers = []
 
     def __str__(self):
         if self._search_self and not self._search_up:
@@ -56,23 +70,29 @@ class BaseProxy(object):
                   "cannot set attribute '%s' on proxy object" % attr
         super(BaseProxy, self).__setattr__(attr, value)
 
-    # support multiplying proxies by constants
+    # support for multiplying proxies by constants or other proxies to
+    # other params
     def __mul__(self, other):
-        if not isinstance(other, (int, long, float)):
-            raise TypeError, "Proxy multiplier must be integer"
-        if self._multiplier == None:
-            self._multiplier = other
-        else:
-            # support chained multipliers
-            self._multiplier *= other
+        if not (isinstance(other, (int, long, float)) or isproxy(other)):
+            raise TypeError, \
+                "Proxy multiplier must be a constant or a proxy to a param"
+        self._multipliers.append(other)
         return self
 
     __rmul__ = __mul__
 
-    def _mulcheck(self, result):
-        if self._multiplier == None:
-            return result
-        return result * self._multiplier
+    def _mulcheck(self, result, base):
+        for multiplier in self._multipliers:
+            if isproxy(multiplier):
+                multiplier = multiplier.unproxy(base)
+                # assert that we are multiplying with a compatible
+                # param
+                if not isinstance(multiplier, params.NumericParamValue):
+                    raise TypeError, \
+                        "Proxy multiplier must be a numerical param"
+                multiplier = multiplier.getValue()
+            result *= multiplier
+        return result
 
     def unproxy(self, base):
         obj = base
@@ -105,7 +125,7 @@ class BaseProxy(object):
                 raise RuntimeError, "Cycle in unproxy"
             result = result.unproxy(obj)
 
-        return self._mulcheck(result)
+        return self._mulcheck(result, base)
 
     def getindex(obj, index):
         if index == None: