[mpich-discuss] Problems with MPI and virtual functions in C++
Hélvio Vairinhos
helvio.vairinhos at gmail.com
Wed Dec 12 13:23:12 CST 2012
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
More information about the discuss
mailing list