|
Boost Users : |
Subject: [Boost-users] [mpi] - why this code hangs on gather?
From: tomasz jankowski (tomasz_jacek_at_[hidden])
Date: 2009-10-27 08:39:38
hello boost users
please look (if you find few minutes) code bellow
first i'm declaring molecule class (with needed serialization)
in main() first I'm building vector of data (which are molecules)
then vector is divided to chunks and send in point to point nonblocking
communication model to rest of mpi processes.
after that some calculation on molecules are done.
at the end I want gather all data but the program hangs on gather in
proces with rank 0
does anyone has idea what is wrong in this code?
tom
#include <vector>
#include <algorithm>
#include <boost/mpi.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <cstdlib>
#include <string>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/format.hpp>
namespace mpi = boost::mpi;
class molecule
{
friend std::ostream & operator<<(std::ostream &os, const molecule &prot);
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int){
ar & x_ & y_ & z_ & number_ & message_;
}
public:
// constructor
molecule(){x_=0; y_=0; z_=0; number_= 0; message_ = "";};
molecule(double x, double y, double z, unsigned int n, std::string m) :
x_(x), y_(y), z_(z), number_(n), message_(m)
{}
void print(){
std::cout << (boost::format("%.6f") % x_) << " | "<<
(boost::format("%.6f") % y_) << " | " << (boost::format("%.6f") % z_) <<
" | " << number_ << "\t| " << message_ << std::endl;
}
double x_;
double y_;
double z_;
unsigned int number_;
std::string message_;
};
int main(int argc, char* argv[])
{
//generator
boost::minstd_rand generator_real(42u);
//distribution
boost::uniform_real<> uni_dist_real(0,1);
//functor
boost::variate_generator<boost::minstd_rand, boost::uniform_real<> >
uni_real(generator_real, uni_dist_real);
mpi::environment env(argc, argv);
mpi::communicator world;
// data construction
std::vector<molecule> data;
if (world.rank() == 0) {
for(unsigned int i=0;i<8020;++i){
std::string txt("see you later aligator");
molecule tmp(1,1,1,i,txt);
data.push_back(tmp);
}
}
//broadcast(world,data,0);
//we could do it by broadcast (line above) - but lets do it by point to
point with only amount of data we need
//work vectors
std::vector<molecule> res;
std::vector<std::vector<molecule> > allRes;
// we need to divide our data between processes
unsigned int nProcs=world.size();
unsigned int chunkSize=data.size() / nProcs;
unsigned int extraBits=data.size() % nProcs;
// extra bits we will do in root process
if( world.rank() == 0 ){
mpi::request reqs[nProcs-1];
for(unsigned int i=1;i<nProcs;++i){
std::vector<molecule> sendmol;
unsigned int pos=extraBits+i*chunkSize;
for(unsigned int j=0;j<chunkSize;++j){
sendmol.push_back(data[pos]);
pos++;
}
reqs[i-1] = world.isend(i, 0, sendmol);
std::cout<<"msg sended to "<< i <<std::endl;std::cout.flush();
}
for(unsigned int i=0;i<chunkSize + extraBits;++i){
molecule tmp = data[i];
tmp.x_ *= uni_real();
tmp.y_ *= uni_real();
tmp.z_ *= uni_real();
tmp.message_ = "from process: " +
boost::lexical_cast<std::string>(world.rank());
res.push_back(tmp);
}
mpi::wait_all(reqs, reqs + nProcs - 1);
std::cout<<"calculation finished in 0 "<<std::endl;std::cout.flush();
}
std::vector<molecule> recvmol;
mpi::request recv;
recv = world.irecv(0, 0, recvmol);
recv.wait();
std::cout<<"receiving finished
"<<world.rank()<<std::endl;std::cout.flush();
for(unsigned int i=0;i<recvmol.size();++i){
molecule tmp = recvmol[i];
tmp.x_ *= uni_real();
tmp.y_ *= uni_real();
tmp.z_ *= uni_real();
tmp.print();
tmp.message_ = "from process: " +
boost::lexical_cast<std::string>(world.rank());
res.push_back(tmp);
}
std::cout<<"calculation finished in
"<<world.rank()<<std::endl;std::cout.flush();
//wysylanie wynikow ze wszystkich procesow mpi do procesu 0
if( world.rank() == 0 ){
gather(world,res,allRes,0);
std::cout<<"gather finished "<<world.rank()<<std::endl;std::cout.flush();
} else {
gather(world,res,0);
std::cout<<"gather finished"<<world.rank()<<std::endl;std::cout.flush();
}
// output
if(world.rank()==0){
for(unsigned int i=0;i<static_cast<unsigned int>(world.size());++i){
std::cout<<"results from process "<<i<<": "<<std::endl;
for(int k=0; k<allRes[i].size();k++){
allRes[i][k].print();
}
std::cout<<std::endl;
}
std::cout<<"making output finished
"<<world.rank()<<std::endl;std::cout.flush();
}
return 0;
}
----------------------------------------------------
Kabaret £owcy.B atakuje!
Wygraj p³ytê DVD.
We¼ udzia³ w konkursie:
http://klik.wp.pl/?adr=http%3A%2F%2Fcorto.www.wp.pl%2Fas%2Fkonkurs_lowcy.html&sid=895
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net