Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

parallel

.pdf
Скачиваний:
167
Добавлен:
13.02.2015
Размер:
2.11 Mб
Скачать

c Каждый процесс определяет первый и последний столбец

c своих расчетов

 

BCol = Rank*Nm/Size+1

 

ECol = (Rank+1)*Nm/Size

c «0»-процесс рассылает всем матрицы А и В

 

Call MPI_BCAST(A(1,1), Nm*Nm,

$

MPI_DOUBLE_PRECISION, 0,

$

MPI_COMM_WORLD, Ierr)

 

Call MPI_BCAST(B(1,1), Nm*Nm,

$

MPI_DOUBLE_PRECISION, 0,

$

MPI_COMM_WORLD, Ierr)

c Каждый процесс ведет расчет свой полосы матрицы С

Do J = BCol, ECol Do K = 1,Nm Do I = 1,Nm

C(I,J) = C(I,J)+A(I,K)*B(K,J) End Do

End Do

End Do

c Каждый процесс производит рассылку своей полосы c остальным процессам

 

Do K = 0,Size-1

c Nr – ширина полосы К-го процесса

 

Nr = (K+1)*Nm/Size-K*Nm/Size

 

Call MPI_BCAST(C(1,K*Nm/Size+1), Nm*Nr,

$

MPI_DOUBLE_PRECISION,K,

$

MPI_COMM_WORLD, Ierr)

 

End Do

 

if (Rank.eq.0) write(6,*) "A=",A

 

if (Rank.eq.0) write(6,*) "B=",B

 

if (Rank.eq.0) write(6,*) "C=",C

Call MPI_FINALIZE(Ierr)

Stop

End

91

Стоит обратить внимание на то, каким образом определяется ширина полосы рассылаемых данных: Nr = (K+1)*Nm/Size- K*Nm/Size. Так как при вычислении Nr используется целочисленное деление, то значение Nr для разных процессов, вообще говоря, разное и не равно Nm/Size.

Способ улучшения предложенного алгоритма напрашивается сам собой – если в определении полосы матрицы C используется лишь такая же полоса матрицы В, а не вся матрица целиком, то каждому процессу достаточно послать лишь свою полосу (рис. 5.5).

A

 

B

C

 

 

1 2 3 4 5 6

 

1 2 3 4 5 6

 

 

 

 

 

Рис. 5.5 Умножение матриц (улучшенный алгоритм)

Так как ширина рассылаемой полосы различна для разных процессов, то удобнее всего будет воспользоваться векторным вариантом функции распределения блоков данных по всем процессам – функцией SCATTERV.

Сбор результатов умножения будет выполняться при вызове функции MPI_ALLTOALLV, которая позволяет каждому процессу распределять по всем процессам свои данные и одновременно получать данные других процессов, причем объем данных может быть различным для разных процессов (эта функция является наиболее мощной и гибкой из всего семейства коллективных операций MPI, но одновременно и наиболее сложной в использовании).

Program Example

 

Implicit None

 

Include 'mpif.h'

 

Integer Rank, Size, Ierr, Nm, I, J, K, BCol, ECol, Nr

C Nm - порядок матрицы

 

Parameter(Nm=100)

 

Double Precision A(Nm,Nm), B(Nm,Nm), Bc(Nm,Nm),

$

C(Nm,Nm), Cc(Nm,Nm)

 

Integer Counts(0:Nm), Shifts(0:Nm),

$

Counts2(0:Nm), Shifts2(0:Nm)

92

Call MPI_INIT(Ierr)

Call MPI_COMM_SIZE(MPI_COMM_WORLD, Size, Ierr) Call MPI_COMM_RANK(MPI_COMM_WORLD, Rank, Ierr)

C Задаются начальные значения матриц А и В

If (Rank.eq.0) Then Do I = 1,Nm

Do J = 1,Nm A(I,J) = I*J*1D0 B(I,J) = 1/A(I,J) End Do

End Do

End If

C Каждый процесc определяет первый и последний столбец C своих расчетов

BCol = Rank*Nm/Size+1

ECol = (Rank+1)*Nm/Size

C Каждый процесc определяет свои массивы размера полоc и C их положение

Do I = 0,Size-1

Counts(I) = ((I+1)*Nm/Size-I*Nm/Size)*Nm Shifts(I) = I*Nm/Size*Nm

End Do

Do I = 0,Size-1

Shifts2(I) = Shifts(Rank)

 

Counts2(I) = Counts(Rank)

 

End Do

C «0» посылает всем процессам матрицу А и соответствующую

C полосу матрицы В

 

Call MPI_BCAST(A(1,1), Nm*Nm,

$

MPI_DOUBLE_PRECISION, 0,

$

MPI_COMM_WORLD, Ierr)

 

