1 / 35

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

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

vita
Download Presentation

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

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

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

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

  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

  5. MPI_MAX максимум MPI_MIN минимум MPI_SUM сумма MPI_PROD произведение MPI_LAND логическое "и" MPI_BAND побитовое "и" MPI_LOR логическое "или" MPI_BOR побитовое "или" MPI_LXOR логическое исключающее "или" MPI_BXOR побитовое исключающее "или"

  6. Вычисление числа Пи 1 3 1 3 1 3 1 2 4 2 2 4 4

  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);

  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;

  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(); }

  10. Функция синхронизации процессов: int MPI_Barrier ( comm ) ; MPI_Comm comm;

  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; 3 0 2 1

  12. 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; 3 0 2 1

  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)); }

  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(); }

  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;

  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;

  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;

  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(); }

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

  20. Интер- и интра-коммуникаторы Интер-коммуникатор 1 1 0 2 4 1 3 Интра-коммуникаторы объединяют процессы из одной группы. Интер-коммуникаторпозволяет передавать данные между процессами из разных интра-коммуникаторов. Интер-коммуникаторы не могут использоваться в коллективных взаимодействиях. 1 0 2 Интра-коммуникаторы 3

  21. Группы и коммуникаторы Совокупности MPI-процессов образуют группы. Понятие ранга процесса имеет смысл только по отношению к определенной группе или коммуникатору. Каждому интра-коммуникатору соответствует группа процессов. По группе процессов можно построить коммуникатор.

  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; новый коммуникатор

  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;

  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;

  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)

  26. Вычисление числа Pi методом Монте-Карло Из книги Gropp, Lusk, Skjellum

  27. Схема вычислений server коммуникатор workers worker processes коммуникатор world

  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 2 int 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);

  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 ); }

  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++; }

  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); } } }

  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(); }

  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 – построенный интер-коммуникатор

  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); else MPI_Intercomm_create(comm, 0, MPI_COMM_WORLD, 0, 10, &icomm);

  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(); }

More Related