2017-07-19 77 views
0

我有一個數據需要廣播給工作人員。 但是我不能接收它,即使我使用MPI_Wait而不是MPI_Test,除非我使用阻塞MPI_Bcast。MPI_Ibcast + MPI_Test無法接收數據

我不知道發生了什麼,我嘗試了很多方法,但都沒有工作。

在我的代碼中是否有任何錯誤?

#include <stdio.h> 
#include <unistd.h> 
#include <mpi.h> 

int main() 
{ 
    int rank, size; 
    int data; 

    MPI_Init(NULL, NULL); 

    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 

    printf("MPI start %d/%d\n", rank, size); 

    if (rank == 0) 
    { 
     sleep(1); 
     data = 1; 
     printf("MPI %d/%d bcast\n", rank, size); 
     MPI_Bcast(&data, 1, MPI_INT, 0, MPI_COMM_WORLD); 
    } 
    else 
    { 
     int flag = 0; 
     MPI_Request req = MPI_REQUEST_NULL; 
     MPI_Status status; 
     MPI_Ibcast(&data, 1, MPI_INT, 0, MPI_COMM_WORLD, &req); 
     while (flag == 0) { 
      MPI_Test(&req, &flag, &status); 
      usleep(100 * 1000); 
     } 
     // MPI_Bcast can be done! 
     //MPI_Bcast(&data, 1, MPI_INT, 0, MPI_COMM_WORLD); 
     printf("MPI %d/%d recv bcast data: %d\n", rank, size, data); 
    } 
    MPI_Barrier(MPI_COMM_WORLD); 

    MPI_Finalize(); 
    return 0; 
} 

它將掛斷這裏:

MPI start 0/5 
MPI start 1/5 
MPI start 2/5 
MPI start 3/5 
MPI start 4/5 
MPI 0/5 bcast 
+0

只是一個小小的rem ark:不要在'MPI_Test'上循環,除非你a)在循環中做了有用的工作,或者b)你希望線程休眠,並且你的MPI實現不能正確支持。否則使用'MPI_Wait'。 – Zulan

+0

是的,我只是用它來代表一些其他的代碼,謝謝你的建議。 – teng

+0

順便說一句,有沒有什麼辦法像'select'一樣將'pthread_cond_wait'和'MPI_Wait'結合起來?我在工作線程中有一個循環,我需要等待來自'pthread_cond_signal'和'MPI_Send'的通知。 – teng

回答

2

吉爾斯是絕對正確的,MPI明確指出

不同點至點操作,非阻塞集體操作不匹配阻止集體行動 [...]

雖然有一個非常簡單的修復方法,只需將MPI_Bcast替換爲:

MPI_Request req; 
MPI_Status status; 
MPI_Ibcast(&data, 1, MPI_INT, 0, MPI_COMM_WORLD, &req); 
MPI_Wait(&req, &status); 
+0

謝謝!有用! – teng

+0

順便說一句,有沒有什麼辦法來模擬MPI_Ibcast的舊版MPI沒有實現MPI 3.0? – teng

+0

看看https://htor.inf.ethz.ch/research/nbcoll/libnbc/ – Zulan

2

恐怕秩0和MPI_Ibcast()對其他隊伍不能簡單地混合MPI_Bcast()

+0

是的,你說得對,我只是覺得它們簡單。 – teng