MPI_Comm_split не работает с MPI_Bcast

#c #c #parallel-processing #mpi #openmpi

Вопрос:

Со следующим кодом я разделяю 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 (amp;argc, amp;argv);
        MPI_Comm_rank (MPI_COMM_WORLD, amp;myrank);
        MPI_Comm_size (MPI_COMM_WORLD, amp;size);      
        MPI_Comm_split(MPI_COMM_WORLD, myrank%2, myrank, amp;col_comm); 
        MPI_Comm_rank (col_comm, amp;localRank);
            
        if(myrank%3==0){
            value = myrank*5 1;
            MPI_Bcast(amp;value, 1, MPI_INT, localRank, col_comm);
        }
        
        printf("Rank=%d | LocalRank=%d | Got broadcast value of %dn", 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
 

Ответ №1:

MPI_Bcast

Передает сообщение от процесса с рангом «root» всем другим процессам коммуникатора

это коллективная процедура общения, следовательно, она должна вызываться всеми процессами в данном коммуникаторе. Поэтому вам необходимо удалить следующее условие if(myrank%3==0) , а затем соответствующим образом адаптировать корневой процесс вместо использования localRank .

В вашем текущем коде вызываются только процессы с myrank 0 и 3 MPI_Bcast (оба принадлежат разным коммуникаторам). Поэтому обработайте 0 вызовов

 MPI_Bcast(amp;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
 

Ранг=0 и Ранг=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 (amp;argc, amp;argv);
    MPI_Comm_rank (MPI_COMM_WORLD, amp;myrank);
    MPI_Comm_size (MPI_COMM_WORLD, amp;size);      
    MPI_Comm_split(MPI_COMM_WORLD, myrank%2, myrank, amp;col_comm); 
    MPI_Comm_rank (col_comm, amp;localRank);
     
    if(myrank == 0 || myrank == 3)    
       value = myrank*5 1;
    
    MPI_Bcast(amp;value, 1, MPI_INT, myrank%2 != 0, col_comm);
    
    printf("Rank=%d | LocalRank=%d | Got broadcast value of %dn", myrank, localRank, value);
    MPI_Finalize();
    return 0;
}
 

Обработайте от 0 передач до 2. И 3 должны транслироваться на 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