簡體   English   中英

從R調用並行fortran MPI子例程

[英]Call parallel fortran MPI subroutine from R

我想在一個可以被R調用的子程序中編寫一些並行的Fortran代碼(我希望從R讀取數據並將其發送到並行的Fortran MPI)。 但是,我注意到,當我將以下程序作為子程序運行時(即代替“子程序”代替“程序”),代碼不再編譯(它在程序時編譯)。 我正在使用Linux中MPICHmpif90編譯代碼。

是否可以在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

這是一個簡單的Fortran / MPI子程序,我想從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

要在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標頭和庫。

這是一個調用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只能調用子程序 ,因此您必須將主程序修改為子程序並傳遞上述參數。 此外,我會嘗試使用Fortran首先處理非並行案例,然后嘗試處理並行案例。

  • 安裝gfortran。 我的R(3.1.2)版本專門針對gfortran-4.8。 我安裝了gfortran-4.9,所以我創建了一個從4.9到4.9的符號鏈接,它似乎有效(例如ln -s gfortran-4.9 gfortran-4.8)

  • 安裝Rmpi庫 有一些說明這里做在命令行上,但僅適用於Linux工作。 因此,您可能需要單獨下載並安裝。 你可以試試:

    > r CMD INSTALL Rmpi​​_0.6-5.tar.gz

  • 創建程序的共享對象庫 如果上面的代碼是名稱test.f90,則在命令行運行:

    $ r CMD SHLIB test.f90

  • 將共享對象加載到R:

    > dyn.load('test.so')

  • 根據這個頁面 ,假設你要調用子程序(不是並行),運行子程序的實際調用應該是這樣的:

    > .Fortran(“test”,n = as.integer(5),x = as.double(rnorm(5)))

  • 從R內啟動MPI作業 您將不得不使用Rmpi接口從R中執行所有MPI初始化(mpi_init(),mpi_comm_size(),mpi_comm_rank())。 有一個像樣的教程在這里

    >圖書館(Rmpi)

    > mpi.spawn.Rslaves(nslaves = 4)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM