从R调用parallel fortran MPI子例程 [英] Call parallel fortran MPI subroutine from R

查看:160
本文介绍了从R调用parallel fortran MPI子例程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在可以被R调用的子例程中编写一些并行Fortran代码(我想从R读取数据并将其发送到并行Fortran MPI)。但是,我注意到,当我将下列程序作为子程序运行时(即将子程序替换为程序),代码不再编译(它在程序中时编译)。我正在使用 MPICH 中的 mpif90 编译代码Linux。



是否可以在Fortran的子例程中初始化并完成MPI?如果没有,是否仍有可能以某种方式从R调用并行Fortran MPI?如果不是在Fortran中,可以在C中完成吗?



以下是代码:

 模块全局
整数numnodes,myid,mpi_err
整数,参数:: my_root = 0
结束模块全局

模块fmpi
include'mpif.h'
end module fmpi

子程序init
使用fmpi
使用全局
隐式无
调用MPI_INIT(mpi_err)
调用MPI_COMM_SIZE(MPI_COMM_WORLD,numnodes,mpi_err)
调用MPI_Comm_rank(MPI_COMM_WORLD,myid,mpi_err)
结束子程序init

程序测试
使用全局
使用fmpi
implicit none
real * 8 :: dat(10)
integer * 4 :: i
调用init
if(myid == my_root )然后
do i = 1,10
dat(i)= i
enddo
print *,dat(1)
endif
call mpi_finalize( mpi_err)
结束程序测试


解决方案

我想调用一个简单的Fortran / MPI子例程从R开始:

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $


$ integer * 4 id,ierr
call MPI_Comm_rank(MPI_COMM_WORLD,id,ierr)
结束子程序测试

要在Linux机器上从R中调用此函数,我使用Open MPI wrapper命令mpif90构建了一个共享对象文件:

  $ mpif90 -fpic -shared -o test.so test.f90 

我尝试过使用R CMD SHLIB,但最终认为获得mpif90创建共享对象要比R CMD SHLIB处理MPI更容易。缺点是命令是特定的。对于不同的编译器,您可以通过使用SHLIB - dry-run 选项获得一些帮助:

 $ R CMD SHLIB  - 延期运行test.f90 

这将显示它将用于使用编译器创建共享对象的命令。您可以修改命令以使用mpif90来处理MPI头文件和库。



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

 #SPMD风格程序:通过mpirun启动所有worker 
library(Rmpi)
dyn.load (test.so)

#这个Fortran子程序将使用MPI函数
r < - .Fortran(test,as.integer(0),as.integer(0) )

#每个工人显示结果
id < - r [[1]]
ierr < - r [[2]]
if(ierr == 0){
cat(sprintf(worker%d:hello\\\
,id))
} else {
cat(sprintf(ierr =%d \\\
,ierr))
}

#完成MPI并退出
mpi.quit()

由于它是一个SPMD风格的程序,它不会产生工人,就像许多 Rmpi​​ 示例一样。相反,所有工作人员都是通过mpirun启动的,这是执行C和Fortran MPI程序的典型方式:

  $ mpirun -n 3 R --slave -f test.R 

这会运行我的R脚本的三个实例,所以输出是:

  worker 0:hello 
worker 1:hello
worker 2:hello

我认为以这种方式构造代码可以很容易地从R和任意数量的Fortran子程序。


I would like to write some parallel Fortran code in a subroutine that can be called by R (I would like to read in data from R and send it to a parallel Fortran MPI). I have noticed, however, that when I run the following program as a subroutine (i.e. substitute "subroutine" for "program"), the code no longer compiles (it does compile when it is a program). I am compiling the code using the mpif90 from MPICH in Linux.

Is it possible to initialize and finalize an MPI in a subroutine in Fortran? If not, is it still possible to somehow call a parallel Fortran MPI from R? If not in Fortran, can this be done in C?

Here's the code:

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

解决方案

Here is a simple Fortran/MPI subroutine that I want to call from R:

subroutine test(id, ierr)
  use mpi
  implicit none
  integer*4 id, ierr
  call MPI_Comm_rank(MPI_COMM_WORLD, id, ierr)
end subroutine test

To call this from R on a Linux machine, I built a shared object file using the Open MPI wrapper command "mpif90":

$ mpif90 -fpic -shared -o test.so test.f90

I tried to use "R CMD SHLIB", but eventually decided that it was easier to get "mpif90" to create a shared object than to get "R CMD SHLIB" to deal with MPI. The downside is that the command is gfortran specific. For a different compiler, you might get some help by using the "SHLIB" --dry-run option:

$ R CMD SHLIB --dry-run test.f90

This will display the commands that it would have used to create the shared object using your compiler. You can then modify the commands to use "mpif90" in order to handle the MPI headers and libraries.

Here is an R script that calls the Fortran test subroutine. It loads Rmpi (which automatically calls MPI_Init), loads the shared object containing my Fortran subroutine, and then calls it:

# 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()

Since it's an SPMD-style program, it doesn't spawn workers, like many Rmpi examples. Instead, all of the workers are started via mpirun, which is the typical way of executing C and Fortran MPI programs:

$ mpirun -n 3 R --slave -f test.R

This runs three instances of my R script, so the output is:

worker 0: hello
worker 1: hello
worker 2: hello

I think that structuring the code in this way makes it easy to use MPI from R and from any number of Fortran subroutines.

这篇关于从R调用parallel fortran MPI子例程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