Скачать презентацию Лекция 26 Параллельное программирование Коллективные операции передачи данных Скачать презентацию Лекция 26 Параллельное программирование Коллективные операции передачи данных

ЯиМП_Лекция 26_Коллективные_опер_перед_данных.ppt

  • Количество слайдов: 33

Лекция 26. Параллельное программирование. Коллективные операции передачи данных Языки и методы программирования. Доцент М. Лекция 26. Параллельное программирование. Коллективные операции передачи данных Языки и методы программирования. Доцент М. А. Сокольская

План. 1. 2. 3. 4. 5. 2 Обобщенная передача данных от всех процессов одному План. 1. 2. 3. 4. 5. 2 Обобщенная передача данных от всех процессов одному процессу Обобщенная передача данных от одного процесса всем процессам Общая передача данных от всех процессов всем процессам. Дополнительные операции редукции данных Пример. Умножение матрицы на вектор

Коллективные операции передачи данных… Определение. Под коллективными операциями в MPI понимаются операции данных, в Коллективные операции передачи данных… Определение. Под коллективными операциями в MPI понимаются операции данных, в которых принимают участие все процессы используемого коммуникатора 3

Распределение данных 4 Распределение данных – ведущий процесс (root) передает процессам различающиеся данные int Распределение данных 4 Распределение данных – ведущий процесс (root) передает процессам различающиеся данные int MPI_Scatter(void *sbuf, int scount, MPI_Datatype stype, void *rbuf, int rcount, MPI_Datatype rtype, int root, MPI_Comm comm), где - sbuf, scount, stype - параметры передаваемого сообщения (scount определяет количество элементов, передаваемых на каждый процесс), - rbuf, rcount, rtype - параметры сообщения, принимаемого в процессах, - root – ранг процесса, выполняющего рассылку данных, - comm - коммуникатор, в рамках которого выполняется передача данных.

Распределение данных l l 5 Вызов MPI_Scatter при выполнении рассылки данных должен быть обеспечен Распределение данных l l 5 Вызов MPI_Scatter при выполнении рассылки данных должен быть обеспечен в каждом процессе коммуникатора, MPI_Scatter передает всем процессам сообщения одинакового размера. Если размеры сообщений для процессов могут быть разными, следует использовать функцию MPI_Scatterv.

Сбор данных - передача данных от всех процессоров одному процессу является обратной к операции Сбор данных - передача данных от всех процессоров одному процессу является обратной к операции распределения данных int MPI_Gather(void *sbuf, int scount, MPI_Datatype stype, void *rbuf, int rcount, MPI_Datatype rtype, int root, MPI_Comm comm), где - sbuf, scount, stype - параметры передаваемого сообщения, - rbuf, rcount, rtype - параметры принимаемого сообщения, - root – ранг процесса, выполняющего сбор данных, - comm - коммуникатор, в рамках которого выполняется передача данных. 6

Сбор данных l 7 MPI_Gather определяет коллективную операцию, и ее вызов при выполнении сбора Сбор данных l 7 MPI_Gather определяет коллективную операцию, и ее вызов при выполнении сбора данных должен быть обеспечен в каждом процессе коммуникатора

Сбор и рассылка данных 8 MPI_Gather собирает данные на одном процессе. Для получения всех Сбор и рассылка данных 8 MPI_Gather собирает данные на одном процессе. Для получения всех собираемых данных на каждом процессе нужно использовать функцию сбора и рассылки: int MPI_Allgather(void *sbuf, int scount, MPI_Datatype stype, void *rbuf, int rcount, MPI_Datatype rtype, MPI_Comm comm) В случае, когда размеры передаваемых процессами сообщений могут быть различны, для передачи данных необходимо использовать функции MPI_Gatherv и MPI_Allgatherv.

Общая передача данных от всех процессов всем процессам… 9 Общая передача данных от всех процессов всем процессам… 9

