简体   繁体   中英

MPI matrix-matrix multiplication

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!

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM