void approximatePI(
const gsMpi & mpi,
const gsMpiComm & comm);
void computeDotProduct(
const gsMpi & mpi,
const gsMpiComm & comm);
void locateDot(
const gsMatrix<> & loc, real_t & count);
int main(int argc, char **argv)
{
gsCmdLine cmd(
"An example for testing MPI with G+Smo.\n"
"Execute (eg. with 10 processes): "
" * mpirun -np 10 ./bin/mpi_example\n"
"or provide a hosts file on a cluster: "
" * mpirun -hostfile hosts.txt ./bin/mpi_example\n"
"If your cluster is using srun: "
" * srun -N 10 ./bin/mpi_example"
);
try { cmd.getValues(argc,argv); } catch (int rv) { return rv; }
#ifdef GISMO_WITH_MPI
gsInfo <<
"Gismo was compiled with MPI support.\n";
#else
gsInfo <<
"Gismo was compiled without MPI support.\n";
#endif
const gsMpi & mpi = gsMpi::init(argc, argv);
double wtime = mpi.wallTime();
if (0==_rank)
gsInfo<<
"Running on "<<_size<<
" processes.\n";
gsInfo <<
"MPI is "<< (mpi.initialized() ?
"" :
"NOT ")
<<"initialized on process "<< _rank <<"\n";
std::string cpuname = mpi.getProcessorName();
gsInfo <<
"Hello G+Smo, from process " << _rank <<
" on "
<< cpuname <<", elapsed time is "<< mpi.wallTime()-wtime<< "\n";
approximatePI(mpi, comm);
computeDotProduct(mpi, comm);
gsInfo <<
"Good bye G+Smo, from process " << _rank <<
" on "
<< cpuname << "\n";
return 0;
}
void approximatePI(
const gsMpi & mpi,
const gsMpiComm & comm)
{
const int N = 10000;
real_t count = 0;
double wtime = mpi.wallTime();
if(_rank == 0)
{
std::srand((unsigned)wtime);
gsInfo<<
"I am the master process of "<<_size<<
" processes.\n";
gsInfo <<
"I will finally compute an approximation of PI! " <<
"\n";
{
for (
index_t i = 0; i < coord.rows(); i++)
{
coord(i, 0) = (real_t)(rand()) / (real_t)RAND_MAX;
coord(i, 1) = (real_t)(rand()) / (real_t)RAND_MAX;
}
if(p > 0)
comm.
send(coord.data(), coord.size(), p, 0);
else
locateDot(coord, count);
}
}
else
{
comm.
recv(coord.data(), coord.size(), 0, 0);
locateDot(coord, count);
}
comm.
gather(&count, result.data(), 1, 0);
if(_rank == 0)
{
count += result(i);
gsInfo <<
"PI is approximately: " << (4. * count) / (N * _size) <<
"\n";
gsInfo <<
"Time needed for parallel computation: " << mpi.wallTime() - wtime <<
"\n";
}
}
void computeDotProduct(
const gsMpi & mpi,
const gsMpiComm & comm)
{
const int N = 1000000;
real_t res = 0;
if(N % _size != 0)
{
gsInfo <<
"Assume that the vectors can be split equivalently \n";
gsInfo << N <<
" is not divisible by " << _size <<
"\n";
gsInfo <<
"Dot product will not be computed! \n";
return;
}
double wtime = mpi.wallTime();
if (_rank == 0)
{
gsInfo <<
"I am the master process of " << _size <<
" processes.\n";
gsInfo <<
"I will finally compute the dot product of two vectors consisting of ones! " <<
"\n";
for (
index_t p = 0; p < _size; p++)
{
for (
index_t i = 0; i < loc.rows(); i++)
{
loc(i, 0) = colVecs(loc.rows() * p + i, 0);
loc(i, 1) = colVecs(loc.rows() * p + i, 1);
}
if (p > 0)
comm.
send(loc.data(), loc.size(), p, 0);
else
res = loc.col(0).dot(loc.col(1));
}
}
else
{
comm.
recv(loc.data(), loc.size(), 0, 0);
res = loc.col(0).dot(loc.col(1));
}
comm.
gather(&res, result.data(), 1, 0);
if (_rank == 0)
{
for (
index_t i = 1; i < _size; i++)
res += result(i);
gsInfo <<
"The result is: " << res <<
"\n";
gsInfo <<
"Time needed for parallel computation: " << mpi.wallTime() - wtime <<
"\n";
}
}
void locateDot(
const gsMatrix<> & loc, real_t & count)
{
count = 0;
for(
index_t row = 0; row < loc.rows(); row++)
{
const real_t pos = loc.row(row).squaredNorm();
if(pos <= 1.)
count += 1;
}
}
Class for command-line argument parsing.
Definition gsCmdLine.h:57
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
A serial communication class.
Definition gsMpiComm.h:289
static int recv(T *, int, int, int=0, const void *=NULL)
Receives data from a source process with a defined tag (blocking)
Definition gsMpiComm.h:503
int rank() const
return rank of process, i.e. zero
Definition gsMpiComm.h:297
static int send(T *, int, int, int=0)
Sends data to a destination process with a defined tag (blocking)
Definition gsMpiComm.h:472
static int barrier()
Wait until all processes have arrived at this point in the program.
Definition gsMpiComm.h:430
static int size()
return rank of process, i.e. one
Definition gsMpiComm.h:302
static int gather(T *in, T *out, int len, int)
Gather arrays on root task.
Definition gsMpiComm.h:546
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
Main header to be included by clients using the G+Smo library.
#define index_t
Definition gsConfig.h:32
#define gsInfo
Definition gsDebug.h:43
The G+Smo namespace, containing all definitions for the library.