2016-12-31 6 views
2

Ich möchte MPI-Communicators erstellen, die den Prozess mit Rang 0 mit jedem anderen Prozess verknüpfen. Angenommen, n ist die Gesamtzahl der Prozesse. Dann soll der Prozess mit Rang 0 n-1 Kommunikatoren haben, während jeder der anderen Prozesse einen Kommunikator hat. Ist dies möglich, und wenn ja, warum kann ich das untenstehende Programm nicht verwenden, um dies zu erreichen?MPI: Multiple Overlapping Communicators

Das Kompilieren des folgenden Codes mit dem MPIC++ - Compiler wird ohne Warnungen und Fehler auf meinem Computer beendet. Aber wenn ich das resultierende Programm mit 3 oder mehr Prozessen (mpiexec -n 3) ausführe, wird es nie beendet.

Vermutlich missverstehe ich das Konzept der Kommunikatoren in MPI. Vielleicht kann mir jemand helfen zu verstehen, warum das Programm unten hängen bleibt, und was ist eine bessere Art, diese Kommunikatoren zu erstellen? Vielen Dank.

#include <iostream> 
#include <vector> 
#include <thread> 
#include <chrono> 
#include "mpi.h" 
void FinalizeMPI(); 
void InitMPI(int argc, char** argv); 
int main(int argc, char** argv) { 
    InitMPI(argc, argv); 

    int rank,comm_size; 
    MPI_Comm_rank(MPI_COMM_WORLD,&rank); 
    MPI_Comm_size(MPI_COMM_WORLD,&comm_size); 

    if(comm_size<2) { 
     FinalizeMPI(); 
     return 0; 
    } 

    MPI_Group GroupAll; 
    MPI_Comm_group(MPI_COMM_WORLD, &GroupAll); 

    if(rank==0) { 
     std::vector<MPI_Group> myGroups(comm_size-1); 
     std::vector<MPI_Comm> myComms(comm_size-1); 
     for(int k=1;k<comm_size;++k) { 
      int ranks[2]{0, k}; 
      MPI_Group_incl(GroupAll, 2, ranks, &myGroups[k-1]); 
      int err = MPI_Comm_create(MPI_COMM_WORLD, myGroups[k-1], &myComms[k-1]); 
      std::cout << "Error: " << err << std::endl; 
     } 
    } else { 
     MPI_Group myGroup; 
     MPI_Comm myComm; 
     int ranks[2]{0,rank}; 
     MPI_Group_incl(GroupAll, 2, ranks, &myGroup); 
     int err = MPI_Comm_create(MPI_COMM_WORLD, myGroup, &myComm); 
     std::cout << "Error: " << err << std::endl; 
    } 
    std::cout << "Communicators created: " << rank << std::endl; 
    std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 

    FinalizeMPI(); 
    return 0; 
} 

void FinalizeMPI() { 
    int flag; 
    MPI_Finalized(&flag); 
    if(!flag) 
     MPI_Finalize(); 
} 

void InitMPI(int argc, char** argv) { 
    int flag; 
    MPI_Initialized(&flag); 
    if(!flag) { 
     int provided_Support; 
     MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided_Support); 
     if(provided_Support!=MPI_THREAD_MULTIPLE) { 
      exit(0); 
     } 
    } 
} 

Antwort

1

MPI_Comm_create ist eine kollektive Operation auf dem Ausgangs Kommunikator (MPI_COMM_WORLD) - Sie können es auf alle Prozesse aufrufen müssen.

Die einfachste Möglichkeit, das Problem zu beheben, besteht darin, MPI_Comm_create_group so zu verwenden, wie Sie es tun. Es ist ähnlich wie MPI_Comm_create, außer dass es kollektiv über die Gruppe ist.