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

问题描述 投票:0回答:1

我正在使用一个 R 脚本,它基本上将命令行命令粘贴在一起通过

system2()
执行。这些命令运行一些 Java 应用程序。

现在,我想立即生成该 Java 应用程序的多个进程,以在集群计算机上执行一些任务。作业通过 Slurm 提交。使用

doParallel
以及为 Slurm 作业保留的核心数量从 R 内部执行系统调用是否有意义?或者是否有更有效的选项(例如,通过 Slurm 并行运行 R 脚本的多个实例,以便生成并行 Java 实例)?

我不确定 Slurm 或

parallel
如何分配资源以及如何最有效地生成进程。哪个进程将控制此设置中 Java 实例的执行位置?

Slurm 作业示例:

#!/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)
  }
java r slurm doparallel system2
1个回答
0
投票

假设您有一个节点集群,每个节点都有 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 代码中创建不同的输出文件名。

© www.soinside.com 2019 - 2024. All rights reserved.