# 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/.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, network, IntLink, ExtLink, Router): """ Recursively make all of the links and routers """ # make a router to connect all of the nodes self.router = Router(router_id=self.num_routers()) network.routers.append(self.router) for node in self.nodes: if type(node) == Cluster: node.makeTopology(options, network, IntLink, ExtLink, Router) # connect this cluster to the router link_out = IntLink(link_id=self.num_int_links(), src_node=self.router, dst_node=node.router) link_in = IntLink(link_id=self.num_int_links(), src_node=node.router, dst_node=self.router) if node.extBW: link_out.bandwidth_factor = node.extBW link_in.bandwidth_factor = node.extBW # if there is an internal b/w for this node # and no ext b/w to override elif self.intBW: link_out.bandwidth_factor = self.intBW link_in.bandwidth_factor = self.intBW if node.extLatency: link_out.latency = node.extLatency link_in.latency = node.extLatency elif self.intLatency: link_out.latency = self.intLatency link_in.latency = self.intLatency network.int_links.append(link_out) network.int_links.append(link_in) 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 network.ext_links.append(link) def __len__(self): return len([i for i in self.nodes if type(i) != Cluster]) + \ sum([len(i) for i in self.nodes if type(i) == Cluster])