2011-11-22 55 views
0

我想在一個MPI_SEND/RECV調用中以mpi方式輕鬆發送someObject帶有數組的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ÿ取決於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 
... 

到目前爲止,我剛開段錯誤,沒有什麼我做錯了太多的指示,或者如果這甚至有可能。該文檔從來沒有說我不能使用結構數據類型內的連續數據類型。

+0

你在哪裏得到段錯誤?在發送或接收? (或其他地方?) – suszterpatt

+0

它似乎是正確的MPI_TYPE_COMMIT(sOtype,ierr),但它根據緊隨其後的內容而變化。 如果在它後面有一個do循環,則報告program.f90:50其中50將是do行,但註釋掉並報告program.f90:48其中48是COMMIT所在的行... – platinummonkey

+0

I能夠編譯它,似乎我用intel編譯器而不是gfortran編譯了一些東西。一旦我用gfortran重新編譯了所有東西,我就可以用mpi編譯。 但是好像這個花哨的結構數據類型將無法正常工作出現...錯誤: [富:13878] ***在MPI_SEND 出錯[富:13878] ***在通信子MPI_COMM_WORLD [富: 13878] *** MPI_ERR_TYPE:無效的數據類型 [foo:13878] *** MPI_ERRORS_ARE_FATAL(goodbye) mpiexec注意到在信號15(Terminated)上退出節點foo上的PID 13877的作業等級爲0。 – platinummonkey

回答

1

從看起來你不能嵌套這些類型的數據類型,是一個完全錯誤的解決方案。

感謝:http://static.msi.umn.edu/tutorial/scicomp/general/MPI/mpi_data.htmlhttp://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

對不起,我無法評論無處不在,所以我不得不在這裏給你一個答案。在你的上面的答案有一個小問題在線:offsets(3) = offsets(2) + dpextent*blocklengths(2) 它應該是offsets(3) = offsets(2) + rextent*blocklengths(2)作爲變量3是real而不是double precision

+0

謝謝,糾正。 – platinummonkey