EvolvingObjects
|
00001 00025 //----------------------------------------------------------------------------- 00026 00027 #ifndef eoPopEvalFunc_H 00028 #define eoPopEvalFunc_H 00029 00030 #include <eoEvalFunc.h> 00031 #include <apply.h> 00032 00033 # ifdef WITH_MPI 00034 #include <mpi/eoMpi.h> 00035 #include <mpi/eoTerminateJob.h> 00036 #include <mpi/eoMpiAssignmentAlgorithm.h> 00037 #include <mpi/eoParallelApply.h> 00038 #include <utils/eoParallel.h> 00039 00040 #include <cmath> // ceil 00041 # endif // WITH_MPI 00042 00060 template<class EOT> 00061 class eoPopEvalFunc : public eoBF<eoPop<EOT> & , eoPop<EOT> &, void> 00062 {}; 00063 00065 // eoPopLoopEval 00067 00073 template<class EOT> 00074 class eoPopLoopEval : public eoPopEvalFunc<EOT> { 00075 public: 00077 eoPopLoopEval(eoEvalFunc<EOT> & _eval) : eval(_eval) {} 00078 00080 void operator()(eoPop<EOT> & _parents, eoPop<EOT> & _offspring) 00081 { 00082 (void)_parents; 00083 apply<EOT>(eval, _offspring); 00084 } 00085 00086 private: 00087 eoEvalFunc<EOT> & eval; 00088 }; 00089 00090 #ifdef WITH_MPI 00091 00111 template<class EOT> 00112 class eoParallelPopLoopEval : public eoPopEvalFunc<EOT> 00113 { 00114 public: 00128 eoParallelPopLoopEval( 00129 // Job parameters 00130 eo::mpi::AssignmentAlgorithm& _assignAlgo, 00131 int _masterRank, 00132 // Default parameters for store 00133 eoEvalFunc<EOT> & _eval, 00134 int _packetSize = 1 00135 ) : 00136 assignAlgo( _assignAlgo ), 00137 masterRank( _masterRank ), 00138 needToDeleteStore( true ) // we used new, we'll have to use delete (RAII) 00139 { 00140 store = new eo::mpi::ParallelApplyStore<EOT>( _eval, _masterRank, _packetSize ); 00141 } 00142 00153 eoParallelPopLoopEval( 00154 // Job parameters 00155 eo::mpi::AssignmentAlgorithm& _assignAlgo, 00156 int _masterRank, 00157 eo::mpi::ParallelApplyStore<EOT>* _store 00158 ) : 00159 assignAlgo( _assignAlgo ), 00160 masterRank( _masterRank ), 00161 store( _store ), 00162 needToDeleteStore( false ) // we haven't used new for creating store, we don't care if we have to delete it (RAII). 00163 { 00164 // empty 00165 } 00166 00171 ~eoParallelPopLoopEval() 00172 { 00173 // Only the master has to send the termination message 00174 if( eo::mpi::Node::comm().rank() == masterRank ) 00175 { 00176 eo::mpi::EmptyJob job( assignAlgo, masterRank ); 00177 job.run(); 00178 } 00179 00180 // RAII 00181 if( needToDeleteStore ) 00182 { 00183 delete store; 00184 } 00185 } 00186 00193 void operator()( eoPop<EOT> & _parents, eoPop<EOT> & _offspring ) 00194 { 00195 (void)_parents; 00196 // Reinits the store and the scheduling algorithm 00197 store->data( _offspring ); 00198 // For static scheduling, it's mandatory to reinit attributions 00199 int nbWorkers = assignAlgo.availableWorkers(); 00200 assignAlgo.reinit( nbWorkers ); 00201 if( ! eo::parallel.isDynamic() ) { 00202 store->data()->packetSize = ceil( static_cast<double>( _offspring.size() ) / nbWorkers ); 00203 } 00204 // Effectively launches the job. 00205 eo::mpi::ParallelApply<EOT> job( assignAlgo, masterRank, *store ); 00206 job.run(); 00207 } 00208 00209 private: 00210 // Scheduling algorithm 00211 eo::mpi::AssignmentAlgorithm & assignAlgo; 00212 // Master MPI rank 00213 int masterRank; 00214 00215 // Store 00216 eo::mpi::ParallelApplyStore<EOT>* store; 00217 // Do we have to delete the store by ourselves ? 00218 bool needToDeleteStore; 00219 }; 00220 00224 #endif 00225 00227 // eoTimeVaryingLoopEval 00229 00236 template<class EOT> 00237 class eoTimeVaryingLoopEval : public eoPopEvalFunc<EOT> { 00238 public: 00240 eoTimeVaryingLoopEval(eoEvalFunc<EOT> & _eval) : eval(_eval) {} 00241 00243 void operator()(eoPop<EOT> & _parents, eoPop<EOT> & _offspring) 00244 { 00245 apply<EOT>(eval, _parents); 00246 apply<EOT>(eval, _offspring); 00247 } 00248 00249 private: 00250 eoEvalFunc<EOT> & eval; 00251 }; 00252 00253 #endif