The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Каталог документации / Раздел "Программирование, языки" / Оглавление документа
next up previous contents
Next: Функция acumulate Up: Коммуникационные вызовы Previous: Get   Contents

Примеры

Пример 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



Alex Otwagin 2002-12-10



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру