Ric*_*ich 4 parallel-processing fortran r mpi subroutine
我想在R可以调用的子例程中编写一些并行的Fortran代码(我想从R中读取数据并将其发送到并行的Fortran MPI)。但是,我注意到,当我将以下程序作为子例程运行(即用“子例程”代替“程序”)时,代码不再编译(当它是程序时确实会编译)。我编译使用的代码mpif90从MPICH的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)
这是我想从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变得容易。