Boost logo

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