mpifort -DMPI 编译错误:派生类型“mpi_status”用作实际参数。适用于英特尔 Fortran,但不适用于 GNU Fortran

Posted

技术标签:

【中文标题】mpifort -DMPI 编译错误:派生类型“mpi_status”用作实际参数。适用于英特尔 Fortran,但不适用于 GNU Fortran【英文标题】:mpifort -DMPI compilation error: Derived type 'mpi_status' is used as an actual argument. Works with Intel Fortran, but not GNU Fortran 【发布时间】:2021-12-09 18:14:01 【问题描述】:

我正在尝试使用带有 -DMPI 标志的 gfortran MPI 包装器 mpifort 编译 Fortran 程序。我收到以下错误:

mpifort -O3 -fopenmp -DMPI -fc=gfortran-11 -fallow-argument-mismatch  -c wavefunction.F90
wavefunction.F90:486:53:

  486 |     call mpi_file_read_all(fh, neig, 1, mpi_integer, mpi_status, ierr)
      |                                                     1
Error: Derived type 'mpi_status' is used as an actual argument at (1)

您可以找到整个 Makefile(和程序代码)here,请参阅 mpifort 选项。我尝试使用 gfortran 版本 9、10 和 11,都产生相同的错误。我已经使用 Intel Fortran 编译器 (mpiifort) 成功地用 -DMPI 编译了这个完全相同的 Fortran 代码,但是这次我不能使用 Intel 编译器,因为我试图在 Raspberry Pi 4 上编译并且我不认为 Intel编译器与 ARM 一起工作。我做了很多 Ducking 试图找到解决方案,但我还没有成功。非常感谢任何帮助!

【问题讨论】:

你需要提供一个状态对象,而不是mpi_status这个词。这个程序是错误的。也许它可以编译,因为 Fortran 没有保留字。 感谢您的评论,维克多。但是这怎么能与英特尔 Fortran 编译器一起工作呢?该程序不仅可以使用 mpiifort 编译,而且可以在超级计算机上的数百个节点上正常运行! @VictorEijkhout mpi_status 是一个整数数组,如第 471 行 here 所示,这似乎与 documentation 一致 变量名称永远不能与文档一致。此外,您的文档使用名称 status。我认为问题在于新版本的 MPI-Fortran 接口 MPI_Status 是一个 fortran“类型”。只需使用不同的名称。 (我不能 100% 确定这个解释,因为通常你需要 use mpi_f08 来获得这个接口,而你只是在做 use mpi。当然,你转向 2008 标准可能是个好主意,所以开始使用mpi_f08 模块吧。它好多了。) 你真的必须展示代码的违规部分。错误消息中的一行和所有相关声明是绝对最小值,sometimes 就足够了,但通常完整的minimal reproducible example 是有序的。不,指向外部存储库的链接是不够的。 【参考方案1】:

我找到了问题的解决方案。首先,我删除了所有 MPI 安装并使用apt install openmpi-bin 重新安装了 MPI。早些时候我使用mpich。重新安装后编译时,我收到另一条错误消息:Error: There is no specific subroutine for the generic 'mpi_file_read_at_all' at (1)。这里的问题是COUNT 到the subroutine 的参数类型错误。在程序中,它是integer(8),但子程序需要integer(4)。由于类型错误,编译器找不到任何匹配签名的子程序,因此出现错误消息。

感谢评论区的人们抽出时间给我建议。

【讨论】:

请注意 1. MPI 主要为参数指定类型integer,而不是integer(4)integer(8)。 2. 在integer(4) 中使用像 4 或 8 这样的文字数字是不可移植的,并且会因多个编译器而失败。见***.com/questions/3170239/… @VladimirF 感谢您的信息!我首先看到有问题的 MPI 子例程不接受程序代码中明确说明的integer(8)。然后我尝试了integer,效果很好。不知道integer 默认有多少字节,我尝试了integer(n) 几个不同的值n,然后发现4 个字节是唯一被接受的。对于我的编译器,integer 必须表示 4 个字节,所以我在帖子中指定了这一点。

以上是关于mpifort -DMPI 编译错误:派生类型“mpi_status”用作实际参数。适用于英特尔 Fortran,但不适用于 GNU Fortran的主要内容,如果未能解决你的问题,请参考以下文章

定义派生类型数组

定义派生类型数组

在不同的命名空间中定义基类和派生类时的编译错误

为啥当我有两个函数时编译器没有显示错误,一个将基类作为参数,一个将派生类作为参数?

C++ 强制转换为派生类

C++将派生类赋值给基类(向上转型)