Call MPI_SCATTERV(B(1,1), Counts, Shifts,

$

MPI_DOUBLE_PRECISION, Bc(1,1),

$

Counts(Rank),MPI_DOUBLE_PRECISION,

$

0, MPI_COMM_WORLD, Ierr)

Do J = BCol,ECol

Do K = 1,Nm

Do I = 1,Nm

C(I,J) = C(I,J)+A(I,K)*Bc(K,J-BCol+1)

93

End Do

End Do

End Do

C Каждый процесс отправляет свою рассчитанную полосу C C и заполняет недостающие полосы данными, поступающими

Cот других процессов

Call MPI_ALLTOALLV(C(1,1), Counts2, Shifts2,

$

MPI_DOUBLE_PRECISION, Cc(1,1), Counts,

$

Shifts, MPI_DOUBLE_PRECISION,

$

MPI_COMM_WORLD, Ierr)

if (Rank.eq.0) write(6,*) "A=",A if (Rank.eq.0) write(6,*) "B=",B if (Rank.eq.0) write(6,*) "C=",Cc Call MPI_FINALIZE(Ierr)

End

Итак, сначала каждый процесс получает матрицу А и свой блок матрицы В. Таким образом, на каждом процессе в массиве (в первых его столбцах) появляются значения, соответствующие выбранному блоку матрицы В. Обратите внимание, обращение к матрице Bc несколько иное, чем в предыдущем примере к матрице В. После проведения вычисления на каждом процессе содержится матрица C с соответствующей рассчитанной полосой. После проведения «коллективного обмена информацией» на каждом процессе содержатся идентичные массивы Сc с результатом перемножения.

Обсудим подробнее вопросы о том, как подготавливается и производится сложный процесс обмена. В примере используются два массива смещений Shifts, Shifts2 и два массива «размеров» пересылаемых блоков. Содержимое этих массивов для случая использования трех процессов следующее:

Таблица 5.3 Значения массивов смещений и размеров блоков для случая трех процессов

 

«0»-процесс

«1»-процесс

«2»-процесс

Counts

3300 3300 3400

3300 3300 3400

3300 3300 3400

Shifts

0

3300 6600

0

3300 6600

0

3300 6600

Counts2

3300 3300 3300

3300 3300 3300

3400 3400 3400

Shifts2

0

0

0

3300 3300 3300

6600 6600 6600

94

При рассылке функцией SCATTERV используются массивы Counts и Shifts. В соответствии с их содержимым «0»-процессу посылаются 3300 элементов (33 столбца) матрицы В, «1»-процессу посылаются 3300 элементов (33 столбца) матрицы В, начиная с 3300-го элемента (с первого элемента 34-го столбца), а «2»-процессу посылаются оставшиеся 3400 элементов (последние 34 столбца) матрицы В.

При обмене данными MPI_ALLTOALLV каждый «0»-процесс посылает всем по 3300 элементов матрицы С (свои рассчитанные 33 столбца) и получает от «1»-процесса 3300 элементов и от «2»-процесса 3400 элементов матрицы С. Причем рассылка ведется в таком случае первых 33 столбцов (Shifts2), а получение – со сдвигами в соответствии с Shifts. Как можно заметить, каждый процесс отправляет всем одни и те же данные и заботится о правильном распределении полученных от других процессов данных.

5.3Задания

1.Написать программу умножения матриц размером 1500х1500. Оценить время выполнения вычислений для различных вариантов порядка следования вложенных циклов. Дать объяснение полученным результатам.

2.Написать программу умножения блочных матриц размером 1000х1000. Определить размер блоков, при котором достигается минимальное время выполнения программы. Дать объяснение полученным результатам. Провести сравнение с подпрограммой DGEMM из пакета BLAS3.

3.Написать MPI-программу, которая считывает из файла или вычисляет по заданной формуле вещественную матрицу А={аij} i=1,2,.. .,n; j=1,2,…,n, рассылает ее по процессорным элементам и определяет номер строки, максимально удаленной от первой строки заданной матрицы. Расстояние между k-й и i-й строками матрицы A

n

определяется как akj aij . Обеспечить равномерную за-

j 1

грузку всех процессорных элементов, участвующих в работе программы.

4. Написать MPI-программу умножения матрицы A на вектор b. Параллельная программа должна считывать из файла или вычислять по заданной формуле вещественную матрицу A размерности n n и

95

вектор b размерности n. Обеспечить равномерную загрузку всех процессорных элементов, участвующих в работе программы.

5. Написать MPI-программу, которая считывает из файла или вычисляет по заданной формуле вещественную матрицу А={аij} i=1,2,...,n; j=1,2,…,n, и определяет норму заданной матрицы

n

max аij . Обеспечить равномерную загрузку всех процессор-

1 i n

j 1

 