Общая передача данных от всех процессов всем процессам… 10 int MPI_Alltoall(void *sbuf, int scount, Общая передача данных от всех процессов всем процессам… 10 int MPI_Alltoall(void *sbuf, int scount, MPI_Datatype stype, void *rbuf, int rcount, MPI_Datatype rtype, MPI_Comm comm), где - sbuf, scount, stype - параметры передаваемых сообщений, - rbuf, rcount, rtype - параметры принимаемых сообщений - comm - коммуникатор, в рамках которого выполняется передача данных. l Вызов функции MPI_Alltoall при выполнении операции общего обмена данными должен быть выполнен в каждом процессе коммуникатора, l Вариант операции общего обмена данных, когда размеры передаваемых процессами сообщений могут быть различны обеспечивается при помощи функций MPI_Alltoallv

Дополнительные операции редукции данных… 11 MPI_Reduce обеспечивает получение результатов редукции данных только на одном Дополнительные операции редукции данных… 11 MPI_Reduce обеспечивает получение результатов редукции данных только на одном процессе, Функция MPI_All. Reduce редукции и рассылки выполняет рассылку между процессами всех результатов операции редукции: int MPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype, MPI_Op op, MPI_Comm comm)

Дополнительные операции редукции данных… Возможность управления распределением этих данных между процессами предоставляется функций MPI_Reduce_scatter, Дополнительные операции редукции данных… Возможность управления распределением этих данных между процессами предоставляется функций MPI_Reduce_scatter, Функция MPI_Scan производит операцию сбора и обработки данных, при которой обеспечивается получение и всех частичных результатов редуцирования int MPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype, MPI_Op op, MPI_Comm comm) 12

Дополнительные операции редукции данных… При выполнении функции MPI_Scan элементы получаемых сообщений представляют собой результаты Дополнительные операции редукции данных… При выполнении функции MPI_Scan элементы получаемых сообщений представляют собой результаты обработки соответствующих элементов передаваемых процессами сообщений, при этом для получения результатов на процессе с рангом i, 0 i

Умножение матрицы на вектор Задача умножения матрицы на вектор может быть сведена к выполнению Умножение матрицы на вектор Задача умножения матрицы на вектор может быть сведена к выполнению m независимых операций умножения строк матрицы A на вектор b 14

Способы распределения данных: ленточная схема Непрерывное (последовательное) распределение горизонтальные полосы 15 вертикальные полосы Способы распределения данных: ленточная схема Непрерывное (последовательное) распределение горизонтальные полосы 15 вертикальные полосы

