【问题标题】:Profile MPI (PMPI) and Fortran配置文件 MPI (PMPI) 和 Fortran
【发布时间】:2021-08-10 19:11:36
【问题描述】:

我正在编写使用 PMPI(Profile MPI 接口)分析 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;
}

分析代码捕获对 MPI_Xxx 函数的调用:

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


static int totalBytes = 0;

int MPI_Init (int *argc, char ***argv) {

   int err = PMPI_Init(argc, argv);

   return err;
}


int MPI_Send(const void* buffer, int count, MPI_Datatype datatype,
             int dest, int tag, MPI_Comm comm) {

   int size;

   printf("Sending ...\n");
   
   int result = PMPI_Send(buffer, count, datatype, dest, tag, comm);

   MPI_Type_size(datatype, &size);
   totalBytes += count*size;
   
   return result;
}

int MPI_Finalize() {
   
   int rank;
   
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   
   if (rank == 0) {
   
      printf("Total bytes: %d\n", totalBytes);
      
   }
   
   return PMPI_Finalize();
}

编译命令为:

$ mpicc -c example.c 
$ mpicc -c prof.c 
$ mpicc -o example prof.o example.o 
$ mpiexec --hostfile hfile --oversubscribe -np 2 ./example

如预期的那样,输出包括以下句子:

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 版本中的分析调用?除了“正常”MPI_INIT 等之外,您似乎没有打电话给其他任何人。
  • 我以为 Fortran 中的 MPI_INIT 只是 MPI_Init 的 C MPI 实现的接口,我想使用配置文件接口捕获调用。
  • 事实上,我将 MPI_Init() 重写为 mpi_init_() 并 Fortran 调用它。也就是说,MPI_INIT 在我的平台中调用 mpi_init_。在 mpi_init_ 中,我调用 PMPI_Init(NULL, NULL) 并且运行良好,但对于像 mpi_send_ 这样更复杂的函数,我在调用 PMPI_Send 和参数时遇到问题。实际上,我不知道该怎么做。

标签: c fortran mpi


【解决方案1】:

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

作为 Gilles Gouaillardet cmets,一些实现(尤其是 MPICH)确实允许在这个问题中开发的拦截。但是,对于那些不适用以下推理的实现。

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

例如,C 源文件定义的符号MPI_Init 与 Fortran 链接器在 Fortran 编译器看到 MPI_INIT 后正在寻找的东西不同。它会寻找mpi_init_(或类似的:具体细节取决于您的系统)。

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

【讨论】:

  • Fortran 绑定是特定于实现的。例如,在 Open MPI 中,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 都应该能够获取此信息。使用 MPI 3 中修订的 Fortran MPI 绑定,分析 Fortran MPI 调用变得更加复杂。如果您需要一些背景知识,请参阅 MPI 标准中的第 17.1.5 章“接口规范、过程名称和分析接口”(mpi-forum.org/docs/mpi-3.1/mpi31-report/node412.htm#Node412)信息。
猜你喜欢
  • 2012-04-14
  • 2015-06-09
  • 2020-04-17
  • 2014-02-24
  • 2013-02-12
  • 2015-03-13
  • 2013-08-14
  • 2012-01-24
  • 2012-06-20
相关资源
最近更新 更多