1. 程式人生 > >MPI 每個rank依次往下一個rank傳送訊息的迴圈

MPI 每個rank依次往下一個rank傳送訊息的迴圈

https://www.sharcnet.ca/help/index.php/Getting_Started_with_MPI

 #include <stdio.h>
 #include <mpi.h>
 
 #define BUFMAX 81
 
 int main(int argc, char *argv[])
 {
     char outbuf[BUFMAX], inbuf[BUFMAX];
     int rank, size;
     int sendto, recvfrom;
     MPI_Status status;
 
 
     MPI_Init(&argc, &argv);
     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
     MPI_Comm_size(MPI_COMM_WORLD, &size);
 
     sprintf(outbuf, "Hello, world! from process %d of %d", rank, size);
 
     sendto = (rank + 1) % size;
     recvfrom = ((rank + size) - 1) % size;
 
     MPI_Send(outbuf, BUFMAX, MPI_CHAR, sendto, 0, MPI_COMM_WORLD);
     MPI_Recv(inbuf, BUFMAX, MPI_CHAR, recvfrom, 0, MPI_COMM_WORLD, &status);
 
     printf("[P_%d] process %d said: \"%s\"]\n", rank, recvfrom, inbuf);
 
     MPI_Finalize();
 
     return(0);
 }
上面的實現之所有沒有死鎖是依賴於資料傳輸的中間buffer,也就是寫的時候直接寫到buffer,不需要等到接收端的迴應,程式碼是可以正確執行的,但是他的實現是並不是完全依賴MPI的標準,下面給出一個MPI 安全的例子
#include <stdio.h>
#include <mpi.h>
 
#define BUFMAX 81
 
int main(int argc, char *argv[])
{
    char outbuf[BUFMAX], inbuf[BUFMAX];
    int rank, size;
    int sendto, recvfrom;
    MPI_Status status;
 
 
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
 
    sprintf(outbuf, "Hello, world! from process %d of %d", rank, size);
 
    sendto = (rank + 1) % size;
    recvfrom = ((rank + size) - 1) % size;
 
    if (!(rank % 2))
    {
        MPI_Send(outbuf, BUFMAX, MPI_CHAR, sendto, 0, MPI_COMM_WORLD);
        MPI_Recv(inbuf, BUFMAX, MPI_CHAR, recvfrom, 0, MPI_COMM_WORLD, &status);
    }
    else
    {
        MPI_Recv(inbuf, BUFMAX, MPI_CHAR, recvfrom, 0, MPI_COMM_WORLD, &status);
        MPI_Send(outbuf, BUFMAX, MPI_CHAR, sendto, 0, MPI_COMM_WORLD);
    }
 
    printf("[P_%d] process %d said: \"%s\"]\n", rank, recvfrom, inbuf);
 
    MPI_Finalize();
 
    return(0);
}


這個例子和上面的最大的不同就是根據rank分成兩組,這兩組的接收和傳送的順序是剛好相反的,這樣如果沒有buffer,一樣可以正確的得到結果,因此是安全的。