//----------------------------------------------------------------------------- // t-eoMpiParallel.cpp //----------------------------------------------------------------------------- #include #include #include // #include #include "../real_value.h" #include #include #include #include using namespace std; //----------------------------------------------------------------------------- class eoRealSerializable : public eoReal< eoMinimizingFitness >, public eoserial::Persistent { public: eoRealSerializable(unsigned size = 0, double value = 0.0): eoReal(size, value) {} eoserial::Object* pack() const { eoserial::Object* obj = new eoserial::Object; obj->add( "array", eoserial::makeArray< vector, eoserial::MakeAlgorithm > ( *this ) ); return obj; } void unpack( const eoserial::Object* obj ) { eoserial::unpackArray< vector, eoserial::Array::UnpackAlgorithm > ( *obj, "array", *this ); } // Gives access to boost serialization friend class boost::serialization::access; /** * Serializes the decomposition in a boost archive (useful for boost::mpi) */ template void save( Archive & ar, const unsigned int version ) const { std::stringstream ss; printOn( ss ); std::string asStr = ss.str(); ar & asStr; (void) version; // avoid compilation warning } /** * Deserializes the decomposition from a boost archive (useful for boost:mpi) */ template void load( Archive & ar, const unsigned int version ) { std::string asStr; ar & asStr; std::stringstream ss; ss << asStr; readFrom( ss ); (void) version; // avoid compilation warning } // Indicates that boost save and load operations are not the same. BOOST_SERIALIZATION_SPLIT_MEMBER() }; 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::quiet ); eoParser parser(ac, av); unsigned int popSize = parser.getORcreateParam((unsigned int)100, "popSize", "Population Size", 'P', "Evolution Engine").value(); unsigned int dimSize = parser.getORcreateParam((unsigned int)10, "dimSize", "Dimension Size", 'd', "Evolution Engine").value(); uint32_t seedParam = parser.getORcreateParam((uint32_t)0, "seed", "Random number seed", 0).value(); if (seedParam == 0) { seedParam = time(0); } make_parallel(parser); make_help(parser); rng.reseed( seedParam ); eoUniformGenerator< double > gen(-5, 5); eoInitFixedLength< EOT > init( dimSize, gen ); eoEvalFuncPtr< EOT, double, const std::vector< double >& > mainEval( real_value ); eoEvalFuncCounter< EOT > eval( mainEval ); int rank = eo::mpi::Node::comm().rank(); eo::mpi::DynamicAssignmentAlgorithm assign; if( rank == eo::mpi::DEFAULT_MASTER ) { eoPop< EOT > pop( popSize, init ); 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; } //-----------------------------------------------------------------------------