ных элементов, участвующих в работе программы. Исследовать ускорение и эффективность полученной параллельной программы.

6.Написать MPI-программу умножения матрицы A на матрицу B. Программа должна считывать из файла или вычислять по заданной формуле соответствующую часть (блок) матриц вещественных чисел A и B размерности n n. Исследовать ускорение и эффективность полученной параллельной программы.

7.Написать MPI-программу, которая считывает из файла или вычисляет по заданной формуле матрицу А={аij} i=1,2,...,n; j=1,2,…,n вещественных чисел и заменяет матрицу А на матрицу (А+АТ)/2, где АТ – транспонированная матрица А. Обеспечить равномерную загрузку всех процессорных элементов, участвующих в работе программы.

8.Написать MPI-программу, которая производит сглаживание исходной матрицы А. Операция сглаживания дает новую матрицу того же размера, каждый элемент которой получается как среднее арифметическое имеющихся соседей соответствующего элемента исходной матрицы. Соседями элемента аij в матрице назовем эле-

менты аkl

i–1 k i+1, j–1 l j+1, (k,l) (i,j). Программа должна

считывать

из файла

или вычислять по заданной формуле соот-

ветствующую часть

(блок) вещественной матрицы А={аij}

i=1,2,...,n;

j=1,2,…,n размерности n n.

9.Написать MPI-программу, которая определяет количество локальных минимумов матрицы А и находит максимум среди всех локальных минимумов. Элемент матрицы аij называется локальным минимумом, если он строго меньше имеющихся у него соседей.

10.Написать MPI-программу, которая среди строк заданной целочисленной матрицы находит строку с минимальной суммой модулей элементов.

11.Написать MPI-программу, которая среди столбцов заданной

матрицы А, содержащей элементы аij <5, находит столбец с ми-

нимальным произведением элементов.

96

12.Для заданной симметричной матрицы, используя степенной метод, найти ее спектральный радиус. Матрица имеет вид

0 2 2 2 n

2 2 0 2 n 1

 

 

 

 

 

.

 

 

 

n

 

n 1

 

 

 

2

2

 

0

 

 

 

 

 

13.Написать MPI-программу решения системы линейных уравнений Ax b методом Якоби, представленным в матрично-

векторной форме: xk 1 D 1(D A)xk D 1b,k 0,1,2,... В матрице A все элементы равны 1 за исключением элементов, расположенных на главной диагонали, которые равны 2n ; n – размерность

матрицы. Диагональная матрица D aii . Все компоненты вектора

bимеют значение 3n 1.

14.Написать MPI-программу решения системы линейных урав-

нений Ax b

методом

Зейделя в матрично-векторной форме:

x

(D L) 1

(D L A)x

 

(D L) 1b,k 0,1,2,... Здесь D – диа-

k 1

 

k

 

гональная матрица, составленная из элементов матрицы A, расположенных на главной диагонали; L – нижняя треугольная матрица, ненулевые элементы которой совпадают с элементами матрицы A, расположенными ниже главной диагонали. В матрице A aii 1для

нечетных i , aii 2 для четных i , кроме того, aii 1 0.5, а все ос-

тальные элементы равны нулю; n – размерность матрицы.

97

6 СИСТЕМЫ ЛИНЕЙНЫХ АЛГЕБРАИЧЕСКИХ УРАВНЕНИЙ

Основная задача вычислительной линейной алгебры – это решение систем линейных алгебраических уравнений (СЛАУ):

a11x1 a12x2 ... a1nxn b1,

a21x1

a22 x2

... a2nxn

b2

,

 

 

...

 

(6.1)

 

 

 

 

an1x1

an2 x2

... ann xn

bn.

Предполагается, что матрица А неособенная, det A 0 , т.е. решение системы (6.1) единственно.

Численные методы решения СЛАУ делятся на две большие группы: прямые и итерационные. Прямые методы при отсутствии ошибок округления за конечное число арифметических операций позволяют получить точное решение x* . В итерационных методах задается начальное приближение x0 и строится последовательность

приближенных решений

 

xk

 

x* , где

k – номер итерации.

 

 

k

 

В действительности итерационный процесс прекращается, как только xk становится достаточно близким к x* .

Итерационные методы привлекательнее с точки зрения объема вычислений и требуемой памяти, когда решаются системы с матрицами высокой размерности. При небольших порядках системы используют прямые методы либо прямые методы в сочетании с итерационными методами.

6.1 Решение СЛАУ методом Гаусса

Рассмотрим систему линейных алгебраических уравнений

Ax b

с невырожденной матрицей A размерностью n n . Будем считать матрицу A заполненной, т.е. содержащей небольшое число ненулевых элементов.

