使用doParallel在Slurm作业中从R启动多个系统调用

yyyllmsg  于 2023-09-27  发布在  其他
关注(0)|答案(1)|浏览(125)

我正在使用一个R脚本,它基本上是将命令行命令粘贴在一起,通过system2()执行。这些命令运行一些Java应用程序。
现在,我想一次生成该Java应用程序的多个进程,以便在集群计算机上执行一些任务。作业通过Slurm提交。使用doParallel从R内部执行系统调用,并为Slurm作业保留一定数量的内核,这有意义吗?或者是否有更有效的选项(例如,通过Slurm并行运行R脚本的多个示例,以便产生并行Java示例)?
我不确定Slurm或parallel如何分配资源,以及如何最有效地生成进程。在此设置中,哪个进程将控制Java示例的执行位置?
泥浆作业示例:

#!/bin/bash

#SBATCH --job-name=somejob
#SBATCH --output=somejob%a.out
#SBATCH --time=2:00:00
#SBATCH --partition=node
#SBATCH --qos=normal
#SBATCH --account=node
#SBATCH --cpus-per-task=20
#SBATCH --mem-per-cpu=3200
#SBATCH --ntasks=1
#SBATCH --array=1#-12

srun R --vanilla -f somescript.R

示例R脚本:

#!/usr/bin/env Rscript

require("doParallel")

cl <- parallel::makeCluster(20)
doParallel::registerDoParallel(cl)

foreach::foreach(
  arg1 = 1:20, .packages = "mypackage"
  ) %dopar% {
    arg2 <- "some_arg"
    system2("/path/to/java.exe", args = c(arg1, arg2), stdout = TRUE)
  }
wribegjk

wribegjk1#

假设您有一个集群,每个集群的节点都有32个内核,下面的R脚本和shell脚本将运行2个R会话,每个会话使用32个内核,对您的Java代码执行64次并行操作。

library(mypackage) # substitute your package name and add others
library(pbdMPI)

my_arg1 = comm.chunk(64, form = "vector") # gets arg1 instances for this rank

sys_call = function(arg1) {
    arg2 <- "some_arg"
    system2("/path/to/java.exe", args = c(arg1, arg2), stdout = TRUE)
}
mclapply(my_arg1, sys_call, mc.cores = 32)

finalize()

将上述内容保存到my_r_script.R中。

#!/bin/bash

#SBATCH --nodes=2
#SBATCH --exclusive

module load r

mpirun  --map-by ppr:1:node Rscript my_r_script.R

将上述内容保存到my_script.sh中,并使用sbatch my_script.sh提交给Slurm。
shell脚本要求2个节点和节点上的所有内核。OpenMPI mpirun为每个节点放置1个R会话,并且由于独占访问,所有核心都可用于mclapply()
您可能需要加载提供软件环境的模块,包括module load r。这些细节通常取决于站点。
您将需要额外的#SBATCH参数,用于帐户、队列、时间和可能的内存,这些参数在具有不同本地默认值的不同集群上可能会有所不同。
arg1参数在64个示例中各不相同,可用于在Java代码中创建不同的输出文件名。

相关问题