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的主要内容,如果未能解决你的问题,请参考以下文章