从R调用并行的fortran MPI子例程

Ric*_*ich 4 parallel-processing fortran r mpi subroutine

我想在R可以调用的子例程中编写一些并行的Fortran代码(我想从R中读取数据并将其发送到并行的Fortran MPI)。但是,我注意到,当我将以下程序作为子例程运行(即用“子例程”代替“程序”)时,代码不再编译(当它是程序时确实会编译)。我编译使用的代码mpif90MPICH的Linux操作系统。

是否可以在Fortran的子例程中初始化和完成MPI?如果不是,是否仍然可以通过R调用并行的Fortran MPI?如果不是在Fortran中,可以在C中完成吗?

这是代码:

module global
  integer numnodes,myid,mpi_err
  integer, parameter :: my_root=0
end module global

module fmpi
  include 'mpif.h'
end module fmpi

subroutine init
  use fmpi
  use global
  implicit none
  call MPI_INIT( mpi_err )
  call MPI_COMM_SIZE( MPI_COMM_WORLD, numnodes, mpi_err )
  call MPI_Comm_rank(MPI_COMM_WORLD, myid, mpi_err)
end subroutine init

program test
  use global
  use fmpi
  implicit none
  real*8:: dat(10)
  integer*4:: i
  call init
  if(myid == my_root) then
    do i=1,10
      dat(i) = i
    enddo
    print *,dat(1)
  endif
  call mpi_finalize(mpi_err)
end program test
Run Code Online (Sandbox Code Playgroud)

Ste*_*ton 5

这是我想从R调用的简单Fortran / MPI子例程:

subroutine test(id, ierr)
  use mpi
  implicit none
  integer*4 id, ierr
  call MPI_Comm_rank(MPI_COMM_WORLD, id, ierr)
end subroutine test
Run Code Online (Sandbox Code Playgroud)

为了在Linux机器上从R调用它,我使用Open MPI包装器命令“ mpif90”构建了一个共享对象文件:

$ mpif90 -fpic -shared -o test.so test.f90
Run Code Online (Sandbox Code Playgroud)

我尝试使用“ R CMD SHLIB”,但最终决定让“ mpif90”创建共享对象要比“ R CMD SHLIB”更容易处理MPI。缺点是该命令是gfortran特定的。对于其他编译器,可以使用“ SHLIB” --dry-run选项获得一些帮助:

$ R CMD SHLIB --dry-run test.f90
Run Code Online (Sandbox Code Playgroud)

这将显示使用编译器创建共享库所需的命令。然后,您可以修改命令以使用“ mpif90”,以便处理MPI标头和库。

这是一个调用Fortran test子例程的R脚本。它加载Rmpi(自动调用MPI_Init),加载包含我的Fortran子例程的共享对象,然后调用它:

# SPMD-style program: start all workers via mpirun
library(Rmpi)
dyn.load("test.so")

# This Fortran subroutine will use MPI functions
r <- .Fortran("test", as.integer(0), as.integer(0))

# Each worker displays the results
id <- r[[1]]
ierr <- r[[2]]
if (ierr == 0) {
  cat(sprintf("worker %d: hello\n", id))
} else {
  cat(sprintf("ierr = %d\n", ierr))
}

# Finalize MPI and quit
mpi.quit()
Run Code Online (Sandbox Code Playgroud)

由于它是SPMD风格的程序,因此它不会像许多Rmpi示例一样生成工作程序。而是通过mpirun启动所有工作程序,这是执行C和Fortran MPI程序的典型方式:

$ mpirun -n 3 R --slave -f test.R
Run Code Online (Sandbox Code Playgroud)

这将运行我的R脚本的三个实例,因此输出为:

worker 0: hello
worker 1: hello
worker 2: hello
Run Code Online (Sandbox Code Playgroud)

我认为,以这种方式构造代码使从R和任何数量的Fortran子例程使用MPI变得容易。