派生型xyzBufferをプロセッサ1からプロセッサ0のxyzにコピーしたい。次のコマンドでMPI_GATHERを試行しました。
call MPI_GATHERV(xyzBuffer,1,inewtype,xyz,1, dispGather,inewtype,0,icomm,ierr)
ただし、プロセッサ0には書き込まれないメモリビットがあります。MPI_GATHERでは派生型の収集が許可されていないようです。MPI_ISEND / MPI_IRECVを使用しましたが、プログラムが次のコード行でハングします。
if ( iproc == 1 ) then
call MPI_ISEND(xyz,1,inewtype,1,itag,icomm,ireq,ierr)
call MPI_WAIT(ireq,istatus,ierr)
else if ( iproc == 0 ) then
call MPI_IRECV(xyz,1,inewtype,0,itag,icomm,ireq,ierr)
call MPI_WAIT(ireq,istatus,ierr)
end if
これらのメソッドは、派生型で使用するためのものではありませんか?
以下は完全なプログラムです。MPI_ISEND、MPI_IRECVブロック、またはその逆をテストするときに、MPI_GATHERをコメントアウトします。
program type_derived_gather
use nodeinfo
implicit none
include 'mpif.h'
integer(4) :: ierr
integer(4) :: istatus(MPI_STATUS_SIZE)
integer(4) :: i
integer(4) :: j
integer(4) :: iblock(8)
integer(4) :: idisp(8)
integer(4) :: itype(8)
integer(4) :: inewtype
integer(4) :: iextent
integer(4) :: itag
integer(4) :: ireq, isend, irecv
integer(4) :: dispGather ! for root
TYPE :: newXYZ
integer :: x, u
integer :: y, v
integer :: z, w
integer,dimension(3) :: uvw
END TYPE
TYPE (newXYZ) :: xyzBuffer
TYPE (newXYZ) :: xyz
call MPI_INIT(ierr)
icomm = MPI_COMM_WORLD
call MPI_COMM_SIZE(icomm,nproc,ierr)
call MPI_COMM_RANK(icomm,iproc,ierr)
if (iproc == 1) then
xyz%x = 1
xyz%y = 2
xyz%z = 3
xyz%u = 4
xyz%v = 5
xyz%w = 6
xyz%uvw = (/10,10,10/)
else
xyz%x = 0
xyz%y = 0
xyz%z = 0
xyz%u = 0
xyz%v = 0
xyz%w = 0
xyz%uvw = (/0,0,0/)
endif
! Derived type
iblock(1) = 1
iblock(2) = 1
iblock(3) = 1
iblock(4) = 1
iblock(5) = 1
iblock(6) = 1
iblock(7) = 3
iblock(8) = 1
idisp(1) = 0 ! in bytes
idisp(2) = 4*1 ! in bytes
idisp(3) = 4*2 ! in bytes
idisp(4) = 4*3 ! in bytes
idisp(5) = 4*4 ! in bytes
idisp(6) = 4*5 ! in bytes
idisp(7) = 4*6 ! in bytes
idisp(8) = 4*9 ! in bytes
itype(1) = MPI_INTEGER
itype(2) = MPI_INTEGER
itype(3) = MPI_INTEGER
itype(4) = MPI_INTEGER
itype(5) = MPI_INTEGER
itype(6) = MPI_INTEGER
itype(7) = MPI_INTEGER
itype(8) = MPI_UB
call MPI_TYPE_STRUCT(8,iblock,idisp,itype,inewtype,ierr)
call MPI_TYPE_EXTENT(inewtype,iextent,ierr)
write(6,*)'newtype extent = ',iextent
call MPI_TYPE_COMMIT(inewtype,ierr)
itag = 1
dispGather = 0
do j = 1, 2
if ( j == 2 ) then
! Gather
call MPI_GATHERV(xyzBuffer,1,inewtype,xyz,1, dispGather,inewtype,0,icomm,ierr)
! Isend Irecv
if ( iproc == 1 ) then
call MPI_ISEND(xyz,1,inewtype,1,itag,icomm,isend,ierr)
write(6,*)'end send'
call MPI_WAIT(isend,istatus,ierr)
else if ( iproc == 0 ) then
call MPI_IRECV(xyz,1,inewtype,0,itag,icomm,irecv,ierr)
write(6,*)'end receive'
call MPI_WAIT(irecv,istatus,ierr)
end if
! Output
end if
call MPI_BARRIER(icomm,ierr)
if ( iproc == 0 )write(6,*)'iproc = ',iproc
if ( iproc == 0 ) write(6,*)xyz
call MPI_BARRIER(icomm,ierr)
if ( iproc == 1 )write(6,*)'iproc = ',iproc
if ( iproc == 1 ) write(6,*)xyz
end do
call MPI_FINALIZE(ierr)
end program type_derived_gather
MPI_ISENDおよびMPI_IRECVブロックを使用して実行すると、プログラムがハングし、出力は次のようになります。
iproc = 0
0 0 0 0 0 0 0 0 0
end receive
newtype extent = 36
iproc = 1
1 4 2 5 3 6 10 10 10
end send
MPI_GATHERを実行すると、次の出力でセグメンテーション違反が発生します。
newtype extent = 36
iproc = 0
0 0 0 0 0 0 0 0 0
newtype extent = 36
iproc = 1
1 4 2 5 3 6 10 10 10
newtype extent = 36
newtype extent = 36
newtype extent = 36
newtype extent = 36
newtype extent = 36
newtype extent = 36
[west0302:17101] *** Process received signal ***
[west0302:17101] Signal: Segmentation fault (11)
[west0302:17101] Signal code: Address not mapped (1)
[west0302:17101] Failing at address: 0x7ff2c8d1ddc0
[west0302:17101] [ 0] /lib64/libpthread.so.0 [0x3d3540eb70]
[west0302:17101] [ 1] /lib64/libc.so.6(memcpy+0xe1) [0x3d3487c321]
[west0302:17101] [ 2] /n/sw/openmpi-1.2.5-gcc-4.1.2/lib64/libmpi.so.0(ompi_convertor_unpack+0x153) [0x2acd5f392093]
[west0302:17101] [ 3] /n/sw/openmpi-1.2.5-gcc-4.1.2/lib/openmpi/mca_pml_ob1.so(mca_pml_ob1_recv_request_progress+0x7d1) [0x2acd6423dd91]
[west0302:17101] [ 4] /n/sw/openmpi-1.2.5-gcc-4.1.2/lib/openmpi/mca_pml_ob1.so [0x2acd6423a4c7]
[west0302:17101] [ 5] /n/sw/openmpi-1.2.5-gcc-4.1.2/lib/openmpi/mca_btl_sm.so(mca_btl_sm_component_progress+0xde2) [0x2acd64ca81c2]
[west0302:17101] [ 6] /n/sw/openmpi-1.2.5-gcc-4.1.2/lib/openmpi/mca_bml_r2.so(mca_bml_r2_progress+0x2a) [0x2acd6444504a]
[west0302:17101] [ 7] /n/sw/openmpi-1.2.5-gcc-4.1.2/lib64/libopen-pal.so.0(opal_progress+0x4a) [0x2acd5f84a9ba]
[west0302:17101] [ 8] /n/sw/openmpi-1.2.5-gcc-4.1.2/lib/openmpi/mca_pml_ob1.so(mca_pml_ob1_recv+0x2b5) [0x2acd64238565]
[west0302:17101] [ 9] /n/sw/openmpi-1.2.5-gcc-4.1.2/lib/openmpi/mca_coll_basic.so(mca_coll_basic_gatherv_intra+0x14a) [0x2acd650bb37a]
[west0302:17101] [10] /n/sw/openmpi-1.2.5-gcc-4.1.2/lib64/libmpi.so.0(MPI_Gatherv+0x1b0) [0x2acd5f3a4170]
[west0302:17101] [11] /n/sw/openmpi-1.2.5-gcc-4.1.2/lib64/libmpi_f77.so.0(mpi_gatherv__+0x134) [0x2acd5f142784]
[west0302:17101] [12] ./type_derived_gather.x(MAIN__+0x342) [0x401742]
[west0302:17101] [13] ./type_derived_gather.x(main+0xe) [0x403fee]
[west0302:17101] [14] /lib64/libc.so.6(__libc_start_main+0xf4) [0x3d3481d994]
[west0302:17101] [15] ./type_derived_gather.x [0x401349]
[west0302:17101] *** End of error message ***