fortran - 使用 MPI-2 的 RMA 函数的 Fortran 程序中的段错误

标签 fortran mpi mpi-rma

以下简短的 Fortran90 程序只要包含 MPI_GET 调用就会崩溃。 等级 1 尝试从等级 0 读取值并挂起在 MPI_WIN_UNLOCK 中。 Rank 0 尝试在 MPI_BARRIER 中因段错误而崩溃。

我反复检查命令的语法,但它们似乎是正确的。 C/C++ 中的类似代码可在同一系统上运行。

我正在使用 OpenMPI 1.4.3 和 gfortran 4.4.5。

PROGRAM mpitest
USE mpi
IMPLICIT NONE

INTEGER :: ierr, npe, rnk, win
INTEGER (KIND=MPI_ADDRESS_KIND) lowerbound, sizeofreal
REAL :: val = 1.0, oval = 2.0

CALL MPI_INIT( ierr )
CALL MPI_COMM_RANK( MPI_COMM_WORLD, rnk, ierr )
CALL MPI_COMM_SIZE( MPI_COMM_WORLD, npe, ierr )

CALL MPI_TYPE_GET_EXTENT(MPI_REAL, lowerbound, sizeofreal, ierr)

CALL MPI_WIN_CREATE(val, sizeofreal, sizeofreal, MPI_INFO_NULL, MPI_COMM_WORLD, win, ierr)

IF( rnk .EQ. 1 ) THEN
   CALL MPI_WIN_LOCK( MPI_LOCK_SHARED, 0, 0, win, ierr )
   CALL MPI_GET( oval, 1, MPI_REAL, 0, 0, 1, MPI_REAL, win, ierr )
   CALL MPI_WIN_UNLOCK( 0, win, ierr )
END IF

CALL MPI_BARRIER( MPI_COMM_WORLD, ierr )
CALL MPI_WIN_FREE(win, ierr)
CALL MPI_FINALIZE(ierr)

END PROGRAM mpitest

mpif90 mpitest.f90
mpirun -n 2 ./a.out

*** Process received signal ***
Signal: Segmentation fault (11)
Signal code: Address not mapped (1)
Failing at address: 0x34006020a0
[ 0] /lib/x86_64-linux-gnu/libc.so.6(+0x36420) [0x7f2d1c8c1420]
[ 1] /lib/x86_64-linux-gnu/libc.so.6(+0x13ae70) [0x7f2d1c9c5e70]
[ 2] /usr/lib/libmpi.so.0(ompi_convertor_pack+0x199) [0x7f2d1c61d629]
[ 3] /usr/lib/openmpi/lib/openmpi/mca_osc_pt2pt.so(+0x56b0) [0x7f2d166876b0]
[ 4] /usr/lib/openmpi/lib/openmpi/mca_osc_pt2pt.so(+0x3a81) [0x7f2d16685a81]
[ 5] /usr/lib/openmpi/lib/openmpi/mca_osc_pt2pt.so(+0x23ac) [0x7f2d166843ac]
[ 6] /usr/lib/libopen-pal.so.0(opal_progress+0x5b) [0x7f2d1ba700db]
[ 7] /usr/lib/libmpi.so.0(+0x35635) [0x7f2d1c60f635]
[ 8] /usr/lib/openmpi/lib/openmpi/mca_coll_tuned.so(+0x1afa) [0x7f2d1688eafa]
[ 9] /usr/lib/openmpi/lib/openmpi/mca_coll_tuned.so(+0x958f) [0x7f2d1689658f]
[10] /usr/lib/libmpi.so.0(MPI_Barrier+0x8d) [0x7f2d1c6250cd]
[11] /usr/lib/libmpi_f77.so.0(PMPI_BARRIER+0x13) [0x7f2d1cf661d3]
[12] ./a.out() [0x401003]
[13] ./a.out(main+0x34) [0x401058]
[14] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7f2d1c8ac30d]
[15] ./a.out() [0x400da9]
*** End of error message ***

最佳答案

这是一个棘手的问题,但一条线索来自这样一个事实:段错误发生在一个不相关且完全安全的例程中,MPI_Barrier()。问题是堆栈损坏。

根本问题只是参数类型不匹配(我希望 MPI Fortran 绑定(bind)能够捕获,但没有)。 MPI_Get 的目标位移参数是一个 MPI_ADDRESS_KIND 类型的整数,但您只是向它传递一个整数。

如果您使用 lowerbound 作为目标偏移量,或者显式地将传入的 0 提升为 MPI_ADDRESS_KIND 类型,则您的程序可以正常工作。

关于fortran - 使用 MPI-2 的 RMA 函数的 Fortran 程序中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11052421/

相关文章:

xcode - 如何设置 Xcode Organizer 以使用 x86_64 二进制文件运行?

fortran - Fortran 90 中的优化例程

c - 如何通过数组使用 MPI 分散和聚集

MPI:如何正确使用 MPI_Win_allocate_shared

algorithm - MPI:确保独占访问共享内存 (RMA)

fortran - 读取语句输入时无法识别“*' and '/”

oop - 现代 Fortran 中的面向对象编程,包括函数指针的成员

c - 由于 MPI_comm_size 导致的段错误

我可以从不同的 MPI_Irecv 写入不同索引位置的相同缓冲区/数组吗?

c++ - MPI2/MPI3 : MPI_allgather vs MPI one sided communication considering synchronization