使用OpenMPI从Fortran调用C++

Ros*_*oss 3 c++ gcc fortran openmpi

我有一个编译时问题,我已经减少到以下测试用例.我想从fortran调用一个C++例程,让C++例程知道MPI.

请考虑以下示例代码,

Fortran主要:

! -- main.f90
program main
   implicit none
   external return_three
   integer return_three

   write(*,*) return_three()
end program main
Run Code Online (Sandbox Code Playgroud)

C++子程序:

// -- subs.cpp
#include <mpi.h>

extern "C"
{
   int return_three_();
}

int return_three_()
{
   return 3;
}
Run Code Online (Sandbox Code Playgroud)

请注意,为了重现问题,我只需要包括mpi.h.

使用GCC 5.3和OpenMPI 1.10.1进行编译(我也检查了GCC 4.8和PGI 15.10)在链接期间出现以下问题:

% mpic++ -c subs.cpp
% mpifort -c main.f90
% mpifort -o main subs.o main.o -lstdc++ -lgcc_s
subs.o: In function `MPI::Intracomm::Intracomm()':
subs.cpp:(.text._ZN3MPI9IntracommC2Ev[_ZN3MPI9IntracommC5Ev]+0x14): undefined reference to `MPI::Comm::Comm()'
subs.o: In function `MPI::Intracomm::Intracomm(ompi_communicator_t*)':
subs.cpp:(.text._ZN3MPI9IntracommC2EP19ompi_communicator_t[_ZN3MPI9IntracommC5EP19ompi_communicator_t]+0x19): undefined reference to `MPI::Comm::Comm()'
subs.o: In function `MPI::Op::Init(void (*)(void const*, void*, int, MPI::Datatype const&), bool)':
subs.cpp:(.text._ZN3MPI2Op4InitEPFvPKvPviRKNS_8DatatypeEEb[_ZN3MPI2Op4InitEPFvPKvPviRKNS_8DatatypeEEb]+0x24): undefined reference to `ompi_mpi_cxx_op_intercept'
subs.o:(.rodata._ZTVN3MPI3WinE[_ZTVN3MPI3WinE]+0x48): undefined reference to `MPI::Win::Free()'
subs.o:(.rodata._ZTVN3MPI8DatatypeE[_ZTVN3MPI8DatatypeE]+0x78): undefined reference to `MPI::Datatype::Free()'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

在我看来,像mpifort缺少一些与C++相关的库.据我所知,mpifort应该用于编译fortran主程序.针对OpenMPI 1.10.1编译的Intel 16.0不会出现此问题.

我的问题是:

  • 这里发生了什么?为什么英特尔能够处理这个示例代码而PGI/GCC不能处理?
  • 有一种可移植的方法在Fortran代码中包含带有MPI的C++子例程吗?
  • (如果可能的话)有没有简单的方法来解决我当前的问题?我正在尝试在我的机器上编译一个包,所以如果我可以添加-lmagicfix或者其他东西最好.

Fig*_*aro 6

通过在最后一步添加-lmpi_cxx,我能够使用GCC 5.3.0和openMPI 1.10.2编译代码:

% mpic++ -c subs.cpp
% mpifort -c main.f90
% mpifort -o main main.o subs.o -lstdc++ -lmpi_cxx
Run Code Online (Sandbox Code Playgroud)

原因是openMPI包装器编译器mpifort和mpic ++链接到不同的MPI库.您可以使用以下-showme:libs选项进行检查:

% mpifort -showme:libs
mpi_usempif08 mpi_usempi_ignore_tkr mpi_mpifh mpi
% mpic++ -showme:libs
mpi_cxx mpi
Run Code Online (Sandbox Code Playgroud)

因此,为了使用C++ MPI库,您必须明确告诉mpifort链接到它.