从 R 调用并行 Fortran MPI 子例程
Call parallel fortran MPI subroutine from R
我想在 R 可以调用的子例程中编写一些并行 Fortran 代码(我想从 R 读取数据并将其发送到并行 Fortran MPI)。然而,我注意到,当我 运行 以下程序作为子例程时(即用 "subroutine" 代替 "program"),代码不再编译(当它是一个程序时它会编译).我正在使用 Linux 中的 MPICH 中的 mpif90
编译代码。
是否可以在 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
这样做应该可以安装,但这不是最简单的事情。该过程通常涉及以下步骤。但首先,一些注意事项:R 只能调用 subroutines,因此您必须将主程序修改为子例程并传递上述参数。
此外,我会尝试首先使用 Fortran 处理非并行案例,然后尝试处理并行案例。
安装 gfortran。 我的 R (3.1.2) 版本专门针对 gfortran-4.8。我安装了 gfortran-4.9,所以我创建了一个从 4.9 到 4.9 的符号 link,它似乎可以工作(例如 ln -s gfortran-4.9 gfortran-4.8)
安装 Rmpi 库。有一些说明 here 可以在命令行上执行此操作,但仅适用于 Linux。因此,您可能需要单独下载并安装。你可以试试:
> r 命令安装 Rmpi_0.6-5.tar.gz
创建程序的共享对象库。如果你上面的代码是name test.f90,在命令行运行:
$ r CMD SHLIB 测试.f90
加载共享对象到R:
> dyn.load('test.so')
根据这个 page,假设你要调用一个子程序(不是并行的),实际调用 运行 子程序应该是类似于:
> .Fortran("test", n=as.integer(5), x=as.double(rnorm(5)))
从 R 中启动 MPI 作业。您将不得不使用 Rmpi 接口从 R 中执行所有 MPI 初始化操作(mpi_init()、mpi_comm_size()、mpi_comm_rank())。有个不错的教程here:
> 图书馆(Rmpi)
> mpi.spawn.Rslaves(nslaves=4)
这是我想从 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
为了在 Linux 机器上从 R 调用它,我使用 Open MPI wrapper 命令构建了一个共享 object 文件 "mpif90":
$ mpif90 -fpic -shared -o test.so test.f90
我尝试使用 "R CMD SHLIB",但最终决定让 "mpif90" 创建共享 object 比让 "R CMD SHLIB" 处理 MPI 更容易.缺点是该命令是特定于 gfortran 的。对于不同的编译器,您可能会通过使用 "SHLIB" --dry-run
选项获得一些帮助:
$ R CMD SHLIB --dry-run test.f90
这将显示用于使用您的编译器创建共享 object 的命令。然后您可以修改命令以使用 "mpif90" 以处理 MPI headers 和库。
这是一个调用 Fortran test
子例程的 R 脚本。它加载 Rmpi
(自动调用 MPI_Init
),加载包含我的 Fortran 子例程的共享 object,然后调用它:
# 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()
因为它是一个 SPMD-style 程序,所以它不像许多 Rmpi
示例那样产生工人。相反,所有 worker 都是通过 mpirun 启动的,这是执行 C 和 Fortran MPI 程序的典型方式:
$ mpirun -n 3 R --slave -f test.R
这会运行我的 R 脚本的三个实例,因此输出为:
worker 0: hello
worker 1: hello
worker 2: hello
我认为以这种方式构建代码可以轻松地从 R 和任意数量的 Fortran 子例程中使用 MPI。
我想在 R 可以调用的子例程中编写一些并行 Fortran 代码(我想从 R 读取数据并将其发送到并行 Fortran MPI)。然而,我注意到,当我 运行 以下程序作为子例程时(即用 "subroutine" 代替 "program"),代码不再编译(当它是一个程序时它会编译).我正在使用 Linux 中的 MPICH 中的 mpif90
编译代码。
是否可以在 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
这样做应该可以安装,但这不是最简单的事情。该过程通常涉及以下步骤。但首先,一些注意事项:R 只能调用 subroutines,因此您必须将主程序修改为子例程并传递上述参数。 此外,我会尝试首先使用 Fortran 处理非并行案例,然后尝试处理并行案例。
安装 gfortran。 我的 R (3.1.2) 版本专门针对 gfortran-4.8。我安装了 gfortran-4.9,所以我创建了一个从 4.9 到 4.9 的符号 link,它似乎可以工作(例如 ln -s gfortran-4.9 gfortran-4.8)
安装 Rmpi 库。有一些说明 here 可以在命令行上执行此操作,但仅适用于 Linux。因此,您可能需要单独下载并安装。你可以试试:
> r 命令安装 Rmpi_0.6-5.tar.gz
创建程序的共享对象库。如果你上面的代码是name test.f90,在命令行运行:
$ r CMD SHLIB 测试.f90
加载共享对象到R:
> dyn.load('test.so')
根据这个 page,假设你要调用一个子程序(不是并行的),实际调用 运行 子程序应该是类似于:
> .Fortran("test", n=as.integer(5), x=as.double(rnorm(5)))
从 R 中启动 MPI 作业。您将不得不使用 Rmpi 接口从 R 中执行所有 MPI 初始化操作(mpi_init()、mpi_comm_size()、mpi_comm_rank())。有个不错的教程here:
> 图书馆(Rmpi)
> mpi.spawn.Rslaves(nslaves=4)
这是我想从 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
为了在 Linux 机器上从 R 调用它,我使用 Open MPI wrapper 命令构建了一个共享 object 文件 "mpif90":
$ mpif90 -fpic -shared -o test.so test.f90
我尝试使用 "R CMD SHLIB",但最终决定让 "mpif90" 创建共享 object 比让 "R CMD SHLIB" 处理 MPI 更容易.缺点是该命令是特定于 gfortran 的。对于不同的编译器,您可能会通过使用 "SHLIB" --dry-run
选项获得一些帮助:
$ R CMD SHLIB --dry-run test.f90
这将显示用于使用您的编译器创建共享 object 的命令。然后您可以修改命令以使用 "mpif90" 以处理 MPI headers 和库。
这是一个调用 Fortran test
子例程的 R 脚本。它加载 Rmpi
(自动调用 MPI_Init
),加载包含我的 Fortran 子例程的共享 object,然后调用它:
# 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()
因为它是一个 SPMD-style 程序,所以它不像许多 Rmpi
示例那样产生工人。相反,所有 worker 都是通过 mpirun 启动的,这是执行 C 和 Fortran MPI 程序的典型方式:
$ mpirun -n 3 R --slave -f test.R
这会运行我的 R 脚本的三个实例,因此输出为:
worker 0: hello
worker 1: hello
worker 2: hello
我认为以这种方式构建代码可以轻松地从 R 和任意数量的 Fortran 子例程中使用 MPI。