當我嘗試發送MPI派生數據類型與「大」數組(每個100 000浮點數2陣列),我的程序段錯誤。它通常與較小的陣列運行。MPI發送錯誤與派生數據類型(Fortran)
下面是一個小的可重複的例子。 這個小程序段錯誤與以下MPI執行: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 implentations之間的比較是不客觀的測試是不是所有在同一臺計算機(其中有些是超級計算機)上。不過,我認爲這不應該有所作爲。
編輯:該代碼適用於靜態數組。這是Fortran 90.
我不知道很多的Fortran,但我不認爲MPI工作與自定義數據類型'allocatable'。您可以嘗試從該結構的其餘部分分開轉移該組件。有人糾正我,如果我錯了。 –
沒有更多的段錯誤與靜態數組!我用不同的編譯器(gfortran,pgf90,ifortran)測試了代碼,沒有任何抱怨。直到我開始增加尺寸時纔有問題。 –