Cluster.py revision 11669
19100SBrad.Beckmann@amd.com# Copyright (c) 2012 Advanced Micro Devices, Inc. 29100SBrad.Beckmann@amd.com# All rights reserved. 39100SBrad.Beckmann@amd.com# 49100SBrad.Beckmann@amd.com# Redistribution and use in source and binary forms, with or without 59100SBrad.Beckmann@amd.com# modification, are permitted provided that the following conditions are 69100SBrad.Beckmann@amd.com# met: redistributions of source code must retain the above copyright 79100SBrad.Beckmann@amd.com# notice, this list of conditions and the following disclaimer; 89100SBrad.Beckmann@amd.com# redistributions in binary form must reproduce the above copyright 99100SBrad.Beckmann@amd.com# notice, this list of conditions and the following disclaimer in the 109100SBrad.Beckmann@amd.com# documentation and/or other materials provided with the distribution; 119100SBrad.Beckmann@amd.com# neither the name of the copyright holders nor the names of its 129100SBrad.Beckmann@amd.com# contributors may be used to endorse or promote products derived from 139100SBrad.Beckmann@amd.com# this software without specific prior written permission. 149100SBrad.Beckmann@amd.com# 159100SBrad.Beckmann@amd.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 169100SBrad.Beckmann@amd.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 179100SBrad.Beckmann@amd.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 189100SBrad.Beckmann@amd.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 199100SBrad.Beckmann@amd.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 209100SBrad.Beckmann@amd.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 219100SBrad.Beckmann@amd.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 229100SBrad.Beckmann@amd.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 239100SBrad.Beckmann@amd.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 249100SBrad.Beckmann@amd.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 259100SBrad.Beckmann@amd.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 269100SBrad.Beckmann@amd.com# 279100SBrad.Beckmann@amd.com# Authors: Jason Power 289100SBrad.Beckmann@amd.com 299100SBrad.Beckmann@amd.com 309100SBrad.Beckmann@amd.comfrom BaseTopology import BaseTopology 319100SBrad.Beckmann@amd.com 329100SBrad.Beckmann@amd.comclass Cluster(BaseTopology): 339100SBrad.Beckmann@amd.com """ A cluster is a group of nodes which are all one hop from eachother 349100SBrad.Beckmann@amd.com Clusters can also contain other clusters 359100SBrad.Beckmann@amd.com When creating this kind of topology, return a single cluster (usually 369100SBrad.Beckmann@amd.com the root cluster) from create_system in configs/ruby/<protocol>.py 379100SBrad.Beckmann@amd.com """ 389100SBrad.Beckmann@amd.com 399100SBrad.Beckmann@amd.com _num_int_links = 0 409100SBrad.Beckmann@amd.com _num_ext_links = 0 419100SBrad.Beckmann@amd.com _num_routers = 0 429100SBrad.Beckmann@amd.com 439100SBrad.Beckmann@amd.com # Below methods for auto counting 449100SBrad.Beckmann@amd.com @classmethod 459100SBrad.Beckmann@amd.com def num_int_links(cls): 469100SBrad.Beckmann@amd.com cls._num_int_links += 1 479100SBrad.Beckmann@amd.com return cls._num_int_links - 1 489100SBrad.Beckmann@amd.com @classmethod 499100SBrad.Beckmann@amd.com def num_ext_links(cls): 509100SBrad.Beckmann@amd.com cls._num_ext_links += 1 519100SBrad.Beckmann@amd.com return cls._num_ext_links - 1 529100SBrad.Beckmann@amd.com @classmethod 539100SBrad.Beckmann@amd.com def num_routers(cls): 549100SBrad.Beckmann@amd.com cls._num_routers += 1 559100SBrad.Beckmann@amd.com return cls._num_routers - 1 569100SBrad.Beckmann@amd.com 579100SBrad.Beckmann@amd.com def __init__(self, intBW=0, extBW=0, intLatency=0, extLatency=0): 589100SBrad.Beckmann@amd.com """ internalBandwidth is bandwidth of all links within the cluster 599100SBrad.Beckmann@amd.com externalBandwidth is bandwidth from this cluster to any cluster 609100SBrad.Beckmann@amd.com connecting to it. 619100SBrad.Beckmann@amd.com internal/externalLatency are similar 629100SBrad.Beckmann@amd.com **** When creating a cluster with sub-clusters, the sub-cluster 639100SBrad.Beckmann@amd.com external bandwidth overrides the internal bandwidth of the 649100SBrad.Beckmann@amd.com super cluster 659100SBrad.Beckmann@amd.com """ 669100SBrad.Beckmann@amd.com self.nodes = [] 679100SBrad.Beckmann@amd.com self.router = None # created in makeTopology 689100SBrad.Beckmann@amd.com self.intBW = intBW 699100SBrad.Beckmann@amd.com self.extBW = extBW 709100SBrad.Beckmann@amd.com self.intLatency = intLatency 719100SBrad.Beckmann@amd.com self.extLatency = extLatency 729100SBrad.Beckmann@amd.com 739100SBrad.Beckmann@amd.com def add(self, node): 749100SBrad.Beckmann@amd.com self.nodes.append(node) 759100SBrad.Beckmann@amd.com 769862Snilay@cs.wisc.edu def makeTopology(self, options, network, IntLink, ExtLink, Router): 779100SBrad.Beckmann@amd.com """ Recursively make all of the links and routers 789100SBrad.Beckmann@amd.com """ 799100SBrad.Beckmann@amd.com 809100SBrad.Beckmann@amd.com # make a router to connect all of the nodes 819100SBrad.Beckmann@amd.com self.router = Router(router_id=self.num_routers()) 829862Snilay@cs.wisc.edu network.routers.append(self.router) 839862Snilay@cs.wisc.edu 849100SBrad.Beckmann@amd.com for node in self.nodes: 859100SBrad.Beckmann@amd.com if type(node) == Cluster: 869862Snilay@cs.wisc.edu node.makeTopology(options, network, IntLink, ExtLink, Router) 879100SBrad.Beckmann@amd.com 889100SBrad.Beckmann@amd.com # connect this cluster to the router 8911663Stushar@ece.gatech.edu link_out = IntLink(link_id=self.num_int_links(), src_node=self.router, 9011669Stushar@ece.gatech.edu dst_node=node.router) 9111663Stushar@ece.gatech.edu link_in = IntLink(link_id=self.num_int_links(), src_node=node.router, 9211669Stushar@ece.gatech.edu dst_node=self.router) 9310088Snilay@cs.wisc.edu 949100SBrad.Beckmann@amd.com if node.extBW: 9511663Stushar@ece.gatech.edu link_out.bandwidth_factor = node.extBW 9611663Stushar@ece.gatech.edu link_in.bandwidth_factor = node.extBW 9710088Snilay@cs.wisc.edu 9811663Stushar@ece.gatech.edu # if there is an internal b/w for this node 9910088Snilay@cs.wisc.edu # and no ext b/w to override 10010088Snilay@cs.wisc.edu elif self.intBW: 10111663Stushar@ece.gatech.edu link_out.bandwidth_factor = self.intBW 10211663Stushar@ece.gatech.edu link_in.bandwidth_factor = self.intBW 1039100SBrad.Beckmann@amd.com 1049100SBrad.Beckmann@amd.com if node.extLatency: 10511663Stushar@ece.gatech.edu link_out.latency = node.extLatency 10611663Stushar@ece.gatech.edu link_in.latency = node.extLatency 1079100SBrad.Beckmann@amd.com elif self.intLatency: 10811663Stushar@ece.gatech.edu link_out.latency = self.intLatency 10911663Stushar@ece.gatech.edu link_in.latency = self.intLatency 1109100SBrad.Beckmann@amd.com 11111663Stushar@ece.gatech.edu network.int_links.append(link_out) 11211663Stushar@ece.gatech.edu network.int_links.append(link_in) 1139100SBrad.Beckmann@amd.com else: 11410088Snilay@cs.wisc.edu # node is just a controller, 11510088Snilay@cs.wisc.edu # connect it to the router via a ext_link 11610088Snilay@cs.wisc.edu link = ExtLink(link_id=self.num_ext_links(), ext_node=node, 11710088Snilay@cs.wisc.edu int_node=self.router) 11810088Snilay@cs.wisc.edu 1199100SBrad.Beckmann@amd.com if self.intBW: 1209100SBrad.Beckmann@amd.com link.bandwidth_factor = self.intBW 1219100SBrad.Beckmann@amd.com if self.intLatency: 1229100SBrad.Beckmann@amd.com link.latency = self.intLatency 1239100SBrad.Beckmann@amd.com 1249862Snilay@cs.wisc.edu network.ext_links.append(link) 1259100SBrad.Beckmann@amd.com 1269148Spowerjg@cs.wisc.edu def __len__(self): 1279148Spowerjg@cs.wisc.edu return len([i for i in self.nodes if type(i) != Cluster]) + \ 1289148Spowerjg@cs.wisc.edu sum([len(i) for i in self.nodes if type(i) == Cluster]) 129