本文介绍了使用MPI_f08模块时,调用mpi_gatherv后数组的Lound发生更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
考虑以下Fortran程序
program test_prg
use iso_fortran_env, only : real64
use mpi_f08
implicit none
real(real64), allocatable :: arr_send(:), arr_recv(:)
integer :: ierr
call MPI_Init(ierr)
allocate(arr_send(3), arr_recv(3))
arr_send = 1
print *, lbound(arr_recv)
call MPI_Gatherv(arr_send, size(arr_send), MPI_DOUBLE_PRECISION, arr_recv, [size(arr_send)], [0], MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, ierr)
print *, lbound(arr_recv)
call MPI_Finalize(ierr)
end program
在1个处理器上执行此程序(使用gfortran 9.3.0和mpich 3.3.2编译),打印:
1
0
SOarr_recv
在调用MPI_Gatherv
后更改了其下限。如果我在调用MPI_Gatherv
时使用arr_recv(1)
而不是arr_recv
,那么它不会改变。如果我将mpi_f08
模块替换为mpi
,则使用arr_recv(1)
或arr_recv
都不会更改下限。
此程序中的下限为何更改?
推荐答案
现阶段,我认为这是gfortran
中影响MPI Fortran 2018绑定的错误(例如use mpi_f08
),我在https://gcc.gnu.org/pipermail/fortran/2020-September/055068.html中报告了此问题。所有gfortran
版本都会受到影响(我尝试了9.2.0
、10.2.0
和最新的master
分支,8
和更早的版本不支持dimension(..)
。
下面的复制器可以用来证明该问题
MODULE FOO
INTERFACE
SUBROUTINE dummyc(x0) BIND(C, name="sync")
type(*), dimension(..) :: x0
END SUBROUTINE
END INTERFACE
contains
SUBROUTINE dummy(x0)
type(*), dimension(..) :: x0
call dummyc(x0)
END SUBROUTINE
END MODULE
PROGRAM main
USE FOO
IMPLICIT NONE
integer :: before(2), after(2)
INTEGER, parameter :: n = 1
DOUBLE PRECISION, ALLOCATABLE :: buf(:)
DOUBLE PRECISION :: buf2(n)
ALLOCATE(buf(n))
before(1) = LBOUND(buf,1)
before(2) = UBOUND(buf,1)
CALL dummy (buf)
after(1) = LBOUND(buf,1)
after(2) = UBOUND(buf,1)
if (before(1) .NE. after(1)) stop 1
if (before(2) .NE. after(2)) stop 2
before(1) = LBOUND(buf2,1)
before(2) = UBOUND(buf2,1)
CALL dummy (buf2)
after(1) = LBOUND(buf2,1)
after(2) = LBOUND(buf2,1)
if (before(1) .NE. after(1)) stop 3
if (before(2) .NE. after(2)) stop 4
END PROGRAM
FWIW,英特尔ifort
编译器(我尝试过18.0.5
)在复制器上运行良好。
这篇关于使用MPI_f08模块时,调用mpi_gatherv后数组的Lound发生更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!