Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

dist_list.tpp

Go to the documentation of this file.
00001 /***
00002  * Copyright (c) 2005, SkeTo Project
00003  * All rights reserved.
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 // Access methods
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 // Constructors
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     // for master process: local copy
00105     std::memcpy( data, array_, sizeof( A ) * local_size );
00106     
00107     // for the other processes
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 // Destructor
00176 
00177 template< typename A >
00178 inline dist_list< A >::~dist_list( )
00179 {
00180   delete[] data;
00181 }
00182 
00183 #endif // __DIST_LIST_TPP__

Generated on Wed Jan 18 22:19:27 2006 for SkeTo -- Skeleton Library in Tokyo by  doxygen 1.4.4