Одним из прямых методов решения линейных систем (6.1) является применение метода исключения Гаусса. Суть этого метода состоит в том, что матрица A сначала упрощается – приводится эквивалентными преобразованиями к треугольному или диагональному

98

виду, а затем решается система с упрощенной матрицей. Наиболее известной формой гауссова исключения является та, в которой система линейных уравнений приводится к верхнетреугольному виду путём вычитания одних уравнений, умноженных на подходящие числа из других уравнений. Полученная треугольная система решается с помощью обратной подстановки.

Приведем псевдокод прямого хода метода Гаусса, где значения верхнетреугольной матрицы в процессе вычислений переписываются в соответствующие элементы матрицы A :

do k=1,n-1 do i=k+1,n

lik = aik/akk

end do

do j=k+1,n+1 do i=k+1,n

aij = aij – lik*akj

end do end do

end do

В цикле j производится вычитание k -й строки матрицы A , умноженной на соответствующее число, из расположенных ниже строк. Правая часть системы (6.1) b добавлена к матрице A (столбец n +1) и обрабатывается в ходе приведения к треугольному виду.

Рассмотрим параллельный алгоритм метода Гаусса. Для сбалансированной загрузки процессоров исходная матрица коэффициентов A распределяется по p процессорным элементам (ПЭ) циклически, т.е. первая строка расширенной матрицы помещается в 0-й ПЭ, вторая – в 1-й ПЭ, и т.д., р-я – в (р-1)-й ПЭ. Затем (р+1)-я снова поме-

щается в 0-й ПЭ, (р+2)-я – в 1-й ПЭ и т.д. (рис. 6.1).

 

 

 

 

 

 

строки:

 

строки:

строки:

строки:

1

 

2

 

m

 

p

p+1

 

p+2

p+m

 

2p

 

(k-1)p+1

 

(k-1)p+2

 

(k-1)p+m

 

kp

ПЭ 0

 

ПЭ 1

 

ПЭ m-1

 

ПЭ p-1

 

 

 

 

 

 

 

Рис. 6.1 Циклическая строчная схема распределения уравнений системы (6.1) по процессорным элементам. k n/ p

99

Строку, которая вычитается из всех остальных строк, после предварительного умножения на нужные коэффициенты, назовем текущей строкой. Общая нумерация строк во всей матрице не совпадает с индексацией строк в каждом ПЭ. В каждом ПЭ индексация строк в массиве начинается с единицы.

Алгоритм прямого хода заключается в следующем. Сначала текущей строкой является строка с индексом 1 в 0-м ПЭ, затем строка с индексом 1 в 1-м ПЭ и т.д., и, наконец, строка с индексом 1 в последнем по номеру ПЭ. После чего цикл по процессорным элементам повторяется и текущей строкой становится строка с индексом 2 в 0-м ПЭ, затем строка с индексом 2 в 1-м ПЭ и т.д. После прямого хода строки матрицы в каждом ПЭ будут иметь вид, показанный на рис. 6.2 (пример приведен для четырех ПЭ, * – вещественные числа).

 

1 * * * * * * * * * * * * * * *

 

0 1 * * * * * * * * * * * * * *

 

0 0 0 0 1 * * * * * * * * * * *

 

0 0 0 0 0 1 * * * * * * * * * *

0 ПЭ

0 0 0 0 0 0 0 0 1 * * * * * * *

1 ПЭ

0 0 0 0 0 0 0 0 0 1 * * * * * *

0 0 0 0 0 0 0 0 0 0 0 0 1 * * *

0 0 0 0 0 0 0 0 0 0 0 0 0 1 * *

 

 

 

 

 

 

 

 

 

0 0 1 * * * * * * * * * * * * *

 

0 0 0 1 * * * * * * * * * * * *

2 ПЭ

0 0 0 0 0 0 1 * * * * * * * * *

3 ПЭ

0 0 0 0 0 0 0 1 * * * * * * * *

0 0 0 0 0 0 0 0 0 0 1 * * * * *

0 0 0 0 0 0 0 0 0 0 0 1 * * * *

 

0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 *

 

3 ПЭ

 

 

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1

 

 

 

 

 

 

 

 

Рис. 6.2 Вид строк матрицы после прямого хода метода Гаусса

Аналогично последовательно по узлам, начиная с последнего по номеру ПЭ, осуществляется обратный ход метода Гаусса.

Особенностью этого алгоритма является то, что как в прямом, так и при обратном ходе ПЭ являются более равномерно загруженными. Процессорные элементы активны в течение всего времени вычислений, и пересылка строк осуществляется всегда на все ПЭ.

Приведем параллельную Фортран-программу численного решения рассмотренным методом системы линейных уравнений с полнозаполненной матрицей, предполагая, что на главной диагонали матрицы в процессе вычислений всегда получаются ненулевые элементы.

100

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]