2

I tried to send the second and third column of a matrix from the processes with rank one and two with MPI to the process with rank zero.

On the internet I found this example http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-1.1/node70.htm#Figure4 and wrote a code:

#include <iostream>
#include <mpi.h>

using namespace std;

int main(int argc, char *argv[]) {
    int id;
    int matrix[3][3];
    int matrixB[9];

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &id);

    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
            if(id == 0)
                matrix[i][j] = 0;
            else
                matrix[i][j] = j+1;

    MPI_Datatype matrixSpalte;

    MPI_Type_vector(3, 1, 3, MPI_INT, &matrixSpalte);
    MPI_Type_commit(&matrixSpalte);

    MPI_Gather(&matrix[0][id], 1, matrixSpalte, &matrixB[0], 1, matrixSpalte, 0, MPI_COMM_WORLD);

    if(id == 0)
        for(int i=0; i<9; i++) {
            if(i % 3 == 0)          
                cout << endl;

            cout << matrixB[i] << " (" << i << ") ";

        }


    MPI_Finalize();
    return 0;
}

but the output is:

0 (0) 0 (1) 1351992736 (2)
0 (3) 254423040 (4) 1 (5)
0 (6) 2 (7) 1351992752 (8)

It should be:

1 (0) 2 (1) 3 (2)
1 (3) 2 (4) 3 (5)
1 (6) 2 (7) 3 (8)

and I have not idea why this isn't working. I hope someone can help me to find the mistake in my code.

Your sincerely,

Heinz

Solution (thx to Jonathan Dursi):

#include <iostream>
#include <mpi.h>

using namespace std;

int main(int argc, char *argv[]) {
    int id;
    int matrix[3][3];
    int matrixB[9];

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &id);

    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
            if(id == 0)
                matrix[i][j] = 0;
            else
                matrix[i][j] = j+1;

    MPI_Datatype matrixSpalte, tmp;

    MPI_Type_vector(3, 1, 3, MPI_INT, &tmp);
    MPI_Type_create_resized(tmp, 0, sizeof(int), &matrixSpalte);  // !!!
    MPI_Type_commit(&matrixSpalte);

    MPI_Gather(&matrix[0][id], 1, matrixSpalte, matrixB, 1, matrixSpalte, 0, MPI_COMM_WORLD);

    if(id == 0)
        for(int i=0; i<9; i++) {
            if(i % 3 == 0)          
                cout << endl;

            cout << matrixB[i] << " (" << i << ") ";

        }


    MPI_Finalize();
    return 0;
}
  • You need to resize the vector type to use it in a gather like this - eg, `MPI_Type_vector(3, 1, 3, MPI_INT, &tmp); MPI_Type_create_resized(tmp, 0, sizeof(int), &matrixSpalte); MPI_Type_commit(&matrixSpalte);`. For an explanation of why, see [this answer](http://stackoverflow.com/questions/9269399/sending-blocks-of-2d-array-in-c-using-mpi/9271753#9271753). – Jonathan Dursi Jan 20 '15 at 21:03
  • 1
    If you do actually have the solution, you should answer your own question and mark it accordingly instead of putting the answer in the question. – Wesley Bland Jan 20 '15 at 21:26

1 Answers1

-1

MPI_Gather should be passed a buffer that can store all the elements in a contiguous array. Take a look at the picture here

That is rbuf must point to an array of 9 ints. This is why you are getting the Abort trap: 6 error as explained here. You are trying to write in matrix[0][3] through matrix[0][8]

Also, your recv_type must be MPI_INT.

Community
  • 1
  • 1
dmg
  • 7,438
  • 2
  • 24
  • 33
  • Thank you. I changed the receive datatype to an one dimensional array. But this sadly did not solved the whole problem. (I wrote the new output and source code in the initial post) – Heinz Mustermann Jan 20 '15 at 18:57
  • Yeah, forgot one more thing. Updated my answer. – dmg Jan 21 '15 at 07:59