1
votes

I am trying to run a matrix multiplication program using MPI. The arrays 'a' and 'b' are of type double and size 512*512. The array 'a' is to be scattered and array 'b' is to be broadcast. The final result after matrix multiplication is to be gathered in master process in array c[512][512] I am trying to implement MPI_Scatter() using MPI_Send() and MPI_Recv() functions but I am kind of stuck in an infinite loop (probably). P is the number of processes.

double a[512][512], b[512][512], c[512][512];
blksz = 512/P;
if(rank == 0) {
    // Scatter input matrix a, implementation of MPI_Scatter()
    for(j = 1 ; j < P ; j++ ) {
        MPI_Send(&a + j*blksz*N*sizeof(double), blksz*N, MPI_DOUBLE, j, 0, MPI_COMM_WORLD);
    }

    // Broadcast the input matrix b, implementation of MPI_Bcast()
    for(j = 1 ; j < P ; j++ ) {
        MPI_Send(&b, N*N, MPI_DOUBLE, j, 1, MPI_COMM_WORLD);
    }
}
else {
    MPI_Recv(&a, blksz*N, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &status);
    MPI_Recv(&b, N*N, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD, &status);
}

for(i = 0 ; i < blksz; i++) {
    for(j = 0 ; j < N ; j++) {
        c[i][j] = 0;
        for(k = 0 ; k < N ; k++) {
            c[i][j] += a[i][k] * b[k][j];
        }
    }
}

// Gather result, implementation of MPI_Gather()
if(rank != 0) {
    MPI_Send(&c, blksz*N, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD);
}
else {
    for(i = 1 ; i < P ; i++) {
        MPI_Recv(&c+i*blksz*N*sizeof(double), blksz*N, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD, &status);
    }
}

I am a kind of a beginner to programming but I was up all night trying to figure it out but to no avail. I would really appreciate if someone could help me out here.

1

1 Answers

0
votes

When you send &a + j*blksize*N*sizeof(double), you are not doing what you want to do. First off, &a is the address of a, which is an array of arrays, which is not what you want to send, you want to send a pointer, or *a (technically this is an array, but it will be implicitly cast to a pointer to the first element of said array). Next, when doing pointer arithmetic, you do not need to (and in fact, should not) multiply by sizeof(type); that will be taken care of for you by the compiler. So your first MPI_Send command should be

MPI_Send(*a + j*blksz*N, blksz*N, MPI_DOUBLE, j, 0, MPI_COMM_WORLD);

Make similar changes (for all sends and receives) and your code should work.