Fortran 错误:两个不相关的子例程调用之间的类型不匹配

bob*_*nto 3 fortran gnu compilation mpi

在我看来,这个 Fortran MPI 程序非常简单:

program what

use mpi

integer(4), parameter :: ksp = 4
integer(4), parameter :: kdp = 8

integer(ksp) :: nreadslb
integer(ksp), ALLOCATABLE :: all_nreadslb(:)

real(kdp) :: compute_time
real(kdp), ALLOCATABLE :: all_compute_times(:)

integer(ksp) :: myrank

integer :: ierr

call mpi_init(ierr)


allocate(all_nreadslb(10), all_compute_times(10))

CALL MPI_GATHER(compute_time, 1, &
             MPI_DOUBLE_PRECISION, all_compute_times, 1, &
             MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, ierr)
CALL MPI_GATHER(nreadslb, 1, MPI_INTEGER4, &
             all_nreadslb, 1, MPI_INTEGER4, 0, &
             MPI_COMM_WORLD, ierr)


call mpi_finalize(ierr)


end program
Run Code Online (Sandbox Code Playgroud)

但它无法在 GNU 下的 Cray 平台上编译。返回的错误是:

   23 |       CALL MPI_GATHER(compute_time, 1, &
      |                      2
......
   26 |       CALL MPI_GATHER(nreadslb, 1, MPI_INTEGER4, &
      |                      1
Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(4)/REAL(8)).
Run Code Online (Sandbox Code Playgroud)

真正的问题是,如果我注释掉第一个 MPI_GATHER,第二个编译就好了,如果我注释掉第二个 MPI_GATHER,第一个编译就好了。GNU 编译器不喜欢在代码中同时包含它们。只是为了咧嘴笑,我在它们之间放了一个调试语句;得到了同样的错误。代码在 Cray 或 Intel Fortran 下编译得很好。

任何想法可能是什么问题?

编辑:我正在使用 Cray 环境 PrgEnv-gnu/6.0.9,它使用来自 gcc 10.1.0 和 Cray MPICH 7.7.16 的 gfortran。我正在使用 Cray "ftn" 命令进行编译,没有标志,只有ftn what.f90. 还发现问题出在gcc 10.1.0;代码在 9.3.0 下编译得很好。这样就解决了眼前的问题。但是,如果有人知道在 10.1.0 下该做什么(因为 9.3.0 不会永远持续下去),我很乐意听到它!谢谢。

Joh*_*ger 6

没有详细说明是否或为什么应该接受示例程序,因为这取决于 Fortran 语言版本和正在使用的 MPI 模块的详细信息,GCC 10 为 Fortran 过程参数带来了更严格的类型检查。通过将-fallow-argument-mismatch选项添加到编译命令行,您应该能够将这些特定错误转换为警告。这对其他项目很有效,例如NetCDF

  • @bob.sacamento,添加该标志是 GCC 推荐的方法,用于让编译器接受因更改而被拒绝的代码。我想,因为它具有将错误转换为警告的效果,所以如果您还指定“-Werror”,它可能会无效。如果没有弗拉基米尔要求的细节,我想我们不能再说更多了。 (2认同)