| |
Пример 6.1
Мы показываем, как реализовать общее присваивание A=B(map)
, где
у
A
, B
и map
распределены одинаковым образом,
и map
является перестановочным вектором.
Для простоты, мы рассмотрим блочное распределение с блоками одинакового размера.
SUBROUTINE MAPVALS(A, B, map, m, comm, p) USE MPI INTEGER m, map(m), comm, p REAL A(m), B(m) INTEGER otype(p), oindex(m), & ! Используется для построения типов данных инициатора ttype(p), tindex(m), & ! Используется для построения типов данных адресата count(p), total(p), & sizeofreal, win, ierr ! Эта часть делает работу, которая зависит от расположения B. ! Может многократно использоваться, пока расположение не изменяется CALL MPI_TYPE_EXTENT(MPI_REAL, sizeofreal, ierr) CALL MPI_WIN_CREATE(B, m*sizeofreal, sizeofreal, MPI_INFO_NULL, & comm, win, ierr) ! Эта часть делает работу, которая зависит от значения MAP и ! расположения массивов. ! Может многократно использоваться, пока те не изменяются ! Вычисляет число записей, которые будут получены от каждого процесса DO i=1,p count(i) = 0 END DO DO i=1,m j = map(i)/m+1 count(j) = count(j)+1 END DO total(1) = 0 DO i=2,p total(i) = total(i-1) + count(i-1) END DO DO i=1,p count(i) = 0 END DO ! Вычисляет origin и target индексы записей. ! Запись i в данном процессе получена из позиции ! k в процессе (j-1), где map(i) = (j-1)*m + (k-1), ! j = 1..p и k = 1..m DO i=1,m j = map(i)/m+1 k = MOD(map(i),m)+1 count(j) = count(j)+1 oindex(total(j) + count(j)) = i tindex(total(j) + count(j)) = k END DO ! Создает типы данных инициатора и адресата для каждой операции GET DO i=1,p CALL MPI_TYPE_INDEXED_BLOCK(count(i), 1, oindex(total(i)+1), & MPI_REAL, otype(i), ierr) CALL MPI_TYPE_COMMIT(otype(i), ierr) CALL MPI_TYPE_INDEXED_BLOCK(count(i), 1, tindex(total(i)+1), & MPI_REAL, ttype(i), ierr) CALL MPI_TYPE_COMMIT(ttype(i), ierr) END DO ! Эта часть непосредственно выполняет присваивание CALL MPI_WIN_FENCE(0, win, ierr) DO i=1,p CALL MPI_GET(A, 1, otype(i), i-1, 0, 1, ttype(i), win, ierr) END DO CALL MPI_WIN_FENCE(0, win, ierr) CALL MPI_WIN_FREE(win, ierr) DO i=1,p CALL MPI_TYPE_FREE(otype(i), ierr) CALL MPI_TYPE_FREE(ttype(i), ierr) END DO RETURN END
Пример 4.2
Можно написать более простую версию, которая не требует, чтобы для буфера
адресата создавался тип данных с использованием отдельного вызова
get
для каждого элемента. Этот код гораздо проще, но обычно менее
эффективен для больших массивов.
SUBROUTINE MAPVALS(A, B, map, m, comm, p) USE MPI INTEGER m, map(m), comm, p REAL A(m), B(m) INTEGER sizeofreal, win, ierr CALL MPI_TYPE_EXTENT(MPI_REAL, sizeofreal, ierr) CALL MPI_WIN_CREATE(B, m*sizeofreal, sizeofreal, & MPI_INFO_NULL, comm, win, ierr) CALL MPI_WIN_FENCE(0, win, ierr) DO i=1,m j = map(i)/p k = MOD(map(i),p) CALL MPI_GET(A(i), 1, MPI_REAL, j, k, 1, MPI_REAL, & win, ierr) END DO CALL MPI_WIN_FENCE(0, win, ierr) CALL MPI_WIN_FREE(win, ierr) RETURN END
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |