ruby: changes how Topologies are created
authorBrad Beckmann <Brad.Beckmann@amd.com>
Wed, 11 Jul 2012 05:51:53 +0000 (22:51 -0700)
committerBrad Beckmann <Brad.Beckmann@amd.com>
Wed, 11 Jul 2012 05:51:53 +0000 (22:51 -0700)
Instead of just passing a list of controllers to the makeTopology function
in src/mem/ruby/network/topologies/<Topo>.py we pass in a function pointer
which knows how to make the topology, possibly with some extra state set
in the configs/ruby/<protocol>.py file. Thus, we can move all of the files
from network/topologies to configs/topologies. A new class BaseTopology
is added which all topologies in configs/topologies must inheirit from and
follow its API.

--HG--
rename : src/mem/ruby/network/topologies/Crossbar.py => configs/topologies/Crossbar.py
rename : src/mem/ruby/network/topologies/Mesh.py => configs/topologies/Mesh.py
rename : src/mem/ruby/network/topologies/MeshDirCorners.py => configs/topologies/MeshDirCorners.py
rename : src/mem/ruby/network/topologies/Pt2Pt.py => configs/topologies/Pt2Pt.py
rename : src/mem/ruby/network/topologies/Torus.py => configs/topologies/Torus.py

28 files changed:
configs/example/ruby_direct_test.py
configs/example/ruby_fs.py
configs/example/ruby_mem_test.py
configs/example/ruby_network_test.py
configs/example/ruby_random_test.py
configs/example/se.py
configs/ruby/MESI_CMP_directory.py
configs/ruby/MI_example.py
configs/ruby/MOESI_CMP_directory.py
configs/ruby/MOESI_CMP_token.py
configs/ruby/MOESI_hammer.py
configs/ruby/Network_test.py
configs/ruby/Ruby.py
configs/topologies/BaseTopology.py [new file with mode: 0644]
configs/topologies/Cluster.py [new file with mode: 0644]
configs/topologies/Crossbar.py [new file with mode: 0644]
configs/topologies/Mesh.py [new file with mode: 0644]
configs/topologies/MeshDirCorners.py [new file with mode: 0644]
configs/topologies/Pt2Pt.py [new file with mode: 0644]
configs/topologies/Torus.py [new file with mode: 0644]
src/mem/ruby/network/topologies/Crossbar.py [deleted file]
src/mem/ruby/network/topologies/Mesh.py [deleted file]
src/mem/ruby/network/topologies/MeshDirCorners.py [deleted file]
src/mem/ruby/network/topologies/Pt2Pt.py [deleted file]
src/mem/ruby/network/topologies/SConscript
src/mem/ruby/network/topologies/TopologyCreator.py [new file with mode: 0644]
src/mem/ruby/network/topologies/Torus.py [deleted file]
src/python/m5/SimObject.py

index f591d47ea543b539dd702bc9854f259ddbef8355..1fcad30a96aa5782d8edaa96939fbfb46fc73664 100644 (file)
@@ -35,6 +35,7 @@ from m5.util import addToPath
 import os, optparse, sys
 addToPath('../common')
 addToPath('../ruby')
+addToPath('../topologies')
 
 import Options
 import Ruby
index 35e485c7a9467d456434f2877bfc433c898098db..97863a46b6e98c691d0d167d995ec2f8edb9f945 100644 (file)
@@ -40,6 +40,7 @@ from m5.util import addToPath, fatal
 
 addToPath('../common')
 addToPath('../ruby')
+addToPath('../topologies')
 
 import Ruby
 
index 4d7932b775fe126d4d2e6ba398d10843e21ddf62..e3dab955c6791a432cfb8f692d7f89fad741537d 100644 (file)
@@ -35,6 +35,7 @@ from m5.util import addToPath
 import os, optparse, sys
 addToPath('../common')
 addToPath('../ruby')
+addToPath('../topologies')
 
 import Options
 import Ruby
index 1d44813acea3e2187ed92bf22f8eba500e6fac12..58e8b2e40caea5d2ba4e76e930423e7b339ab167 100644 (file)
@@ -35,6 +35,7 @@ from m5.util import addToPath
 import os, optparse, sys
 addToPath('../common')
 addToPath('../ruby')
+addToPath('../topologies')
 
 import Options
 import Ruby
index b4d32b72cca3b625d01a8c92787abce40fd247c5..eae3873b75a6391f68dd225b921407873dcfd2ef 100644 (file)
@@ -35,6 +35,7 @@ from m5.util import addToPath
 import os, optparse, sys
 addToPath('../common')
 addToPath('../ruby')
+addToPath('../topologies')
 
 import Options
 import Ruby
index 83abbd2f38ea292a42b9a5469f840c12ea08226c..fa20c37db9f749fcd3e6628fb1c6a99189331230 100644 (file)
@@ -52,6 +52,7 @@ from m5.util import addToPath, fatal
 
 addToPath('../common')
 addToPath('../ruby')
+addToPath('../topologies')
 
 import Options
 import Ruby
index cd503ddc96807861285a48637d928e06bce399f8..d877543c0c9f4e9246137e1e89ac48d28c8d4293 100644 (file)
@@ -31,6 +31,7 @@ import math
 import m5
 from m5.objects import *
 from m5.defines import buildEnv
+from Ruby import create_topology
 
 #
 # Note: the L1 Cache latency is only used by the sequencer on fast path hits
@@ -185,4 +186,6 @@ def create_system(options, system, piobus, dma_ports, ruby_system):
                  dir_cntrl_nodes + \
                  dma_cntrl_nodes
 
-    return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)
+    topology = create_topology(all_cntrls, options)
+
+    return (cpu_sequencers, dir_cntrl_nodes, topology)
index de82c38f6cab92db3b777921470bf3d35e743cf3..4fb55b89f8f4a58cfeb3fd9265da48342a9a4abc 100644 (file)
@@ -31,6 +31,7 @@ import math
 import m5
 from m5.objects import *
 from m5.defines import buildEnv
+from Ruby import create_topology
 
 #
 # Note: the cache latency is only used by the sequencer on fast path hits
@@ -155,4 +156,6 @@ def create_system(options, system, piobus, dma_ports, ruby_system):
 
     all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes
 
-    return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)
+    topology = create_topology(all_cntrls, options)
+
+    return (cpu_sequencers, dir_cntrl_nodes, topology)
index 10eeaf21a7b440110d7400f85595188540228c73..bce7be5d6ac6ecc0a3e5151f75719cc8ca86a94b 100644 (file)
@@ -31,6 +31,7 @@ import math
 import m5
 from m5.objects import *
 from m5.defines import buildEnv
+from Ruby import create_topology
 
 #
 # Note: the L1 Cache latency is only used by the sequencer on fast path hits
@@ -182,4 +183,6 @@ def create_system(options, system, piobus, dma_ports, ruby_system):
                  dir_cntrl_nodes + \
                  dma_cntrl_nodes
 
-    return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)
+    topology = create_topology(all_cntrls, options)
+
+    return (cpu_sequencers, dir_cntrl_nodes, topology)
index 4da7d7adf7aec7aff68cef8d4cfd8f4cbc8c270d..51cc5fb92f50a48aafb7093e18a60e78bcac5d57 100644 (file)
@@ -31,6 +31,7 @@ import math
 import m5
 from m5.objects import *
 from m5.defines import buildEnv
+from Ruby import create_topology
 
 #
 # Note: the L1 Cache latency is only used by the sequencer on fast path hits
@@ -206,4 +207,6 @@ def create_system(options, system, piobus, dma_ports, ruby_system):
                  dir_cntrl_nodes + \
                  dma_cntrl_nodes
 
-    return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)
+    topology = create_topology(all_cntrls, options)
+
+    return (cpu_sequencers, dir_cntrl_nodes, topology)
index 622296289d73884304487ed05d01cb1e67c54fe3..48129c0a4e0156c821081cbcf1204a57d797c19e 100644 (file)
@@ -31,6 +31,7 @@ import math
 import m5
 from m5.objects import *
 from m5.defines import buildEnv
+from Ruby import create_topology
 
 #
 # Note: the L1 Cache latency is only used by the sequencer on fast path hits
@@ -219,4 +220,6 @@ def create_system(options, system, piobus, dma_ports, ruby_system):
 
     all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes
 
-    return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)
+    topology = create_topology(all_cntrls, options)
+
+    return (cpu_sequencers, dir_cntrl_nodes, topology)
index b84fabde64c5980adef7e0b12919b0b901da9980..6eae52e863e801559a442b2354627310e74f3904 100644 (file)
@@ -31,6 +31,7 @@ import m5
 from m5.objects import *
 from m5.defines import buildEnv
 from m5.util import addToPath
+from Ruby import create_topology
 
 #
 # Note: the cache latency is only used by the sequencer on fast path hits
@@ -135,4 +136,6 @@ def create_system(options, system, piobus, dma_ports, ruby_system):
 
     all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes
 
-    return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)
+    topology = create_topology(all_cntrls, options)
+
+    return (cpu_sequencers, dir_cntrl_nodes, topology)
index 87939fac88dfae8883ff2af4d9fadd1a8a88b35d..82b8d0111472ce8db580d13b659eb6b13fffab97 100644 (file)
@@ -79,6 +79,16 @@ def define_options(parser):
     exec "import %s" % protocol
     eval("%s.define_options(parser)" % protocol)
 
