| # 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. |
| |
| from topologies.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, 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]) |