Code organisation, splitted headers files in implementation files, as much as possible (impossible for templates functions, thank you C++)
This commit is contained in:
parent
0e56778327
commit
191b280371
10 changed files with 559 additions and 487 deletions
|
|
@ -14,6 +14,9 @@ SET(LIBRARY_OUTPUT_PATH ${EOMPI_LIB_OUTPUT_PATH})
|
||||||
|
|
||||||
SET(EOMPI_SOURCES
|
SET(EOMPI_SOURCES
|
||||||
eoMpi.cpp
|
eoMpi.cpp
|
||||||
|
eoMpiAssignmentAlgorithm.cpp
|
||||||
|
eoMpiNode.cpp
|
||||||
|
implMpi.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_LIBRARY(eompi STATIC ${EOMPI_SOURCES})
|
ADD_LIBRARY(eompi STATIC ${EOMPI_SOURCES})
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,24 @@ namespace eo
|
||||||
{
|
{
|
||||||
namespace mpi
|
namespace mpi
|
||||||
{
|
{
|
||||||
bmpi::communicator Node::_comm;
|
/**********************************************
|
||||||
|
* *********** GLOBALS ************************
|
||||||
|
* *******************************************/
|
||||||
eoTimerStat timerStat;
|
eoTimerStat timerStat;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace mpi
|
namespace Channel
|
||||||
{
|
{
|
||||||
void broadcast( communicator & comm, int value, int root )
|
const int Commands = 0;
|
||||||
{
|
const int Messages = 1;
|
||||||
comm; // unused
|
}
|
||||||
MPI_Bcast( &value, 1, MPI_INT, root, MPI_COMM_WORLD );
|
|
||||||
|
namespace Message
|
||||||
|
{
|
||||||
|
const int Continue = 0;
|
||||||
|
const int Finish = 1;
|
||||||
|
const int Kill = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int DEFAULT_MASTER = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,8 +143,8 @@ namespace eo
|
||||||
*/
|
*/
|
||||||
namespace Channel
|
namespace Channel
|
||||||
{
|
{
|
||||||
const int Commands = 0;
|
extern const int Commands;
|
||||||
const int Messages = 1;
|
extern const int Messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -157,9 +157,9 @@ namespace eo
|
||||||
*/
|
*/
|
||||||
namespace Message
|
namespace Message
|
||||||
{
|
{
|
||||||
const int Continue = 0;
|
extern const int Continue;
|
||||||
const int Finish = 1;
|
extern const int Finish;
|
||||||
const int Kill = 2;
|
extern const int Kill;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -167,7 +167,7 @@ namespace eo
|
||||||
*
|
*
|
||||||
* @ingroup MPI
|
* @ingroup MPI
|
||||||
*/
|
*/
|
||||||
const int DEFAULT_MASTER = 0;
|
extern const int DEFAULT_MASTER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Base class for the 4 algorithm functors.
|
* @brief Base class for the 4 algorithm functors.
|
||||||
|
|
|
||||||
204
eo/src/mpi/eoMpiAssignmentAlgorithm.cpp
Normal file
204
eo/src/mpi/eoMpiAssignmentAlgorithm.cpp
Normal file
|
|
@ -0,0 +1,204 @@
|
||||||
|
# include "eoMpiAssignmentAlgorithm.h"
|
||||||
|
|
||||||
|
# include "eoMpiNode.h"
|
||||||
|
|
||||||
|
namespace eo
|
||||||
|
{
|
||||||
|
namespace mpi
|
||||||
|
{
|
||||||
|
const int REST_OF_THE_WORLD = -1;
|
||||||
|
|
||||||
|
/********************************************************
|
||||||
|
* DYNAMIC ASSIGNMENT ALGORITHM *************************
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
|
DynamicAssignmentAlgorithm::DynamicAssignmentAlgorithm( )
|
||||||
|
{
|
||||||
|
for(int i = 1; i < Node::comm().size(); ++i)
|
||||||
|
{
|
||||||
|
availableWrk.push_back( i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicAssignmentAlgorithm::DynamicAssignmentAlgorithm( int unique )
|
||||||
|
{
|
||||||
|
availableWrk.push_back( unique );
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicAssignmentAlgorithm::DynamicAssignmentAlgorithm( const std::vector<int> & workers )
|
||||||
|
{
|
||||||
|
availableWrk = workers;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicAssignmentAlgorithm::DynamicAssignmentAlgorithm( int first, int last )
|
||||||
|
{
|
||||||
|
if( last == REST_OF_THE_WORLD )
|
||||||
|
{
|
||||||
|
last = Node::comm().size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int i = first; i <= last; ++i)
|
||||||
|
{
|
||||||
|
availableWrk.push_back( i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int DynamicAssignmentAlgorithm::get( )
|
||||||
|
{
|
||||||
|
int assignee = -1;
|
||||||
|
if (! availableWrk.empty() )
|
||||||
|
{
|
||||||
|
assignee = availableWrk.back();
|
||||||
|
availableWrk.pop_back();
|
||||||
|
}
|
||||||
|
return assignee;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DynamicAssignmentAlgorithm::availableWorkers()
|
||||||
|
{
|
||||||
|
return availableWrk.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicAssignmentAlgorithm::confirm( int rank )
|
||||||
|
{
|
||||||
|
availableWrk.push_back( rank );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> DynamicAssignmentAlgorithm::idles( )
|
||||||
|
{
|
||||||
|
return availableWrk;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicAssignmentAlgorithm::reinit( int _ )
|
||||||
|
{
|
||||||
|
++_;
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************
|
||||||
|
* STATIC ASSIGNMENT ALGORITHM **************************
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
|
StaticAssignmentAlgorithm::StaticAssignmentAlgorithm( std::vector<int>& workers, int runs )
|
||||||
|
{
|
||||||
|
init( workers, runs );
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticAssignmentAlgorithm::StaticAssignmentAlgorithm( int first, int last, int runs )
|
||||||
|
{
|
||||||
|
std::vector<int> workers;
|
||||||
|
|
||||||
|
if( last == REST_OF_THE_WORLD )
|
||||||
|
{
|
||||||
|
last = Node::comm().size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = first; i <= last; ++i)
|
||||||
|
{
|
||||||
|
workers.push_back( i );
|
||||||
|
}
|
||||||
|
init( workers, runs );
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticAssignmentAlgorithm::StaticAssignmentAlgorithm( int runs )
|
||||||
|
{
|
||||||
|
std::vector<int> workers;
|
||||||
|
for(int i = 1; i < Node::comm().size(); ++i)
|
||||||
|
{
|
||||||
|
workers.push_back( i );
|
||||||
|
}
|
||||||
|
|
||||||
|
init( workers, runs );
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticAssignmentAlgorithm::StaticAssignmentAlgorithm( int unique, int runs )
|
||||||
|
{
|
||||||
|
std::vector<int> workers;
|
||||||
|
workers.push_back( unique );
|
||||||
|
init( workers, runs );
|
||||||
|
}
|
||||||
|
|
||||||
|
void StaticAssignmentAlgorithm::init( std::vector<int> & workers, int runs )
|
||||||
|
{
|
||||||
|
unsigned int nbWorkers = workers.size();
|
||||||
|
freeWorkers = nbWorkers;
|
||||||
|
|
||||||
|
busy.clear();
|
||||||
|
busy.resize( nbWorkers, false );
|
||||||
|
realRank = workers;
|
||||||
|
|
||||||
|
if( runs <= 0 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
attributions.clear();
|
||||||
|
attributions.reserve( nbWorkers );
|
||||||
|
|
||||||
|
// Let be the euclidean division of runs by nbWorkers :
|
||||||
|
// runs == q * nbWorkers + r, 0 <= r < nbWorkers
|
||||||
|
// This one liner affects q requests to each worker
|
||||||
|
for (unsigned int i = 0; i < nbWorkers; attributions[i++] = runs / nbWorkers) ;
|
||||||
|
// The first line computes r and the one liner affects the remaining
|
||||||
|
// r requests to workers, in ascending order
|
||||||
|
unsigned int diff = runs - (runs / nbWorkers) * nbWorkers;
|
||||||
|
for (unsigned int i = 0; i < diff; ++attributions[i++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int StaticAssignmentAlgorithm::get( )
|
||||||
|
{
|
||||||
|
int assignee = -1;
|
||||||
|
for( unsigned i = 0; i < busy.size(); ++i )
|
||||||
|
{
|
||||||
|
if( !busy[i] && attributions[i] > 0 )
|
||||||
|
{
|
||||||
|
busy[i] = true;
|
||||||
|
--freeWorkers;
|
||||||
|
assignee = realRank[ i ];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return assignee;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StaticAssignmentAlgorithm::availableWorkers( )
|
||||||
|
{
|
||||||
|
return freeWorkers;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> StaticAssignmentAlgorithm::idles()
|
||||||
|
{
|
||||||
|
std::vector<int> ret;
|
||||||
|
for(unsigned int i = 0; i < busy.size(); ++i)
|
||||||
|
{
|
||||||
|
if( !busy[i] )
|
||||||
|
{
|
||||||
|
ret.push_back( realRank[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StaticAssignmentAlgorithm::confirm( int rank )
|
||||||
|
{
|
||||||
|
int i = -1; // i is the real index in table
|
||||||
|
for( unsigned int j = 0; j < realRank.size(); ++j )
|
||||||
|
{
|
||||||
|
if( realRank[j] == rank )
|
||||||
|
{
|
||||||
|
i = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--attributions[ i ];
|
||||||
|
busy[ i ] = false;
|
||||||
|
++freeWorkers;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StaticAssignmentAlgorithm::reinit( int runs )
|
||||||
|
{
|
||||||
|
init( realRank, runs );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,7 +23,6 @@ Authors:
|
||||||
# define __MPI_ASSIGNMENT_ALGORITHM_H__
|
# define __MPI_ASSIGNMENT_ALGORITHM_H__
|
||||||
|
|
||||||
# include <vector> // std::vector
|
# include <vector> // std::vector
|
||||||
# include "eoMpiNode.h"
|
|
||||||
|
|
||||||
namespace eo
|
namespace eo
|
||||||
{
|
{
|
||||||
|
|
@ -35,7 +34,7 @@ namespace eo
|
||||||
*
|
*
|
||||||
* @ingroup MPI
|
* @ingroup MPI
|
||||||
*/
|
*/
|
||||||
const int REST_OF_THE_WORLD = -1;
|
extern const int REST_OF_THE_WORLD;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains informations on the available workers and allows to find assignees for jobs.
|
* @brief Contains informations on the available workers and allows to find assignees for jobs.
|
||||||
|
|
@ -115,33 +114,21 @@ namespace eo
|
||||||
/**
|
/**
|
||||||
* @brief Uses all the hosts whose rank is higher to 1, inclusive, as workers.
|
* @brief Uses all the hosts whose rank is higher to 1, inclusive, as workers.
|
||||||
*/
|
*/
|
||||||
DynamicAssignmentAlgorithm( )
|
DynamicAssignmentAlgorithm( );
|
||||||
{
|
|
||||||
for(int i = 1; i < Node::comm().size(); ++i)
|
|
||||||
{
|
|
||||||
availableWrk.push_back( i );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Uses the unique host with given rank as a worker.
|
* @brief Uses the unique host with given rank as a worker.
|
||||||
*
|
*
|
||||||
* @param unique MPI rank of the unique worker.
|
* @param unique MPI rank of the unique worker.
|
||||||
*/
|
*/
|
||||||
DynamicAssignmentAlgorithm( int unique )
|
DynamicAssignmentAlgorithm( int unique );
|
||||||
{
|
|
||||||
availableWrk.push_back( unique );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Uses the workers whose ranks are present in the argument as workers.
|
* @brief Uses the workers whose ranks are present in the argument as workers.
|
||||||
*
|
*
|
||||||
* @param workers std::vector containing MPI ranks of workers.
|
* @param workers std::vector containing MPI ranks of workers.
|
||||||
*/
|
*/
|
||||||
DynamicAssignmentAlgorithm( const std::vector<int> & workers )
|
DynamicAssignmentAlgorithm( const std::vector<int> & workers );
|
||||||
{
|
|
||||||
availableWrk = workers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Uses a range of ranks as workers.
|
* @brief Uses a range of ranks as workers.
|
||||||
|
|
@ -150,50 +137,17 @@ namespace eo
|
||||||
* @param last The last worker to be included (inclusive). If last == eo::mpi::REST_OF_THE_WORLD, all
|
* @param last The last worker to be included (inclusive). If last == eo::mpi::REST_OF_THE_WORLD, all
|
||||||
* hosts whose rank is higher than first are taken.
|
* hosts whose rank is higher than first are taken.
|
||||||
*/
|
*/
|
||||||
DynamicAssignmentAlgorithm( int first, int last )
|
DynamicAssignmentAlgorithm( int first, int last );
|
||||||
{
|
|
||||||
if( last == REST_OF_THE_WORLD )
|
|
||||||
{
|
|
||||||
last = Node::comm().size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for( int i = first; i <= last; ++i)
|
virtual int get( );
|
||||||
{
|
|
||||||
availableWrk.push_back( i );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int get( )
|
int availableWorkers();
|
||||||
{
|
|
||||||
int assignee = -1;
|
|
||||||
if (! availableWrk.empty() )
|
|
||||||
{
|
|
||||||
assignee = availableWrk.back();
|
|
||||||
availableWrk.pop_back();
|
|
||||||
}
|
|
||||||
return assignee;
|
|
||||||
}
|
|
||||||
|
|
||||||
int availableWorkers()
|
void confirm( int rank );
|
||||||
{
|
|
||||||
return availableWrk.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void confirm( int rank )
|
std::vector<int> idles( );
|
||||||
{
|
|
||||||
availableWrk.push_back( rank );
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<int> idles( )
|
void reinit( int _ );
|
||||||
{
|
|
||||||
return availableWrk;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reinit( int _ )
|
|
||||||
{
|
|
||||||
++_;
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector< int > availableWrk;
|
std::vector< int > availableWrk;
|
||||||
|
|
@ -223,10 +177,7 @@ namespace eo
|
||||||
* @param workers std::vector of MPI ranks of workers which will be used.
|
* @param workers std::vector of MPI ranks of workers which will be used.
|
||||||
* @param runs Fixed amount of runs, strictly positive.
|
* @param runs Fixed amount of runs, strictly positive.
|
||||||
*/
|
*/
|
||||||
StaticAssignmentAlgorithm( std::vector<int>& workers, int runs )
|
StaticAssignmentAlgorithm( std::vector<int>& workers, int runs );
|
||||||
{
|
|
||||||
init( workers, runs );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Uses a range of workers.
|
* @brief Uses a range of workers.
|
||||||
|
|
@ -236,21 +187,7 @@ namespace eo
|
||||||
* workers from the first one are taken as workers.
|
* workers from the first one are taken as workers.
|
||||||
* @param runs Fixed amount of runs, strictly positive.
|
* @param runs Fixed amount of runs, strictly positive.
|
||||||
*/
|
*/
|
||||||
StaticAssignmentAlgorithm( int first, int last, int runs )
|
StaticAssignmentAlgorithm( int first, int last, int runs );
|
||||||
{
|
|
||||||
std::vector<int> workers;
|
|
||||||
|
|
||||||
if( last == REST_OF_THE_WORLD )
|
|
||||||
{
|
|
||||||
last = Node::comm().size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = first; i <= last; ++i)
|
|
||||||
{
|
|
||||||
workers.push_back( i );
|
|
||||||
}
|
|
||||||
init( workers, runs );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Uses all the hosts whose rank is higher than 1 (inclusive) as workers.
|
* @brief Uses all the hosts whose rank is higher than 1 (inclusive) as workers.
|
||||||
|
|
@ -258,16 +195,7 @@ namespace eo
|
||||||
* @param runs Fixed amount of runs, strictly positive. If it's not set, you'll have to call reinit()
|
* @param runs Fixed amount of runs, strictly positive. If it's not set, you'll have to call reinit()
|
||||||
* later.
|
* later.
|
||||||
*/
|
*/
|
||||||
StaticAssignmentAlgorithm( int runs = 0 )
|
StaticAssignmentAlgorithm( int runs = 0 );
|
||||||
{
|
|
||||||
std::vector<int> workers;
|
|
||||||
for(int i = 1; i < Node::comm().size(); ++i)
|
|
||||||
{
|
|
||||||
workers.push_back( i );
|
|
||||||
}
|
|
||||||
|
|
||||||
init( workers, runs );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Uses an unique host as worker.
|
* @brief Uses an unique host as worker.
|
||||||
|
|
@ -275,12 +203,7 @@ namespace eo
|
||||||
* @param unique The MPI rank of the host which will be the worker.
|
* @param unique The MPI rank of the host which will be the worker.
|
||||||
* @param runs Fixed amount of runs, strictly positive.
|
* @param runs Fixed amount of runs, strictly positive.
|
||||||
*/
|
*/
|
||||||
StaticAssignmentAlgorithm( int unique, int runs )
|
StaticAssignmentAlgorithm( int unique, int runs );
|
||||||
{
|
|
||||||
std::vector<int> workers;
|
|
||||||
workers.push_back( unique );
|
|
||||||
init( workers, runs );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
@ -292,89 +215,18 @@ namespace eo
|
||||||
* @param workers Vector of hosts' ranks
|
* @param workers Vector of hosts' ranks
|
||||||
* @param runs Fixed amount of runs, strictly positive.
|
* @param runs Fixed amount of runs, strictly positive.
|
||||||
*/
|
*/
|
||||||
void init( std::vector<int> & workers, int runs )
|
void init( std::vector<int> & workers, int runs );
|
||||||
{
|
|
||||||
unsigned int nbWorkers = workers.size();
|
|
||||||
freeWorkers = nbWorkers;
|
|
||||||
|
|
||||||
busy.clear();
|
|
||||||
busy.resize( nbWorkers, false );
|
|
||||||
realRank = workers;
|
|
||||||
|
|
||||||
if( runs <= 0 )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
attributions.clear();
|
|
||||||
attributions.reserve( nbWorkers );
|
|
||||||
|
|
||||||
// Let be the euclidean division of runs by nbWorkers :
|
|
||||||
// runs == q * nbWorkers + r, 0 <= r < nbWorkers
|
|
||||||
// This one liner affects q requests to each worker
|
|
||||||
for (unsigned int i = 0; i < nbWorkers; attributions[i++] = runs / nbWorkers) ;
|
|
||||||
// The first line computes r and the one liner affects the remaining
|
|
||||||
// r requests to workers, in ascending order
|
|
||||||
unsigned int diff = runs - (runs / nbWorkers) * nbWorkers;
|
|
||||||
for (unsigned int i = 0; i < diff; ++attributions[i++]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int get( )
|
int get( );
|
||||||
{
|
|
||||||
int assignee = -1;
|
|
||||||
for( unsigned i = 0; i < busy.size(); ++i )
|
|
||||||
{
|
|
||||||
if( !busy[i] && attributions[i] > 0 )
|
|
||||||
{
|
|
||||||
busy[i] = true;
|
|
||||||
--freeWorkers;
|
|
||||||
assignee = realRank[ i ];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return assignee;
|
|
||||||
}
|
|
||||||
|
|
||||||
int availableWorkers( )
|
int availableWorkers( );
|
||||||
{
|
|
||||||
return freeWorkers;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<int> idles()
|
std::vector<int> idles();
|
||||||
{
|
|
||||||
std::vector<int> ret;
|
|
||||||
for(unsigned int i = 0; i < busy.size(); ++i)
|
|
||||||
{
|
|
||||||
if( !busy[i] )
|
|
||||||
{
|
|
||||||
ret.push_back( realRank[i] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void confirm( int rank )
|
void confirm( int rank );
|
||||||
{
|
|
||||||
int i = -1; // i is the real index in table
|
|
||||||
for( unsigned int j = 0; j < realRank.size(); ++j )
|
|
||||||
{
|
|
||||||
if( realRank[j] == rank )
|
|
||||||
{
|
|
||||||
i = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
--attributions[ i ];
|
void reinit( int runs );
|
||||||
busy[ i ] = false;
|
|
||||||
++freeWorkers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reinit( int runs )
|
|
||||||
{
|
|
||||||
init( realRank, runs );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<int> attributions;
|
std::vector<int> attributions;
|
||||||
|
|
|
||||||
19
eo/src/mpi/eoMpiNode.cpp
Normal file
19
eo/src/mpi/eoMpiNode.cpp
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# include "eoMpiNode.h"
|
||||||
|
|
||||||
|
namespace eo
|
||||||
|
{
|
||||||
|
namespace mpi
|
||||||
|
{
|
||||||
|
void Node::init( int argc, char** argv )
|
||||||
|
{
|
||||||
|
static bmpi::environment env( argc, argv );
|
||||||
|
}
|
||||||
|
|
||||||
|
bmpi::communicator& Node::comm()
|
||||||
|
{
|
||||||
|
return _comm;
|
||||||
|
}
|
||||||
|
|
||||||
|
bmpi::communicator Node::_comm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -22,7 +22,7 @@ Authors:
|
||||||
# ifndef __MPI_NODE_H__
|
# ifndef __MPI_NODE_H__
|
||||||
# define __MPI_NODE_H__
|
# define __MPI_NODE_H__
|
||||||
|
|
||||||
# include "implMpi.hpp"
|
# include "implMpi.h"
|
||||||
namespace bmpi = mpi;
|
namespace bmpi = mpi;
|
||||||
|
|
||||||
namespace eo
|
namespace eo
|
||||||
|
|
@ -30,9 +30,9 @@ namespace eo
|
||||||
namespace mpi
|
namespace mpi
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Global object used to reach boost::mpi::communicator everywhere.
|
* @brief Global object used to reach mpi::communicator everywhere.
|
||||||
*
|
*
|
||||||
* boost::mpi::communicator is the main object used to send and receive messages between the different hosts of
|
* mpi::communicator is the main object used to send and receive messages between the different hosts of
|
||||||
* a MPI algorithm.
|
* a MPI algorithm.
|
||||||
*
|
*
|
||||||
* @ingroup MPI
|
* @ingroup MPI
|
||||||
|
|
@ -49,18 +49,12 @@ namespace eo
|
||||||
* @param argc Main's argc
|
* @param argc Main's argc
|
||||||
* @param argv Main's argv
|
* @param argv Main's argv
|
||||||
*/
|
*/
|
||||||
static void init( int argc, char** argv )
|
static void init( int argc, char** argv );
|
||||||
{
|
|
||||||
static bmpi::environment env( argc, argv );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the global boost::mpi::communicator
|
* @brief Returns the global mpi::communicator
|
||||||
*/
|
*/
|
||||||
static bmpi::communicator& comm()
|
static bmpi::communicator& comm();
|
||||||
{
|
|
||||||
return _comm;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static bmpi::communicator _comm;
|
static bmpi::communicator _comm;
|
||||||
|
|
|
||||||
146
eo/src/mpi/implMpi.cpp
Normal file
146
eo/src/mpi/implMpi.cpp
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
# include "implMpi.h"
|
||||||
|
|
||||||
|
namespace mpi
|
||||||
|
{
|
||||||
|
const int any_source = MPI_ANY_SOURCE;
|
||||||
|
const int any_tag = MPI_ANY_TAG;
|
||||||
|
|
||||||
|
environment::environment(int argc, char**argv)
|
||||||
|
{
|
||||||
|
MPI_Init(&argc, &argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
environment::~environment()
|
||||||
|
{
|
||||||
|
MPI_Finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
status::status( const MPI_Status & s )
|
||||||
|
{
|
||||||
|
_source = s.MPI_SOURCE;
|
||||||
|
_tag = s.MPI_TAG;
|
||||||
|
_error = s.MPI_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
communicator::communicator( )
|
||||||
|
{
|
||||||
|
_rank = -1;
|
||||||
|
_size = -1;
|
||||||
|
|
||||||
|
_buf = 0;
|
||||||
|
_bufsize = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
communicator::~communicator()
|
||||||
|
{
|
||||||
|
if( _buf )
|
||||||
|
{
|
||||||
|
delete _buf;
|
||||||
|
_buf = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int communicator::rank()
|
||||||
|
{
|
||||||
|
if ( _rank == -1 )
|
||||||
|
{
|
||||||
|
MPI_Comm_rank( MPI_COMM_WORLD, &_rank );
|
||||||
|
}
|
||||||
|
return _rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
int communicator::size()
|
||||||
|
{
|
||||||
|
if ( _size == -1 )
|
||||||
|
{
|
||||||
|
MPI_Comm_size( MPI_COMM_WORLD, &_size );
|
||||||
|
}
|
||||||
|
return _size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SEND / RECV INT
|
||||||
|
*/
|
||||||
|
void communicator::send( int dest, int tag, int n )
|
||||||
|
{
|
||||||
|
MPI_Send( &n, 1, MPI_INT, dest, tag, MPI_COMM_WORLD );
|
||||||
|
}
|
||||||
|
|
||||||
|
void communicator::recv( int src, int tag, int& n )
|
||||||
|
{
|
||||||
|
MPI_Status stat;
|
||||||
|
MPI_Recv( &n, 1, MPI_INT, src, tag, MPI_COMM_WORLD , &stat );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SEND / RECV STRING
|
||||||
|
*/
|
||||||
|
void communicator::send( int dest, int tag, const std::string& str )
|
||||||
|
{
|
||||||
|
int size = str.size() + 1;
|
||||||
|
send( dest, tag, size );
|
||||||
|
MPI_Send( (char*)str.c_str(), size, MPI_CHAR, dest, tag, MPI_COMM_WORLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
void communicator::recv( int src, int tag, std::string& str )
|
||||||
|
{
|
||||||
|
int size = -1;
|
||||||
|
MPI_Status stat;
|
||||||
|
recv( src, tag, size );
|
||||||
|
|
||||||
|
if( _buf == 0 )
|
||||||
|
{
|
||||||
|
_buf = new char[ size ];
|
||||||
|
_bufsize = size;
|
||||||
|
} else if( _bufsize < size )
|
||||||
|
{
|
||||||
|
delete [] _buf;
|
||||||
|
_buf = new char[ size ];
|
||||||
|
_bufsize = size;
|
||||||
|
}
|
||||||
|
MPI_Recv( _buf, size, MPI_CHAR, src, tag, MPI_COMM_WORLD, &stat );
|
||||||
|
str.assign( _buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SEND / RECV Objects
|
||||||
|
*/
|
||||||
|
void communicator::send( int dest, int tag, const eoserial::Persistent & persistent )
|
||||||
|
{
|
||||||
|
eoserial::Object* obj = persistent.pack();
|
||||||
|
std::stringstream ss;
|
||||||
|
obj->print( ss );
|
||||||
|
delete obj;
|
||||||
|
send( dest, tag, ss.str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void communicator::recv( int src, int tag, eoserial::Persistent & persistent )
|
||||||
|
{
|
||||||
|
std::string asText;
|
||||||
|
recv( src, tag, asText );
|
||||||
|
eoserial::Object* obj = eoserial::Parser::parse( asText );
|
||||||
|
persistent.unpack( obj );
|
||||||
|
delete obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Other methods
|
||||||
|
*/
|
||||||
|
status communicator::probe( int src, int tag )
|
||||||
|
{
|
||||||
|
MPI_Status stat;
|
||||||
|
MPI_Probe( src, tag, MPI_COMM_WORLD , &stat );
|
||||||
|
return status( stat );
|
||||||
|
}
|
||||||
|
|
||||||
|
void communicator::barrier()
|
||||||
|
{
|
||||||
|
MPI_Barrier( MPI_COMM_WORLD );
|
||||||
|
}
|
||||||
|
|
||||||
|
void broadcast( communicator & comm, int value, int root )
|
||||||
|
{
|
||||||
|
comm; // unused
|
||||||
|
MPI_Bcast( &value, 1, MPI_INT, root, MPI_COMM_WORLD );
|
||||||
|
}
|
||||||
|
}
|
||||||
129
eo/src/mpi/implMpi.h
Normal file
129
eo/src/mpi/implMpi.h
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
# ifndef __EO_MPI_HPP__
|
||||||
|
# define __EO_MPI_HPP__
|
||||||
|
|
||||||
|
# include <mpi.h>
|
||||||
|
# include <serial/eoSerial.h>
|
||||||
|
|
||||||
|
namespace mpi
|
||||||
|
{
|
||||||
|
extern const int any_source;
|
||||||
|
extern const int any_tag;
|
||||||
|
|
||||||
|
class environment
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
environment(int argc, char**argv);
|
||||||
|
|
||||||
|
~environment();
|
||||||
|
};
|
||||||
|
|
||||||
|
class status
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
status( const MPI_Status & s );
|
||||||
|
|
||||||
|
int tag() { return _tag; }
|
||||||
|
int error() { return _error; }
|
||||||
|
int source() { return _source; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _source;
|
||||||
|
int _tag;
|
||||||
|
int _error;
|
||||||
|
};
|
||||||
|
|
||||||
|
class communicator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
communicator( );
|
||||||
|
|
||||||
|
~communicator();
|
||||||
|
|
||||||
|
int rank();
|
||||||
|
|
||||||
|
int size();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SEND / RECV INT
|
||||||
|
*/
|
||||||
|
void send( int dest, int tag, int n );
|
||||||
|
|
||||||
|
void recv( int src, int tag, int& n );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SEND / RECV STRING
|
||||||
|
*/
|
||||||
|
void send( int dest, int tag, const std::string& str );
|
||||||
|
|
||||||
|
void recv( int src, int tag, std::string& str );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SEND / RECV Objects
|
||||||
|
*/
|
||||||
|
void send( int dest, int tag, const eoserial::Persistent & persistent );
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
void send( int dest, int tag, T* table, int size )
|
||||||
|
{
|
||||||
|
// Puts all the values into an array
|
||||||
|
eoserial::Array* array = new eoserial::Array;
|
||||||
|
|
||||||
|
for( int i = 0; i < size; ++i )
|
||||||
|
{
|
||||||
|
array->push_back( table[i].pack() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encapsulates the array into an object
|
||||||
|
eoserial::Object* obj = new eoserial::Object;
|
||||||
|
obj->add( "array", array );
|
||||||
|
std::stringstream ss;
|
||||||
|
obj->print( ss );
|
||||||
|
delete obj;
|
||||||
|
|
||||||
|
// Sends the object as a string
|
||||||
|
send( dest, tag, ss.str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void recv( int src, int tag, eoserial::Persistent & persistent );
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
void recv( int src, int tag, T* table, int size )
|
||||||
|
{
|
||||||
|
// Receives the string which contains the object
|
||||||
|
std::string asText;
|
||||||
|
recv( src, tag, asText );
|
||||||
|
|
||||||
|
// Parses the object and retrieves the table
|
||||||
|
eoserial::Object* obj = eoserial::Parser::parse( asText );
|
||||||
|
eoserial::Array* array = static_cast<eoserial::Array*>( (*obj)["array"] );
|
||||||
|
|
||||||
|
// Retrieves all the values from the array
|
||||||
|
for( int i = 0; i < size; ++i )
|
||||||
|
{
|
||||||
|
eoserial::unpackObject( *array, i, table[i] );
|
||||||
|
}
|
||||||
|
delete obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Other methods
|
||||||
|
*/
|
||||||
|
status probe( int src = any_source, int tag = any_tag );
|
||||||
|
|
||||||
|
void barrier();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _rank;
|
||||||
|
int _size;
|
||||||
|
|
||||||
|
char* _buf;
|
||||||
|
int _bufsize;
|
||||||
|
};
|
||||||
|
|
||||||
|
void broadcast( communicator & comm, int value, int root );
|
||||||
|
} // namespace mpi
|
||||||
|
|
||||||
|
# endif //__EO_MPI_HPP__
|
||||||
|
|
@ -1,283 +0,0 @@
|
||||||
# ifndef __EO_MPI_HPP__
|
|
||||||
# define __EO_MPI_HPP__
|
|
||||||
|
|
||||||
# include <mpi.h>
|
|
||||||
# include <serial/eoSerial.h>
|
|
||||||
|
|
||||||
# include <fstream>
|
|
||||||
|
|
||||||
namespace mpi
|
|
||||||
{
|
|
||||||
const int any_source = MPI_ANY_SOURCE;
|
|
||||||
const int any_tag = MPI_ANY_TAG;
|
|
||||||
|
|
||||||
class environment
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
environment(int argc, char**argv)
|
|
||||||
{
|
|
||||||
MPI_Init(&argc, &argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
~environment()
|
|
||||||
{
|
|
||||||
MPI_Finalize();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class status
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
status( const MPI_Status & s )
|
|
||||||
{
|
|
||||||
_source = s.MPI_SOURCE;
|
|
||||||
_tag = s.MPI_TAG;
|
|
||||||
_error = s.MPI_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tag() { return _tag; }
|
|
||||||
int error() { return _error; }
|
|
||||||
int source() { return _source; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
int _source;
|
|
||||||
int _tag;
|
|
||||||
int _error;
|
|
||||||
};
|
|
||||||
|
|
||||||
class communicator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
communicator( )
|
|
||||||
{
|
|
||||||
_rank = -1;
|
|
||||||
_size = -1;
|
|
||||||
|
|
||||||
_buf = 0;
|
|
||||||
_bufsize = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
~communicator()
|
|
||||||
{
|
|
||||||
if( _buf )
|
|
||||||
{
|
|
||||||
delete _buf;
|
|
||||||
_buf = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int rank()
|
|
||||||
{
|
|
||||||
if ( _rank == -1 )
|
|
||||||
{
|
|
||||||
MPI_Comm_rank( MPI_COMM_WORLD, &_rank );
|
|
||||||
}
|
|
||||||
return _rank;
|
|
||||||
}
|
|
||||||
|
|
||||||
int size()
|
|
||||||
{
|
|
||||||
if ( _size == -1 )
|
|
||||||
{
|
|
||||||
MPI_Comm_size( MPI_COMM_WORLD, &_size );
|
|
||||||
}
|
|
||||||
return _size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SEND / RECV INT
|
|
||||||
*/
|
|
||||||
void send( int dest, int tag, int n )
|
|
||||||
{
|
|
||||||
//send( dest, tag, &n, 1 );
|
|
||||||
MPI_Send( &n, 1, MPI_INT, dest, tag, MPI_COMM_WORLD );
|
|
||||||
}
|
|
||||||
|
|
||||||
void recv( int src, int tag, int& n )
|
|
||||||
{
|
|
||||||
MPI_Status stat;
|
|
||||||
MPI_Recv( &n, 1, MPI_INT, src, tag, MPI_COMM_WORLD , &stat );
|
|
||||||
//recv( src, tag, &n, 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void send( int dest, int tag, int* table, int size )
|
|
||||||
{
|
|
||||||
MPI_Send( table, size, MPI_INT, dest, tag, MPI_COMM_WORLD );
|
|
||||||
}
|
|
||||||
|
|
||||||
void recv( int src, int tag, int* table, int size )
|
|
||||||
{
|
|
||||||
MPI_Status stat;
|
|
||||||
MPI_Recv( table, size, MPI_INT, src, tag, MPI_COMM_WORLD , &stat );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SEND / RECV STRING
|
|
||||||
*/
|
|
||||||
void send( int dest, int tag, const std::string& str )
|
|
||||||
{
|
|
||||||
int size = str.size() + 1;
|
|
||||||
send( dest, tag, size );
|
|
||||||
MPI_Send( (char*)str.c_str(), size, MPI_CHAR, dest, tag, MPI_COMM_WORLD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void recv( int src, int tag, std::string& str )
|
|
||||||
{
|
|
||||||
int size = -1;
|
|
||||||
MPI_Status stat;
|
|
||||||
recv( src, tag, size );
|
|
||||||
|
|
||||||
if( _buf == 0 )
|
|
||||||
{
|
|
||||||
_buf = new char[ size ];
|
|
||||||
_bufsize = size;
|
|
||||||
} else if( _bufsize < size )
|
|
||||||
{
|
|
||||||
delete [] _buf;
|
|
||||||
_buf = new char[ size ];
|
|
||||||
_bufsize = size;
|
|
||||||
}
|
|
||||||
MPI_Recv( _buf, size, MPI_CHAR, src, tag, MPI_COMM_WORLD, &stat );
|
|
||||||
str.assign( _buf );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SEND / RECV Objects
|
|
||||||
*/
|
|
||||||
void send( int dest, int tag, const eoserial::Persistent & persistent )
|
|
||||||
{
|
|
||||||
eoserial::Object* obj = persistent.pack();
|
|
||||||
std::stringstream ss;
|
|
||||||
obj->print( ss );
|
|
||||||
delete obj;
|
|
||||||
send( dest, tag, ss.str() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void send( int dest, int tag, eoserial::Persistent* table, int size )
|
|
||||||
{
|
|
||||||
// Puts all the values into an array
|
|
||||||
eoserial::Array* array = new eoserial::Array;
|
|
||||||
|
|
||||||
std::cout << "DEBUG EO: @ premier: " << table << " / @ second: " << table+1 << std::endl;
|
|
||||||
|
|
||||||
for( int i = 0; i < size; ++i )
|
|
||||||
{
|
|
||||||
array->push_back( table[i].pack() );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encapsulates the array into an object
|
|
||||||
eoserial::Object* obj = new eoserial::Object;
|
|
||||||
obj->add( "array", array );
|
|
||||||
std::stringstream ss;
|
|
||||||
obj->print( ss );
|
|
||||||
delete obj;
|
|
||||||
|
|
||||||
// Sends the object as a string
|
|
||||||
send( dest, tag, ss.str() );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
template< class T >
|
|
||||||
void send( int dest, int tag, T* table, int size )
|
|
||||||
{
|
|
||||||
// Puts all the values into an array
|
|
||||||
eoserial::Array* array = new eoserial::Array;
|
|
||||||
|
|
||||||
for( int i = 0; i < size; ++i )
|
|
||||||
{
|
|
||||||
array->push_back( table[i].pack() );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encapsulates the array into an object
|
|
||||||
eoserial::Object* obj = new eoserial::Object;
|
|
||||||
obj->add( "array", array );
|
|
||||||
std::stringstream ss;
|
|
||||||
obj->print( ss );
|
|
||||||
delete obj;
|
|
||||||
|
|
||||||
// Sends the object as a string
|
|
||||||
send( dest, tag, ss.str() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void recv( int src, int tag, eoserial::Persistent & persistent )
|
|
||||||
{
|
|
||||||
std::string asText;
|
|
||||||
recv( src, tag, asText );
|
|
||||||
eoserial::Object* obj = eoserial::Parser::parse( asText );
|
|
||||||
persistent.unpack( obj );
|
|
||||||
delete obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void recv( int src, int tag, eoserial::Persistent* table, int size )
|
|
||||||
{
|
|
||||||
// Receives the string which contains the object
|
|
||||||
std::string asText;
|
|
||||||
recv( src, tag, asText );
|
|
||||||
|
|
||||||
// Parses the object and retrieves the table
|
|
||||||
eoserial::Object* obj = eoserial::Parser::parse( asText );
|
|
||||||
eoserial::Array* array = static_cast<eoserial::Array*>( (*obj)["array"] );
|
|
||||||
|
|
||||||
// Retrieves all the values from the array
|
|
||||||
for( int i = 0; i < size; ++i )
|
|
||||||
{
|
|
||||||
eoserial::unpackObject( *array, i, table[i] );
|
|
||||||
}
|
|
||||||
delete obj;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
template< class T >
|
|
||||||
void recv( int src, int tag, T* table, int size )
|
|
||||||
{
|
|
||||||
// Receives the string which contains the object
|
|
||||||
std::string asText;
|
|
||||||
recv( src, tag, asText );
|
|
||||||
|
|
||||||
// Parses the object and retrieves the table
|
|
||||||
eoserial::Object* obj = eoserial::Parser::parse( asText );
|
|
||||||
eoserial::Array* array = static_cast<eoserial::Array*>( (*obj)["array"] );
|
|
||||||
|
|
||||||
// Retrieves all the values from the array
|
|
||||||
for( int i = 0; i < size; ++i )
|
|
||||||
{
|
|
||||||
eoserial::unpackObject( *array, i, table[i] );
|
|
||||||
}
|
|
||||||
delete obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Other methods
|
|
||||||
*/
|
|
||||||
status probe( int src = any_source, int tag = any_tag )
|
|
||||||
{
|
|
||||||
MPI_Status stat;
|
|
||||||
MPI_Probe( src, tag, MPI_COMM_WORLD , &stat );
|
|
||||||
return status( stat );
|
|
||||||
}
|
|
||||||
|
|
||||||
void barrier()
|
|
||||||
{
|
|
||||||
MPI_Barrier( MPI_COMM_WORLD );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int _rank;
|
|
||||||
int _size;
|
|
||||||
|
|
||||||
char* _buf;
|
|
||||||
int _bufsize;
|
|
||||||
};
|
|
||||||
|
|
||||||
void broadcast( communicator & comm, int value, int root );
|
|
||||||
} // namespace mpi
|
|
||||||
|
|
||||||
# endif //__EO_MPI_HPP__
|
|
||||||
Reference in a new issue