Communicators
Bibliotecas, topologias, etc.
Intra-communicators: entre processos do mesmo communicator
Inter-communicators: entre diferentes communicators
Rotinas associadas:
MPI_Comm_group
MPI_Group_incl
MPI_Comm_excl
MPI_Group_rank
MPI_Group_free
MPI_Comm_create
MPI_Comm_split
MPI_Comm_group
define o handle para o grupo de processadores
int MPI_Comm_group( MPI_Comm comm, MPI_Group *group)
typedef int MPI_Group;
MPI_Group_incl
cria um novo grupo a partir de um grupo já existente
especificando os membros do grupo
int MPI_Group_incl( MPI_Group old_group,
int count, int *members,
MPI_Group *new_group )
members[count] define quais os ranks do old_group que pertencem
ao new_group
MPI_Group_excl
cria um novo grupo a partir de um grupo já existente
excluindo ranks
int MPI_Group_excl( MPI_Group group,
int count, int *nonmembers,
MPI_Group *new_group )
nonmembers[count] define quais os ranks do group que são excluídos
int Neven, Nodd, members[6], even_rank, odd_rank;
MPI_Group group_world, even_group, odd_group;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
Neven = (p + 1)/2; Nodd = p - Neven;
members[0] = 2; members[1] = 0; members[2] = 4;
MPI_Comm_group(MPI_COMM_WORLD, &group_world);
MPI_Group_incl(group_world, Neven, members, &even_group);
MPI_Group_excl(group_world, Neven, members, &odd_group);
MPI_Group_rank
int MPI_Group_rank( MPI_Group group, int *rank)
MPI_UNDEFINED se processo não pertencer ao grupo
MPI_Group_free
int MPI_Group_free(MPI_Group *group)
liberta o grupo, mas não o comunicator
MPI_Comm_create
int MPI_Comm_create( MPI_Comm old_comm,
MPI_Group group,
MPI_Comm *new_comm )
collective communication;
MPI_COMM_NULL se o processo não pertencer ao grupo
#include "mpi.h"
MPI_Comm comm_world, comm_worker;
MPI_Group group_world, group_worker;
int ierr;
comm_world = MPI_COMM_WORLD;
MPI_Comm_group(comm_world, &group_world);
MPI_Group_excl(group_world, 1, 0, &group_worker);
MPI_Comm_create(comm_world, group_worker, &comm_worker);
MPI_Group_free(&group_worker);
...
MPI_Comm_free(&comm_worker);
Mecanismo que ajusta o padrão das
Topologias Virtuais
comunicações num communicator
Equação de Poisson – decomposição do domínio
Código mais simples
Y
Optimização
0
1
2
3
4
5
6
7
8
9
10
11
X
MPI_Cart_create
MPI_Cart_coords
MPI_Cart_rank
MPI_Cart_shift
MPI_Cart_sub
MPI_Cartdim_get
MPI_Cart_get
Vamos considerar apenas topologias cartesianas virtuais!!!
MPI_Cart_create
cria um novo communicator com topologia cartesiana
int MPI_Cart_create( MPI_Comm old_comm,
int ndims,
int *dim_size,
int *periods,
int reorder,
MPI_Comm *new_comm)
dim_size[ndims], periods[ndims]
> collective blocking communication
> MPI_COMM_NULL processos não incluídos no novo communicator
MPI_Comm old_comm, new_comm;
int ndims, reorder, periods[2], dim_size[2];
old_comm = MPI_COMM_WORLD;
ndims = 2;
dim_size[0] = 3; /* linhas */
dim_size[1] = 2; /* colunas */
periods[0] = 1; /* condições periódicas nas linhas */
periods[1] = 0; /* não periódicas nas colunas */
reorder = 1;
/* permite reordenação para possivel
ganho de eficiência
MPI_Cart_create(old_comm, ndims, dim_size,
periods, reorder, &new_comm);
*/
P0
(0,0)
P1
(0,1)
P2
(1,0)
P3
(1,1)
P4
(2,0)
P5
(2,1)
dim_size[0] = 3;
dim_size[1] = 2;
periods[0] = 1;
periods[1] = 0;
MPI_Cart_coords devolve as correspondentes coordenadas cartesianas
de um rank linear
int MPI_Cart_coords( MPI_Comm, int rank, int maxdims, int *coords)
maxdims = número de dimensões topologia cartesiana
coords[ndims]
MPI_Cart_rank
rank das coordenadas cartesianas numa topologia virtual
int MPI_Cart_rank( MPI_Comm comm, int *coords, int *rank )
coords[ndims]
MPI_Cart_sub
cria um novo communicator para subgrid até dimensão
N-1 a partir de uma grid cartesiana de dimensão N
int MPI_Cart_sub( MPI_Comm old, int *belongs, MPI_Comm *new)
belongs[ndims] = 0 pertence subgrid; 1 não pertence à subgrid
comprimento total de cada dimensão é utilizado nas subgrids
/* Topologia cartesina 2D */
MPI_Cart_create(MPI_COMM_WORLD, ndim, dims, period,
reorder, &comm2D);
MPI_Comm_rank(comm2D, &id2D);
MPI_Cart_coords(comm2D, id2D, ndim, coords2D);
/* subgrid 1D linha */
belongs[0] = 0; belongs[1] = 1;
MPI_Cart_sub(comm2D, belongs, &commrow);
/* subrgid 1D coluna */
belongs[0] = 1; belongs[1] = 0;
MPI_Cart_sub(comm2D, belongs, &commcol);
MPI_Cartdim_get
determina o número de dimensões de uma subgrid
int MPI_Cartdim_get( MPI_Comm comm, int *ndims )
/* subgrids columna */
belongs[0] = 1; belongs[1] = 0;
MPI_Cart_sub(grid_comm, belongs, &col_comm);
/* número de dimensões de uma grid cartesiana */
MPI_Cartdim_get(col_comm, &ndims);
MPI_Cart_shift
determina os ranks fonte e destino, para uma certo
deslocamento (displ), numa certa direcção
int MPI_Cart_shift( MPI_Comm comm, int direction, int displ,
int *source, int *dest )
0
1
2
3
4
5
6
7
8
9
10
11
/* create Cartesian topology for processes */
dims[0] = nrow; /* number of rows */
dims[1] = mcol; /* number of columns */
period[0] = 1;
/* cyclic in this direction */
period[1] = 0;
/* no cyclic in this direction */
MPI_Cart_create(MPI_COMM_WORLD, ndim, dims, period,
reorder, &comm2D);
MPI_Comm_rank(comm2D, &me);
MPI_Cart_coords(comm2D, me, ndim, coords);
index = 0; /* shift along the 1st index (out of 2) */
displ = 1; /* shift by 1 */
MPI_Cart_shift(comm2D, index, displ, &source, &dest1);
Download

ppt - Nautilus