From 69f2911e04ffb1b19eef1fafb8c040af271f656e Mon Sep 17 00:00:00 2001 From: Tor Aamodt Date: Thu, 15 Jul 2010 18:09:46 -0800 Subject: creating branch for adding support for CUDA 3.x and Fermi [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 6829] --- src/intersim/kncube.cpp | 253 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 src/intersim/kncube.cpp (limited to 'src/intersim/kncube.cpp') diff --git a/src/intersim/kncube.cpp b/src/intersim/kncube.cpp new file mode 100644 index 0000000..f4e1c71 --- /dev/null +++ b/src/intersim/kncube.cpp @@ -0,0 +1,253 @@ +#include "booksim.hpp" +#include +#include + +#include "kncube.hpp" +#include "random_utils.hpp" +#include "misc_utils.hpp" + +KNCube::KNCube( const Configuration &config, bool mesh ) : +Network( config ) +{ + _mesh = mesh; + + _ComputeSize( config ); + _Alloc( ); + _BuildNet( config ); +} + +void KNCube::_ComputeSize( const Configuration &config ) +{ + _k = config.GetInt( "k" ); + _n = config.GetInt( "n" ); + + gK = _k; gN = _n; + + _size = powi( _k, _n ); + _channels = 2*_n*_size; + + _sources = _size; + _dests = _size; +} + +void KNCube::_BuildNet( const Configuration &config ) +{ + int left_node; + int right_node; + + int right_input; + int left_input; + + int right_output; + int left_output; + + ostringstream router_name; + + for ( int node = 0; node < _size; ++node ) { + + router_name << "router"; + + for ( int dim_offset = _size / _k; dim_offset >= 1; dim_offset /= _k ) { + router_name << "_" << ( node / dim_offset ) % _k; + } + + _routers[node] = Router::NewRouter( config, this, router_name.str( ), + node, 2*_n + 1, 2*_n + 1 ); + + router_name.seekp( 0, ios::beg ); + + for ( int dim = 0; dim < _n; ++dim ) { + + left_node = _LeftNode( node, dim ); + right_node = _RightNode( node, dim ); + + // + // Current (N)ode + // (L)eft node + // (R)ight node + // + // L--->N<---R + // L<---N--->R + // + + right_input = _LeftChannel( right_node, dim ); + left_input = _RightChannel( left_node, dim ); + + _routers[node]->AddInputChannel( &_chan[right_input], &_chan_cred[right_input] ); + _routers[node]->AddInputChannel( &_chan[left_input], &_chan_cred[left_input] ); + + right_output = _RightChannel( node, dim ); + left_output = _LeftChannel( node, dim ); + + _routers[node]->AddOutputChannel( &_chan[right_output], &_chan_cred[right_output] ); + _routers[node]->AddOutputChannel( &_chan[left_output], &_chan_cred[left_output] ); + } + + _routers[node]->AddInputChannel( &_inject[node], &_inject_cred[node] ); + _routers[node]->AddOutputChannel( &_eject[node], &_eject_cred[node] ); + } +} + +int KNCube::_LeftChannel( int node, int dim ) +{ + // The base channel for a node is 2*_n*node + int base = 2*_n*node; + + // The offset for a left channel is 2*dim + 1 + int off = 2*dim + 1; + + return( base + off ); +} + +int KNCube::_RightChannel( int node, int dim ) +{ + // The base channel for a node is 2*_n*node + int base = 2*_n*node; + + // The offset for a right channel is 2*dim + int off = 2*dim; + + return( base + off ); +} + +int KNCube::_LeftNode( int node, int dim ) +{ + int k_to_dim = powi( _k, dim ); + int loc_in_dim = ( node / k_to_dim ) % _k; + int left_node; + + // if at the left edge of the dimension, wraparound + if ( loc_in_dim == 0 ) { + left_node = node + (_k-1)*k_to_dim; + } else { + left_node = node - k_to_dim; + } + + return left_node; +} + +int KNCube::_RightNode( int node, int dim ) +{ + int k_to_dim = powi( _k, dim ); + int loc_in_dim = ( node / k_to_dim ) % _k; + int right_node; + + // if at the right edge of the dimension, wraparound + if ( loc_in_dim == ( _k-1 ) ) { + right_node = node - (_k-1)*k_to_dim; + } else { + right_node = node + k_to_dim; + } + + return right_node; +} + +int KNCube::GetN( ) const +{ + return _n; +} + +int KNCube::GetK( ) const +{ + return _k; +} + +void KNCube::InsertRandomFaults( const Configuration &config ) +{ + int num_fails; + unsigned long prev_seed; + + int node, chan; + int i, j, t, n, c; + bool *fail_nodes; + bool available; + + bool edge; + + num_fails = config.GetInt( "link_failures" ); + + if ( num_fails ) { + prev_seed = RandomIntLong( ); + RandomSeed( config.GetInt( "fail_seed" ) ); + + fail_nodes = new bool [_size]; + + for ( i = 0; i < _size; ++i ) { + node = i; + + // edge test + edge = false; + for ( n = 0; n < _n; ++n ) { + if ( ( ( node % _k ) == 0 ) || + ( ( node % _k ) == _k - 1 ) ) { + edge = true; + } + node /= _k; + } + + if ( edge ) { + fail_nodes[i] = true; + } else { + fail_nodes[i] = false; + } + } + + for ( i = 0; i < num_fails; ++i ) { + j = RandomInt( _size - 1 ); + available = false; + + for ( t = 0; ( t < _size ) && (!available); ++t ) { + node = ( j + t ) % _size; + + if ( !fail_nodes[node] ) { + // check neighbors + c = RandomInt( 2*_n - 1 ); + + for ( n = 0; ( n < 2*_n ) && (!available); ++n ) { + chan = ( n + c ) % 2*_n; + + if ( chan % 1 ) { + available = fail_nodes[_LeftNode( node, chan/2 )]; + } else { + available = fail_nodes[_RightNode( node, chan/2 )]; + } + } + } + + if ( !available ) { + cout << "skipping " << node << endl; + } + } + + if ( t == _size ) { + Error( "Could not find another possible fault channel" ); + } + + + OutChannelFault( node, chan ); + fail_nodes[node] = true; + + for ( n = 0; ( n < _n ) && available ; ++n ) { + fail_nodes[_LeftNode( node, n )] = true; + fail_nodes[_RightNode( node, n )] = true; + } + + cout << "failure at node " << node << ", channel " + << chan << endl; + } + + delete [] fail_nodes; + + RandomSeed( prev_seed ); + } +} + +double KNCube::Capacity( ) const +{ + if ( _mesh ) { + return(double)_k / 4.0; + } else { + return(double)_k / 8.0; + } +} + -- cgit v1.3