Коллективные взаимодействия процессов
DESCRIPTION
Коллективные взаимодействия процессов. Коллективные взаимодействия процессов. MPI предоставляет ряд функций для коллективного взаимодейстия процессов. Эти функции называют коллективными, поскольку они должны вызываться одновременно на всех - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/1.jpg)
Коллективные взаимодействия процессов
![Page 2: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/2.jpg)
Коллективные взаимодействия процессов
MPI предоставляет ряд функций для коллективного взаимодейстия процессов.
Эти функции называют коллективными, поскольку они должны вызываться одновременно на всех процессах, принадлежащих некоторому коммуникатору.
![Page 3: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/3.jpg)
int MPI_Bcast ( buffer, count, datatype, root, comm )
void* buffer - начальный адрес буфера для передачи собщенийint count - число передаваемых элементов данныхMPI_Datatype datatype - тип передаваемых данныхint root - ранг процесса, посылающего данныеMPI_Comm comm - коммуникатор
![Page 4: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/4.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/5.jpg)
MPI_MAX максимум
MPI_MIN минимум MPI_SUM сумма
MPI_PROD произведение MPI_LAND логическое "и"
MPI_BAND побитовое "и"
MPI_LOR логическое "или"
MPI_BOR побитовое "или"
MPI_LXOR логическое исключающее "или"
MPI_BXOR побитовое исключающее "или"
![Page 6: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/6.jpg)
Вычисление числа Пи
1
021
4
x
12 3
41
23
41
23
4 1
![Page 7: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/7.jpg)
Вычисление числа 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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/8.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/9.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/10.jpg)
Функция синхронизации процессов:
int MPI_Barrier ( comm ) ;
MPI_Comm comm;
![Page 11: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/11.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/12.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/13.jpg)
#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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/14.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/15.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/16.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/17.jpg)
#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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/18.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/19.jpg)
Группы и коммуникаторы
![Page 20: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/20.jpg)
Интер- и интра-коммуникаторы
Интра-коммуникаторы
Интер-коммуникатор
Интра-коммуникаторы объединяют процессы из одной группы.
Интер-коммуникаторпозволяет передавать данные между процессами из разных интра-коммуникаторов.
Интер-коммуникаторы не могут использоваться в коллективных взаимодействиях.
01
2
3
4
1
0
3
2
1
1
![Page 21: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/21.jpg)
Группы и коммуникаторы
Совокупности MPI-процессов образуют группы.
Понятие ранга процесса имеет смысл только по отношению к определенной группе или коммуникатору.
Каждому интра-коммуникатору соответствует группа процессов. По группе процессов можно построить коммуникатор.
![Page 22: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/22.jpg)
Получение группы процессов по коммуникатору:
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/23.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/24.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/25.jpg)
Создание и удаление интра-коммуникаторов
Получение дубликата коммуникатора:
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/26.jpg)
Вычисление числа Pi методом Монте-Карло
Из книги Gropp, Lusk, Skjellum
![Page 27: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/27.jpg)
Схема вычислений
server
workerprocesses
коммуникаторworkers
коммуникаторworld
![Page 28: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/28.jpg)
/* 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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/29.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/30.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/31.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/32.jpg)
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/33.jpg)
Создание интер-коммуникаторов
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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/34.jpg)
#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: Коллективные взаимодействия процессов](https://reader036.vdocuments.mx/reader036/viewer/2022062408/56813ff4550346895dab116c/html5/thumbnails/35.jpg)
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();
}