MPI_Comm_split 无法使用 MPI_Bcast

MPI_Comm_split not working with MPI_Bcast

使用以下代码,我在列组中拆分 4 个进程,然后从对角线 (0,3) 在同一列中广播。进程 0 广播到 2。3 应该广播到 1。但它没有按预期工作。有人能看出哪里出了问题吗?

0 1
2 3

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    #include <mpi.h>
    #include <mpi.h>
    using namespace std;
    
    int main(int argc, char **argv){
        MPI_Comm col_comm,row_comm;
        int myrank, size, even, value=0;
        int localRank=0;
        MPI_Init (&argc, &argv);
        MPI_Comm_rank (MPI_COMM_WORLD, &myrank);
        MPI_Comm_size (MPI_COMM_WORLD, &size);      
        MPI_Comm_split(MPI_COMM_WORLD, myrank%2, myrank, &col_comm); 
        MPI_Comm_rank (col_comm, &localRank);
            
        if(myrank%3==0){
            value = myrank*5+1;
            MPI_Bcast(&value, 1, MPI_INT, localRank, col_comm);
        }
        
        printf("Rank=%d | LocalRank=%d | Got broadcast value of %d\n", myrank, localRank, value);
        MPI_Finalize();
        return 0;
    }

输出

ubuntu@root:~/matrixmult$ mpirun comtest -np 4
Rank=0 | LocalRank=0 | Got broadcast value of 1
Rank=1 | LocalRank=0 | Got broadcast value of 0
Rank=2 | LocalRank=1 | Got broadcast value of 0
Rank=3 | LocalRank=1 | Got broadcast value of 16

MPI_Bcast

Broadcasts a message from the process with rank "root" to all other processes of the communicator

是一个集体通信例程,因此它应该被给定通信器中的所有进程调用。因此,您需要删除以下条件 if(myrank%3==0) 然后您需要相应地调整 root 进程,而不是使用 localRank.

在您当前的代码中,只有 myrank 0 和 3 的进程称为 MPI_Bcast(均属于不同的通信器)。所以处理 0 次调用

MPI_Bcast(&value, 1, MPI_INT, localRank, col_comm);

这基本上意味着它向自己广播了值。过程 3 也是如此。因此,输出:

Rank=0 | LocalRank=0 | Got broadcast value of 1
Rank=1 | LocalRank=0 | Got broadcast value of 0
Rank=2 | LocalRank=1 | Got broadcast value of 0
Rank=3 | LocalRank=1 | Got broadcast value of 16

Rank=0 和 Rank=3 与自己通信,而其他进程不属于 MPI_Bcast。因此,它们的值为 0。

尝试以下操作:

int main(int argc, char **argv){
    MPI_Comm col_comm,row_comm;
    int myrank, size, even, value=0;
    int localRank=0;
    MPI_Init (&argc, &argv);
    MPI_Comm_rank (MPI_COMM_WORLD, &myrank);
    MPI_Comm_size (MPI_COMM_WORLD, &size);      
    MPI_Comm_split(MPI_COMM_WORLD, myrank%2, myrank, &col_comm); 
    MPI_Comm_rank (col_comm, &localRank);
     
    if(myrank == 0 || myrank == 3)    
       value = myrank*5+1;
    
    MPI_Bcast(&value, 1, MPI_INT, myrank%2 != 0, col_comm);
    
    printf("Rank=%d | LocalRank=%d | Got broadcast value of %d\n", myrank, localRank, value);
    MPI_Finalize();
    return 0;
}

Process 0 broadcasts to 2. And 3 should broadcast to 1.

输出:

Rank=0 | LocalRank=0 | Got broadcast value of 1
Rank=1 | LocalRank=0 | Got broadcast value of 16
Rank=2 | LocalRank=1 | Got broadcast value of 1
Rank=3 | LocalRank=1 | Got broadcast value of 16