MPI Group

De Wiki de Calcul Québec
Aller à : Navigation, rechercher
Cette page est une traduction de la page MPI Group et la traduction est complétée à 100 % et à jour.

Autres langues :anglais 100% • ‎français 100%

This example shows how to use groups.

Each process determines its rank. Then they are grouped into two groups of 4 processes each using MPI_Group_incl. Following that, the processes construct a communicator inside their new group. Using MPI_Allreduce shows well that the new communicator only applies to the group. The operation required by MPI_Allreduce adds the initial rank of the processes belonging to the group. The processes that belong to the first group return the value 6 (0 + 1 + 2 + 3), and those belonging to the second group return 22 (4 + 5 + 6 + 7).

In the C++ version of this program, you should specify if the communicator acts on the inside or on the outside of the group.

In Fortran

File : group.f
!--------------------------------------------------------
! This program only runs using 8 MPI processes.
! The first version of this code comes from the
! Minnesota Supercomputing Institute.
 
! Author: Steve Allen
!        Centre de calcul scientifique
!        Université de Sherbrooke
 
! Modified by : François Guertin
!               RQCHP, Université de Montréal
 
! Last update: August 2009
! --------------------------------------------------------
     Program Example_Group
 
      include 'mpif.h'
      integer,parameter               :: NPROCS = 8
      integer                         :: rank, new_rank1, new_rank2
      integer,dimension(4)            :: ranks1=(/0,1,2,3/), ranks2=(/4,5,6,7/)
      integer(kind=MPI_ADDRESS_KIND)  :: orig_group, new_group1, new_group2
      integer(kind=MPI_ADDRESS_KIND)  :: new_comm, new_comm1, new_comm2
      integer(kind=MPI_ADDRESS_KIND)  :: split_comm
      integer                         :: color
      integer                         :: sendbuf_rank, recvbuf_sum
      integer                         :: ierr
 
      call MPI_INIT(ierr)
      call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
      sendbuf_rank = rank
      sendbuf = rank
 
    ! *********** With MPI_Comm_create *********
 
   ! Extract the original group handle
 
      call MPI_COMM_GROUP(MPI_COMM_WORLD, orig_group, ierr)
 
   ! Divide processes into two distinct groups
 
      call MPI_GROUP_INCL(orig_group, NPROCS/2, ranks1, new_group1, ierr)
      call MPI_GROUP_INCL(orig_group, NPROCS/2, ranks2, new_group2, ierr)
 
   ! Create new communicators
 
      call MPI_COMM_CREATE(MPI_COMM_WORLD, new_group1, new_comm1, ierr)
      call MPI_COMM_CREATE(MPI_COMM_WORLD, new_group2, new_comm2, ierr)
 
   ! Keep communicators different than MPI_COMM_NULL based on the rank
 
      if( rank .lt. NPROCS/2 )then
         new_comm = new_comm1
      else
         new_comm = new_comm2
      endif
 
   ! and then perform collective communications
 
      call MPI_ALLREDUCE(sendbuf_rank, recvbuf_sum, 1, MPI_INTEGER, MPI_SUM, new_comm, ierr)
      call MPI_Comm_RANK(new_comm, new_rank, ierr)
 
      print*,'Create: rank= ',rank,' newrank= ',new_rank,' recvbuf_sum= ',recvbuf_sum
 
      call MPI_COMM_FREE(new_comm, ierr)
      call MPI_GROUP_FREE(new_group1, ierr)
      call MPI_GROUP_FREE(new_group2, ierr)
 
   ! *********** With MPI_Comm_split *********
 
      if( rank .lt. NPROCS/2 )then
         color = 0
      else
         color = 1
      endif
 
 
   ! Create new communicators
 
      call MPI_COMM_SPLIT(MPI_COMM_WORLD, color, rank, split_comm,ierr)
 
   ! Perform collective communications
 
      call MPI_ALLREDUCE(sendbuf_rank, recvbuf_sum, 1, MPI_INTEGER, MPI_SUM, split_comm, ierr)
      call MPI_COMM_RANK(split_comm, new_rank, ierr)
 
      print*,'Split: rank= ',rank,' newrank= ',new_rank,' recvbuf_sum= ',recvbuf_sum
 
      call MPI_COMM_FREE(split_comm, ierr)
 
      call MPI_FINALIZE(ierr)
 
      end program Example_Group


In C

File : group.c
/*--------------------------------------------------------
 This program only runs using 8 MPI processes.
 The first version of this code comes from the
 Minnesota Supercomputing Institute.
 
 Author: Steve Allen
         Centre de calcul scientifique
         Université de Sherbrooke
 
 Modified by : François Guertin
               RQCHP, Université de Montréal
 
 Last update: August 2009
--------------------------------------------------------*/
 
#include <stdio.h>
#include <mpi.h>
#define NPROCS 8
 
int main(int argc,char** argv)
{
   int        rank, new_rank, sendbuf_rank, recvbuf_sum;
   int        ranks1[4]={0,1,2,3}, ranks2[4]={4,5,6,7};
   MPI_Group  orig_group, new_group1, new_group2;
   MPI_Comm   new_comm, new_comm1, new_comm2;
   MPI_Comm   split_comm;
   int        color;
 
   MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   sendbuf_rank = rank;
 
   /*********** With MPI_Comm_create *********/
 
   /* Extract the original group handle */
 
   MPI_Comm_group(MPI_COMM_WORLD, &orig_group);
 
   /* Divide processes into two distinct groups based upon rank */   
 
   MPI_Group_incl(orig_group, NPROCS/2, ranks1, &new_group1);
   MPI_Group_incl(orig_group, NPROCS/2, ranks2, &new_group2);
 
   /* Create new communicators */ 
 
   MPI_Comm_create(MPI_COMM_WORLD, new_group1, &new_comm1);
   MPI_Comm_create(MPI_COMM_WORLD, new_group2, &new_comm2);
 
   /* Keep communicators different than MPI_COMM_NULL based on the rank */
   if( rank < NPROCS/2 ){
     new_comm = new_comm1;
   } else {
     new_comm = new_comm2;
   }
 
 
   /* Perform collective communications */
   MPI_Allreduce(&sendbuf_rank, &recvbuf_sum, 1, MPI_INT, MPI_SUM, new_comm);
   MPI_Comm_rank(new_comm, &new_rank);
 
   printf("Create: rank= %d newrank= %d recvbuf_sum= %d\n",rank,new_rank,recvbuf_sum);
 
   MPI_Comm_free(&new_comm);
   MPI_Group_free(&new_group1);
   MPI_Group_free(&new_group2);
 
 
   /********** With MPI_Comm_split *********/
 
   /* Choose the "color" of each process */
   if( rank < NPROCS/2 ){
     color = 0;
   } else {
     color = 1;
   }
   /* Create new communicators */
   MPI_Comm_split (MPI_COMM_WORLD, color, rank, &split_comm);
 
   /* Perform collective communications */
   MPI_Allreduce(&sendbuf_rank, &recvbuf_sum, 1, MPI_INT, MPI_SUM, split_comm);
   MPI_Comm_rank(split_comm, &new_rank);
 
   printf("Split:   rank= %d newrank= %d recvbuf_sum= %d\n",rank,new_rank,recvbuf_sum);
 
   MPI_Comm_free(&split_comm);
 
   MPI_Finalize();
}


Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Ressources de Calcul Québec
Outils
Partager