КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Программа умножения матрицы на вектор
Результатом умножения матрицы на вектор является вектор результата. Для решения задачи используется алгоритм, в котором один процесс (главный) координирует работу других процессов (подчиненных). Для наглядности единая программа матрично-векторного умножения разбита на три части: общую часть, код главного процесса и код подчиненного процесса. В общей части программы описываются основные объекты задачи: матрица А, вектор b, результирующий вектор с, определяется число процессов (не меньше двух). Задача разбивается на две части: главный процесс (master) и подчиненные процессы. В задаче умножения матрицы на вектор единица работы, которую нужно раздать процессам, состоит из скалярного произведения строки матрицы A на вектор b. Знаком! отмечены комментарии.
program main use mpi integer MAX_ROWS, MAX_COLS, rows, cols parameter (MAX_ROWS = 1000, MAX_COLS = 1000) ! матрица А, вектор b, результирующий вектор с double precision a(MAX_ROWS,MAX_COLS), b(MAX_COLS), с(MAX_ROWS) double precision buffer (MAX_COLS), ans /* ans – имя результата*/ integer myid, master, numprocs, ierr, status (MPI_STATUS_SIZE) integer i, j, numsent, sender, anstype, row /* numsent – число посланных строк, sender – имя процесса-отправителя, anstype – номер посланной строки*/ call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, numprocs, ierr) ! главный процесс – master master = 0 ! количество строк и столбцов матрицы А rows = 100 cols = 100 if (myid.eq. master) then ! код главного процесса else ! код подчиненного процесса endif call MPI_FINALIZE(ierr) stop end
Код главного процесса. Единицей работы подчиненного процесса является умножение строки матрицы на вектор. ! инициализация А и b do 20 j = 1, cols b(j) = j do 10 i = 1, rows a(i,j) = i 10 continue 20 continue numsent = 0 ! посылка b каждому подчиненному процессу call MPI_BCAST(b, cols, MPI_DOUBLE_PRECISION, master, MPI_COMM_WORLD, ierr) ! посылка строки каждому подчиненному процессу; в TAG номер строки = i do 40 i = 1,min(numprocs-l, rows) do 30 j = I, cols buffer(j) = a(i,j) 30 continue call MPI_SEND(buffer, cols, MPI_DOUBLE_PRECISION, i, i, MPI_COMM_WORLD, ierr) numsent = numsent + l 40 continue ! прием результата от подчиненного процесса do 70 i = 1, rows ! MPI_ANY_TAG – указывает, что принимается любая строка call MPI_RECV(ans, 1, MPI_DOUBLE_PRECISION, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, status, ierr) sender = status (MPI_SOURCE) anstype = status (MPI_TAG) ! определяем номер строки c(anstype) = ans if (numsent.lt. rows) then ! посылка следующей строки do 50 j = 1, cols buffer(j) = a(numsent+l, j) 50 continue call MPI_SEND (buffer, cols, MPI_DOUBLE_PRECISION, sender, numsent+l, MPI_COMM_WORLD, ierr) numsent = numsent+l else ! посылка признака конца работы call MPI_SEND(MPI_BOTTQM, 0, MPI_DOUBLE_PRECISION,sender, 0, MPI_COMM_WORLD, ierr) endif 70 continue
Сначала главный процесс передает вектор b в каждый подчиненный про- цесс, затем пересылает одну строку матрицы A в каждый подчиненный процесс. Главный процесс, получая результат от очередного подчиненного процесса, пе- редает ему новую работу. Цикл заканчивается, когда все строки будут розданы и получены результаты. При передаче данных из главного процесса в параметре tag указывается номер передаваемой строки. Этот номер после вычисления произведения вме- сте с результатом будет отправлен в главный процесс, чтобы главный процесс знал, где размещать результат. Подчиненные процессы посылают результаты в главный процесс и пара- метр MPI_ANY_TAG в операции приема главного процесса указывает, что главный процесс принимает строки в любой последовательности. Параметр status обеспечивает информацию, относящуюся к полученному сообщению. В языке Fortran это – массив целых чисел размера MPI_STATUS_SIZE. Аргу- мент SOURCE содержит номер процесса, который послал сообщение, по этому адресу главный процесс будет пересылать новую работу. Аргумент TAG хра- нит номер обработанной строки, что обеспечивает размещение полученного ре- зультата. После того как главной процесс разослал все строки матрицы А, на запросы подчиненных процессов он отвечает сообщением с отметкой 0. Код подчиненного процесса. ! прием вектора b всеми подчиненными процессами call MPI_BCAST(b, cols, MPI_DOUBLE_PRECISION, master, MPI_COMM_WORLD, ierr) ! выход, если процессов больше количества строк матрицы if (numprocs.gt. rows) goto 200 ! прием строки матрицы 90 call MPI_RECV(buffer, cols, MPI_DOUBLE_PRECISION, master, MPI_ANY_TAG, MPI_COMM_WORLD, status, ierr) if (status (MPI_TAG).eq. 0) then go to 200 ! конец работы else row = status (MPI_TAG) ! номер полученной строки ans = 0.0 do 100 i = 1, cols ! скалярное произведение векторов ans = ans+buffer(i)*b(i) 100 continue ! передача результата головному процессу call MPI_SEND(ans,1,MPI_DOUBLE_PRECISION,master,row, MPI_COMM_WORLD, ierr) go to 90 ! цикл для приема следующей строки матрицы endif 200 continue Каждый подчиненный процесс получает вектор b. Затем организуется цикл, состоящий в том, что подчиненный процесс получает очередную строку матрицы А, формирует скалярное произведение строки и вектора b, посылает результат главному процессу, получает новую строку и так далее.
Дата добавления: 2014-01-07; Просмотров: 557; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |