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 }
void Tree4::_BuildNet( const Configuration& config ) { // // Allocate Routers // ostringstream name; int h, pos, nPos, degree, id; for ( h = 0; h < _n; h++ ) { nPos = _speedup[h] * powi( _k, h ); for ( pos = 0; pos < nPos; ++pos) { if ( h < _n-1 ) degree = 8; else degree = 6; name.str(""); name << "router_" << h << "_" << pos; id = h * powi( _k, _n-1 ) + pos; _Router( h, pos ) = Router::NewRouter( config, this, name.str( ), id, degree, degree ); } } // // Connect Channels to Routers // int pp, pc; // // Connection Rule: Output Ports 0:3 Move DOWN Network // Output Ports 4:7 Move UP Network // // Injection & Ejection Channels nPos = powi( _k, _n - 1 ); for ( pos = 0 ; pos < nPos ; ++pos ) { for ( int port = 0 ; port < _k ; ++port ) { _Router( _n-1, pos)->AddInputChannel( _inject[_k*pos+port], _inject_cred[_k*pos+port]); _inject[_k*pos+port]->SetLatency( 0 ); _inject_cred[_k*pos+port]->SetLatency( 0 ); _Router( _n-1, pos)->AddOutputChannel( _eject[_k*pos+port], _eject_cred[_k*pos+port]); _eject[_k*pos+port]->SetLatency( 0 ); _eject_cred[_k*pos+port]->SetLatency( 0 ); } } // Connections between h = 1 and h = 2 Levels int c = 0; nPos = _speedup[1] * powi( _k, 1 ); for ( pos = 0; pos < nPos; ++pos ) { for ( int port = 0; port < _k; ++port ) { pp = pos; pc = _k * ( pos / 2 ) + port; // cout << "connecting (1,"<<pp<<") <-> (2,"<<pc<<")"<<endl; _Router( 1, pp)->AddOutputChannel( _chan[c], _chan_cred[c] ); _Router( 2, pc)->AddInputChannel( _chan[c], _chan_cred[c] ); //_chan[c]->SetLatency( L ); //_chan_cred[c]->SetLatency( L ); _chan[c]->SetLatency( 0 ); _chan_cred[c]->SetLatency( 0 ); c++; _Router(1, pp)->AddInputChannel( _chan[c], _chan_cred[c] ); _Router(2, pc)->AddOutputChannel( _chan[c], _chan_cred[c] ); //_chan[c]->SetLatency( L ); //_chan_cred[c]->SetLatency( L ); _chan[c]->SetLatency( 0 ); _chan_cred[c]->SetLatency( 0 ); c++; } } // Connections between h = 0 and h = 1 Levels nPos = _speedup[0] * powi( _k, 0 ); for ( pos = 0; pos < nPos; ++pos ) { for ( int port = 0; port < 2 * _k; ++port ) { pp = pos; pc = port; // cout << "connecting (0,"<<pp<<") <-> (1,"<<pc<<")"<<endl; _Router(0, pp)->AddOutputChannel( _chan[c], _chan_cred[c] ); _Router(1, pc)->AddInputChannel( _chan[c], _chan_cred[c] ); // _chan[c]->SetLatency( L ); //_chan_cred[c]->SetLatency( L ); _chan[c]->SetLatency( 0 ); _chan_cred[c]->SetLatency( 0 ); c++; _Router(0, pp)->AddInputChannel( _chan[c], _chan_cred[c] ); _Router(1, pc)->AddOutputChannel( _chan[c], _chan_cred[c] ); // _chan[c]->SetLatency( L ); // _chan_cred[c]->SetLatency( L ); _chan[c]->SetLatency( 0 ); _chan_cred[c]->SetLatency( 0 ); c++; } } // cout << "Used " << c << " of " << _channels << " channels" << endl; }