1

I am trying to send a serialised struct from one rank to another. It results in

Segmentation fault: 11

and I have no clue from where it comes.

I have tried to locate the problem by printing out some values and the code always breaks between MPI_Send and MPI_Recv, but since it is segmentation fault one cannot be sure that it is the origin of the problem. Please do enlighten me.

int N = 11;
struct tests{
    int number;
    double *fx;
};

void locateMemoryTests(struct tests *t){
    t->fx = (double*) malloc(N*sizeof(double));
}

void he(struct tests *t, int N){
    int NRank, MyRank;
    MPI_Comm_rank( MPI_COMM_WORLD, &MyRank );
    MPI_Comm_size( MPI_COMM_WORLD, &NRank );
    int st = MyRank * int(N/2);
    int en = (MyRank+1) * int(N/2) + (N%2)*MyRank;

    for (int i=st; i<en; i++){
        t->fx[i] = i*i + 5*(i + t->number);
    }
    const int nitems        = 2;
    int blocklengths[2]     = {1, N};
    MPI_Datatype types[2]   = {MPI_INT, MPI_DOUBLE};
    MPI_Datatype mpi_tests_type;
    MPI_Aint offsets[2];

    offsets[0] = offsetof(tests, number);
    offsets[1] = offsetof(tests, fx);

    MPI_Type_create_struct(nitems, blocklengths, offsets, types, &mpi_tests_type);
    MPI_Type_commit(&mpi_tests_type);
    MPI_Comm_rank(MPI_COMM_WORLD, &MyRank);

    if (MyRank == 0){
        struct tests send;
        send.number = t->number;
        locateMemoryTests(&send);

        for (int i=0; i<N; i++){
            send.fx[i] = t->fx[i];
        }   

        MPI_Send(&send, 2, mpi_tests_type, 1, 111, MPI_COMM_WORLD);
        }
    else if (MyRank == 1){
        MPI_Status status;
        struct tests recv;
        locateMemoryTests(&recv);
        MPI_Recv(&recv, 2, mpi_tests_type, 0, 111, MPI_COMM_WORLD, &status);

    MPI_Type_free(&mpi_tests_type);
}


int main( int argc, char *argv[] ){
    int NRank, MyRank;
    MPI_Init( &argc, &argv );
    MPI_Comm_rank( MPI_COMM_WORLD, &MyRank );
    MPI_Comm_size( MPI_COMM_WORLD, &NRank );

    struct tests tt;
    tt.number = 5;
    locateMemoryTests(&tt);

    he(&tt,N);

    MPI_Finalize();
    return 0;
}
12
  • 1
    MPI_Recv receives two elements, but recv variable can only hold only one? Commented Jun 8, 2019 at 15:51
  • Isn't it the purpose of serialisation, to send/receive a struct with multiple elements? Or do you mean I can only send one type of element? I learnt that "int count" in this case should be the number of the kinds of data my structure has from stackoverflow.com/questions/18165277/… Commented Jun 8, 2019 at 16:15
  • I mean you want two elements, but prepared storage only for one. Commented Jun 8, 2019 at 16:17
  • Could you please elaborate a bit? I am new to C++ and I am not quite sure why I have prepared storage only for one instead of two. Commented Jun 8, 2019 at 16:38
  • Try struct tests recv[2]; and struct tests send[2]; and see if it makes any difference. Commented Jun 8, 2019 at 16:56

1 Answer 1

1

Your MPI derived datatype describes the following C struct

struct tests{
    int number;
    double fx[N];
};

but you are using a different one

struct tests{
    int number;
    double *fx;
};

if N is not a constant, you can either declare

struct tests{
    int number;
    double fx[];
};

and it is up to you to correctly allocate such a struct.

An other option is to keep the same struct definition, and manually MPI_Pack() and MPI_Unpack() the data to/from a temporary buffer.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.