summaryrefslogtreecommitdiff
path: root/src/intersim2/networks/fattree.cpp
diff options
context:
space:
mode:
authorDongdong Li <[email protected]>2013-08-08 00:15:58 -0800
committerAndrew Boktor <[email protected]>2014-08-14 13:50:58 -0700
commit7f49fe9feb174d34efc2a011bad79b38522a360b (patch)
treeab5b7b66e40315a81871acbf386722981020f866 /src/intersim2/networks/fattree.cpp
parent5f91e7435742bab74dfbeca18afc63e466498f36 (diff)
Intesim2 Integration
Details: See Review 80001 https://gpgpu-sim-code-review.appspot.com/80001/ [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 16747]
Diffstat (limited to 'src/intersim2/networks/fattree.cpp')
-rw-r--r--src/intersim2/networks/fattree.cpp270
1 files changed, 270 insertions, 0 deletions
diff --git a/src/intersim2/networks/fattree.cpp b/src/intersim2/networks/fattree.cpp
new file mode 100644
index 0000000..81cd2b1
--- /dev/null
+++ b/src/intersim2/networks/fattree.cpp
@@ -0,0 +1,270 @@
+// $Id: fattree.cpp 5188 2012-08-30 00:31:31Z dub $
+
+/*
+ Copyright (c) 2007-2012, Trustees of The Leland Stanford Junior University
+ 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.
+
+ 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.
+*/
+
+////////////////////////////////////////////////////////////////////////
+//
+// FatTree
+//
+// Each level of the hierarchical indirect Network has
+// k^(n-1) Routers. The Routers are organized such that
+// each node has k descendents, and each parent is
+// replicated k times.
+// most routers has 2K ports, excep the top level has only K
+////////////////////////////////////////////////////////////////////////
+//
+// RCS Information:
+// $Author: jbalfour $
+// $Date: 2007/06/26 22:50:48 $
+// $Id: fattree.cpp 5188 2012-08-30 00:31:31Z dub $
+//
+////////////////////////////////////////////////////////////////////////
+
+
+#include "booksim.hpp"
+#include <vector>
+#include <sstream>
+#include <cmath>
+
+#include "fattree.hpp"
+#include "misc_utils.hpp"
+
+
+ //#define FATTREE_DEBUG
+
+FatTree::FatTree( const Configuration& config,const string & name )
+ : Network( config ,name)
+{
+
+
+ _ComputeSize( config );
+ _Alloc( );
+ _BuildNet( config );
+
+}
+
+void FatTree::_ComputeSize( const Configuration& config )
+{
+
+ _k = config.GetInt( "k" );
+ _n = config.GetInt( "n" );
+
+ gK = _k; gN = _n;
+
+ _nodes = powi( _k, _n );
+
+ //levels * routers_per_level
+ _size = _n * powi( _k , _n - 1 );
+
+ //(channels per level = k*routers_per_level* up/down) * (levels-1)
+ _channels = (2*_k * powi( _k , _n-1 ))*(_n-1);
+
+
+}
+
+
+void FatTree::RegisterRoutingFunctions() {
+
+}
+
+void FatTree::_BuildNet( const Configuration& config )
+{
+ cout << "Fat Tree" << endl;
+ cout << " k = " << _k << " levels = " << _n << endl;
+ cout << " each switch - total radix = "<< 2*_k << endl;
+ cout << " # of switches = "<< _size << endl;
+ cout << " # of channels = "<< _channels << endl;
+ cout << " # of nodes ( size of network ) = " << _nodes << endl;
+
+
+ // Number of router positions at each depth of the network
+ const int nPos = powi( _k, _n-1);
+
+ //
+ // Allocate Routers
+ //
+ ostringstream name;
+ int level, pos, id, degree, port;
+ for ( level = 0 ; level < _n ; ++level ) {
+ for ( pos = 0 ; pos < nPos ; ++pos ) {
+
+ if ( level == 0 ) //top routers is zero
+ degree = _k;
+ else
+ degree = 2 * _k;
+
+ id = level * nPos + pos;
+
+ name.str("");
+ name << "router_level" << level << "_" << pos;
+ Router * r = Router::NewRouter( config, this, name.str( ), id,
+ degree, degree );
+ _Router( level, pos ) = r;
+ _timed_modules.push_back(r);
+ }
+ }
+
+ //
+ // Connect Channels to Routers
+ //
+
+ //
+ // Router Connection Rule: Output Ports <gK Move DOWN Network
+ // Output Ports >=gK Move UP Network
+ // Input Ports <gK from DOWN Network
+ // Input Ports >=gK from up Network
+
+ // Connecting Injection & Ejection Channels
+ for ( pos = 0 ; pos < nPos ; ++pos ) {
+ for(int index = 0; index<_k; index++){
+ int link = pos*_k + index;
+ _Router( _n-1, pos)->AddInputChannel( _inject[link],
+ _inject_cred[link]);
+ _Router( _n-1, pos)->AddOutputChannel( _eject[link],
+ _eject_cred[link]);
+ _inject[link]->SetLatency( 1 );
+ _inject_cred[link]->SetLatency( 1 );
+ _eject[link]->SetLatency( 1 );
+ _eject_cred[link]->SetLatency( 1 );
+ }
+ }
+
+#ifdef FATTREE_DEBUG
+ cout<<"\nAssigning output\n";
+#endif
+
+ //channels are numbered sequentially from an output channel perspective
+ int chan_per_direction = (_k * powi( _k , _n-1 )); //up or down
+ int chan_per_level = 2*(_k * powi( _k , _n-1 )); //up+down
+
+ //connect all down output channels
+ //level n-1's down channel are injection channels
+ for (level = 0; level<_n-1; level++){
+ for ( pos = 0; pos < nPos; ++pos ) {
+ for ( port = 0; port < _k; ++port ) {
+ int link = (level*chan_per_level) + pos*_k + port;
+ _Router(level, pos)->AddOutputChannel( _chan[link],
+ _chan_cred[link] );
+ _chan[link]->SetLatency( 1 );
+ _chan_cred[link]->SetLatency( 1 );
+#ifdef FATTREE_DEBUG
+ cout<<_Router(level, pos)->Name()<<" "
+ <<"down output "<<port<<" "
+ <<"channel_id "<<link<<endl;
+#endif
+
+ }
+ }
+ }
+ //connect all up output channels
+ //level 0 has no up chnanels
+ for (level = 1; level<_n; level++){
+ for ( pos = 0; pos < nPos; ++pos ) {
+ for ( port = 0; port < _k; ++port ) {
+ int link = (level*chan_per_level - chan_per_direction) + pos*_k + port ;
+ _Router(level, pos)->AddOutputChannel( _chan[link],
+ _chan_cred[link] );
+ _chan[link]->SetLatency( 1 );
+ _chan_cred[link]->SetLatency( 1 );
+#ifdef FATTREE_DEBUG
+ cout<<_Router(level, pos)->Name()<<" "
+ <<"up output "<<port<<" "
+ <<"channel_id "<<link<<endl;
+#endif
+ }
+ }
+ }
+
+#ifdef FATTREE_DEBUG
+ cout<<"\nAssigning Input\n";
+#endif
+
+ //connect all down input channels
+ for (level = 0; level<_n-1; level++){
+ //input channel are numbered interleavely, the interleaev depends on level
+ int routers_per_neighborhood = powi(_k,_n-1-(level));
+ int routers_per_branch = powi(_k,_n-1-(level+1));
+ int level_offset = routers_per_neighborhood*_k;
+ for ( pos = 0; pos < nPos; ++pos ) {
+ int neighborhood = pos/routers_per_neighborhood;
+ int neighborhood_pos = pos%routers_per_neighborhood;
+ for ( port = 0; port < _k; ++port ) {
+ int link =
+ ((level+1)*chan_per_level - chan_per_direction) //which levellevel
+ +neighborhood*level_offset //region in level
+ +port*routers_per_branch*gK //sub region in region
+ +(neighborhood_pos)%routers_per_branch*gK //router in subregion
+ +(neighborhood_pos)/routers_per_branch; //port on router
+
+ _Router(level, pos)->AddInputChannel( _chan[link],
+ _chan_cred[link] );
+#ifdef FATTREE_DEBUG
+ cout<<_Router(level, pos)->Name()<<" "
+ <<"down input "<<port<<" "
+ <<"channel_id "<<link<<endl;
+#endif
+ }
+ }
+ }
+
+
+ //connect all up input channels
+ for (level = 1; level<_n; level++){
+ //input channel are numbered interleavely, the interleaev depends on level
+ int routers_per_neighborhood = powi(_k,_n-1-(level-1));
+ int routers_per_branch = powi(_k,_n-1-(level));
+ int level_offset = routers_per_neighborhood*_k;
+ for ( pos = 0; pos < nPos; ++pos ) {
+ int neighborhood = pos/routers_per_neighborhood;
+ int neighborhood_pos = pos%routers_per_neighborhood;
+ for ( port = 0; port < _k; ++port ) {
+ int link =
+ ((level-1)*chan_per_level) //which levellevel
+ +neighborhood*level_offset //region in level
+ +port*routers_per_branch*gK //sub region in region
+ +(neighborhood_pos)%routers_per_branch*gK //router in subregion
+ +(neighborhood_pos)/routers_per_branch; //port on router
+
+ _Router(level, pos)->AddInputChannel( _chan[link],
+ _chan_cred[link] );
+#ifdef FATTREE_DEBUG
+ cout<<_Router(level, pos)->Name()<<" "
+ <<"up input "<<port<<" "
+ <<"channel_id "<<link<<endl;
+#endif
+ }
+ }
+ }
+#ifdef FATTREE_DEBUG
+ cout<<"\nChannel assigned\n";
+#endif
+}
+
+Router*& FatTree::_Router( int depth, int pos )
+{
+ assert( depth < _n && pos < powi( _k, _n-1) );
+ return _routers[depth * powi( _k, _n-1) + pos];
+}