+def create_topology(controllers, options):
+    """ Called from create_system in configs/ruby/<protocol>.py
+        Must return an object which is a subclass of BaseTopology
+        found in configs/topologies/BaseTopology.py
+        This is a wrapper for the legacy topologies.
+    """
+    exec "import %s as Topo" % options.topology
+    topology = eval("Topo.%s(controllers)" % options.topology)
+    return topology
+
 def create_system(options, system, piobus = None, dma_ports = []):
 
     system.ruby = RubySystem(clock = options.clock,
@@ -89,7 +99,7 @@ def create_system(options, system, piobus = None, dma_ports = []):
     protocol = buildEnv['PROTOCOL']
     exec "import %s" % protocol
     try:
-        (cpu_sequencers, dir_cntrls, all_cntrls) = \
+        (cpu_sequencers, dir_cntrls, topology) = \
              eval("%s.create_system(options, system, piobus, dma_ports, ruby)"
                   % protocol)
     except:
@@ -128,17 +138,17 @@ def create_system(options, system, piobus = None, dma_ports = []):
         class RouterClass(BasicRouter): pass
     
     #
-    # Important: the topology must be created before the network and after the
-    # controllers.
+    # Important: the topology must be instantiated before the network and after
+    # the controllers. Hence the separation between topology definition and
+    # instantiation. TopologyCreator is in src/mem/ruby/network/topologies/.
     #
-    exec "import %s" % options.topology
+    from TopologyCreator import instantiateTopology
     try:
-        net_topology = eval("%s.makeTopology(all_cntrls, options, \
-                                             IntLinkClass, ExtLinkClass, \
-                                             RouterClass)" \
-                            % options.topology)
+        net_topology = instantiateTopology(topology, options, \
+                                           IntLinkClass, ExtLinkClass, \
+                                           RouterClass)
     except:
-        print "Error: could not create topology %s" % options.topology
+        print "Error: could not make topology %s" % options.topology
         raise
 
     if options.network_fault_model:
diff --git a/configs/topologies/BaseTopology.py b/configs/topologies/BaseTopology.py
new file mode 100644 (file)
index 0000000..114a29f
--- /dev/null
@@ -0,0 +1,51 @@
+# Copyright (c) 2012 Advanced Micro Devices, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Jason Power
+
+
+class BaseTopology(object):
+    description = "BaseTopology"
+
+    def __init__(self):
+        """ When overriding place any objects created in
+            configs/ruby/<protocol>.py that are needed in
+            makeTopology (below) here. The minimum is usually
+            all of the controllers created in the above file.
+        """
+
+    def makeTopology(self, options, IntLink, ExtLink, Router):
+        """ Called from src/mem/ruby/network/topologies/TopologyCreatory.py
+            The return value is ( list(Router), list(IntLink), list(ExtLink))
+            The API of this function cannot change when subclassing!!
+            Any additional information needed to create this topology should
+            be passed into the constructor when it's instantiated in
+            configs/ruby/<protocol>.py
+        """
+        print "BaseTopology should have been overridden in a sub class!!"
+        import sys
+        sys.exit(1)
+
diff --git a/configs/topologies/Cluster.py b/configs/topologies/Cluster.py
new file mode 100644 (file)
index 0000000..e5c6dac
--- /dev/null
@@ -0,0 +1,117 @@
+# Copyright (c) 2012 Advanced Micro Devices, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Jason Power
+
+
+from BaseTopology import BaseTopology
+
+class Cluster(BaseTopology):
+    """ A cluster is a group of nodes which are all one hop from eachother
+        Clusters can also contain other clusters
+        When creating this kind of topology, return a single cluster (usually
+        the root cluster) from create_system in configs/ruby/<protocol>.py
+    """
+
+    _num_int_links = 0
+    _num_ext_links = 0
+    _num_routers = 0
+
+    # Below methods for auto counting
+    @classmethod
+    def num_int_links(cls):
+        cls._num_int_links += 1
+        return cls._num_int_links - 1
+    @classmethod
+    def num_ext_links(cls):
+        cls._num_ext_links += 1
+        return cls._num_ext_links - 1
+    @classmethod
+    def num_routers(cls):
+        cls._num_routers += 1
+        return cls._num_routers - 1
+
+    def __init__(self, intBW=0, extBW=0, intLatency=0, extLatency=0):
+        """ internalBandwidth is bandwidth of all links within the cluster
+            externalBandwidth is bandwidth from this cluster to any cluster
+                connecting to it.
+            internal/externalLatency are similar
+            **** When creating a cluster with sub-clusters, the sub-cluster
+                 external bandwidth overrides the internal bandwidth of the
+                 super cluster
+        """
+        self.nodes = []
+        self.router = None # created in makeTopology
+        self.intBW = intBW
+        self.extBW = extBW
+        self.intLatency = intLatency
+        self.extLatency = extLatency
+
+    def add(self, node):
+        self.nodes.append(node)
+
+    def makeTopology(self, options, IntLink, ExtLink, Router):
+        """ Recursively make all of the links and routers
+        """
+        routers = []
+        int_links = []
+        ext_links = []
+
+        # make a router to connect all of the nodes
+        self.router = Router(router_id=self.num_routers())
+        routers.append(self.router)
+        for node in self.nodes:
+            if type(node) == Cluster:
+                subRouters, subIntLinks, subExtLinks = node.makeTopology(options, IntLink, ExtLink, Router)
+                routers += subRouters
+                int_links += subIntLinks
+                ext_links += subExtLinks
+
+                # connect this cluster to the router
+                link = IntLink(link_id=self.num_int_links(), node_a=self.router, node_b=node.router)
+                if node.extBW:
+                    link.bandwidth_factor = node.extBW
+                elif self.intBW: # if there is an interanl b/w for this node and no ext b/w to override
+                    link.bandwidth_factor = self.intBW
+
+                if node.extLatency:
+                    link.latency = node.extLatency
+                elif self.intLatency:
+                    link.latency = self.intLatency
+
+                int_links.append(link)
+            else:
+                # node is just a controller connect it to the router via a ext_link
+                link = ExtLink(link_id=self.num_ext_links(), ext_node=node, int_node=self.router)
+                if self.intBW:
+                    link.bandwidth_factor = self.intBW
+                if self.intLatency:
+                    link.latency = self.intLatency
+
+                ext_links.append(link)
+
+        return routers, int_links, ext_links
+
diff --git a/configs/topologies/Crossbar.py b/configs/topologies/Crossbar.py
new file mode 100644 (file)
index 0000000..e664929
--- /dev/null
@@ -0,0 +1,56 @@
+# Copyright (c) 2010 Advanced Micro Devices, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Steve Reinhardt
+
+from m5.params import *
+from m5.objects import *
+
+from BaseTopology import BaseTopology
+
+class Crossbar(BaseTopology):
+    description='Crossbar'
+
+    def __init__(self, controllers):
+        self.nodes = controllers
+
+    def makeTopology(self, options, IntLink, ExtLink, Router):
+        # Create an individual router for each controller plus one more for the
+        # centralized crossbar.  The large numbers of routers are needed because
+        # external links do not model outgoing bandwidth in the simple network, but
+        # internal links do.
+
+        routers = [Router(router_id=i) for i in range(len(self.nodes)+1)]
+        ext_links = [ExtLink(link_id=i, ext_node=n, int_node=routers[i])
+                        for (i, n) in enumerate(self.nodes)]
+        link_count = len(self.nodes)
+        xbar = routers[len(self.nodes)] # the crossbar router is the last router created
+        int_links = [IntLink(link_id=(link_count+i),
+                             node_a=routers[i], node_b=xbar)
+                        for i in range(len(self.nodes))]
+
+        return routers, int_links, ext_links
+
diff --git a/configs/topologies/Mesh.py b/configs/topologies/Mesh.py
new file mode 100644 (file)
index 0000000..b1f2e67
--- /dev/null
@@ -0,0 +1,114 @@
+# Copyright (c) 2010 Advanced Micro Devices, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Brad Beckmann
+
+from m5.params import *
+from m5.objects import *
+
+from BaseTopology import BaseTopology
+
+class Mesh(BaseTopology):
+    description='Mesh'
+
+    def __init__(self, controllers):
+        self.nodes = controllers
+
+    # Makes a generic mesh assuming an equal number of cache and directory cntrls
+
+    def makeTopology(self, options, IntLink, ExtLink, Router):
+        nodes = self.nodes
+
+        num_routers = options.num_cpus
+        num_rows = options.mesh_rows
+
+        # There must be an evenly divisible number of cntrls to routers
+        # Also, obviously the number or rows must be <= the number of routers
+        cntrls_per_router, remainder = divmod(len(nodes), num_routers)
+        assert(num_rows <= num_routers)
+        num_columns = int(num_routers / num_rows)
+        assert(num_columns * num_rows == num_routers)
+
+        # Create the routers in the mesh
+        routers = [Router(router_id=i) for i in range(num_routers)]
+
+        # link counter to set unique link ids
+        link_count = 0
+
+        # Add all but the remainder nodes to the list of nodes to be uniformly
+        # distributed across the network.
+        network_nodes = []
+        remainder_nodes = []
+        for node_index in xrange(len(nodes)):
+            if node_index < (len(nodes) - remainder):
+                network_nodes.append(nodes[node_index])
+            else:
+                remainder_nodes.append(nodes[node_index])
+
+        # Connect each node to the appropriate router
+        ext_links = []
+        for (i, n) in enumerate(network_nodes):
+            cntrl_level, router_id = divmod(i, num_routers)
+            assert(cntrl_level < cntrls_per_router)
+            ext_links.append(ExtLink(link_id=link_count, ext_node=n,
+                                    int_node=routers[router_id]))
+            link_count += 1
+
+        # Connect the remainding nodes to router 0.  These should only be
+        # DMA nodes.
+        for (i, node) in enumerate(remainder_nodes):
+            assert(node.type == 'DMA_Controller')
+            assert(i < remainder)
+            ext_links.append(ExtLink(link_id=link_count, ext_node=node,
+                                    int_node=routers[0]))
+            link_count += 1
+
+        # Create the mesh links.  First row (east-west) links then column
+        # (north-south) links
+        int_links = []
+        for row in xrange(num_rows):
+            for col in xrange(num_columns):
+                if (col + 1 < num_columns):
+                    east_id = col + (row * num_columns)
+                    west_id = (col + 1) + (row * num_columns)
+                    int_links.append(IntLink(link_id=link_count,
+                                            node_a=routers[east_id],
+                                            node_b=routers[west_id],
+                                            weight=1))
+                    link_count += 1
+
+        for col in xrange(num_columns):
+            for row in xrange(num_rows):
+                if (row + 1 < num_rows):
+                    north_id = col + (row * num_columns)
+                    south_id = col + ((row + 1) * num_columns)
+                    int_links.append(IntLink(link_id=link_count,
+                                            node_a=routers[north_id],
+                                            node_b=routers[south_id],
+                                            weight=2))
+                    link_count += 1
+
+        return routers, int_links, ext_links
diff --git a/configs/topologies/MeshDirCorners.py b/configs/topologies/MeshDirCorners.py
new file mode 100644 (file)
index 0000000..23bcde5
--- /dev/null
@@ -0,0 +1,134 @@
+# Copyright (c) 2010 Advanced Micro Devices, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Brad Beckmann
+
+from m5.params import *
+from m5.objects import *
+
+from BaseTopology import BaseTopology
+
+class MeshDirCorners(BaseTopology):
+    description='MeshDirCorners'
+
+    def __init__(self, controllers):
+        self.nodes = controllers
+
+    # This file contains a special network creation function.  This
+    # networks is not general and will only work with specific system
+    # configurations.  The network specified is similar to GEMS old file
+    # specified network.
+
+    def makeTopology(self, options, IntLink, ExtLink, Router):
+        nodes = self.nodes
+
+        num_routers = options.num_cpus
+        num_rows = options.mesh_rows
+
+        # First determine which nodes are cache cntrls vs. dirs vs. dma
+        cache_nodes = []
+        dir_nodes = []
+        dma_nodes = []
+        for node in nodes:
+            if node.type == 'L1Cache_Controller' or \
+            node.type == 'L2Cache_Controller':
+                cache_nodes.append(node)
+            elif node.type == 'Directory_Controller':
+                dir_nodes.append(node)
+            elif node.type == 'DMA_Controller':
+                dma_nodes.append(node)
+
+        # Obviously the number or rows must be <= the number of routers
+        # and evenly divisible.  Also the number of caches must be a
+        # multiple of the number of routers and the number of directories
+        # must be four.
+        assert(num_rows <= num_routers)
+        num_columns = int(num_routers / num_rows)
+        assert(num_columns * num_rows == num_routers)
+        caches_per_router, remainder = divmod(len(cache_nodes), num_routers)
+        assert(remainder == 0)
+        assert(len(dir_nodes) == 4)
+
+        # Create the routers in the mesh
+        routers = [Router(router_id=i) for i in range(num_routers)]
+
+        # link counter to set unique link ids
+        link_count = 0
+
+        # Connect each cache controller to the appropriate router
+        ext_links = []
+        for (i, n) in enumerate(cache_nodes):
+            cntrl_level, router_id = divmod(i, num_routers)
+            assert(cntrl_level < caches_per_router)
+            ext_links.append(ExtLink(link_id=link_count, ext_node=n,
+                                    int_node=routers[router_id]))
+            link_count += 1
+
+        # Connect the dir nodes to the corners.
+        ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[0],
+                                int_node=routers[0]))
+        link_count += 1
+        ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[1],
+                                int_node=routers[num_columns - 1]))
+        link_count += 1
+        ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[2],
+                                int_node=routers[num_routers - num_columns]))
+        link_count += 1
+        ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[3],
+                                int_node=routers[num_routers - 1]))
+        link_count += 1
+
+        # Connect the dma nodes to router 0.  These should only be DMA nodes.
+        for (i, node) in enumerate(dma_nodes):
+            assert(node.type == 'DMA_Controller')
+            ext_links.append(ExtLink(link_id=link_count, ext_node=node, int_node=routers[0]))
+
+        # Create the mesh links.  First row (east-west) links then column
+        # (north-south) links
+        int_links = []
+        for row in xrange(num_rows):
+            for col in xrange(num_columns):
+                if (col + 1 < num_columns):
+                    east_id = col + (row * num_columns)
+                    west_id = (col + 1) + (row * num_columns)
+                    int_links.append(IntLink(link_id=link_count,
+                                            node_a=routers[east_id],
+                                            node_b=routers[west_id],
+                                            weight=1))
+                    link_count += 1
+
+        for col in xrange(num_columns):
+            for row in xrange(num_rows):
+                if (row + 1 < num_rows):
+                    north_id = col + (row * num_columns)
+                    south_id = col + ((row + 1) * num_columns)
+                    int_links.append(IntLink(link_id=link_count,
+                                            node_a=routers[north_id],
+                                            node_b=routers[south_id],
+                                            weight=2))
+                    link_count += 1
+
+        return routers, int_links, ext_links
diff --git a/configs/topologies/Pt2Pt.py b/configs/topologies/Pt2Pt.py
new file mode 100644 (file)
index 0000000..3608112
--- /dev/null
@@ -0,0 +1,60 @@
+# Copyright (c) 2011 Advanced Micro Devices, Inc.
+#               2011 Massachusetts Institute of Technology
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Brad Beckmann
+#          Tushar Krishna
+
+from m5.params import *
+from m5.objects import *
+
+from BaseTopology import BaseTopology
+
+class Pt2Pt(BaseTopology):
+    description='Pt2Pt'
+
+    def __init__(self, controllers):
+        self.nodes = controllers
+
+    def makeTopology(self, options, IntLink, ExtLink, Router):
+        nodes = self.nodes
+        # Create an individual router for each controller, and connect all to all.
+
+        routers = [Router(router_id=i) for i in range(len(nodes))]
+        ext_links = [ExtLink(link_id=i, ext_node=n, int_node=routers[i])
+                    for (i, n) in enumerate(nodes)]
+        link_count = len(nodes)
+
+        int_links = []
+        for i in xrange(len(nodes)):
+            for j in xrange(len(nodes)):
+                if (i != j):
+                    link_count += 1
+                    int_links.append(IntLink(link_id=link_count,
+                                            node_a=routers[i],
+                                            node_b=routers[j]))
+
+        return routers, int_links, ext_links
diff --git a/configs/topologies/Torus.py b/configs/topologies/Torus.py
new file mode 100644 (file)
index 0000000..7fbcbf5
--- /dev/null
@@ -0,0 +1,126 @@
+# Copyright (c) 2011 Advanced Micro Devices, Inc.
+#               2011 Massachusetts Institute of Technology
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Brad Beckmann
+#          Tushar Krishna
+
+from m5.params import *
+from m5.objects import *
+
+from BaseTopology import BaseTopology
+
+class Torus(BaseTopology):
+    description='Torus'
+
+    def __init__(self, controllers):
+        self.nodes = controllers
+
+    # Makes a generic torus assuming an equal number of cache and directory cntrls
+    # Assuming a folded-torus on-chip layout (as shown on gem5 wiki).
+    # All links (including the wrap-around ones) are of equal length, double that
+    # of a mesh. Thus, each link is assigned a latency of 2 cycles.
+
+    def makeTopology(self, options, IntLink, ExtLink, Router):
+        nodes = self.nodes
+
+        num_routers = options.num_cpus
+        num_rows = options.mesh_rows
+
+        # There must be an evenly divisible number of cntrls to routers
+        # Also, obviously the number or rows must be <= the number of routers
+        cntrls_per_router, remainder = divmod(len(nodes), num_routers)
+        assert(num_rows <= num_routers)
+        num_columns = int(num_routers / num_rows)
+        assert(num_columns * num_rows == num_routers)
+
+        # Create the routers in the torus
+        routers = [Router(router_id=i) for i in range(num_routers)]
+
+        # link counter to set unique link ids
+        link_count = 0
+
+        # Add all but the remainder nodes to the list of nodes to be uniformly
+        # distributed across the network.
+        network_nodes = []
+        remainder_nodes = []
+        for node_index in xrange(len(nodes)):
+            if node_index < (len(nodes) - remainder):
+                network_nodes.append(nodes[node_index])
+            else:
+                remainder_nodes.append(nodes[node_index])
+
+        # Connect each node to the appropriate router
+        ext_links = []
+        for (i, n) in enumerate(network_nodes):
+            cntrl_level, router_id = divmod(i, num_routers)
+            assert(cntrl_level < cntrls_per_router)
+            ext_links.append(ExtLink(link_id=link_count, ext_node=n,
+                                    int_node=routers[router_id]))
+            link_count += 1
+
+        # Connect the remainding nodes to router 0.  These should only be
+        # DMA nodes.
+        for (i, node) in enumerate(remainder_nodes):
+            assert(node.type == 'DMA_Controller')
+            assert(i < remainder)
+            ext_links.append(ExtLink(link_id=link_count, ext_node=node,
+                                    int_node=routers[0]))
+            link_count += 1
+
+        # Create the torus links.  First row (east-west) links then column
+        # (north-south) links
+        # column links are given higher weights to implement XY routing
+        int_links = []
+        for row in xrange(num_rows):
+            for col in xrange(num_columns):
+                west_id = col + (row * num_columns)
+                if (col + 1 < num_columns):
+                    east_id = (col + 1) + (row * num_columns)
+                else:
+                    east_id = (row * num_columns)
+                int_links.append(IntLink(link_id=link_count,
+                                        node_a=routers[east_id],
+                                        node_b=routers[west_id],
+                                        latency=2,
+                                        weight=1))
+                link_count += 1
+
+        for col in xrange(num_columns):
+            for row in xrange(num_rows):
+                north_id = col + (row * num_columns)
+                if (row + 1 < num_rows):
+                    south_id = col + ((row + 1) * num_columns)
+                else:
+                    south_id = col
+                int_links.append(IntLink(link_id=link_count,
+                                        node_a=routers[north_id],
+                                        node_b=routers[south_id],
+                                        latency=2,
+                                        weight=2))
+                link_count += 1
+
+        return routers, int_links, ext_links
diff --git a/src/mem/ruby/network/topologies/Crossbar.py b/src/mem/ruby/network/topologies/Crossbar.py
deleted file mode 100644 (file)
index 04e01ee..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright (c) 2010 Advanced Micro Devices, Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met: redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer;
-# redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution;
-# neither the name of the copyright holders nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Authors: Steve Reinhardt
-
-from m5.params import *
-from m5.objects import *
-
-class Crossbar(Topology):
-    description='Crossbar'
-
-def makeTopology(nodes, options, IntLink, ExtLink, Router):
-    # Create an individual router for each controller plus one more for the
-    # centralized crossbar.  The large numbers of routers are needed because
-    # external links do not model outgoing bandwidth in the simple network, but
-    # internal links do.
-    cb = Crossbar()
-    cb.routers = [Router(router_id=i) for i in range(len(nodes)+1)]
-    cb.ext_links = [ExtLink(link_id=i, ext_node=n, int_node=cb.routers[i])
-                    for (i, n) in enumerate(nodes)]
-    link_count = len(nodes)
-    xbar = cb.routers[len(nodes)] # the crossbar router is the last router created
-    cb.int_links = [IntLink(link_id=(link_count+i),
-                            node_a=cb.routers[i], node_b=xbar)
-                    for i in range(len(nodes))]
-    return cb
-
-
diff --git a/src/mem/ruby/network/topologies/Mesh.py b/src/mem/ruby/network/topologies/Mesh.py
deleted file mode 100644 (file)
index fa6e633..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-# Copyright (c) 2010 Advanced Micro Devices, Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met: redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer;
-# redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution;
-# neither the name of the copyright holders nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Authors: Brad Beckmann
-
-from m5.params import *
-from m5.objects import *
-
-class Mesh(Topology):
-    description='Mesh'
-
-# Makes a generic mesh assuming an equal number of cache and directory cntrls
-
-def makeTopology(nodes, options, IntLink, ExtLink, Router):
-
-    num_routers = options.num_cpus
-    num_rows = options.mesh_rows
-
-    # There must be an evenly divisible number of cntrls to routers
-    # Also, obviously the number or rows must be <= the number of routers
-    cntrls_per_router, remainder = divmod(len(nodes), num_routers)
-    assert(num_rows <= num_routers)
-    num_columns = int(num_routers / num_rows)
-    assert(num_columns * num_rows == num_routers)
-
-    # Create the mesh object
-    mesh = Mesh()
-
-    # Create the routers in the mesh
-    mesh.routers = [Router(router_id=i) for i in range(num_routers)]
-
-    # link counter to set unique link ids
-    link_count = 0
-
-    # Add all but the remainder nodes to the list of nodes to be uniformly
-    # distributed across the network.
-    network_nodes = []
-    remainder_nodes = []
-    for node_index in xrange(len(nodes)):
-        if node_index < (len(nodes) - remainder):
-            network_nodes.append(nodes[node_index])
-        else:
-            remainder_nodes.append(nodes[node_index])
-
-    # Connect each node to the appropriate router
-    ext_links = []
-    for (i, n) in enumerate(network_nodes):
-        cntrl_level, router_id = divmod(i, num_routers)
-        assert(cntrl_level < cntrls_per_router)
-        ext_links.append(ExtLink(link_id=link_count, ext_node=n,
-                                 int_node=mesh.routers[router_id]))
-        link_count += 1
-
-    # Connect the remainding nodes to router 0.  These should only be
-    # DMA nodes.
-    for (i, node) in enumerate(remainder_nodes):
-        assert(node.type == 'DMA_Controller')
-        assert(i < remainder)
-        ext_links.append(ExtLink(link_id=link_count, ext_node=node,
-                                 int_node=mesh.routers[0]))
-        link_count += 1
-
-    # Create the mesh links.  First row (east-west) links then column
-    # (north-south) links
-    int_links = []
-    for row in xrange(num_rows):
-        for col in xrange(num_columns):
-            if (col + 1 < num_columns):
-                east_id = col + (row * num_columns)
-                west_id = (col + 1) + (row * num_columns)
-                int_links.append(IntLink(link_id=link_count,
-                                         node_a=mesh.routers[east_id],
-                                         node_b=mesh.routers[west_id],
-                                         weight=1))
-                link_count += 1
-                
-    for col in xrange(num_columns):
-        for row in xrange(num_rows):
-            if (row + 1 < num_rows):
-                north_id = col + (row * num_columns)
-                south_id = col + ((row + 1) * num_columns)
-                int_links.append(IntLink(link_id=link_count,
-                                         node_a=mesh.routers[north_id],
-                                         node_b=mesh.routers[south_id],
-                                         weight=2))
-                link_count += 1
-
-    mesh.int_links = int_links
-    mesh.ext_links = ext_links
-
-    return mesh
diff --git a/src/mem/ruby/network/topologies/MeshDirCorners.py b/src/mem/ruby/network/topologies/MeshDirCorners.py
deleted file mode 100644 (file)
index 7be8b91..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-# Copyright (c) 2010 Advanced Micro Devices, Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met: redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer;
-# redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution;
-# neither the name of the copyright holders nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Authors: Brad Beckmann
-
-from m5.params import *
-from m5.objects import *
-
-class MeshDirCorners(Topology):
-    description='MeshDirCorners'
-
-# This file contains a special network creation function.  This
-# networks is not general and will only work with specific system
-# configurations.  The network specified is similar to GEMS old file
-# specified network.
-
-def makeTopology(nodes, options, IntLink, ExtLink, Router):
-    num_routers = options.num_cpus
-    num_rows = options.mesh_rows
-
-    # First determine which nodes are cache cntrls vs. dirs vs. dma
-    cache_nodes = []
-    dir_nodes = []
-    dma_nodes = []
-    for node in nodes:
-        if node.type == 'L1Cache_Controller' or \
-           node.type == 'L2Cache_Controller':
-            cache_nodes.append(node)
-        elif node.type == 'Directory_Controller':
-            dir_nodes.append(node)
-        elif node.type == 'DMA_Controller':
-            dma_nodes.append(node)
-
-    # Obviously the number or rows must be <= the number of routers
-    # and evenly divisible.  Also the number of caches must be a
-    # multiple of the number of routers and the number of directories
-    # must be four.
-    assert(num_rows <= num_routers)
-    num_columns = int(num_routers / num_rows)
-    assert(num_columns * num_rows == num_routers)
-    caches_per_router, remainder = divmod(len(cache_nodes), num_routers)
-    assert(remainder == 0)
-    assert(len(dir_nodes) == 4)
-
-    mesh = MeshDirCorners()
-
-    # Create the routers in the mesh
-    mesh.routers = [Router(router_id=i) for i in range(num_routers)]
-
-    # link counter to set unique link ids
-    link_count = 0
-
-    # Connect each cache controller to the appropriate router
-    ext_links = []
-    for (i, n) in enumerate(cache_nodes):
-        cntrl_level, router_id = divmod(i, num_routers)
-        assert(cntrl_level < caches_per_router)
-        ext_links.append(ExtLink(link_id=link_count, ext_node=n,
-                                 int_node=mesh.routers[router_id]))
-        link_count += 1
-
-    # Connect the dir nodes to the corners.
-    ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[0],
-                             int_node=mesh.routers[0]))
-    link_count += 1
-    ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[1],
-                             int_node=mesh.routers[num_columns - 1]))
-    link_count += 1
-    ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[2],
-                             int_node=mesh.routers[num_routers - num_columns]))
-    link_count += 1
-    ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[3],
-                             int_node=mesh.routers[num_routers - 1]))
-    link_count += 1
-
-    # Connect the dma nodes to router 0.  These should only be DMA nodes.
-    for (i, node) in enumerate(dma_nodes):
-        assert(node.type == 'DMA_Controller')
-        ext_links.append(ExtLink(link_id=link_count, ext_node=node, int_node=mesh.routers[0]))
-
-    # Create the mesh links.  First row (east-west) links then column
-    # (north-south) links
-    int_links = []
-    for row in xrange(num_rows):
-        for col in xrange(num_columns):
-            if (col + 1 < num_columns):
-                east_id = col + (row * num_columns)
-                west_id = (col + 1) + (row * num_columns)
-                int_links.append(IntLink(link_id=link_count,
-                                         node_a=mesh.routers[east_id],
-                                         node_b=mesh.routers[west_id],
-                                         weight=1))
-                link_count += 1
-                
-    for col in xrange(num_columns):
-        for row in xrange(num_rows):
-            if (row + 1 < num_rows):
-                north_id = col + (row * num_columns)
-                south_id = col + ((row + 1) * num_columns)
-                int_links.append(IntLink(link_id=link_count,
-                                         node_a=mesh.routers[north_id],
-                                         node_b=mesh.routers[south_id],
-                                         weight=2))
-                link_count += 1
-
-    mesh.ext_links = ext_links
-    mesh.int_links = int_links
-
-    return mesh
diff --git a/src/mem/ruby/network/topologies/Pt2Pt.py b/src/mem/ruby/network/topologies/Pt2Pt.py
deleted file mode 100644 (file)
index f6ca136..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (c) 2011 Advanced Micro Devices, Inc.
-#               2011 Massachusetts Institute of Technology
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met: redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer;
-# redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution;
-# neither the name of the copyright holders nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Authors: Brad Beckmann
-#          Tushar Krishna
-
-from m5.params import *
-from m5.objects import *
-
-class Pt2Pt(Topology):
-    description='Pt2Pt'
-
-def makeTopology(nodes, options, IntLink, ExtLink, Router):
-    # Create an individual router for each controller, and connect all to all.
-    pt2pt = Pt2Pt()
-    pt2pt.routers = [Router(router_id=i) for i in range(len(nodes))]
-    ext_links = [ExtLink(link_id=i, ext_node=n, int_node=pt2pt.routers[i])
-                 for (i, n) in enumerate(nodes)]
-    link_count = len(nodes)
-
-    int_links = []
-    for i in xrange(len(nodes)):
-        for j in xrange(len(nodes)):
-            if (i != j):
-                link_count += 1
-                int_links.append(IntLink(link_id=link_count,
-                                         node_a=pt2pt.routers[i],
-                                         node_b=pt2pt.routers[j]))
-
-    pt2pt.ext_links = ext_links
-    pt2pt.int_links = int_links
-
-    return pt2pt
index a3c41a6d333fc6bab221b2cf273e7b6b1100b8fa..3d61f6dd1922cbcd5199e38356119435161a172e 100644 (file)
@@ -33,8 +33,4 @@ Import('*')
 if env['PROTOCOL'] == 'None':
     Return()
 
