0
votes

Im currently trying to implement a matrix-matrix multiplication using C. I have the following code

for(index=0; index<p; index++) 
    {
        /* calculate the partial sum for matC given the row band of A and
         B */
        for (i=0; i<n/p; i++) 
            for (j=0; j<n; j++) 
                for (k=0; k<n; k++) 
                    storage_matC[i*n+j] += storage_matA[i*n+k]*storage_matB[k*n+j];

        if(index < p-1) 
        {
            /* mpi send storage_matB to the next process (id+1)%p */
            MPI_Send(storage_matB, n, MPI_FLOAT, (id+1)%p, 0, MPI_COMM_WORLD); 
            /* mpi receive storage_matB from the previous process */
            MPI_Recv(&storage_matB, n, MPI_FLOAT, id, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        }
    }

I need to be able to send the matrix_b used in the current process, and then receive it in the current process from the previous process. My program just hangs there and i have to terminate it. Can someone shed me some light on how to approach this problem...

Thank you so much for your time, your help is greatly appreciate it!

1

1 Answers

1
votes

From MPI_Send docs:

This routine may block until the message is received by the destination process.

and this is what is tripping you up. Everyone is trying to send, but no-one is listening since everyone is trying to send, so everyone keeps waiting for someone to shut up and listen, but no-one ever does, and everyone is wondering what the hell everyone else is doing. :P

One method I can see for this is to stagger the communication. For example, assuming an even number of slices, first all the even processes send while all the odd processes listen; then the odd processes send, and the even processes listen.

EDIT: "How can I do that?" Pretty much as I have explained. Instead of your "send then recv", do something like this:

odd_ring = p % 2

// first trip: evens send, odds receive
if (id % 2) recv();
else if (!odd_ring || id != p - 1) send();

// second trip: odds send, evens receive
if (id % 2) send();
else if (!odd_ring || id) recv();

// only when we have odd number of processes -
// collecting stragglers: last sends to first
if (odd_ring)
  if (id == p - 1) send();
  else if (!id) recv();

Haven't tested, so there might be bugs, but in essence that's how I'd implement it.