Fortran MPI - Ping pong程序段错误

时间:2014-07-01 14:20:19

标签: segmentation-fault fortran mpi

我正在尝试在Fortran中学习一些MPI,但我遇到了一些问题。这个ping pong程序在SEGFAULT HERE的两条评论之间发生了段落,但对于我的生活,我无法理解为什么会这样。

program MPI_PING_PONG
    implicit none
    include 'mpif.h'
    integer rank, size, ierror, tag, status(MPI_STATUS_SIZE)
    integer ping_pong_counter ! This will increment each time a message is received.
    integer isEven
    integer partner_rank
    call MPI_INIT(ierror)                            ! Initialize MPI on all processes.
    call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierror) ! Tell each process the size of the world.
    call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierror) ! Tell each process its rank.

    ping_pong_counter = 0
    partner_rank = mod(rank + 1,2)
    print *,'Process has rank ',rank
    do
        if (ping_pong_counter == 50) then
            exit
        endif
        isEven = mod(ping_pong_counter,2)
        if (rank == isEven) then
            ping_pong_counter = ping_pong_counter + 1
            print *,'Process ',rank,'sending counter value of ',ping_pong_counter
            call MPI_SEND(ping_pong_counter,1,MPI_INTEGER,partner_rank,5,MPI_COMM_WORLD,ierror)
        else
!******************** SEGFAULT HERE ********************!
            call MPI_RECV(ping_pong_counter,1,MPI_INTEGER,partner_rank,5,MPI_COMM_WORLD,ierror)
!******************** SEGFAULT HERE ********************!
            print *,'Process ',rank,' has received a counter with value ',ping_pong_counter
        endif
    enddo
end program MPI_PING_PONG

这是下面的输出:

Process has rank 0
Process 0 sending counter value of 1
Process has rank 1

Program received signal SIGSEGV: Segmentation Fault - invalid memory reference

Backtrace for this error:
#0: 0x7F49425F2117
#1: 0x7F49425F26F4
#2: 0x7F49425F20AF
#3: 0x7F49425F22C7
#4: 0X400DDF in mpi_ping_pong at MPI_PING_PONG.f90:28

2 个答案:

答案 0 :(得分:2)

您缺少status参数。 MPI_Recv的正确签名是

 MPI_RECV(BUF, COUNT, DATATYPE, SOURCE, TAG, COMM, STATUS, IERROR)   
 <type>    BUF(*)
     INTEGER    COUNT, DATATYPE, SOURCE, TAG, COMM
     INTEGER    STATUS(MPI_STATUS_SIZE), IERROR

您的参数数量错误。

答案 1 :(得分:1)

通常属于堆栈空间的地址的回溯存在暗示缺少非可选子例程或函数参数。

不应在现代Fortran程序中使用mpif.h接口,而应使用mpi模块接口(USE mpi)。使用MPI-3.0实现时,应使用mpi_f08接口。 mpi模块接口为许多函数提供参数检查,并且在编译程序期间将捕获传递错误数量的参数。不幸的是MPI_RECV是一个接受不同类型参数(缓冲区)的函数,因此经常从mpi模块接口中省略,因为2008版之前的Fortran不允许具有不同类型参数的接口声明。一些MPI实现通过使用缓冲区参数的可能类型的长列表来解决此限制。这同样适用于其他通信呼叫,例如,到MPI_SEND

在理想的世界中,我们都将拥有MPI-3.0兼容的实现和实现TR 29113的Fortran 2008编译器。mpi_f08模块接口利用了使用不同类型和形状的参数声明子例程接口的能力。编译器能够在编译时轻松检查所有参数。