Included MPI tests into compilation, if WITH_MPI is defined.
This commit is contained in:
parent
ad74755d8e
commit
d2816d530a
7 changed files with 73 additions and 2 deletions
|
|
@ -120,6 +120,11 @@ ENDIF (ENABLE_CMAKE_TESTING)
|
||||||
ADD_SUBDIRECTORY(doc)
|
ADD_SUBDIRECTORY(doc)
|
||||||
ADD_SUBDIRECTORY(src)
|
ADD_SUBDIRECTORY(src)
|
||||||
ADD_SUBDIRECTORY(test)
|
ADD_SUBDIRECTORY(test)
|
||||||
|
|
||||||
|
IF(WITH_MPI)
|
||||||
|
ADD_SUBDIRECTORY(test/mpi)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(tutorial)
|
ADD_SUBDIRECTORY(tutorial)
|
||||||
|
|
||||||
######################################################################################
|
######################################################################################
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,23 @@ INCLUDE_DIRECTORIES(${EO_SOURCE_DIR}/contrib)
|
||||||
INCLUDE_DIRECTORIES(${EO_SOURCE_DIR}/contrib/MGE)
|
INCLUDE_DIRECTORIES(${EO_SOURCE_DIR}/contrib/MGE)
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
|
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
|
IF(WITH_MPI)
|
||||||
|
INCLUDE_DIRECTORIES(${BOOST_DIR}/include)
|
||||||
|
INCLUDE_DIRECTORIES(${MPI_DIR}/include)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
######################################################################################
|
######################################################################################
|
||||||
### 2) Specify where CMake can find the libraries
|
### 2) Specify where CMake can find the libraries
|
||||||
######################################################################################
|
######################################################################################
|
||||||
|
|
||||||
LINK_DIRECTORIES(${EO_BINARY_DIR}/lib)
|
LINK_DIRECTORIES(${EO_BINARY_DIR}/lib)
|
||||||
|
|
||||||
|
IF(WITH_MPI)
|
||||||
|
LINK_DIRECTORIES(${BOOST_DIR}/lib)
|
||||||
|
LINK_DIRECTORIES(${MPI_DIR}/lib)
|
||||||
|
SET(CMAKE_CXX_COMPILER "${MPI_DIR}/bin/mpicxx")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
######################################################################################
|
######################################################################################
|
||||||
### 3) Define your targets and link the librairies
|
### 3) Define your targets and link the librairies
|
||||||
######################################################################################
|
######################################################################################
|
||||||
|
|
@ -65,8 +76,8 @@ SET (TEST_LIST
|
||||||
t-eoExtendedVelocity
|
t-eoExtendedVelocity
|
||||||
t-eoLogger
|
t-eoLogger
|
||||||
t-eoIQRStat
|
t-eoIQRStat
|
||||||
t-eoParallel
|
#t-eoParallel
|
||||||
t-openmp
|
#t-openmp
|
||||||
#t-eoDualFitness
|
#t-eoDualFitness
|
||||||
t-eoParser
|
t-eoParser
|
||||||
)
|
)
|
||||||
|
|
|
||||||
55
eo/test/mpi/CMakeLists.txt
Normal file
55
eo/test/mpi/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
###############################################################################
|
||||||
|
##
|
||||||
|
## CMakeLists file for eo/test/mpi
|
||||||
|
##
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
######################################################################################
|
||||||
|
### 1) Include the sources
|
||||||
|
######################################################################################
|
||||||
|
|
||||||
|
MESSAGE("EO SOURCE DIR: ${EO_SOURCE_DIR}")
|
||||||
|
MESSAGE("OMPI: ${MPI_DIR}")
|
||||||
|
MESSAGE("BOOST: ${BOOST_DIR}")
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(${MPI_DIR}/include)
|
||||||
|
INCLUDE_DIRECTORIES(${BOOST_DIR}/include)
|
||||||
|
INCLUDE_DIRECTORIES(${EO_SOURCE_DIR}/src)
|
||||||
|
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
|
######################################################################################
|
||||||
|
### 2) Specify where CMake can find the libraries
|
||||||
|
######################################################################################
|
||||||
|
|
||||||
|
LINK_DIRECTORIES(${EO_BINARY_DIR}/lib)
|
||||||
|
LINK_DIRECTORIES(${MPI_DIR}/lib)
|
||||||
|
LINK_DIRECTORIES(${BOOST_DIR}/lib)
|
||||||
|
|
||||||
|
######################################################################################
|
||||||
|
### 3) Define your targets and link the librairies
|
||||||
|
######################################################################################
|
||||||
|
|
||||||
|
SET (TEST_LIST
|
||||||
|
t-mpi-parallelApply
|
||||||
|
t-mpi-wrapper
|
||||||
|
t-mpi-multipleRoles
|
||||||
|
t-mpi-eval
|
||||||
|
)
|
||||||
|
|
||||||
|
FOREACH (test ${TEST_LIST})
|
||||||
|
SET ("T_${test}_SOURCES" "${test}.cpp")
|
||||||
|
ENDFOREACH (test)
|
||||||
|
|
||||||
|
SET(CMAKE_CXX_COMPILER "${MPI_DIR}/bin/mpicxx")
|
||||||
|
ADD_DEFINITIONS(-DWITH_MPI)
|
||||||
|
|
||||||
|
IF(ENABLE_CMAKE_TESTING)
|
||||||
|
FOREACH (test ${TEST_LIST})
|
||||||
|
ADD_EXECUTABLE(${test} ${T_${test}_SOURCES})
|
||||||
|
ADD_TEST(${test} ${test})
|
||||||
|
TARGET_LINK_LIBRARIES(${test} boost_mpi boost_serialization eoutils eompi eoserial eo)
|
||||||
|
INSTALL(TARGETS ${test} RUNTIME DESTINATION share/eo/test COMPONENT test)
|
||||||
|
ENDFOREACH (test)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
######################################################################################
|
||||||
168
eo/test/mpi/t-mpi-eval.cpp
Normal file
168
eo/test/mpi/t-mpi-eval.cpp
Normal file
|
|
@ -0,0 +1,168 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// t-eoMpiParallel.cpp
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <eo>
|
||||||
|
#include <eoPopEvalFunc.h>
|
||||||
|
|
||||||
|
#include <es/make_real.h>
|
||||||
|
// #include <apply.h>
|
||||||
|
#include "../real_value.h"
|
||||||
|
|
||||||
|
#include <mpi/eoMpi.h>
|
||||||
|
|
||||||
|
#include <boost/mpi.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class eoRealSerializable : public eoReal< eoMinimizingFitness >, public eoserial::Persistent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
eoRealSerializable(unsigned size = 0, double value = 0.0):
|
||||||
|
eoReal<eoMinimizingFitness>(size, value) {}
|
||||||
|
|
||||||
|
eoserial::Object* pack() const
|
||||||
|
{
|
||||||
|
eoserial::Object* obj = new eoserial::Object;
|
||||||
|
obj->add( "array",
|
||||||
|
eoserial::makeArray< vector<double>, eoserial::MakeAlgorithm >
|
||||||
|
( *this )
|
||||||
|
);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unpack( const eoserial::Object* obj )
|
||||||
|
{
|
||||||
|
eoserial::unpackArray< vector<double>, 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 <class Archive>
|
||||||
|
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 <class Archive>
|
||||||
|
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<EOT>
|
||||||
|
{
|
||||||
|
CatBestAnswers()
|
||||||
|
{
|
||||||
|
best.fitness( 1000000000. );
|
||||||
|
}
|
||||||
|
|
||||||
|
using eo::mpi::HandleResponseParallelApply<EOT>::_wrapped;
|
||||||
|
using eo::mpi::HandleResponseParallelApply<EOT>::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::ParallelApplyStore< EOT > store( eval, eo::mpi::DEFAULT_MASTER );
|
||||||
|
store.wrapHandleResponse( new CatBestAnswers );
|
||||||
|
|
||||||
|
eoParallelPopLoopEval< EOT > popEval( assign, eo::mpi::DEFAULT_MASTER, &store );
|
||||||
|
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( assign, eo::mpi::DEFAULT_MASTER, eval );
|
||||||
|
popEval( pop, pop );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
113
eo/test/mpi/t-mpi-multipleRoles.cpp
Normal file
113
eo/test/mpi/t-mpi-multipleRoles.cpp
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
# include <mpi/eoMpi.h>
|
||||||
|
# include <mpi/eoParallelApply.h>
|
||||||
|
# include <mpi/eoTerminateJob.h>
|
||||||
|
|
||||||
|
# include <boost/serialization/vector.hpp>
|
||||||
|
|
||||||
|
# include <iostream>
|
||||||
|
|
||||||
|
# include <vector>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
using namespace eo::mpi;
|
||||||
|
|
||||||
|
// Role map
|
||||||
|
// 0 : general master
|
||||||
|
// 1, 2 : worker of general job, master of subjob
|
||||||
|
// 3 to 7 : workers of subjob
|
||||||
|
|
||||||
|
struct SubWork: public eoUF< int&, void >
|
||||||
|
{
|
||||||
|
void operator() ( int & x )
|
||||||
|
{
|
||||||
|
cout << "Subwork phase." << endl;
|
||||||
|
++x;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void subtask( vector<int>& v, int rank )
|
||||||
|
{
|
||||||
|
vector<int> workers;
|
||||||
|
workers.push_back( rank + 2 );
|
||||||
|
workers.push_back( rank + 4 );
|
||||||
|
DynamicAssignmentAlgorithm algo( workers );
|
||||||
|
SubWork sw;
|
||||||
|
|
||||||
|
ParallelApplyStore<int> store( sw, rank );
|
||||||
|
store.data( v );
|
||||||
|
ParallelApply<int> job( algo, rank, store );
|
||||||
|
job.run();
|
||||||
|
EmptyJob stop( algo, rank );
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Work: public eoUF< vector<int>&, void >
|
||||||
|
{
|
||||||
|
void operator() ( vector<int>& v )
|
||||||
|
{
|
||||||
|
cout << "Work phase..." << endl;
|
||||||
|
subtask( v, Node::comm().rank() );
|
||||||
|
for( int i = 0; i < v.size(); ++i )
|
||||||
|
{
|
||||||
|
v[i] *= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
// eo::log << eo::setlevel( eo::debug );
|
||||||
|
Node::init( argc, argv );
|
||||||
|
vector<int> v;
|
||||||
|
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(3);
|
||||||
|
v.push_back(3);
|
||||||
|
v.push_back(7);
|
||||||
|
v.push_back(42);
|
||||||
|
|
||||||
|
vector< vector<int> > metaV;
|
||||||
|
metaV.push_back( v );
|
||||||
|
metaV.push_back( v );
|
||||||
|
|
||||||
|
switch( Node::comm().rank() )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
Work w;
|
||||||
|
DynamicAssignmentAlgorithm algo( 1, 2 );
|
||||||
|
ParallelApplyStore< vector<int> > store( w, 0 );
|
||||||
|
store.data( metaV );
|
||||||
|
ParallelApply< vector<int> > job( algo, 0, store );
|
||||||
|
job.run();
|
||||||
|
if( job.isMaster() )
|
||||||
|
{
|
||||||
|
EmptyJob stop( algo, 0 );
|
||||||
|
v = metaV[0];
|
||||||
|
cout << "Results : " << endl;
|
||||||
|
for(int i = 0; i < v.size(); ++i)
|
||||||
|
{
|
||||||
|
cout << v[i] << ' ';
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// all the other nodes are sub workers
|
||||||
|
int rank = Node::comm().rank();
|
||||||
|
if ( rank == 3 or rank == 5 )
|
||||||
|
{
|
||||||
|
subtask( v, 1 );
|
||||||
|
} else {
|
||||||
|
subtask( v, 2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
150
eo/test/mpi/t-mpi-parallelApply.cpp
Normal file
150
eo/test/mpi/t-mpi-parallelApply.cpp
Normal file
|
|
@ -0,0 +1,150 @@
|
||||||
|
# include <mpi/eoMpi.h>
|
||||||
|
# include <mpi/eoParallelApply.h>
|
||||||
|
# include <mpi/eoTerminateJob.h>
|
||||||
|
|
||||||
|
# include <iostream>
|
||||||
|
|
||||||
|
# include <vector>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
using namespace eo::mpi;
|
||||||
|
|
||||||
|
struct plusOne : public eoUF< int&, void >
|
||||||
|
{
|
||||||
|
void operator() ( int & x )
|
||||||
|
{
|
||||||
|
++x;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Test
|
||||||
|
{
|
||||||
|
AssignmentAlgorithm * assign;
|
||||||
|
string description;
|
||||||
|
int requiredNodesNumber; // nb : chosen nodes ranks must be sequential
|
||||||
|
};
|
||||||
|
|
||||||
|
// These tests require at least 3 processes to be launched.
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
// eo::log << eo::setlevel( eo::debug );
|
||||||
|
eo::log << eo::setlevel( eo::quiet );
|
||||||
|
bool launchOnlyOne = false ; // Set this to true if you wanna launch only the first test.
|
||||||
|
|
||||||
|
Node::init( argc, argv );
|
||||||
|
|
||||||
|
srand( time(0) );
|
||||||
|
vector<int> v;
|
||||||
|
for( int i = 0; i < 1000; ++i )
|
||||||
|
{
|
||||||
|
v.push_back( rand() );
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
vector<int> originalV = v;
|
||||||
|
|
||||||
|
plusOne plusOneInstance;
|
||||||
|
|
||||||
|
vector< Test > tests;
|
||||||
|
|
||||||
|
const int ALL = Node::comm().size();
|
||||||
|
|
||||||
|
Test tIntervalStatic;
|
||||||
|
tIntervalStatic.assign = new StaticAssignmentAlgorithm( 1, REST_OF_THE_WORLD, v.size() );
|
||||||
|
tIntervalStatic.description = "Correct static assignment with interval.";
|
||||||
|
tIntervalStatic.requiredNodesNumber = ALL;
|
||||||
|
tests.push_back( tIntervalStatic );
|
||||||
|
|
||||||
|
if( !launchOnlyOne )
|
||||||
|
{
|
||||||
|
Test tWorldStatic;
|
||||||
|
tWorldStatic.assign = new StaticAssignmentAlgorithm( v.size() );
|
||||||
|
tWorldStatic.description = "Correct static assignment with whole world as workers.";
|
||||||
|
tWorldStatic.requiredNodesNumber = ALL;
|
||||||
|
tests.push_back( tWorldStatic );
|
||||||
|
|
||||||
|
Test tStaticOverload;
|
||||||
|
tStaticOverload.assign = new StaticAssignmentAlgorithm( v.size()+100 );
|
||||||
|
tStaticOverload.description = "Static assignment with too many runs.";
|
||||||
|
tStaticOverload.requiredNodesNumber = ALL;
|
||||||
|
tests.push_back( tStaticOverload );
|
||||||
|
|
||||||
|
Test tUniqueStatic;
|
||||||
|
tUniqueStatic.assign = new StaticAssignmentAlgorithm( 1, v.size() );
|
||||||
|
tUniqueStatic.description = "Correct static assignment with unique worker.";
|
||||||
|
tUniqueStatic.requiredNodesNumber = 2;
|
||||||
|
tests.push_back( tUniqueStatic );
|
||||||
|
|
||||||
|
Test tVectorStatic;
|
||||||
|
vector<int> workers;
|
||||||
|
workers.push_back( 1 );
|
||||||
|
workers.push_back( 2 );
|
||||||
|
tVectorStatic.assign = new StaticAssignmentAlgorithm( workers, v.size() );
|
||||||
|
tVectorStatic.description = "Correct static assignment with precise workers specified.";
|
||||||
|
tVectorStatic.requiredNodesNumber = 3;
|
||||||
|
tests.push_back( tVectorStatic );
|
||||||
|
|
||||||
|
Test tIntervalDynamic;
|
||||||
|
tIntervalDynamic.assign = new DynamicAssignmentAlgorithm( 1, REST_OF_THE_WORLD );
|
||||||
|
tIntervalDynamic.description = "Dynamic assignment with interval.";
|
||||||
|
tIntervalDynamic.requiredNodesNumber = ALL;
|
||||||
|
tests.push_back( tIntervalDynamic );
|
||||||
|
|
||||||
|
Test tUniqueDynamic;
|
||||||
|
tUniqueDynamic.assign = new DynamicAssignmentAlgorithm( 1 );
|
||||||
|
tUniqueDynamic.description = "Dynamic assignment with unique worker.";
|
||||||
|
tUniqueDynamic.requiredNodesNumber = 2;
|
||||||
|
tests.push_back( tUniqueDynamic );
|
||||||
|
|
||||||
|
Test tVectorDynamic;
|
||||||
|
tVectorDynamic.assign = new DynamicAssignmentAlgorithm( workers );
|
||||||
|
tVectorDynamic.description = "Dynamic assignment with precise workers specified.";
|
||||||
|
tVectorDynamic.requiredNodesNumber = tVectorStatic.requiredNodesNumber;
|
||||||
|
tests.push_back( tVectorDynamic );
|
||||||
|
|
||||||
|
Test tWorldDynamic;
|
||||||
|
tWorldDynamic.assign = new DynamicAssignmentAlgorithm;
|
||||||
|
tWorldDynamic.description = "Dynamic assignment with whole world as workers.";
|
||||||
|
tWorldDynamic.requiredNodesNumber = ALL;
|
||||||
|
tests.push_back( tWorldDynamic );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( unsigned int i = 0; i < tests.size(); ++i )
|
||||||
|
{
|
||||||
|
ParallelApplyStore< int > store( plusOneInstance, eo::mpi::DEFAULT_MASTER, 3 );
|
||||||
|
store.data( v );
|
||||||
|
ParallelApply< int > job( *(tests[i].assign), eo::mpi::DEFAULT_MASTER, store );
|
||||||
|
|
||||||
|
if( job.isMaster() )
|
||||||
|
{
|
||||||
|
cout << "Test : " << tests[i].description << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Node::comm().rank() < tests[i].requiredNodesNumber )
|
||||||
|
{
|
||||||
|
job.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( job.isMaster() )
|
||||||
|
{
|
||||||
|
EmptyJob stop( *(tests[i].assign), eo::mpi::DEFAULT_MASTER );
|
||||||
|
++offset;
|
||||||
|
for(int i = 0; i < v.size(); ++i)
|
||||||
|
{
|
||||||
|
cout << v[i] << ' ';
|
||||||
|
if( originalV[i] + offset != v[i] )
|
||||||
|
{
|
||||||
|
cout << " <-- ERROR at this point." << endl;
|
||||||
|
exit( EXIT_FAILURE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::comm().barrier();
|
||||||
|
|
||||||
|
delete tests[i].assign;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
91
eo/test/mpi/t-mpi-wrapper.cpp
Normal file
91
eo/test/mpi/t-mpi-wrapper.cpp
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
# include <mpi/eoMpi.h>
|
||||||
|
# include <mpi/eoParallelApply.h>
|
||||||
|
# include <mpi/eoTerminateJob.h>
|
||||||
|
|
||||||
|
# include <iostream>
|
||||||
|
|
||||||
|
# include <vector>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
using namespace eo::mpi;
|
||||||
|
|
||||||
|
struct plusOne : public eoUF< int&, void >
|
||||||
|
{
|
||||||
|
void operator() ( int & x )
|
||||||
|
{
|
||||||
|
++x;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class EOT >
|
||||||
|
struct ShowWrappedResult : public IsFinishedParallelApply<EOT>
|
||||||
|
{
|
||||||
|
using IsFinishedParallelApply<EOT>::_wrapped;
|
||||||
|
|
||||||
|
ShowWrappedResult ( IsFinishedParallelApply<EOT> * w = 0 ) : IsFinishedParallelApply<EOT>( w ), times( 0 )
|
||||||
|
{
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()()
|
||||||
|
{
|
||||||
|
bool wrappedValue = _wrapped->operator()(); // (*_wrapped)();
|
||||||
|
cout << times << ") Wrapped function would say that it is " << ( wrappedValue ? "":"not ") << "finished" << std::endl;
|
||||||
|
++times;
|
||||||
|
return wrappedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int times;
|
||||||
|
};
|
||||||
|
|
||||||
|
// These tests require at least 3 processes to be launched.
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
// eo::log << eo::setlevel( eo::debug );
|
||||||
|
eo::log << eo::setlevel( eo::quiet );
|
||||||
|
|
||||||
|
Node::init( argc, argv );
|
||||||
|
|
||||||
|
srand( time(0) );
|
||||||
|
vector<int> v;
|
||||||
|
for( int i = 0; i < 1000; ++i )
|
||||||
|
{
|
||||||
|
v.push_back( rand() );
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
vector<int> originalV = v;
|
||||||
|
|
||||||
|
plusOne plusOneInstance;
|
||||||
|
|
||||||
|
StaticAssignmentAlgorithm assign( v.size() );
|
||||||
|
|
||||||
|
ParallelApplyStore< int > store( plusOneInstance, eo::mpi::DEFAULT_MASTER, 1 );
|
||||||
|
store.data( v );
|
||||||
|
store.wrapIsFinished( new ShowWrappedResult<int> );
|
||||||
|
|
||||||
|
ParallelApply<int> job( assign, eo::mpi::DEFAULT_MASTER, store );
|
||||||
|
// Equivalent to:
|
||||||
|
// Job< ParallelApplyData<int> > job( assign, 0, store );
|
||||||
|
job.run();
|
||||||
|
EmptyJob stop( assign, eo::mpi::DEFAULT_MASTER );
|
||||||
|
|
||||||
|
if( job.isMaster() )
|
||||||
|
{
|
||||||
|
++offset;
|
||||||
|
for(int i = 0; i < v.size(); ++i)
|
||||||
|
{
|
||||||
|
cout << v[i] << ' ';
|
||||||
|
if( originalV[i] + offset != v[i] )
|
||||||
|
{
|
||||||
|
cout << " <-- ERROR at this point." << endl;
|
||||||
|
exit( EXIT_FAILURE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in a new issue