280 likes | 960 Vues
Параллельное программирование с использованием технологии MPI. Лекция 7 Томский политехнический университет. Аксёнов Сергей Владимирович к.т.н., доцент каф.ОСУ ТПУ. int MPI _ Barrier ( MPI _ Comm comm ) Вход comm: Коммуникатор. Барьерная синхронизация.
E N D
Параллельное программирование с использованием технологии MPI Лекция 7 Томский политехнический университет Аксёнов Сергей Владимирович к.т.н., доцент каф.ОСУ ТПУ Параллельное программирование с использованием технологии MPI Аксёнов С.В.
int MPI_Barrier(MPI_Comm comm) Вход comm: Коммуникатор Барьерная синхронизация Функция блокирует вызывающий процесс пока все процессы группы не вызовут её. В каждом процессе управление возвращается только тогда, когда все процессы в группе вызовут процедуру Параллельное программирование с использованием технологии MPI Аксёнов С.В.
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(“Отправка данных окончена \n”); } else 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(“Прием данных окончен \n”); } MPI_Barrier(MPI_COMM_WORLD); printf(“Завершение работы процесса %d \n”,rank); Барьерная синхронизация Параллельное программирование с использованием технологии MPI Аксёнов С.В.
int MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm) Вход/Выход buf: Адрес начала буфера Вход count: Количество записей в буфере Вход: datatype: Тип данных в буфере Вход root: Номер корневого процесса Вход comm: Коммуникатор Широковещательный обмен Функция поcылает сообщение из корневого процесса всем процессам группы, включая себя. Параллельное программирование с использованием технологии MPI Аксёнов С.В.
Широковещательный обмен Параллельное программирование с использованием технологии MPI Аксёнов С.В.
#include “mpi.h” #include <stdio.h> 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(int i =0; i<100; i++) a[i] =i; MPI_Bcast(a, 100, MPI_INT, 0, MPI_COMM_WORLD); MPI_Finalize(); return 0; } Широковещательный обмен Параллельное программирование с использованием технологии MPI Аксёнов С.В.
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_Scatter Процесс с рангом root распределяет содержимое буфера передачи sendbuf среди всех процессов. Содержимое буфера передачи разбивается на несколько фрагментов, каждый из которых содержит sendcount элементов. Параллельное программирование с использованием технологии MPI Аксёнов С.В.
Распределение данных Параллельное программирование с использованием технологии MPI Аксёнов С.В.
#include “mpi.h” #include <stdio.h> int main (int argc, char *argv[]) { int rank, gsize,*sendbuf, size; int root =0, rbuf[100]; 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<size; i++) sendbuf[i] =i; MPI_Scatter(sendbuf, 100, MPI_INT, rbuf, 100, MPI_INT, root, MPI_COMM_WORLD); MPI_Finalize(); return 0; } Пример MPI_Scatter Параллельное программирование с использованием технологии MPI Аксёнов С.В.
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_Scatterv позволяет передавать каждому процессу переменное число элементов данных. Параллельное программирование с использованием технологии MPI Аксёнов С.В.
MPI_Scatterv Сравнение MPI_Scatterv и MPI_Scatter MPI_Scatter Параллельное программирование с использованием технологии MPI Аксёнов С.В.
#include “mpi.h” #include <stdio.h> int main (int argc, char *argv[]) { int gsize,*sendbuf, root, rbuf[100], i, *displs, *scounts; MPI_Init(&argc, &argv); 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<gsize; ++i) { displs[i] = i*stride; scounts[i] = 100; } MPI_Scatterv( sendbuf, scounts, displs, MPI_INT, rbuf, 100, MPI_INT, root, MPI_COMM_WORLD); MPI_Finalize(); return 0; } Пример MPI_Scatterv Параллельное программирование с использованием технологии MPI Аксёнов С.В.
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_Gather каждый процесс, включая корневой, посылает содержимое своего буфера в корневой процесс. Параллельное программирование с использованием технологии MPI Аксёнов С.В.
Сбор данных Параллельное программирование с использованием технологии MPI Аксёнов С.В.
#include “mpi.h” #include <stdio.h> int main (int argc, char *argv[]) { int gsize,sendarray[100]; int root=0, rank, *rbuf; MPI_Init(&argc, &argv); MPI_Comm_rank( comm, &rank); if ( rank == root) { MPI_Comm_size(MPI_COMM_WORLD, &gsize); rbuf = malloc(gsize*100*sizeof(int)); } MPI_Gather(sendarray,100,MPI_INT, rbuf,100, MPI_INT, root, MPI_COMM_WORLD); MPI_Finalize(); return 0; } Пример MPI_Gather Параллельное программирование с использованием технологии MPI Аксёнов С.В.
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_Gatherv Параллельное программирование с использованием технологии MPI Аксёнов С.В.
MPI_Gather Сравнение MPI_Gather и MPI_Gatherv MPI_Gatherv Параллельное программирование с использованием технологии MPI Аксёнов С.В.
#include “mpi.h” #include <stdio.h> int main (int argc, char *argv[]) { int gsize,sendarray[100], root=0, *rbuf, stride=105, *displs, *rcounts; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &gsize); rbuf = malloc(gsize*stride*sizeof(int)); displs = malloc(gsize*sizeof(int)); rcounts = malloc(gsize*sizeof(int)); for (int i=0; i<gsize; i++) { displs[i] = i*stride; rcounts[i] = 100; } MPI_Gatherv( sendarray, 100, MPI_INT, rbuf, rcounts, displs,MPI_INT, root, MPI_COMM_WORLD); MPI_Filnalize(); return 0; } Пример MPI_Gatherv Параллельное программирование с использованием технологии MPI Аксёнов С.В.
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_Allgather можно представить как функциюMPI_Gather, где результат принимают все процессы, а не толькоглавный. Параллельное программирование с использованием технологии MPI Аксёнов С.В.
Сбор для всех процессов Параллельное программирование с использованием технологии MPI Аксёнов С.В.
#include “mpi.h” #include <stdio.h> int main (int argc, char *argv[]) { int gsize,sendarray[100], *rbuf; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &gsize); rbuf = malloc(gsize*100*sizeof(int)); MPI_Allgather( sendarray, 100, MPI_INT, rbuf, 100, MPI_INT, MPI_COMM_WORLD); MPI_Finalize(); return 0; } Пример MPI_Allgather Параллельное программирование с использованием технологии MPI Аксёнов С.В.