2012-09-15 50 views
3

我已創建使用結構MPI_Comm_split()一個溝通,然後我想嘗試一些發送/接收都在MPI_COMM_WORLD水平,並在新的傳播者層次的溝通。創建兩個傳播者(一個偶數進程,另一個進入奇數階段)。如何確定是否MPI進程屬於給定通訊

注:我需要嘗試只內包含偶數過程行列(雖然進程的排名是不是原來的一個新的溝通交流,我仍然關心的是什麼這些過程都在他們的記憶空間)

我的代碼如下,

#include<stdio.h> 
    #include "mpi.h" 
    int main(int arg, char **argv){ 
    int rank,newrank,newrank2; 
    int size, newSize,newSize2; 
    int data; 
    int recv; 
    MPI_Comm newComm, newComm2; 
    MPI_Status status, newStatus; 
    MPI_Init(&arg,&argv); 

    MPI_Comm_size(MPI_COMM_WORLD,&size); 
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);  
    //sample data 
    data = rank * 100 + 1; 

    printf("my rank in the WORLD is: %d\n", rank); 
    fflush(stdout); 

    if(rank%2==0){ 
    MPI_Comm_split(MPI_COMM_WORLD,0,rank,&newComm); 
    MPI_Comm_rank(newComm,&newrank); 
    MPI_Comm_size(newComm,&newSize);  
    printf("my rank in the newComm1 is : %d\n", newrank); 
    }else{  
      MPI_Comm_split(MPI_COMM_WORLD,1,rank,&newComm2); 
      MPI_Comm_rank(newComm2,&newrank2); 
      MPI_Comm_size(newComm2,&newSize2);   
    printf("my rank in the newComm2 is : %d\n", newrank2); 
    } 

    //Now try some communication at the newCommunicator and at the WORLD level 
    if(rank == 0){ 
    //sending to process 1 wrt WOLD_Comm 
    MPI_Send(&data,1,MPI_INT,1,99,MPI_COMM_WORLD);  
    } 
    if(rank==1){ 
    //Receive from process at WORLD_Comm level. 
    MPI_Recv(&recv,1,MPI_INT,0,99,MPI_COMM_WORLD,&status); 
    printf("Received at WORLD Level : %d \n\n",recv); 
    } 
    if(newSize > 2){ 
    if(newrank == 2){ 
     //send to process 1 wrt the newComm 
     MPI_Send(&data,1,MPI_INT,1,0,newComm); 
    } 
    if(newrank==1){ 
     //Receive from process at newComm level. 
     MPI_Recv(&recv,1,MPI_INT,2,0,newComm,&status); 
     printf("Received at newComm Level : %d \n\n",recv); 
    } 
    } 
    MPI_Finalize(); 
    return 0; 
    } 

當我嘗試發送/接收內部new Communicator數據的錯誤發生。錯誤是有意義的,因爲不屬於新通信器(奇數級進程)的進程不能使用新的通信器句柄(newComm)。

所以我的問題是如何檢查給定的過程是否屬於新的傳播者。
爲了在做任何溝通之前我可以把這個警衛。

感謝,

回答

2

我重溫代碼做MPI_Comm_split。從我可以告訴,你不需要兩個單獨的變量newCommnewComm2。當您撥打MPI_Comm_split時,您可以考慮全球創建多個通訊器:每個值爲color。但是每個調用MPI_Comm_split的進程只能獲得一個參與者 - 它屬於的一個參與者。

if語句MPI_Comm_split可以通過

替代創建
MPI_Comm_split(MPI_COMM_WORLD, (rank % 2 == 0), rank, &newComm); 
MPI_Comm_rank(newComm, &newrank); 
MPI_Comm_size(newComm, &newSize); 

兩個傳播者,但newComm是指在不同的進程不同的傳播者。

如果奇數進程根本不需要進行通信,那麼可以讓它們爲color提供MPI_UNDEFINED。這將使他們newComm得到MPI_COMM_NULL值:

MPI_Comm_split(MPI_COMM_WORLD, (rank % 2) ? MPI_UNDEFINED : 0, rank, &newComm); 

然後你的代碼可以檢查是否(newcomm == MPI_COMM_NULL)

+0

嘿Greg Inozemtsev,非常感謝! 只是一個問題:如果我仍然需要奇數進程的通信,但現在不用,它們將在代碼中稍後使用。現在,當我檢查if(rank == 0)時,記住這一點,兩個進程能夠通過這個if語句,一個來自偶數組,另一個來自奇數組。這是我不想要的,這就是爲什麼我嘗試使用兩個單獨的句柄。 請問有沒有其他方法? – LeTex

+1

這就是第一個片段的功能。我們使用'(rank%2 == 0)'作爲顏色參數。這意味着在偶數進程中,'color == 1'和奇數進程'color == 0'。在'MPI_Comm_split'返回後,我們有3個通信器:原始的'MPI_COMM_WORLD',以及每個'color'的通信器。在偶數級別上,'newComm'指的是調用者提供'color == 1'(所以是偶數級別)的通信器。在奇數行列中,'newComm'是具有'color == 0'(奇數行列)的進程的通信者。而'MPI_COMM_WORLD'仍包含所有進程。 –

+0

oky!我現在明白了。謝謝 – LeTex

相關問題