c - 由于 MPI_comm_size 导致的段错误

标签 c fortran mpi

我有一个 Fortran 代码,设计为使用默认通信器 MPI_COMM_WORLD 运行,但我打算只使用几个处理器运行它。我有另一个代码,它使用 MPI_comm_split 获取另一个通信器 MyComm。它是一个整数,当我打印它的值时我得到了 3。现在我在我的 Fortran 代码中调用一个 C 函数来获取对应于 MyComm 的等级和大小。但我在这里面临几个问题。

  1. 在 Fortran 中,当我打印 MyComm 时,它的值为 3,但是当我在 C 函数中打印它时,它变成了 17278324。我还打印了 MPI_COMM_WORLD 的值,它的值大约是 1140850688。我不知道这些值是什么意思,为什么 MyComm 的值会改变?

  2. 我的代码运行正常并创建了可执行文件,但是当我执行它时,我遇到了段错误。我使用 gdb 调试我的代码,进程在下一行终止

程序终止,信号 11,段错误。

#0  0x00007fe5e8f6248c in PMPI_Comm_size (comm=0x107a574, size=0x13c4ba0) at pcomm_size.c:62
62      *size = ompi_comm_size((ompi_communicator_t*)comm);

我注意到 MPI_comm_rank 给出了对应于 MyComm 的排名,但问题仅在于 MPI_comm_sizeMPI_COMM_WORLD 没有这样的问题。所以我无法理解是什么原因造成的。我检查了我的输入,但没有得到任何线索。这是我的 C 代码,

#include <stdio.h>
#include "utils_sub_names.h"
#include <mpi.h>
#define MAX_MSGTAG 1000
int flag_msgtag=0;
MPI_Request mpi_msgtags[MAX_MSGTAG];

char *ibuff;
int ipos,nbuff;

MPI_Comm MyComm;
 void par_init_fortran (MPI_Fint *MyComm_r,MPI_Fint*machnum,MPI_Fint *machsize)
{
 MPI_Fint comm_in
 comm_in=*MyComm_r;
 MyComm=MPI_Comm_f2c(comm_in);
 printf("my comm is %d \n",MyComm);

  MPI_Comm_rank(MyComm,machnum);
  printf("my machnum is %d \n ", machnum);
  MPI_Comm_rank(MyComm,machsize);
  printf("my machnum is %d \n ", machsize);
}

编辑:

我想将 MyComm 声明为我的 C 代码中列出的所有函数的全局通信器。但是不知道为什么我的通讯器还是无效。请注意,MPI 例程仅在 Fortran 中初始化和完成,我希望我不必再次在 C 中初始化它们。我正在使用以下 Fortran 代码。

     implicit none
      include 'mpif.h'
      integer :: MyColor, MyCOMM, MyError, MyKey, Nnodes
      integer :: MyRank, pelast
      CALL mpi_init (MyError)
      CALL mpi_comm_size (MPI_COMM_WORLD, Nnodes, MyError)
      CALL mpi_comm_rank (MPI_COMM_WORLD, MyRank, MyError)
      MyColor=1
      MyKey=0 

   CALL mpi_comm_split (MPI_COMM_WORLD, MyColor, MyKey, MyComm,MyError)
   CALL ramcpl (MyComm)
   CALL mpi_barrier (MPI_COMM_WORLD, MyError)
   CALL MCTWorld_clean ()
   CALL mpi_finalize (MyError)

我的子程序 ramcpl 位于另一个地方

subroutine ramcpl (MyComm_r)
implicit none
integer :: MyComm_r, ierr
.
.
.
CALL par_init_fortran (MyComm_r, my_mpi_num,nmachs);
End Subroutine ramcpl

命令行和输出是,

    mpirun -np 4 ./ramcplM ramcpl.in

       Model Coupling: 

[localhost:31472] *** Process received signal ***
[localhost:31473] *** Process received signal ***
[localhost:31472] Signal: Segmentation fault (11)
[localhost:31472] Signal code: Address not mapped (1)
[localhost:31472] Failing at address: (nil)
[localhost:31473] Signal: Segmentation fault (11)
[localhost:31473] Signal code: Address not mapped (1)
[localhost:31473] Failing at address: (nil)
[localhost:31472] [ 0] /lib64/libpthread.so.0() [0x3120c0f7e0]
[localhost:31472] [ 1] ./ramcplM(par_init_fortran_+0x122) [0x842db2]
[localhost:31472] [ 2] ./ramcplM(__rams_MOD_rams_cpl+0x7a0) [0x8428c0]
[localhost:31472] [ 3] ./ramcplM(MAIN__+0xea6) [0x461086]
[localhost:31472] [ 4] ./ramcplM(main+0x2a) [0xc3eefa]
[localhost:31472] [ 5] /lib64/libc.so.6(__libc_start_main+0xfd) [0x312081ed1d]
[localhost:31472] [ 6] ./ramcplM() [0x45e2d9]
[localhost:31472] *** End of error message ***
[localhost:31473] [ 0] /lib64/libpthread.so.0() [0x3120c0f7e0]
[localhost:31473] [ 1] ./ramcplM(par_init_fortran_+0x122) [0x842db2]
[localhost:31473] [ 2] ./ramcplM(__rammain_MOD_ramcpl+0x7a0) [0x8428c0]
[localhost:31473] [ 3] ./ramcplM(MAIN__+0xea6) [0x461086]
[localhost:31473] [ 4] ./ramcplM(main+0x2a) [0xc3eefa]
[localhost:31473] [ 5] /lib64/libc.so.6(__libc_start_main+0xfd) [0x312081ed1d]
[localhost:31473] [ 6] ./ramcplM() [0x45e2d9]
[localhost:31473] *** End of error message ***

最佳答案

Fortran 和 C 中的句柄不兼容。使用 MPI_Comm_f2c https://linux.die.net/man/3/mpi_comm_f2c以及相关的转换函数。在 C 和 Fortran 之间将其作为整数传递,而不是作为 MPI_Comm

关于c - 由于 MPI_comm_size 导致的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51113057/

相关文章:

fortran - MPI_alltoallw 工作和 MPI_Ialltoallw 失败

c - 将图像的一部分写入文件

c - MPI Communicator MPI_Comm_split 无组

c - 从 C 中的十六进制字符串获取 uint

command-line - Fortran 命令行参数

interface - fortran选择按过程调用派生类型

fortran - 为什么 Fortran 用于科学计算?

c++ - 为什么我不能在特定进程的范围内使用 MPI_Scatter()?

c - recvmsg 返回 EDEADLK?

c++ - 重新定义宏时会发生什么?