From 603268b053dafbe0c545486f2354b1970d683a79 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Wed, 4 Jul 2012 10:53:57 +0200 Subject: [PATCH] Added store management to eoPopEvalFunc. --- eo/src/apply.h | 8 +-- eo/src/eoPopEvalFunc.h | 100 ++++++++++++++++++------------ eo/src/mpi/eoMultiParallelApply.h | 14 ++++- eo/src/mpi/eoParallelApply.h | 12 +++- eo/test/mpi/eval.cpp | 66 +++++++++++++++++--- 5 files changed, 143 insertions(+), 57 deletions(-) diff --git a/eo/src/apply.h b/eo/src/apply.h index 86fc8927..df3c43e1 100644 --- a/eo/src/apply.h +++ b/eo/src/apply.h @@ -88,15 +88,13 @@ void apply(eoUF& _proc, std::vector& _pop) #ifdef WITH_MPI template void parallelApply( - eoUF& _proc, std::vector& _pop, eo::mpi::AssignmentAlgorithm& _algo, int _masterRank, - int _packetSize, - int _maxTime) + eo::mpi::ParallelEvalStore & _store ) { - eo::mpi::ParallelEvalStore store( _proc, _pop, _masterRank, _packetSize ); - eo::mpi::ParallelApply job( _algo, _masterRank, store ); + _store.data( _pop ); + eo::mpi::ParallelApply job( _algo, _masterRank, _store ); job.run(); } #endif diff --git a/eo/src/eoPopEvalFunc.h b/eo/src/eoPopEvalFunc.h index 1b7b447f..ce4dc5cf 100644 --- a/eo/src/eoPopEvalFunc.h +++ b/eo/src/eoPopEvalFunc.h @@ -80,48 +80,72 @@ private: #ifdef WITH_MPI // TODO TODOB commenter template -class eoParallelPopLoopEval : public eoPopEvalFunc { -public: - /** Ctor: set value of embedded eoEvalFunc */ - eoParallelPopLoopEval( - eoEvalFunc & _eval, - eo::mpi::AssignmentAlgorithm& _assignAlgo, - int _masterRank, - int _packetSize = 1, - int _maxTime = 0 - ) : - eval(_eval), - assignAlgo( _assignAlgo ), - masterRank( _masterRank ), - packetSize( _packetSize ), - maxTime( _maxTime ) - { - // empty - } +class eoParallelPopLoopEval : public eoPopEvalFunc +{ + public: + /** Ctor: set value of embedded eoEvalFunc */ + eoParallelPopLoopEval( + eoEvalFunc & _eval, + eo::mpi::AssignmentAlgorithm& _assignAlgo, + int _masterRank, + int _packetSize = 1 + ) : + eval(_eval), + assignAlgo( _assignAlgo ), + masterRank( _masterRank ), + packetSize( _packetSize ), + needToDeleteStore( true ) + { + store = new eo::mpi::ParallelEvalStore( _eval, _masterRank, _packetSize ); + } - ~eoParallelPopLoopEval() - { - if( eo::mpi::Node::comm().rank() == masterRank ) - { - eo::mpi::EmptyJob job( assignAlgo, masterRank ); - job.run(); - } - } + eoParallelPopLoopEval( + eoEvalFunc & _eval, + eo::mpi::AssignmentAlgorithm& _assignAlgo, + eo::mpi::ParallelEvalStore* _store, + int _masterRank, + int _packetSize = 1 + ) : + eval(_eval), + assignAlgo( _assignAlgo ), + masterRank( _masterRank ), + packetSize( _packetSize ), + needToDeleteStore( false ), + store( _store ) + { + // empty + } - /** Do the job: simple loop over the offspring */ - void operator()(eoPop & _parents, eoPop & _offspring) - { - (void)_parents; - parallelApply(eval, _offspring, assignAlgo, masterRank, packetSize, maxTime); - } + ~eoParallelPopLoopEval() + { + if( eo::mpi::Node::comm().rank() == masterRank ) + { + eo::mpi::EmptyJob job( assignAlgo, masterRank ); + job.run(); + } -private: - eoEvalFunc & eval; + if( needToDeleteStore ) + { + delete store; + } + } - eo::mpi::AssignmentAlgorithm & assignAlgo; - int masterRank; - int packetSize; - int maxTime; + /** Do the job: simple loop over the offspring */ + void operator()(eoPop & _parents, eoPop & _offspring) + { + (void)_parents; + parallelApply(_offspring, assignAlgo, masterRank, *store); + } + + private: + eoEvalFunc & eval; + + eo::mpi::AssignmentAlgorithm & assignAlgo; + eo::mpi::ParallelEvalStore* store; + int masterRank; + int packetSize; + + bool needToDeleteStore; }; #endif diff --git a/eo/src/mpi/eoMultiParallelApply.h b/eo/src/mpi/eoMultiParallelApply.h index 121e0b74..85b1689e 100644 --- a/eo/src/mpi/eoMultiParallelApply.h +++ b/eo/src/mpi/eoMultiParallelApply.h @@ -24,6 +24,11 @@ namespace eo d->comm.recv( d->masterRank, Channel::Commands, order ); } } + + ~ProcessTaskParallelEval() + { + delete _wrapped; + } }; template< class EOT > @@ -33,15 +38,20 @@ namespace eo ParallelEvalStore( eoUF & _proc, - std::vector& _pop, int _masterRank, // long _maxTime = 0, int _packetSize = 1 ) : - ParallelApplyStore< EOT >( _proc, _pop, _masterRank, _packetSize ) + ParallelApplyStore< EOT >( _proc, *( new std::vector ), _masterRank, _packetSize ) + // FIXME memory leak because of vector ==> use const correctness { wrapProcessTask( new ProcessTaskParallelEval ); } + + void data( std::vector& _pop ) + { + ParallelApplyStore::_data.init( _pop ); + } }; } } diff --git a/eo/src/mpi/eoParallelApply.h b/eo/src/mpi/eoParallelApply.h index f195965a..faedc7b3 100644 --- a/eo/src/mpi/eoParallelApply.h +++ b/eo/src/mpi/eoParallelApply.h @@ -21,7 +21,7 @@ namespace eo { ParallelApplyData( eoUF & _proc, - std::vector& _pop, + std::vector & _pop, int _masterRank, // long _maxTime = 0, int _packetSize @@ -35,6 +35,14 @@ namespace eo tempArray = new EOT[ _packetSize ]; } + void init( std::vector& _pop ) + { + index = 0; + size = _pop.size(); + data = _pop; + assignedTasks.clear(); + } + ~ParallelApplyData() { delete [] tempArray; @@ -180,7 +188,7 @@ namespace eo ParallelApplyData* data() { return &_data; } - ~ParallelApplyStore() + virtual ~ParallelApplyStore() { delete _stf; delete _hrf; diff --git a/eo/test/mpi/eval.cpp b/eo/test/mpi/eval.cpp index 7d8666cb..06fa8ad3 100644 --- a/eo/test/mpi/eval.cpp +++ b/eo/test/mpi/eval.cpp @@ -82,10 +82,40 @@ class eoRealSerializable : public eoReal< eoMinimizingFitness >, public eoserial typedef eoRealSerializable EOT; +struct CatBestAnswers : public eo::mpi::HandleResponseParallelApply +{ + CatBestAnswers() + { + best.fitness( 1000000000. ); + } + + using eo::mpi::HandleResponseParallelApply::_wrapped; + using eo::mpi::HandleResponseParallelApply::d; + + void operator()(int wrkRank) + { + int index = d->assignedTasks[wrkRank].index; + int size = d->assignedTasks[wrkRank].size; + (*_wrapped)( wrkRank ); + for(int i = index; i < index+size; ++i) + { + if( best.fitness() < d->data[ i ].fitness() ) + { + eo::log << eo::quiet << "Better solution found:" << d->data[i].fitness() << std::endl; + best = d->data[ i ]; + } + } + } + + protected: + + EOT best; +}; + int main(int ac, char** av) { eo::mpi::Node::init( ac, av ); - eo::log << eo::setlevel( eo::debug ); + eo::log << eo::setlevel( eo::quiet ); eoParser parser(ac, av); @@ -106,17 +136,33 @@ int main(int ac, char** av) eoEvalFuncPtr< EOT, double, const std::vector< double >& > mainEval( real_value ); eoEvalFuncCounter< EOT > eval( mainEval ); - eoPop< EOT > pop( popSize, init ); - - eo::log << "Size of population : " << popSize << std::endl; - - eo::log << eo::setlevel( eo::debug ); - + int rank = eo::mpi::Node::comm().rank(); eo::mpi::DynamicAssignmentAlgorithm assign; - eoParallelPopLoopEval< EOT > popEval( eval, assign, eo::mpi::DEFAULT_MASTER, 3 ); - popEval( pop, pop ); + if( rank == eo::mpi::DEFAULT_MASTER ) + { + eoPop< EOT > pop( popSize, init ); - eo::log << eo::quiet << "DONE!" << std::endl; + eo::log << "Size of population : " << popSize << std::endl; + + eo::mpi::ParallelEvalStore< EOT > store( eval, eo::mpi::DEFAULT_MASTER ); + store.wrapHandleResponse( new CatBestAnswers ); + + eoParallelPopLoopEval< EOT > popEval( eval, assign, &store, eo::mpi::DEFAULT_MASTER, 3 ); + eo::log << eo::quiet << "Before first evaluation." << std::endl; + popEval( pop, pop ); + eo::log << eo::quiet << "After first evaluation." << std::endl; + + pop = eoPop< EOT >( popSize, init ); + popEval( pop, pop ); + eo::log << eo::quiet << "After second evaluation." << std::endl; + + eo::log << eo::quiet << "DONE!" << std::endl; + } else + { + eoPop< EOT > pop( popSize, init ); + eoParallelPopLoopEval< EOT > popEval( eval, assign, eo::mpi::DEFAULT_MASTER, 3 ); + popEval( pop, pop ); + } return 0; }