diff --git a/eo/src/apply.h b/eo/src/apply.h index f685f8d3..39a36505 100644 --- a/eo/src/apply.h +++ b/eo/src/apply.h @@ -33,6 +33,11 @@ #include #include +# ifdef WITH_MPI +# include +# include +# endif // WITH_MPI + /** Applies a unary function to a std::vector of things. @@ -48,33 +53,48 @@ void apply(eoUF& _proc, std::vector& _pop) double t1 = 0; if ( eo::parallel.enableResults() ) - { - t1 = omp_get_wtime(); - } + { + t1 = omp_get_wtime(); + } if (!eo::parallel.isDynamic()) - { + { #pragma omp parallel for if(eo::parallel.isEnabled()) //default(none) shared(_proc, _pop, size) - for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } - } + for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } + } else - { + { #pragma omp parallel for schedule(dynamic) if(eo::parallel.isEnabled()) - //doesnot work with gcc 4.1.2 - //default(none) shared(_proc, _pop, size) - for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } - } + //doesnot work with gcc 4.1.2 + //default(none) shared(_proc, _pop, size) + for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } + } if ( eo::parallel.enableResults() ) - { - double t2 = omp_get_wtime(); - eoLogger log; - log << eo::file(eo::parallel.prefix()) << t2 - t1 << ' '; - } + { + double t2 = omp_get_wtime(); + eoLogger log; + log << eo::file(eo::parallel.prefix()) << t2 - t1 << ' '; + } #else // _OPENMP +#ifdef WITH_MPI + ParallelApply job( _proc, _pop ); + MasterNode* master = dynamic_cast( MpiNodeStore::instance() ); + if ( master ) + { + DynamicAssignmentAlgorithm algo; + master->setAssignmentAlgorithm( &algo ); + master->run( job ); + } else + { + WorkerNode* wrk = dynamic_cast( MpiNodeStore::instance() ); + wrk->run( job ); + } +#else // !_MPI for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } +#endif #endif // !_OPENMP } diff --git a/eo/test/t-eoMpiParallel.cpp b/eo/test/t-eoMpiParallel.cpp new file mode 100644 index 00000000..5529b8e2 --- /dev/null +++ b/eo/test/t-eoMpiParallel.cpp @@ -0,0 +1,111 @@ +//----------------------------------------------------------------------------- +// t-eoMpiParallel.cpp +//----------------------------------------------------------------------------- + +#include +#include +//#include +#include "real_value.h" + +#include + +//----------------------------------------------------------------------------- + +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; + +int main(int ac, char** av) +{ + MpiSingletonFactory::init( ac, av ); + + 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 ); + + eoPop< EOT > pop( popSize, init ); + + eo::log << "Size of population : " << popSize << std::endl; + + eoPopLoopEval< EOT > popEval( eval ); + popEval( pop, pop ); + + eo::log << eo::quiet << "DONE!" << std::endl; + + return 0; +} + +//-----------------------------------------------------------------------------