「大きな」配列(それぞれ100 000フロートの2つの配列)を使用してMPI派生データ型を送信しようとすると、プログラムが失敗します。ただし、通常は小さいアレイで実行されます。
以下は、再現可能な小さな例です。この小さなプログラムは、次のMPI実装でsegfaultします: IntelMPI、BullXMPI。OpenMPIおよびPlatformMPIで正常に動作します。例のバックトレースを含むログは次のとおりです:http://pastebin.com/FMBpCuj2
に変更mpi_send
してmpi_ssend
も効果はありません。ただし、mpi_send
2 * 100 000フロートの単一の大きな配列では、正常に機能します。私の意見では、これは派生データ型の問題を示しています。
program struct
include 'mpif.h'
type Data
integer :: id
real, allocatable :: ratio(:)
real, allocatable :: winds(:)
end type
type (Data) :: test
integer :: datatype, oldtypes(3), blockcounts(3)
integer :: offsets(3)
integer :: numtasks, rank, i, ierr
integer :: n, status(mpi_status_size)
call mpi_init(ierr)
call mpi_comm_rank(mpi_comm_world, rank, ierr)
call mpi_comm_size(mpi_comm_world, numtasks, ierr)
if (numtasks /= 2) then
write (*,*) "Needs 2 procs"
call exit(1)
endif
n = 100000
allocate(test%ratio(n))
allocate(test%winds(n))
if (rank == 0) then
test%ratio = 6
test%winds = 7
test%id = 2
else
test%id = 0
test%ratio = 0
test%winds = 0
endif
call mpi_get_address(test%id, offsets(1), ierr)
call mpi_get_address(test%ratio, offsets(2), ierr)
call mpi_get_address(test%winds, offsets(3), ierr)
do i = 2, size(offsets)
offsets(i) = offsets(i) - offsets(1)
end do
offsets(1) = 0
oldtypes = (/mpi_integer, mpi_real, mpi_real/)
blockcounts = (/1, n, n/)
call mpi_type_struct(3, blockcounts, offsets, oldtypes, datatype, ierr)
call mpi_type_commit(datatype, ierr)
if (rank == 0) then
!call mpi_ssend(test, 1, datatype, 1, 0, mpi_comm_world, ierr)
call mpi_send(test, 1, datatype, 1, 0, mpi_comm_world, ierr)
else
call mpi_recv(test, 1, datatype, 0, 0, mpi_comm_world, status, ierr)
end if
print *, 'rank= ',rank
print *, 'data= ',test%ratio(1:5),test%winds(1:5)
deallocate (test%ratio)
deallocate (test%winds)
call mpi_finalize(ierr)
end
注:テストがすべて同じマシン上で行われたわけではないため、異なるMPIの実装間の比較は客観的ではありません(一部はスーパーコンピューターです)。それでも、私はそれが違いを生むべきではないと思います。
編集:コードは静的配列で機能します。そしてこれはFortran90です。