Коллективные взаимодействия процессов

35
Коллективные взаимодействия процессов

Upload: vita

Post on 08-Jan-2016

79 views

Category:

Documents


2 download

DESCRIPTION

Коллективные взаимодействия процессов. Коллективные взаимодействия процессов. MPI предоставляет ряд функций для коллективного взаимодейстия процессов. Эти функции называют коллективными, поскольку они должны вызываться одновременно на всех - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Коллективные взаимодействия процессов

Коллективные взаимодействия процессов

Page 2: Коллективные взаимодействия процессов

Коллективные взаимодействия процессов

MPI предоставляет ряд функций для коллективного взаимодейстия процессов.

Эти функции называют коллективными, поскольку они должны вызываться одновременно на всех процессах, принадлежащих некоторому коммуникатору.

Page 3: Коллективные взаимодействия процессов

int MPI_Bcast ( buffer, count, datatype, root, comm )

void* buffer - начальный адрес буфера для передачи собщенийint count - число передаваемых элементов данныхMPI_Datatype datatype - тип передаваемых данныхint root - ранг процесса, посылающего данныеMPI_Comm comm - коммуникатор

Page 4: Коллективные взаимодействия процессов

int MPI_Reduce ( sendbuf, recvbuf, count, datatype, op, root, comm )

void *sendbuf; буфер операндовvoid *recvbuf; буфер приемаint count; число данныхMPI_Datatype datatype; тип данныхMPI_Op op; операцияint root; ранг процесса, содержащего результатMPI_Comm comm; коммуникатор

op

Page 5: Коллективные взаимодействия процессов

MPI_MAX максимум

MPI_MIN минимум MPI_SUM сумма

MPI_PROD произведение MPI_LAND логическое "и"

MPI_BAND побитовое "и"

MPI_LOR логическое "или"

MPI_BOR побитовое "или"

MPI_LXOR логическое исключающее "или"

MPI_BXOR побитовое исключающее "или"

Page 6: Коллективные взаимодействия процессов

Вычисление числа Пи

1

021

4

x

12 3

41

23

41

23

4 1

Page 7: Коллективные взаимодействия процессов

Вычисление числа Pi

#include "mpi.h" #include <math.h> int main(argc,argv) int argc; char *argv[]; { int done = 0, n, myid, numprocs, i, rc; double PI25DT = 3.141592653589793238462643; double mypi, pi, h, sum, x, a; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&numprocs); MPI_Comm_rank(MPI_COMM_WORLD,&myid);

Page 8: Коллективные взаимодействия процессов

while (!done) { if (myid == 0) { printf("Enter the number of intervals: (0 quits) "); scanf("%d",&n); } MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); if (n == 0) break; h = 1.0 / (double) n; sum = 0.0; for (i = myid + 1; i <= n; i += numprocs) { x = h * ((double)i - 0.5); sum += 4.0 / (1.0 + x*x); } mypi = h * sum;

Page 9: Коллективные взаимодействия процессов

MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); if (myid == 0) printf("pi is approximately %.16f, Error is %.16f\n", pi, fabs(pi - PI25DT)); } MPI_Finalize(); }

Page 10: Коллективные взаимодействия процессов

Функция синхронизации процессов:

int MPI_Barrier ( comm ) ;

MPI_Comm comm;

Page 11: Коллективные взаимодействия процессов

int MPI_Scatter ( sendbuf, sendcnt, sendtype, recvbuf, recvcnt, recvtype, root, comm )

void *sendbuf;int sendcnt;MPI_Datatype sendtype;void *recvbuf;int recvcnt;MPI_Datatype recvtype;int root;MPI_Comm comm;

0

12

3

Page 12: Коллективные взаимодействия процессов

0

12

3

int MPI_Gather ( sendbuf, sendcnt, sendtype, recvbuf, recvcount, recvtype, root, comm ) void *sendbuf; int sendcnt; MPI_Datatype sendtype; void *recvbuf; int recvcount; MPI_Datatype recvtype; int root; MPI_Comm comm;

Page 13: Коллективные взаимодействия процессов

#include <stdio.h>#include <mpi.h>

#define N 5

int main( int argc, char **argv ){

int* dta;int ldta;int i;int size;int rank;MPI_Comm comm;

MPI_Init(&argc, &argv);comm = MPI_COMM_WORLD;

MPI_Comm_size(comm, &size);MPI_Comm_rank(comm, &rank);

if(rank == 0) {dta = (int*) calloc(size, sizeof(int));

}

Page 14: Коллективные взаимодействия процессов

for(i = 0; i < N; i ++) {int j;

MPI_Scatter(dta, 1, MPI_INT, &ldta, 1, MPI_INT, 0, comm);

ldta += rank;MPI_Gather(&ldta, 1, MPI_INT, dta, 1,

MPI_INT, 0, comm);

if(rank == 0) {for(j = 0; j < size; j ++)

printf("[%d]", dta[j]);printf("\n");fflush(stdout);

}}

MPI_Finalize();}

