【发布时间】:2015-11-22 02:42:40
【问题描述】:
以下基本代码有问题:
program foo
use mpi
implicit none
type bartype
real(8) :: x
integer :: i
end type bartype
integer :: mpi_bar_type
integer :: &
count=2, &
blocklengths(2)=(/1,1/), &
types(2)=(/mpi_double_precision, &
mpi_integer/)
integer(kind=mpi_address_kind) :: displs(2)
type(bartype) :: bar, bararray(4)
integer :: rank, ierr, i, test(4), addr0
call mpi_init(ierr)
call mpi_comm_rank(mpi_comm_world, rank, ierr)
call mpi_get_address(bar, addr0)
call mpi_get_address(bar%x, displs(1))
call mpi_get_address(bar%i, displs(2))
do i=1,2
displs(i)=displs(i)-addr0
enddo
call mpi_type_create_struct(2,blocklengths,displs,types,mpi_bar_type,ierr)
call mpi_type_commit(mpi_bar_type,ierr)
bararray(:)%x=rank
bararray(:)%i=rank
test(:)=rank
call mpi_bcast(test, 4, mpi_integer, 0, mpi_comm_world,ierr)
call mpi_bcast(bararray, 4, mpi_bar_type, 0, mpi_comm_world,ierr)
call mpi_finalize(ierr)
end program foo
我在调试器 (DDT) 中的派生类型 Bcast(使用 intelMPI 和 openMPI)处遇到段错误,据说这可能是对齐问题...
我已经看到this线程,问题似乎是一样的,但我仍然没有解决...
感谢您的帮助!
【问题讨论】:
-
(1) 一直使用
implicit none; (2)use mpi而不是include mpif.h。一旦 (1) 和 (2) 完成,您会注意到 (3) 您没有为 mpi_cadna_double_st 定义类型(应该是整数)和 (4) displs 的类型是错误的(您应该使用integer(kind=mpi_address_kind). 应该这样做。 -
是的,我的示例代码非常糟糕。我更正了它(并按照我的要求编辑了我的帖子),但我仍然有一个段错误......
-
更新后的代码现在差不多了,但
addr0也需要integer(kind=mpi_address_kind);如果您在创建类型之前print *, displs,您会注意到这些值是无意义的,这很容易导致段错误,因为它们描述了内存访问。我真的很惊讶 gfortran 没有在那里发出警告。
标签: fortran mpi fortran90 memory-alignment derived-types