【问题标题】:Fortran MPI - Ping pong program segfaultsFortran MPI - 乒乓程序段错误
【发布时间】:2014-08-22 03:37:07
【问题描述】:

我正在尝试在 Fortran 中学习一些 MPI 内容,但遇到了一些问题。这个乒乓球程序在说 SEGFAULT HERE 的两个 cmets 之间出现了段错误,但对于我的生活,我无法理解为什么会这样。

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

【问题讨论】:

    标签: segmentation-fault fortran mpi


    【解决方案1】:

    您缺少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
    

    您的参数数量错误。

    【讨论】:

      【解决方案2】:

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

      不应在现代 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 模块接口利用了声明具有不同类型和形状的参数的子例程接口的能力以及编译器能够在编译时轻松检查所有参数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多