Page 15: Коллективные взаимодействия процессов

int MPI_Allreduce ( sendbuf, recvbuf, count, datatype, op, comm )

void *sendbuf;void *recvbuf;int count;MPI_Datatype datatype;MPI_Op op;MPI_Comm comm;

int MPI_Allgather ( sendbuf, sendcount, sendtype,recvbuf, recvcount, recvtype, comm )

void *sendbuf;int sendcount;MPI_Datatype sendtype;void *recvbuf;int recvcount;MPI_Datatype recvtype;MPI_Comm comm;

Page 16: Коллективные взаимодействия процессов

int MPI_Alltoall( sendbuf, sendcount, sendtype, recvbuf, recvcnt, recvtype, comm )

void *sendbuf;int sendcount;MPI_Datatype sendtype;void *recvbuf;int recvcnt;MPI_Datatype recvtype;MPI_Comm comm;

Page 17: Коллективные взаимодействия процессов

#include <stdio.h>#include <mpi.h>#define N 5

int main( int argc, char **argv ){

int* sdta;int* rdta;int i;int size;int rank;MPI_Comm comm;

MPI_Init(&argc, &argv);comm = MPI_COMM_WORLD;

MPI_Comm_size(comm, &size);MPI_Comm_rank(comm, &rank);

sdta = (int*) malloc(sizeof(int) * size);rdta = (int*) malloc(sizeof(int) * size);

for(i = 0; i < size; i ++) sdta[i] = i;

Page 18: Коллективные взаимодействия процессов

for(i = 0; i < N; i ++) { int j;

MPI_Alltoall(sdta, 1, MPI_INT, rdta, 1, MPI_INT, comm);

for(j = 0; j < size; j ++) sdta[j] = rdta[j];if(rank == 0) {

printf("[");for(j = 0; j < size; j ++) printf(" %d", sdta[j]);

printf("]\n");fflush(stdout);

}

}

MPI_Finalize();}

Page 19: Коллективные взаимодействия процессов

Группы и коммуникаторы

Page 20: Коллективные взаимодействия процессов

Интер- и интра-коммуникаторы

Интра-коммуникаторы

Интер-коммуникатор

Интра-коммуникаторы объединяют процессы из одной группы.

Интер-коммуникаторпозволяет передавать данные между процессами из разных интра-коммуникаторов.

Интер-коммуникаторы не могут использоваться в коллективных взаимодействиях.

01

2

3

4

1

0

3

2

1

1

Page 21: Коллективные взаимодействия процессов

Группы и коммуникаторы

Совокупности MPI-процессов образуют группы.

Понятие ранга процесса имеет смысл только по отношению к определенной группе или коммуникатору.

Каждому интра-коммуникатору соответствует группа процессов. По группе процессов можно построить коммуникатор.

Page 22: Коллективные взаимодействия процессов

Получение группы процессов по коммуникатору:

int MPI_Comm_group ( comm, group )

MPI_Comm comm; MPI_Group *group;

Создание коммуникатора по группе процессов:

int MPI_Comm_create ( comm, group, comm_out )

MPI_Comm comm; “старый” коммуникатор

MPI_Group group; группа процессов

MPI_Comm *comm_out; новый коммуникатор

Page 23: Коллективные взаимодействия процессов

int MPI_Group_excl ( group, n, ranks, newgroup )

MPI_Group group, *newgroup;

int n, *ranks;

int MPI_Group_incl ( group, n, ranks, group_out )

MPI_Group group, *group_out;

int n, *ranks;

Page 24: Коллективные взаимодействия процессов

int MPI_Group_intersection ( group1, group2, group_out )

int MPI_Group_union ( group1, group2, group_out )

int MPI_Group_difference ( group1, group2, group_out )

MPI_Group group1, group2, *group_out;

Page 25: Коллективные взаимодействия процессов

Создание и удаление интра-коммуникаторов

Получение дубликата коммуникатора:

int MPI_Comm_dup(MPI_Comm comm, MPI_Comm* newcomm)

Разбиение коммуникатора на несколько:

int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* newcomm)

comm – «старый коммуникатор»

color – селектор коммуникатора

key – задает порядок на создаваемых коммуникаторах

newcomm – создаваемый коммуникатор

Удаление коммуникатора:

int MPI_Comm_free(MPI_Comm* comm)

Page 26: Коллективные взаимодействия процессов

Вычисление числа Pi методом Монте-Карло

