Problems with MPI and virtual functions in C++
Hi, I came across a strange behaviour of MPI when I try to do a simple send/receive of an object of a class which contains virtual functions. I wrote a short code to exemplify what happens: #include <mpi.h> #include <iostream> using namespace std; class Pair { double elem[2]; public: Pair(); Pair(const double&, const double&); //virtual Pair& operator += (const Pair&); void print(); static MPI_Datatype mpi_type; static void Init(); static void Finalize(); }; Pair::Pair() { elem[0]=0.; elem[1]=0.; } Pair::Pair(const double& x, const double& y) { elem[0]=x; elem[1]=y; } Pair& Pair::operator += (const Pair& q) { elem[0] += q.elem[0]; elem[1] += q.elem[1]; return *this; } void Pair::print() { std::cout << "(" << elem[0] << "," << elem[1] << ")" << std::endl; } MPI_Datatype Pair::mpi_type; void Pair::Init() { MPI_Type_contiguous(2,MPI_DOUBLE,&mpi_type); MPI_Type_commit(&mpi_type); } void Pair::Finalize() { MPI_Type_free(&mpi_type); } int main() { int rank; MPI_Init(0,0); MPI_Comm_rank(MPI_COMM_WORLD,&rank); Pair::Init(); Pair q; if (rank == 0) { q = Pair(1,2); MPI_Send(&q, 1, Pair::mpi_type, 1, 99, MPI_COMM_WORLD); } if (rank == 1) { q = Pair(3,4); MPI_Status status; MPI_Recv(&q, 1, Pair::mpi_type, 0, 99, MPI_COMM_WORLD, &status); q.print(); } Pair::Finalize(); MPI_Finalize(); return 0; } I compiled it with mpic++, and ran it on 2 processes. Process 0 simply sends the pair q=(1,2) to process 1, which prints the result on the screen. The MPI datatype is contiguous with 2 MPI_DOUBLE components. The program above behaves just fine, and prints the correct result (1,2). However, if I make the operator += virtual within the Pair class (i.e. if I uncomment the corresponding line above), then the process 1 prints the result (1,4). In other words, process 0 only sends the 1st element of the pair. The 2nd element of the pair is only sent if I create an MPI datatype with 3 MPI_DOUBLE elements, i.e. if I use MPI_Type_contiguous(3,MPI_DOUBLE,&mpi_type). It behaves as if the buffer of MPI_Send starts at the address "&q-1" instead of "&q" when the virtual keyword is present. Does anyone know why this happens, or if I am being careless at some point? I need to virtualize some functions in classes like this one, and I would like to trust that MPI communication is being done correctly. Thank you in advance, Helvio Vairinhos
participants (1)
-
Hélvio Vairinhos