这个任务适合rslurm吗?

blpfk2vs  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(110)

我有几个实验,我想在每个节点上运行一个实验,每个实验都是几个核心的执行序列。现在我的代码看起来像:

run_seeds <- c(1,2,3,4,5,6,7,8,9,10)

write_lines(paste("problem", "run_seed", "num_patients", "method", "name", "type", "error", sep="\t"), file=err_file_name)

# initialize loop
for (j in 1:length(run_seeds)) {
    ...
}

# start loop
for (i in range_pat) {

  print(paste("iteration",i))
  
  for (j in 1:length(run_seeds)) {

    run_seed<-run_seeds[[j]]
    set.seed(run_seed)
    ...
    write_lines(paste(problem, run_seed, i, "dst", ind_name, type, error, sep="\t"), file=err_file_name, append=TRUE)

  }
}

字符串
这个任务适合rslurm吗?如果是,我如何更改代码?通过查看https://cran.r-project.org/web/packages/rslurm/vignettes/rslurm.html的示例,我不一定想导出rds文件或生成slurm脚本。我想在一个slurm脚本中运行它。它是否可行?或者我需要将其更改为rslurm可接受的格式?另外,节点返回的结果有一定的顺序,这仍然可行吗?
如果没有,你会推荐我使用什么软件包?

bqf10yzr

bqf10yzr1#

Slurm仍然以不同的默认值使用,并且在不同的HPC中心有不同的R最佳实践,因此在尝试通过R脚本(如rslurm)管理Slurm之前,学习一些直接使用Slurm的基础知识是值得的。
对于多节点实验,您应该编写两个脚本:一个Slurm提交脚本(比如script.sh)和一个支持MPI的R脚本(比如script.R)。
提交脚本请求节点并设置您的软件环境(R版本、BLAS库、MPI版本等),这些环境因HPC中心而异,您需要查阅文档以了解可用的软件环境。登录节点上的module avail将告诉您可用的软件环境。
例如,script.sh可能如下所示:

#!/bin/bash
#SBATCH -A <your-account>
#SBATCH -p <submission-queue-name>
#SBATCH --nodes=4
#SBATCH --exclusive
#SBATCH -t 00:02:00

cd <directory-of-your-rscript>

module load r
module load openmpi

time mpirun --map-by ppr:1:node Rscript  script.R

字符串
使用sbatch script.sh提交脚本。这将请求独占访问4个节点上的所有核心,作业限制为2分钟。中的项<...>应该是不言自明的。加载的模块在集群上可能有所不同,并且可能需要其他模块,具体取决于R的部署方式。最后一行使用OpenMPI在每个节点上运行一个script.R示例。
script.R将使用软件包pbdMPI,您可以在登录节点上的交互式R会话中从CRAN安装该软件包(同样,在特定于您的群集的相应module load rmodule load openmpi之后)。

pbdMPI提供独立于所使用的节点和内核数量的RNG可重复性。在底层,它使用来自parallel程序包的独立流。script.R将如下所示:

library(pbdMPI)
num_streams <- 10

my_streams <- comm.chunk(num_streams, form = "vector", rng = TRUE, seed = 12345)

# initialize loop
for (j in my_streams) {
    err_file_name <- paste0("err_file_", j, ".txt")
    write_lines(paste("problem", "run_seed", "num_patients", "method", "name", "type", "error", sep="\t"), file=err_file_name)
    ...
}

# start loop
for (i in range_pat) {

  comm.print(paste("iteration",i))
  
  for (j in my_streams) {
    comm.set.stream(j)
    err_file_name <- paste0("err_file_", j, ".txt")
    ...
    write_lines(paste(problem, j, i, "dst", ind_name, type, error, sep="\t"), file=err_file_name, append=TRUE)
  }
}

finalize()


这里需要注意几点:

  • 为了避免这个代码的并行示例写在彼此的顶部,每个种子写到一个不同的文件。
  • 只有一个示例(秩0)将迭代次数写入标准输出。
  • 由于每个节点上运行一个示例,因此该节点上的所有内核都可用于并行工作。如果您自己管理,我建议使用mclapply()。如果您不需要一个节点上的所有内核,则可以通过在--map-by OpenMPI参数中指定,在每个节点上运行此代码的多个示例。
  • 代码的每个示例都从comm.chunk()中获取自己的一组my_streamsmy_streams只是一组索引值,用于为每个值设置一个独立的随机数流。这些随机数流将从它们停止的地方继续到下一个i值。也可以通过参数将它们重置回它们的开始,每个ireset = TRUE的一个。
  • 如果您有大量的种子,最后这会扩展到任意数量的节点。它也可以使用单个种子进行复制,而与您使用的节点数或每个节点的示例数无关。
  • finalize()提供了从MPI中正常退出的功能。

相关问题