-PySource('', 'Crossbar.py')
-PySource('', 'Mesh.py')
-PySource('', 'MeshDirCorners.py')
-PySource('', 'Pt2Pt.py')
-PySource('', 'Torus.py')
+PySource('', 'TopologyCreator.py')
diff --git a/src/mem/ruby/network/topologies/TopologyCreator.py b/src/mem/ruby/network/topologies/TopologyCreator.py
new file mode 100644 (file)
index 0000000..d9b989e
--- /dev/null
@@ -0,0 +1,19 @@
+
+
+
+
+from m5.params import *
+from m5.objects import *
+
+def instantiateTopology(topology, options, IntLink, ExtLink, Router):
+
+    topo = Topology()
+    topo.description = topology.description
+
+    routers, int_links, ext_links = topology.makeTopology(options, IntLink, ExtLink, Router)
+
+    topo.routers = routers
+    topo.int_links = int_links
+    topo.ext_links = ext_links
+
+    return topo
diff --git a/src/mem/ruby/network/topologies/Torus.py b/src/mem/ruby/network/topologies/Torus.py
deleted file mode 100644 (file)
index f3583bf..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-# Copyright (c) 2011 Advanced Micro Devices, Inc.
-#               2011 Massachusetts Institute of Technology
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met: redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer;
-# redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution;
-# neither the name of the copyright holders nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Authors: Brad Beckmann
-#          Tushar Krishna
-
-from m5.params import *
-from m5.objects import *
-
-class Torus(Topology):
-    description='Torus'
-
-# Makes a generic torus assuming an equal number of cache and directory cntrls
-# Assuming a folded-torus on-chip layout (as shown on gem5 wiki).
-# All links (including the wrap-around ones) are of equal length, double that
-# of a mesh. Thus, each link is assigned a latency of 2 cycles.
-
-def makeTopology(nodes, options, IntLink, ExtLink, Router):
-
-    num_routers = options.num_cpus
-    num_rows = options.mesh_rows
-
-    # There must be an evenly divisible number of cntrls to routers
-    # Also, obviously the number or rows must be <= the number of routers
-    cntrls_per_router, remainder = divmod(len(nodes), num_routers)
-    assert(num_rows <= num_routers)
-    num_columns = int(num_routers / num_rows)
-    assert(num_columns * num_rows == num_routers)
-
-    # Create the torus object
-    torus = Torus()
-
-    # Create the routers in the torus
-    torus.routers = [Router(router_id=i) for i in range(num_routers)]
-
-    # link counter to set unique link ids
-    link_count = 0
-
-    # Add all but the remainder nodes to the list of nodes to be uniformly
-    # distributed across the network.
-    network_nodes = []
-    remainder_nodes = []
-    for node_index in xrange(len(nodes)):
-        if node_index < (len(nodes) - remainder):
-            network_nodes.append(nodes[node_index])
-        else:
-            remainder_nodes.append(nodes[node_index])
-
-    # Connect each node to the appropriate router
-    ext_links = []
-    for (i, n) in enumerate(network_nodes):
-        cntrl_level, router_id = divmod(i, num_routers)
-        assert(cntrl_level < cntrls_per_router)
-        ext_links.append(ExtLink(link_id=link_count, ext_node=n, 
-                                 int_node=torus.routers[router_id]))
-        link_count += 1
-
-    # Connect the remainding nodes to router 0.  These should only be
-    # DMA nodes.
-    for (i, node) in enumerate(remainder_nodes):
-        assert(node.type == 'DMA_Controller')
-        assert(i < remainder)
-        ext_links.append(ExtLink(link_id=link_count, ext_node=node,
-                                 int_node=torus.routers[0]))
-        link_count += 1
-
-    # Create the torus links.  First row (east-west) links then column
-    # (north-south) links
-    # column links are given higher weights to implement XY routing
-    int_links = []
-    for row in xrange(num_rows):
-        for col in xrange(num_columns):
-            west_id = col + (row * num_columns)
-            if (col + 1 < num_columns):
-                east_id = (col + 1) + (row * num_columns)
-            else:
-                east_id = (row * num_columns)
-            int_links.append(IntLink(link_id=link_count,
-                                     node_a=torus.routers[east_id],
-                                     node_b=torus.routers[west_id],
-                                     latency=2,
-                                     weight=1))
-            link_count += 1
-
-    for col in xrange(num_columns):
-        for row in xrange(num_rows):
-            north_id = col + (row * num_columns)
-            if (row + 1 < num_rows):
-                south_id = col + ((row + 1) * num_columns)
-            else:
-                south_id = col
-            int_links.append(IntLink(link_id=link_count,
-                                     node_a=torus.routers[north_id],
-                                     node_b=torus.routers[south_id],
-                                     latency=2,
-                                     weight=2))
-            link_count += 1
-
-    torus.ext_links = ext_links
-    torus.int_links = int_links
-
-    return torus
index fe0f1f606b0ce767291c7ecdc39dfdcdd5a2275a..0f742a3a210758aa7fe537ba83f07bc0d00244e4 100644 (file)
@@ -168,10 +168,15 @@ class MetaSimObject(type):
         cls._port_refs = multidict() # port ref objects
         cls._instantiated = False # really instantiated, cloned, or subclassed
 
-        # We don't support multiple inheritance.  If you want to, you
-        # must fix multidict to deal with it properly.
-        if len(bases) > 1:
-            raise TypeError, "SimObjects do not support multiple inheritance"
+        # We don't support multiple inheritance of sim objects.  If you want
+        # to, you must fix multidict to deal with it properly. Non sim-objects
+        # are ok, though
+        bTotal = 0
+        for c in bases:
+            if isinstance(c, MetaSimObject):
+                bTotal += 1
+            if bTotal > 1:
+                raise TypeError, "SimObjects do not support multiple inheritance"
 
         base = bases[0]