C 配置文件MPI(PMPI)和Fortran

C 配置文件MPI(PMPI)和Fortran,c,fortran,mpi,C,Fortran,Mpi,我正在编写使用PMPI(profileMPI接口)评测MPI代码的示例代码。 虽然C中的一个示例运行良好,但类似Fortran的简单代码却无法运行 这是我的C代码: #include "mpi.h" #include <stdio.h> int main (int argc, char *argv[]) { int size; int rank; char b[100]; MPI_Status st; MP

我正在编写使用PMPI(profileMPI接口)评测MPI代码的示例代码。 虽然C中的一个示例运行良好,但类似Fortran的简单代码却无法运行

这是我的C代码:

#include "mpi.h"
#include <stdio.h>


int main (int argc, char *argv[]) {
   
   int size;
   int rank;
   char b[100];
   MPI_Status st;
   
   
   MPI_Init (&argc, &argv);
   
   MPI_Pcontrol(2);
   
   MPI_Comm_size(MPI_COMM_WORLD, &size);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   
   if (rank == 0) {
      
      MPI_Send(b, 100, MPI_CHAR, 1, 99, MPI_COMM_WORLD);
      
   } else {
      
      MPI_Recv(b, 100, MPI_CHAR, 0, 99, MPI_COMM_WORLD, &st);
      
   }
   
   MPI_Finalize();
   
   return 0;
}
正如预期的那样,输出包括以下句子:

Sending ...
Total bytes: 100
在fortran中,代码为:

PROGRAM send_recv_mpi
include 'mpif.h'

integer process_Rank, size_Of_Cluster, ierror, message_Item

call MPI_INIT(ierror)
call MPI_COMM_SIZE(MPI_COMM_WORLD, size_Of_Cluster, ierror)
call MPI_COMM_RANK(MPI_COMM_WORLD, process_Rank, ierror)

IF(process_Rank == 0) THEN
    message_Item = 42
    call MPI_SEND(message_Item, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, ierror)
    print *, "Sending message containing: ", message_Item
ELSE IF(process_Rank == 1) THEN
    call MPI_RECV(message_Item, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierror)
    print *, "Received message containing: ", message_Item
END IF

call MPI_FINALIZE(ierror)
END PROGRAM
汇编如下:

$ mpicc -c prof.c 
$ mpif77 -c simple.f90 
$ mpif77 -o simple prof.o simple.o 
$ mpiexec --hostfile hfile --oversubscribe -np 2 ./simple
但是,Fortran执行不会显示分析消息。似乎没有调用分析代码


非常感谢。

Fortran程序不会直接调用任何PMPI过程或拦截C提供的函数。Fortran绑定是否间接调用它们取决于实现:您的实现没有

正如Gilles Gouaillardet评论的那样,一些实现(尤其是MPICH)确实允许本问题中开发的拦截。然而,对于那些没有实现的实现,以下推理适用

尽管您有一个C编译的对象,该对象通过Fortran主程序链接到可执行文件,但这并不影响Fortran程序的操作:Fortran程序不引用该C对象定义的任何符号

例如,C源文件定义的符号
MPI_Init
与Fortran编译器看到
MPI_Init
后Fortran链接器寻找的符号不同。它将查找
mpi\u init\u
(或者类似的内容:精确的细节将取决于您的系统)


要让Fortran程序使用用户定义的C对象,您需要使用适当的语言间操作(例如,使用标准化的C与Fortran的互操作性,或手动更改名称)。但是,您还需要解决MPI多语言使用的更复杂方面。

您认为在Fortran版本中启用分析调用应该采用什么机制?除了“normal”
MPI_INIT
等,您似乎没有调用任何东西。我认为Fortran中的MPI_INIT只是MPI_INIT的C MPI实现的一个接口,我希望使用profile接口捕获调用。事实上,我将MPI_INIT()重写为MPI_INIT(),然后Fortran调用它。也就是说,MPI_INIT在我的平台中调用MPI_INIT。在mpi_init_ui内部调用PMPI_init(NULL,NULL)并运行良好,但对于更复杂的函数,如mpi_send_I,调用PMPI_send和参数时会遇到问题。实际上,我不知道该怎么做。Fortran绑定是特定于实现的。例如,在OpenMPI中,Fortran绑定通常会调用匹配的
PMPI
符号(重点是
P
),这意味着Fortran的包装器必须用Fortran编写(并调用
PMPI
Fortran子例程)。我的理解是,MPICH Fortran绑定确实调用了
MPI
C绑定(无
P
),因此OP方法可以用于此实现及其派生工具。@GillesGouaillardet,有一个原则是“如果可以包装,就不要重写”,但是对于这个问题的简单例子来说,Fortran截取肯定比去C@GillesGouaillardet更有意义。哦,我不是说这是一件明智的事情。我只是说,我看不出它不能正常工作的原因。@toño,如果通信网络是您所追求的,那么您可能会发现已建立的MPI分析工具将为您提供现成的功能。(试图在低水平上理解机制没有什么错,但如果你只关心结果,那么使用现有的工具就很有意义。)@Tono Score-P/Vampir和TAU都应该能够获得这些信息。由于MPI3中修订的Fortran MPI绑定,分析Fortran MPI调用变得更加复杂。如果您需要一些背景信息,请参阅MPI标准中的第17.1.5章“接口规范、过程名称和分析接口”()。
PROGRAM send_recv_mpi
include 'mpif.h'

integer process_Rank, size_Of_Cluster, ierror, message_Item

call MPI_INIT(ierror)
call MPI_COMM_SIZE(MPI_COMM_WORLD, size_Of_Cluster, ierror)
call MPI_COMM_RANK(MPI_COMM_WORLD, process_Rank, ierror)

IF(process_Rank == 0) THEN
    message_Item = 42
    call MPI_SEND(message_Item, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, ierror)
    print *, "Sending message containing: ", message_Item
ELSE IF(process_Rank == 1) THEN
    call MPI_RECV(message_Item, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierror)
    print *, "Received message containing: ", message_Item
END IF

call MPI_FINALIZE(ierror)
END PROGRAM
$ mpicc -c prof.c 
$ mpif77 -c simple.f90 
$ mpif77 -o simple prof.o simple.o 
$ mpiexec --hostfile hfile --oversubscribe -np 2 ./simple