我想在 R 可以调用的子例程中编写一些并行 Fortran 代码(我想从 R 读取数据并将其发送到并行 Fortran MPI)。然而,我注意到,当我将以下程序作为子例程运行时(即将“子例程”替换为“程序”),代码不再编译(当它是程序时,它会编译)。我正在使用 MPICH 中的 mpif90
编译代码。在 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
最佳答案
这是一个我想从 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 包装器命令“mpif90”构建了一个共享对象文件:
$ mpif90 -fpic -shared -o test.so test.f90
我尝试使用“R CMD SHLIB”,但最终决定让“mpif90”创建共享对象比让“R CMD SHLIB”处理MPI更容易。缺点是该命令是 gfortran 特定的。对于不同的编译器,您可能会通过使用“SHLIB”--dry-run
选项获得一些帮助:
$ R CMD SHLIB --dry-run test.f90
这将显示使用编译器创建共享对象所使用的命令。然后,您可以修改命令以使用“mpif90”来处理 MPI header 和库。
这是一个调用 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()
由于它是 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 子例程中使用 MPI。
关于r - 从 R 调用并行 fortran MPI 子例程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28491478/