Из книги Gropp, Lusk, Skjellum

Page 27: Коллективные взаимодействия процессов

Схема вычислений

server

workerprocesses

коммуникаторworkers

коммуникаторworld

Page 28: Коллективные взаимодействия процессов

/* compute pi using Monte Carlo method */#include <math.h>#include "mpi.h"

#define CHUNKSIZE 1000#define INT_MAX 1000000000/* message tags */#define REQUEST 1#define REPLY 2int main( int argc, char *argv[] ){ int iter; int in, out, i, iters, max, ix, iy, ranks[1], done, temp; double x, y, Pi, error, epsilon; int numprocs, myid, server, totalin, totalout, workerid; int rands[CHUNKSIZE], request; MPI_Comm world, workers; MPI_Group world_group, worker_group; MPI_Status status;

MPI_Init(&argc,&argv); world = MPI_COMM_WORLD; MPI_Comm_size(world,&numprocs); MPI_Comm_rank(world,&myid);

Page 29: Коллективные взаимодействия процессов

if (myid == server) { /* I am the rand server */do { MPI_Recv(&request, 1, MPI_INT, MPI_ANY_SOURCE, REQUEST, world, &status);

if (request) {for (i = 0; i < CHUNKSIZE; i++) rands[i] = random();MPI_Send(rands, CHUNKSIZE, MPI_INT,

status.MPI_SOURCE, REPLY, world);}

} while( request>0 ); }

Page 30: Коллективные взаимодействия процессов

else { /* I am a worker process */ request = 1; done = in = out = 0; max = INT_MAX; /* max int, for normalization */ MPI_Send( &request, 1, MPI_INT, server, REQUEST, world ); MPI_Comm_rank( workers, &workerid ); iter = 0; while (!done) { iter++;

request = 1; MPI_Recv( rands, CHUNKSIZE, MPI_INT, server, REPLY, world, &status ); for (i=0; i<CHUNKSIZE; ) { x = (((double) rands[i++])/max) * 2 - 1; y = (((double) rands[i++])/max) * 2 - 1; if (x*x + y*y < 1.0) in++; else out++; }

Page 31: Коллективные взаимодействия процессов

MPI_Allreduce(&in, &totalin, 1, MPI_INT, MPI_SUM, workers);

MPI_Allreduce(&out, &totalout, 1, MPI_INT, MPI_SUM, workers);

Pi = (4.0*totalin)/(totalin + totalout); error = fabs( Pi-3.141592653589793238462643); done = (error < epsilon || (totalin+totalout) > 1000000); request = (done) ? 0 : 1; if (myid == 0) {

printf( "\rpi = %23.20f", Pi );MPI_Send( &request, 1, MPI_INT, server, REQUEST,

world ); } else {

if (request) MPI_Send(&request, 1, MPI_INT, server, REQUEST,

world); }}

}

Page 32: Коллективные взаимодействия процессов

if (myid == 0) { printf( "\npoints: %d\nin: %d, out: %d, <ret> to exit\n",

totalin+totalout, totalin, totalout );getchar();

} MPI_Comm_free(&workers); MPI_Finalize();}

Page 33: Коллективные взаимодействия процессов

Создание интер-коммуникаторов

int MPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm* new_comm)

local_comm – коммуникатор, которому принадлежит вызывающий процесс

local_leader – ранг некоторого процесса в немpeer_comm – коммуникатор, которому принадлежат процессы local_leader и remote_leader (часто COMM_WORLD)tag – используется для взаимодействия между local_leader и remote_leader (целесообразно проверять уникальность)new_comm – построенный интер-коммуникатор

Page 34: Коллективные взаимодействия процессов

#include <mpi.h>

main(int argc, char* argv[]){

int color;int rank;int m;MPI_Comm comm;MPI_Comm icomm;MPI_Status st;

MPI_Init(&argc, &argv);MPI_Comm_rank(MPI_COMM_WORLD, &rank);color = rank % 2;

MPI_Comm_split(MPI_COMM_WORLD, color, rank, &comm);if(color == 0)

MPI_Intercomm_create(comm, 0, MPI_COMM_WORLD, 1, 10, &icomm);

elseMPI_Intercomm_create(comm, 0, MPI_COMM_WORLD,

0, 10, &icomm);

Page 35: Коллективные взаимодействия процессов

if(color == 0) {

int lrank;

MPI_Comm_rank(comm, &lrank);

MPI_Send(&lrank, 1, MPI_INT, lrank, 0, icomm);

}

else {

int lrank;

MPI_Comm_rank(comm, &lrank);

MPI_Recv(&m, 1, MPI_INT, lrank, 0, icomm, &st);

}

printf("rank = %d, m = %d\n", rank, m);

MPI_Finalize();

}