Cluster.py revision 13885
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 2913774Sandreas.sandberg@arm.comfrom __future__ import print_function 3013774Sandreas.sandberg@arm.comfrom __future__ import absolute_import 319100SBrad.Beckmann@amd.com 3213774Sandreas.sandberg@arm.comfrom .BaseTopology import BaseTopology 339100SBrad.Beckmann@amd.com 349100SBrad.Beckmann@amd.comclass Cluster(BaseTopology): 359100SBrad.Beckmann@amd.com """ A cluster is a group of nodes which are all one hop from eachother 369100SBrad.Beckmann@amd.com Clusters can also contain other clusters 379100SBrad.Beckmann@amd.com When creating this kind of topology, return a single cluster (usually 389100SBrad.Beckmann@amd.com the root cluster) from create_system in configs/ruby/<protocol>.py 399100SBrad.Beckmann@amd.com """ 409100SBrad.Beckmann@amd.com 419100SBrad.Beckmann@amd.com _num_int_links = 0 429100SBrad.Beckmann@amd.com _num_ext_links = 0 439100SBrad.Beckmann@amd.com _num_routers = 0 449100SBrad.Beckmann@amd.com 459100SBrad.Beckmann@amd.com # Below methods for auto counting 469100SBrad.Beckmann@amd.com @classmethod 479100SBrad.Beckmann@amd.com def num_int_links(cls): 489100SBrad.Beckmann@amd.com cls._num_int_links += 1 499100SBrad.Beckmann@amd.com return cls._num_int_links - 1 509100SBrad.Beckmann@amd.com @classmethod 519100SBrad.Beckmann@amd.com def num_ext_links(cls): 529100SBrad.Beckmann@amd.com cls._num_ext_links += 1 539100SBrad.Beckmann@amd.com return cls._num_ext_links - 1 549100SBrad.Beckmann@amd.com @classmethod 559100SBrad.Beckmann@amd.com def num_routers(cls): 569100SBrad.Beckmann@amd.com cls._num_routers += 1 579100SBrad.Beckmann@amd.com return cls._num_routers - 1 589100SBrad.Beckmann@amd.com 599100SBrad.Beckmann@amd.com def __init__(self, intBW=0, extBW=0, intLatency=0, extLatency=0): 609100SBrad.Beckmann@amd.com """ internalBandwidth is bandwidth of all links within the cluster 619100SBrad.Beckmann@amd.com externalBandwidth is bandwidth from this cluster to any cluster 629100SBrad.Beckmann@amd.com connecting to it. 639100SBrad.Beckmann@amd.com internal/externalLatency are similar 649100SBrad.Beckmann@amd.com **** When creating a cluster with sub-clusters, the sub-cluster 659100SBrad.Beckmann@amd.com external bandwidth overrides the internal bandwidth of the 669100SBrad.Beckmann@amd.com super cluster 679100SBrad.Beckmann@amd.com """ 689100SBrad.Beckmann@amd.com self.nodes = [] 699100SBrad.Beckmann@amd.com self.router = None # created in makeTopology 709100SBrad.Beckmann@amd.com self.intBW = intBW 719100SBrad.Beckmann@amd.com self.extBW = extBW 729100SBrad.Beckmann@amd.com self.intLatency = intLatency 739100SBrad.Beckmann@amd.com self.extLatency = extLatency 749100SBrad.Beckmann@amd.com 759100SBrad.Beckmann@amd.com def add(self, node): 769100SBrad.Beckmann@amd.com self.nodes.append(node) 779100SBrad.Beckmann@amd.com 789862Snilay@cs.wisc.edu def makeTopology(self, options, network, IntLink, ExtLink, Router): 799100SBrad.Beckmann@amd.com """ Recursively make all of the links and routers 809100SBrad.Beckmann@amd.com """ 819100SBrad.Beckmann@amd.com 829100SBrad.Beckmann@amd.com # make a router to connect all of the nodes 839100SBrad.Beckmann@amd.com self.router = Router(router_id=self.num_routers()) 849862Snilay@cs.wisc.edu network.routers.append(self.router) 859862Snilay@cs.wisc.edu 869100SBrad.Beckmann@amd.com for node in self.nodes: 879100SBrad.Beckmann@amd.com if type(node) == Cluster: 8813885Sdavid.hashe@amd.com node.makeTopology(options, network, IntLink, 8913885Sdavid.hashe@amd.com ExtLink, Router) 909100SBrad.Beckmann@amd.com 919100SBrad.Beckmann@amd.com # connect this cluster to the router 9211663Stushar@ece.gatech.edu link_out = IntLink(link_id=self.num_int_links(), src_node=self.router, 9311669Stushar@ece.gatech.edu dst_node=node.router) 9411663Stushar@ece.gatech.edu link_in = IntLink(link_id=self.num_int_links(), src_node=node.router, 9511669Stushar@ece.gatech.edu dst_node=self.router) 9610088Snilay@cs.wisc.edu 979100SBrad.Beckmann@amd.com if node.extBW: 9811663Stushar@ece.gatech.edu link_out.bandwidth_factor = node.extBW 9911663Stushar@ece.gatech.edu link_in.bandwidth_factor = node.extBW 10010088Snilay@cs.wisc.edu 10111663Stushar@ece.gatech.edu # if there is an internal b/w for this node 10210088Snilay@cs.wisc.edu # and no ext b/w to override 10310088Snilay@cs.wisc.edu elif self.intBW: 10411663Stushar@ece.gatech.edu link_out.bandwidth_factor = self.intBW 10511663Stushar@ece.gatech.edu link_in.bandwidth_factor = self.intBW 1069100SBrad.Beckmann@amd.com 1079100SBrad.Beckmann@amd.com if node.extLatency: 10811663Stushar@ece.gatech.edu link_out.latency = node.extLatency 10911663Stushar@ece.gatech.edu link_in.latency = node.extLatency 1109100SBrad.Beckmann@amd.com elif self.intLatency: 11111663Stushar@ece.gatech.edu link_out.latency = self.intLatency 11211663Stushar@ece.gatech.edu link_in.latency = self.intLatency 1139100SBrad.Beckmann@amd.com 11411663Stushar@ece.gatech.edu network.int_links.append(link_out) 11511663Stushar@ece.gatech.edu network.int_links.append(link_in) 1169100SBrad.Beckmann@amd.com else: 11710088Snilay@cs.wisc.edu # node is just a controller, 11810088Snilay@cs.wisc.edu # connect it to the router via a ext_link 11910088Snilay@cs.wisc.edu link = ExtLink(link_id=self.num_ext_links(), ext_node=node, 12010088Snilay@cs.wisc.edu int_node=self.router) 12110088Snilay@cs.wisc.edu 1229100SBrad.Beckmann@amd.com if self.intBW: 1239100SBrad.Beckmann@amd.com link.bandwidth_factor = self.intBW 1249100SBrad.Beckmann@amd.com if self.intLatency: 1259100SBrad.Beckmann@amd.com link.latency = self.intLatency 1269100SBrad.Beckmann@amd.com 1279862Snilay@cs.wisc.edu network.ext_links.append(link) 1289100SBrad.Beckmann@amd.com 1299148Spowerjg@cs.wisc.edu def __len__(self): 1309148Spowerjg@cs.wisc.edu return len([i for i in self.nodes if type(i) != Cluster]) + \ 1319148Spowerjg@cs.wisc.edu sum([len(i) for i in self.nodes if type(i) == Cluster]) 132