Параллельное программирование с использованием технологии MPI Аксёнов Сергей Владимирович к.т.н., доцент каф.ОСУ ТПУ Лекция 8 Томский политехнический университет 1 Параллельное программирование с использованием технологии MPI Аксёнов С.В.
Барьерная синхронизация Функция блокирует вызывающий процесс пока все процессы группы не вызовут её. В каждом процессе управление возвращается только тогда, когда все процессы в группе вызовут процедуру Параллельное программирование с использованием технологии MPI Аксёнов С.В. 2 int MPI_Barrier(MPI_Comm comm) Вход comm: Коммуникатор
Барьерная синхронизация MPI_Comm_rank( MPI_COMM_WORLD, &rank ); if (rank == 0) { MPI_Bsend(buf1,20,MPI_INT,1,25,MPI_COMM_WORLD); MPI_Ssend(buf2,20,MPI_INT,1,26,MPI_COMM_WORLD); printf(Отправка данных окончена); } if (rank==1) { MPI_Recv(source1, 20, MPI_INT, 0, 26, MPI_COMM_WORLD, &status); MPI_Recv(source2, 20, MPI_INT, 0, 25, MPI_COMM_WORLD, &status); printf(Прием данных окончен); } MPI_Barrier(MPI_COMM_WORLD); printf(Завершение работы процесса %d,rank); Параллельное программирование с использованием технологии MPI Аксёнов С.В. 3
Широковещательный обмен Функция поcылает сообщение из корневого процесса всем процессам группы, включая себя. Параллельное программирование с использованием технологии MPI Аксёнов С.В. 4 int MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm) Вход/Выход buf: Адрес начала буфера Вход count: Количество записей в буфере Вход: datatype:Тип данных в буфере Вход root: Номер корневого процесса Входcomm:Коммуникатор
Широковещательный обмен Параллельное программирование с использованием технологии MPI Аксёнов С.В. 5
Широковещательный обмен #include mpi.h #include int main (int argc, char *argv[]) { int rank, *a; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD,&rank); a = malloc(100*sizeof(int)); if (rank==0) { for( i =0; i
Распределение данных MPI_Scatter Процесс с рангом root распределяет содержимое буфера передачи sendbuf среди всех процессов. Содержимое буфера передачи разбивается на несколько фрагментов, каждый из которых содержит sendcount элементов. Параллельное программирование с использованием технологии MPI Аксёнов С.В. 7 int MPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) Входsendbuf: Адрес буфера рассылки Вход sendcount: Количество элементов, посылаемых каждому процессу Вход sendtype:Тип данных в буфере рассылки Вход/Выходrecvbuf:Адрес буфера-получателя Входrecvcount:Количество элементов в буфере приема Входrecvtype:Тип данных в буфере приема Вход root: Номер корневого процесса Входcomm:Коммуникатор
Распределение данных Параллельное программирование с использованием технологии MPI Аксёнов С.В. 8
Пример MPI_Scatter Параллельное программирование с использованием технологии MPI Аксёнов С.В. 9 #include mpi.h #include int main (int argc, char *argv[]) { int rank, *a; int gsize,*sendbuf, size; int root, rbuf[100]; root =0; MPI_Init(&argc, &argv); MPI_Comm_size( comm, &gsize); MPI_Comm_rank(MPI_COMM_WORLD,&rank); size = gsize*100; sendbuf = malloc(size*sizeof(int)); if (rank==root) { for( i =0; i
Распределение данных MPI_Scatterv Функция MPI_Scatterv позволяет передавать каждому процессу переменное число элементов данных. Параллельное программирование с использованием технологии MPI Аксёнов С.В. 10 int MPI_Scatterv(void *sendbuf, int *sendcounts, int displs, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) Входsendbuf: Адрес буфера рассылки Вход sendcount: Массив определяющий, число элементов для пересылки каждому процессу Входdispls:Смещение Вход sendtype:Тип данных в буфере рассылки Вход/Выходrecvbuf:Адрес буфера-получателя Входrecvcount:Количество элементов в буфере приема Входrecvtype:Тип данных в буфере приема Вход root: Номер корневого процесса Входcomm:Коммуникатор
Сравнение MPI_Scatterv и MPI_Scatter MPI_Scatter Параллельное программирование с использованием технологии MPI Аксёнов С.В. 11 MPI_Scatterv
Пример MPI_Scatterv int gsize,*sendbuf, root, rbuf[100], i, *displs, *scounts; MPI_Comm_size( comm, &gsize); sendbuf = malloc(gsize*stride*sizeof(int)); displs = malloc(gsize*sizeof(int)); scounts = malloc(gsize*sizeof(int)); for (i=0; i
Сбор данных MPI-Gather Параллельное программирование с использованием технологии MPI Аксёнов С.В. 13 int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) Входsendbuf: Адрес буфера рассылки Вход sendcount: Количество элементов в отсылаемом сообщении Вход sendtype:Тип данных в буфере рассылки Вход/Выходrecvbuf:Адрес буфера-процесса сборки Входrecvcount:Количество элементов в принимаемом сообщении Входrecvtype:Тип данных в буфере приема Вход root: Номер процесса-получателя Входcomm:Коммуникатор При выполнении операции сборки данных MPI_Gather каждый процесс, включая корневой, посылает содержимое своего буфера в корневой процесс.
Сбор данных Параллельное программирование с использованием технологии MPI Аксёнов С.В. 14
Пример MPI_Gather int gsize,sendarray[100]; int root, myrank, *rbuf; MPI_Comm_rank( comm, &myrank); if ( myrank == root) { MPI_Comm_size( comm, &gsize); rbuf = malloc(gsize*100*sizeof(int)); } MPI_Gather(sendarray,100,MPI_INT, rbuf,100, MPI_INT,root, MPI_COMM_WORLD); Параллельное программирование с использованием технологии MPI Аксёнов С.В. 15
Сбор данных MPI_Gatherv Параллельное программирование с использованием технологии MPI Аксёнов С.В. 16 int MPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcount, int *displs, MPI_Datatype recvtype, int root, MPI_Comm comm) Входsendbuf: Адрес буфера рассылки Вход sendcount: Количество элементов в буфере рассылки Вход sendtype:Тип данных в буфере рассылки Вход/Выходrecvbuf:Адрес буфера-получателя Входrecvcount:Количество элементов, полученных от каждого процесса в буфере приема Входdispls:Элемент i определяет смещение относительно recvbuf, в котором размещаются данные из процесса i Входrecvtype:Тип данных в буфере приема Вход root: Номер процесса-получателя Входcomm:Коммуникатор
Сравнение MPI_Gather и MPI_Gatherv Параллельное программирование с использованием технологии MPI Аксёнов С.В. 17 MPI_Gather MPI_Gatherv
Пример MPI_Gatherv Параллельное программирование с использованием технологии MPI Аксёнов С.В. 18 int gsize,sendarray[100], root, *rbuf, stride, *displs,i,*rcounts; MPI_Comm_size( comm, &gsize); rbuf = malloc(gsize*stride*sizeof(int)); displs = malloc(gsize*sizeof(int)); rcounts = malloc(gsize*sizeof(int)); for (i=0; i
Сбор для всех процессов Параллельное программирование с использованием технологии MPI Аксёнов С.В. 19 Функцию MPI_Allgather можно представить как функцию MPI_Gather, где результат принимают все процессы, а не только главный. int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm) Входsendbuf: Адрес буфера рассылки Вход sendcount: Количество элементов в буфере рассылки Вход sendtype:Тип данных в буфере рассылки Вход/Выходrecvbuf:Адрес буфера-получателя Входrecvcount:Количество элементов, полученных от любого процесса Входrecvtype:Тип данных в буфере приема Входcomm:Коммуникатор
Сбор для всех процессов Параллельное программирование с использованием технологии MPI Аксёнов С.В. 20
Пример MPI_Allgather Параллельное программирование с использованием технологии MPI Аксёнов С.В. 21 MPI_Comm comm; int gsize,sendarray[100], *rbuf; MPI_Comm_size( comm, &gsize); rbuf = malloc(gsize*100*sizeof(int)); MPI_Allgather( sendarray, 100, MPI_INT, rbuf, 100, MPI_INT, MPI_COMM_WORLD);