00001
00002
00003
00004
00012 #ifndef __DIST_LIST_TPP__
00013 #define __DIST_LIST_TPP__
00014 #ifdef __SKETO_DEBUG__
00015 #define debug(x) x
00016 #else // __SKETO_DEBUG__
00017 #define debug(x)
00018 #endif // __SKETO_DEBUG__
00019
00020
00021
00022
00023 template< typename A >
00024 inline int
00025 dist_list< A >::get_global_size( ) const
00026 {
00027 return global_size;
00028 }
00029
00030 template< typename A >
00031 inline A&
00032 dist_list< A >::at( int index )
00033 {
00034 return data[ index ];
00035 }
00036
00037 template< typename A >
00038 inline const A&
00039 dist_list< A >::at( int index ) const
00040 {
00041 return data[ index ];
00042 }
00043
00044 template< typename A >
00045 inline int
00046 dist_list< A >::get_begin_index( int rank ) const
00047 {
00048 const int div = global_size / skeleton::procs;
00049 const int mod = global_size % skeleton::procs;
00050 if( rank <= mod ) {
00051 return ( div + 1 ) * rank;
00052 }
00053 else {
00054 return ( div + 1 ) * mod + div * ( rank - mod );
00055 }
00056 }
00057
00058 template< typename A >
00059 inline int
00060 dist_list< A >::get_end_index( int rank ) const
00061 {
00062 const int div = global_size / skeleton::procs;
00063 const int mod = global_size % skeleton::procs;
00064 if( rank < mod ) {
00065 return ( div + 1 ) * ( rank + 1 );
00066 }
00067 else {
00068 return ( div + 1 ) * mod + div * ( rank - mod + 1 );
00069 }
00070 }
00071
00072 template< typename A >
00073 inline int
00074 dist_list< A >::get_local_size( int rank ) const
00075 {
00076 if( global_size % skeleton::procs > rank ) {
00077 return ( global_size / skeleton::procs ) + 1;
00078 }
00079 else {
00080 return global_size / skeleton::procs;
00081 }
00082 }
00083
00084
00085
00086
00087 template< typename A >
00088 inline
00089 dist_list<A>::dist_list( int list_size_ )
00090 : global_size( list_size_ )
00091 {
00092 this->init( );
00093 }
00094
00095 template< typename A >
00096 inline
00097 dist_list<A>::dist_list( int array_size_,
00098 const A *array_ )
00099 : global_size( array_size_ )
00100 {
00101 this->init( );
00102
00103 if ( skeleton::rank == 0 ) {
00104
00105 std::memcpy( data, array_, sizeof( A ) * local_size );
00106
00107
00108 for ( int dest = 1; dest < skeleton::procs; dest++ ) {
00109 MPI_Send( const_cast< A* >( &array_[ get_begin_index( dest ) ] ),
00110 get_local_size( dest ),
00111 mpitype, dest, TAG_DISTRIBUTE,
00112 MPI_COMM_WORLD );
00113 }
00114 }
00115 else {
00116 MPI_Status st;
00117 MPI_Recv( data, local_size, mpitype, 0, TAG_DISTRIBUTE, MPI_COMM_WORLD, &st );
00118 }
00119 }
00120
00121 template< typename A> template< typename F >
00122 inline
00123 dist_list< A >::dist_list( const F &f,
00124 int list_size_ )
00125 : global_size( list_size_ )
00126 {
00127 this->init( );
00128
00129 for( int i = 0, index = begin; i < local_size; i++, index++ ){
00130 this->at( i ) = f( index );
00131 }
00132 }
00133
00134 template< typename A >
00135 inline
00136 dist_list< A >::dist_list( const dist_list< A > &as )
00137 : global_size( as.global_size )
00138 {
00139 this->init( );
00140 for ( int i = 0; i < local_size; i++ ) {
00141 this->at( i ) = as.at( i );
00142 }
00143 }
00144
00145 template< typename A >
00146 inline dist_list< A > &
00147 dist_list< A >::operator=( const dist_list< A > &as )
00148 {
00149 if ( this == &as ) return *this;
00150
00151 if ( data ) delete[] data;
00152 this->global_size = as.global_size;
00153 this->init( );
00154
00155 for ( int i = 0; i < local_size; i++ ) {
00156 this->at( i ) = as.at( i );
00157 }
00158
00159 return *this;
00160 }
00161
00162 template< typename A >
00163 inline void
00164 dist_list< A >::init( )
00165 {
00166 MPI_Bcast( &global_size, 1, MPI_INT, 0, MPI_COMM_WORLD );
00167 begin = this->get_begin_index( skeleton::rank );
00168 end = this->get_end_index( skeleton::rank );
00169 local_size = this->get_local_size( skeleton::rank );
00170 mpitype = template_mpitype< A >::type( );
00171 data = new A[ local_size ];
00172 }
00173
00174
00175
00176
00177 template< typename A >
00178 inline dist_list< A >::~dist_list( )
00179 {
00180 delete[] data;
00181 }
00182
00183 #endif // __DIST_LIST_TPP__