Последовательный алгоритм for ( i = 0; i < m; i++ ) { c Последовательный алгоритм for ( i = 0; i < m; i++ ) { c [ i ] = 0; for ( j = 0; j < n; j++ ) { c [ i ] += A [ i ][ j ] * b [ j ]; } } 16

Умножение матрицы на вектор Распределение данных – ленточная схема (разбиение матрицы по строкам) Базовая Умножение матрицы на вектор Распределение данных – ленточная схема (разбиение матрицы по строкам) Базовая подзадача - операция скалярного умножения одной строки матрицы на вектор 17

Выделение информационных зависимостей 18 Базовая подзадача для выполнения вычисления должна содержать строку матрицы А Выделение информационных зависимостей 18 Базовая подзадача для выполнения вычисления должна содержать строку матрицы А и копию вектора b. После завершения вычислений каждая базовая подзадача будет содержать один из элементов вектора результата c Для объединения результатов расчетов и получения полного вектора c на каждом из процессоров вычислительной системы необходимо выполнить операцию обобщенного сбора данных

Программная реализация Главная функция программы реализует логику работы алгоритма, последовательно вызывая необходимые подпрограммы. void Программная реализация Главная функция программы реализует логику работы алгоритма, последовательно вызывая необходимые подпрограммы. void main (int argc, char *argv[ ]) { double *p. Matrix; //исходная матрица double *p. Vector; //исходный вектор double *p. Result; //результат умножения int Size; //размеры исходных матрицы и вектора double *p. Proc. Rows; //часть матрицы на процессе double *p. Proc. Result; //результаты вычислений процесса int Row. Num; double Start, Finish, Duration; int Proc. Num, Proc. Rank; 19

Программная реализация 20 MPI_Init (&argc, &argv); MPI_Comm_size (MPI_COMM_WORLD, &Proc. Num); MPI_Comm_rank (MPI_COMM_WORLD, &Proc. Rank); Программная реализация 20 MPI_Init (&argc, &argv); MPI_Comm_size (MPI_COMM_WORLD, &Proc. Num); MPI_Comm_rank (MPI_COMM_WORLD, &Proc. Rank); //выделение памяти и инициализация исходных //данных Proc. Init (p. Matrix, p. Vector, p. Result, p. Proc. Rows, p. Proc. Result, Size, Row. Num); //распределение исходных данных между //процессорами Data. Distrib (p. Matrix, p. Proc. Rows, p. Vector, Size, Row. Num);

Программная реализация //параллельное выполнение умножения матрицы на вектор Paral. Res. Calc (p. Proc. Rows, Программная реализация //параллельное выполнение умножения матрицы на вектор Paral. Res. Calc (p. Proc. Rows, p. Vector, p. Proc. Result, Size, Row. Num); //сбор результирующего вектора на всех процессах Res. Replication (p. Proc. Result, p. Result, Size, Row. Num); //завершение процесса вычислений Proc. Termination (p. Matrix, p. Vector, p. Result, p. Proc. Rows, p. Proc. Result); MPI_Finalize (); 21 }

Функция Proc. Init 22 Задает размер и элементы для матрицы A и вектора b Функция Proc. Init 22 Задает размер и элементы для матрицы A и вектора b void Proc. Init (double *p. Matrix, double *p. Vector, double *p. Result, double *p. Proc. Rows, double *p. Proc. Result, int Size, int Row. Num) { int Rest. Rows; //кол-во строк матрицы, которые еще не //распределены int i; if (Proc. Rank == 0) { do {

Функция Proc. Init printf(“n. Введите размер матрицы: ”); scanf(“%d”, &Size); if (Size < Proc. Функция Proc. Init printf(“n. Введите размер матрицы: ”); scanf(“%d”, &Size); if (Size < Proc. Num) printf (“Малый размерn”); } while (Size < Proc. Num); 23 } MPI_Bcast(&Size, 1, MPI_INT, 0, MPI_COMM_WORLD); Rest. Rows = Size; for (i = 0; i < Proc. Rank; i++) Rest. Rows = Rest. Rows – Rest. Rows/(Proc. Num - 1) Row. Num = Rest. Rows / (Proc. Num - Proc. Rank);

Функция Proc. Init p. Vector = new double [Size]; p. Result = new double Функция Proc. Init p. Vector = new double [Size]; p. Result = new double [Size]; p. Proc. Rows = new double [Row. Num * Size]; p. Proc. Result = new double [Row. Num]; if (Proc. Rank == 0) { p. Matrix = new double [Size * Size]; Random. Data. Init (p. Matrix, p. Vector, Size); //функцию задать самостоятельно } } 24

Функция Data. Distrib 25 Осуществляет рассылку вектора b и распределение строк исходной матрицы A Функция Data. Distrib 25 Осуществляет рассылку вектора b и распределение строк исходной матрицы A по процессам. void Data. Distrib (double *p. Matrix, double *p. Proc. Rows, double *p. Vector, int Size, int Row. Num) { int *p. Send. Num; //кол-во элементов, посылаемых //процессу int *p. Send. Ind; //индекс первого элемента данных, //посылаемого процессу int Rest. Rows = Size; //кол-во строк матрицы, которые //еще не распределены MPI_Bcast (p. Vector, Size, MPI_DOUBLE, 0, MPI_COMM_WORLD);

Функция Data. Distrib 26 //выделение памяти для хранения временных //объектов p. Send. Ind = Функция Data. Distrib 26 //выделение памяти для хранения временных //объектов p. Send. Ind = new int [Proc. Num]; p. Send. Num = new int [Proc. Num]; //определение положения строк матрицы, //предназначенных каждому процессу Row. Num = Size / Proc. Num; p. Send. Num [ 0 ] = Row. Num + Size; p. Send. Ind [ 0 ] = 0; for (int i = 1; i < Proc. Num; i++) { Rest. Rows = Rest. Rows – Row. Num;

Функция Data. Distrib Row. Num = Rest. Rows / (Proc. Num - i); p. Функция Data. Distrib Row. Num = Rest. Rows / (Proc. Num - i); p. Send. Num [ i ] = Row. Num * Size; p. Send. Ind [ i ] = p. Send. Ind [ i-1 ] + p. Send. Num [ i-1 ]; }; //рассылка строк матрицы MPI_Scatterv (p. Matrix, PSend. Num, p. Send. Ind, MPI_DOUBLE, p. Proc. Rows, p. Send. Num[Proc. Rank], MPI_DOUBLE, 0, MPI_COMM_WORLD); //освобождение памяти delete [] p. Send. Num; delete [] p. Send. Ind; 27 }

Функция Paral. Res. Calc 28 Вычисление части результирующего вектора void Paral. Res. Calc (double Функция Paral. Res. Calc 28 Вычисление части результирующего вектора void Paral. Res. Calc (double *p. Proc. Rows, double *p. Vector, double *p. Proc. Result, int Size, int Row. Num) { int i, j; for (i = 0; i < Row. Num; i++) { p. Proc. Result [i] = 0; for (j = 0; j < Size; j++) p. Proc. Result [i] = p. Proc. Result [ i ] + p. Proc. Rows[i * Size + j] * p. Vector[ j ]; } }

Функция Res. Replication Объединяет блоки результирующего вектора c, полученного на разных процессах и копирует Функция Res. Replication Объединяет блоки результирующего вектора c, полученного на разных процессах и копирует вектор результата на все процессы. void Res. Replication (double *p. Proc. Result, double *p. Result, int Size, int Row. Num) { int *p. Receive. Num; //кол-во элементов, посылаемых процессом int *p. Receive. Ind; //индекс элемента данных в результирующем векторе int Rest. Rows = Size; //кол-во строк матрицы, которые еще не распределены int i; 29

Функция Res. Replication 30 //выделение памяти для временных объектов p. Receive. Ind = new Функция Res. Replication 30 //выделение памяти для временных объектов p. Receive. Ind = new int [Proc. Num]; p. Receive. Num = new int [Proc. Num]; //определение положения блоков результирующего вектора p. Receive. Ind [ 0 ] = 0; p. Receive. Num [ 0 ] = Size / Proc. Num; for (i = 1; i < Proc. Num; i++) { Rest. Rows = Rest. Rows – p. Receive. Num [i-1]; p. Receive. Num [i] = Rest. Rows / (Proc. Num - 1); p. Receive. Ind [i] = p. Receive. Ind [i-1] + p. Receive. Num [i-1] }

Функция Res. Replication //сбор всего вектора на всех процессах MPI_Allgatherv (p. Proc. Result, p. Функция Res. Replication //сбор всего вектора на всех процессах MPI_Allgatherv (p. Proc. Result, p. Receive. Num[Proc. Rank], MPI_DOUBLE, p. Result, p. Receive. Num, p. Receive. Ind, MPI_DOUBLE, MPI_COMM_WORLD); //освобождение памяти delete [] p. Receive. Num; delete [] p. Receive. Ind; } 31

Самостоятельно 1. Дописать функции a) b) 2. 32 Random. Data. Init (p. Matrix, p. Самостоятельно 1. Дописать функции a) b) 2. 32 Random. Data. Init (p. Matrix, p. Vector, Size) Proc. Termination (p. Matrix, p. Vector, p. Result, p. Proc. Rows, p. Proc. Result). Запустить доработанную программу на кластере.

Итоги Мы рассмотрели: Функции коллективной передачи данных, функции управления группами процессов и коммуникаторами, пример Итоги Мы рассмотрели: Функции коллективной передачи данных, функции управления группами процессов и коммуникаторами, пример параллельной программы умножения матрицы на вектор. 33