Тип данных структуры MPI с массивом - PullRequest
0 голосов
/ 22 ноября 2011

Я хотел бы легко отправить someObject в одном вызове MPI_SEND / RECV в формате mpi.

   type someObject
     integer :: foo
     real :: bar,baz
     double precision :: a,b,c
     double precision, dimension(someParam) :: x, y
   end type someObject

Я начал использовать MPI_TYPE_STRUCT, но затем понял размеры массивов x и y зависят от someParam.Сначала я думал о вложении MPI_TYPE_CONTIGUOUS в структуру для представления массивов, но не могу заставить это работать.Если это вообще возможно?

  ! Setup description of the 1 MPI_INTEGER field
  offsets(0) = 0
  oldtypes(0) = MPI_INTEGER
  blockcounts(0) = 1
  ! Setup description of the 2 MPI_REAL fields
  call MPI_TYPE_EXTENT(MPI_INTEGER, extent, ierr)
  offsets(1) = blockcounts(0) * extent
  oldtypes(1) = MPI_REAL
  blockcounts(1) = 2
  ! Setup descripton of the 3 MPI_DOUBLE_PRECISION fields
  call MPI_TYPE_EXTENT(MPI_DOUBLE_PRECISION, extent, ierr)
  offsets(2) = offsets(1) + blockcounts(1) * extent
  oldtypes(2) = MPI_DOUBLE_PRECISION
  blockcounts(2) = 3
  ! Setup x and y MPI_DOUBLE_PRECISION array fields
  call MPI_TYPE_CONTIGUOUS(someParam, MPI_DOUBLE_PRECISION, sOarraytype, ierr)
  call MPI_TYPE_COMMIT(sOarraytype, ierr)
  call MPI_TYPE_EXTENT(sOarraytype, extent, ierr)
  offsets(3) = offsets(2) + blockcounts(2) * extent
  oldtypes(3) = sOarraytype
  blockcounts(3) = 2 ! x and y

  ! Now Define structured type and commit it
  call MPI_TYPE_STRUCT(4, blockcounts, offsets, oldtypes, sOtype, ierr)
  call MPI_TYPE_COMMIT(sOtype, ierr)

Что я хотел бы сделать:

...
type(someObject) :: newObject, rcvObject
double precision, dimension(someParam) :: x, y
do i=1,someParam
  x(i) = i
  y(i) = i
end do
newObject = someObject(1,0.0,1.0,2.0,3.0,4.0,x,y)
MPI_SEND(newObject, 1, sOtype, 1, 1, MPI_COMM_WORLD, ierr) ! master
...
! slave would:
MPI_RECV(rcvObject, 1, sOtype, master, MPI_ANY_TAG, MPI_COMM_WORLD, status, ierr)
WRITE(*,*) rcvObject%foo
do i=1,someParam
  WRITE(*,*) rcvObject%x(i), rcvObject%y(i)
end do
...

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

Ответы [ 2 ]

1 голос
/ 23 ноября 2011

Судя по всему, вы не можете вложить эти типы данных, и это было совершенно неправильное решение.

Спасибо: http://static.msi.umn.edu/tutorial/scicomp/general/MPI/mpi_data.html и http://www.osc.edu/supercomputing/training/mpi/Feb_05_2008/mpi_0802_mod_datatypes.pdf за руководство.

правильный способ определить MPI_TYPE_STRUCT заключается в следующем:

type(someObject) :: newObject, rcvObject
double precision, dimension(someParam) :: x, y
data x/someParam * 0/, w/someParam * 0/
integer sOtype, oldtypes(0:7), blocklengths(0:7), offsets(0:7), iextent, rextent, dpextent
! Define MPI datatype for someObject object
! set up extents
call MPI_TYPE_EXTENT(MPI_INTEGER, iextent, ierr)
call MPI_TYPE_EXTENT(MPI_REAL, rextent, ierr)
call MPI_TYPE_EXTENT(MPI_DOUBLE_PRECISION, dpextent, ierr)
! setup blocklengths /foo,bar,baz,a,b,c,x,y/
data blocklengths/1,1,1,1,1,1,someParam,someParam/
! setup oldtypes
oldtypes(0) = MPI_INTEGER
oldtypes(1) = MPI_REAL
oldtypes(2) = MPI_REAL
oldtypes(3) = MPI_DOUBLE_PRECISION
oldtypes(4) = MPI_DOUBLE_PRECISION
oldtypes(5) = MPI_DOUBLE_PRECISION
oldtypes(6) = MPI_DOUBLE_PRECISION
oldtypes(7) = MPI_DOUBLE_PRECISION
! setup offsets
offsets(0) = 0
offsets(1) = iextent * blocklengths(0)
offsets(2) = offsets(1) + rextent*blocklengths(1)
offsets(3) = offsets(2) + rextent*blocklengths(2)
offsets(4) = offsets(3) + dpextent*blocklengths(3)
offsets(5) = offsets(4) + dpextent*blocklengths(4)
offsets(6) = offsets(5) + dpextent*blocklengths(5)
offsets(7) = offsets(6) + dpextent*blocklengths(6)
! Now Define structured type and commit it
call MPI_TYPE_STRUCT(8, blocklengths, offsets, oldtypes, sOtype, ierr)
call MPI_TYPE_COMMIT(sOtype, ierr)

Это позволяет мне отправлять и получать объект так, как я изначально хотел!

0 голосов
/ 27 февраля 2012

Извините, я пока не могу комментировать, поэтому я должен дать вам ответ здесь. В вашем ответе выше есть небольшая проблема в строке: offsets(3) = offsets(2) + dpextent*blocklengths(2) оно должно быть offsets(3) = offsets(2) + rextent*blocklengths(2), поскольку переменная 3 является real, а не double precision.

...