【问题标题】:how to identify if MPI process belongs to a given Communicator如何识别 MPI 进程是否属于给定的 Communicator
【发布时间】:2012-09-15 15:14:01
【问题描述】:

我已经使用MPI_Comm_split() 构造创建了一个通信器,然后我想在 MPI_Comm_World 级别和新通信器级别尝试一些发送/接收通信。创建了两个通信器(一个具有偶数进程等级,另一个具有奇数等级)。

注意:我只需要在包含 even-process-ranks 的新通信器内尝试通信(虽然进程的排名不是原来的,但我仍然关心那些进程有他们的记忆空间)

我的代码如下,

    #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)。

所以我的问题是如何检查给定进程是否属于新的通信器。
这样我就可以在进行任何沟通之前放置这个警卫。

谢谢,

【问题讨论】:

    标签: mpi


    【解决方案1】:

    我会重新审视 MPI_Comm_split 的代码。据我所知,您不需要两个单独的变量newCommnewComm2。当您调用MPI_Comm_split 时,您可以想到全局创建了多个通信器:color 的每个值对应一个。但是每个调用MPI_Comm_split 的进程只得到一个对一个通信器的引用——它所属的那个。

    带有MPI_Comm_splitif 语句可以替换为

    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)

    【讨论】:

    • 嘿,格雷格 Inozemtsev,非常感谢!不过只有一个问题:如果我仍然需要奇数进程的通信,但现在不需要,它们将在后面的代码中使用。现在,当我检查 if(rank==0) 时考虑到这一点,两个进程能够传递这个 if 语句,一个来自偶数组,另一个来自奇数组。这是我不想要的,这就是为什么我尝试使用两个单独的手柄。请问还有什么办法吗??
    • 这就是第一个 sn-p 所做的。我们使用(rank % 2 == 0) 作为颜色参数。这意味着在偶数进程color == 1 和奇数进程color == 0 上。 MPI_Comm_split 返回后,我们有 3 个通信器:原始的MPI_COMM_WORLD,以及每个color 的通信器。在偶数排名中,newComm 指的是调用者提供color == 1 的通信器(因此,偶数排名)。在奇数列上,newComm 是与具有 color == 0(奇数列)的进程的通信器。而MPI_COMM_WORLD 仍然包含所有进程。
    猜你喜欢
    • 1970-01-01
    • 2017-09-08
    • 2017-07-24
    • 2020-03-14
    • 2015-12-23
    • 1970-01-01
    • 2016-05-20
    • 2013-05-12
    • 1970-01-01
    相关资源
    最近更新 更多