当我尝试发送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)测试了代码,没有任何抱怨。直到我开始增加尺寸时才有问题。 –