2012-04-02 92 views
8

(初學者問題)我試圖用MPI_Comm_Spawn動態生成進程,然後向子進程廣播一條消息,但程序停止在從根進程到廣播這些孩子。我正在關注來自http://www.mpi-forum.org/docs/docs.html的文檔,但我無法使其工作。有人可以幫我嗎?MPI Spawn:根進程不與子進程通信

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

int main(int argc, char *argv[]) 
{ 
    MPI_Init(&argc, &argv); 
    MPI_Comm parentcomm; 

    MPI_Comm_get_parent(&parentcomm); 

    if (parentcomm == MPI_COMM_NULL) { 
     MPI_Comm intercomm; 
     MPI_Status status; 
     char msg_rec[1024]; 
     char msg_send[1024]; 
     int size, i; 

     int np = (argc > 0) ? atoi(argv[1]) : 3; 

     printf("Spawner will spawn %d processes\n", np); 
     MPI_Comm_spawn(argv[0], MPI_ARGV_NULL, np, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercomm, MPI_ERRCODES_IGNORE); 
     MPI_Comm_size(intercomm, &size); 

     sprintf(msg_send, "Hello!"); 
     printf("Spawner will broadcast '%s'\n", msg_send); 
     MPI_Bcast((void*)msg_send, 1024, MPI_CHAR, 0, intercomm); 

     printf("Spawner will receive answers\n"); 
     for (i=0; i < size; i++) { 
      MPI_Recv((void*)msg_rec, 1024, MPI_CHAR, i, MPI_ANY_TAG, intercomm, &status); 
      printf("Spawner received '%s' from rank %d\n", msg_rec, i); 
     };  

    } else { 
     int rank, size; 
     char msg_rec[1024]; 
     char msg_send[1024]; 

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

     printf(" Rank %d ready\n", rank); 

     MPI_Bcast((void*)msg_rec, 1024, MPI_CHAR, 0, parentcomm); 

     printf(" Rank %d received '%s' from broadcast!\n", rank, msg_rec); 
     sprintf(msg_send, "Hi there from rank %d!\n", rank); 
     MPI_Send((void*)msg_send, 1024, MPI_CHAR, 0, rank, parentcomm); 
    }; 
    MPI_Finalize(); 
    return 0; 
}; 

我不知道它是否重要,但我使用的是Ubuntu 11.10和Hidra Process Manager。

回答

-1

集體通信電話如Bcast()需要一個intracommunicator:你正在嘗試使用互通器(intercommparentcomm)。您必須使用組創建方法來定義包含父進程和所有子進程的組,然後在該組中創建一個新的intracommunicator。

+0

這並不準確,因爲@ bfroehle指出。您可以與對講機進行集體呼叫。你只需要小心並閱讀單獨的規範。 – 2013-08-21 13:16:47

3

正如@suszterpatt指出的,你正在使用「Intercommunicator」(而不是「Intracommunicator」)。知道了這一點,看着MPI_Bcast,我們看到:

如果通訊是一個intercommunicator,則調用涉及到intercommunicator所有進程,但有一個組(A組),其定義根進程。另一組(組B)中的所有進程都在參數根中傳遞相同的值,這是根組A中的根的等級。根以root身份傳遞值MPI_ROOT。組A中的所有其他進程都以root身份傳遞值MPI_PROC_NULL。數據從根節點向組B中的所有進程廣播。組B中進程的接收緩衝區參數必須與根的發送緩衝區參數一致。

這意味着你只需要與家長代替廣播呼叫:

MPI_Bcast((void*)msg_send, 1024, MPI_CHAR, MPI_ROOT, intercomm); 

其他一些錯誤:

  • 支票上的參數的數目應該是argc > 1
  • MPI_Comm_size(intercomm, &size)將返回1。您需要改用MPI_Comm_remote_size(intercomm, &size)
2

如果您在產生子流程後不想處理intercommunicator,則可以使用MPI_Intercomm_merge從您的intercommunicator創建intracommunicator。從本質上講,它應該是這樣的:

產卵:

MPI_Comm_spawn(argv[0], MPI_ARGV_NULL, np, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercomm, MPI_ERRCODES_IGNORE); 
MPI_Intercomm_merge(intercomm, 0, &intracomm); 

Spawnee:

MPI_Intercomm_merge(parentcomm, 1, &intracomm); 

之後,你可以繼續使用intracomm(或任何你想將它命名),就好像它是一個普通的intracommunicator。在這種情況下,產卵過程將具有較低的等級,新的過程將具有較高的等級,但您可以使用第二個參數對其進行修改。

+0

這項工作到底如何?我剛剛發佈了一個相關的[問題](http:// stackoverflow。com/questions/20755060/can-a-spawned-process-communicate-with-the-main-mpi-communicator),這個合併聲明可能會起作用,但我對「inter」,「intra」不同部分感到困惑碼。 – user989762 2013-12-24 05:05:18