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
}
Exemple #2
0
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;

}