MPI Group

De Wiki de Calcul Québec
Aller à : Navigation, rechercher
Autres langues :anglais 100% • ‎français 100%

Cet exemple illustre l'utilisation des groupes.

Chaque processus identifie son rang. Elles sont ensuite regroupées en deux groupes de quatre processus à l'aide de MPI_Group_incl. Par la suite, les processus construisent un communicateur à l'intérieur de leur nouveau groupe. L'utilisation de MPI_Allreduce montre bien que le nouveau communicateur est réduit au groupe. L'opération requise par MPI_Allreduce additionne le rang initial des processus appartenant au groupe. Les processus associés au premier groupe retournent la valeur 6 (0 + 1 + 2 + 3), tandis que ceux du deuxième groupe retournent 22 (4 + 5 + 6 + 7).

Dans la version C++ du programme, on doit préciser si le communicateur agit à l'intérieur du groupe ou à l'extérieur de celui-ci.

En Fortran

Fichier : group.f
!--------------------------------------------------------
! Le programme est fait pour être exécuté en huit processus MPI.
! La première version de ce code provient du 
! Minnesota Supercomputing Institute
 
! Auteur : Steve Allen
!          Centre de calcul scientifique
!          Université de Sherbrooke
 
! Modifié par : François Guertin
!               RQCHP, Université de Montréal
 
! Dernière révision : août 2009
! --------------------------------------------------------
      Program Exemple_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
 
    ! *********** Avec MPI_Comm_create *********
 
   ! Extrait le descripteur du groupe original
 
      call MPI_COMM_GROUP(MPI_COMM_WORLD, orig_group, ierr)
 
   ! Divise les processus en deux groupes
 
      call MPI_GROUP_INCL(orig_group, NPROCS/2, ranks1, new_group1, ierr)
      call MPI_GROUP_INCL(orig_group, NPROCS/2, ranks2, new_group2, ierr)
 
   ! Crée les nouveaux communicateurs
 
      call MPI_COMM_CREATE(MPI_COMM_WORLD, new_group1, new_comm1, ierr)
      call MPI_COMM_CREATE(MPI_COMM_WORLD, new_group2, new_comm2, ierr)
 
   ! Conserve le communicateur qui n'est pas MPI_COMM_NULL selon le rang
 
      if( rank .lt. NPROCS/2 )then
         new_comm = new_comm1
      else
         new_comm = new_comm2
      endif
 
   ! et fait des communications collectives
 
      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)
 
   ! *********** Avec MPI_Comm_split *********
 
      if( rank .lt. NPROCS/2 )then
         color = 0
      else
         color = 1
      endif
 
 
   ! Crée les nouveaux communicateurs
 
      call MPI_COMM_SPLIT(MPI_COMM_WORLD, color, rank, split_comm,ierr)
 
   ! et fait des communications collectives
 
      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 Exemple_Group


En C

Fichier : group.c
/*--------------------------------------------------------
 Le programme est fait pour être exécuté en huit processus MPI.
 La première version de ce code provient du 
 Minnesota Supercomputing Institute.
 
 Auteur : Steve Allen
          Centre de calcul scientifique
          Université de Sherbrooke
 
 Modifié par : François Guertin
               RQCHP, Université de Montréal
 
 Dernière révision : août 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;
 
   /********** Avec MPI_Comm_create *********/
 
   /* Extrait le descripteur du groupe original */
 
   MPI_Comm_group(MPI_COMM_WORLD, &orig_group);
 
   /* Divise les processus en deux groupes */   
 
   MPI_Group_incl(orig_group, NPROCS/2, ranks1, &new_group1);
   MPI_Group_incl(orig_group, NPROCS/2, ranks2, &new_group2);
 
   /* Crée les nouveaux communicateurs */ 
 
   MPI_Comm_create(MPI_COMM_WORLD, new_group1, &new_comm1);
   MPI_Comm_create(MPI_COMM_WORLD, new_group2, &new_comm2);
 
   /* Conserve le communicateur qui n'est pas MPI_COMM_NULL selon le rang */
   if( rank < NPROCS/2 ){
     new_comm = new_comm1;
   } else {
     new_comm = new_comm2;
   }
 
 
   /* et fait des communications collectives */
   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);
 
 
   /********** Avec MPI_Comm_split *********/
 
   /* Choisit la "couleur" pour chaque processus */
   if( rank < NPROCS/2 ){
     color = 0;
   } else {
     color = 1;
   }
   /* Crée les nouveaux communicateurs */
   MPI_Comm_split (MPI_COMM_WORLD, color, rank, &split_comm);
 
   /* et fait des communications collectives */
   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