14

myscript.R使用作业调度程序(特别是PBS)在集群从节点上运行

目前,我使用以下命令将 R 脚本提交到从节点

qsub -S /bin/bash -p -1 -cwd -pe mpich 1 -j y -o output.log ./myscript.R

R 中是否有允许我在头节点上运行 myscript.R 并将单个任务发送到从节点的函数?就像是:

foreach(i=c('file1.csv', 'file2.csv', pbsoptions = list()) %do% read.csv(i)

更新: qsub 命令的替代解决方案是#/usr/bin/Rscript从第一行中删除myscript.R并直接调用它,正如@Josh 所指出的那样

qsub -S /usr/bin/Rscript -p -1 -cwd -pe mpich 1 -j y -o output.log myscript.R
4

4 回答 4

5

如果您想从 R 脚本中提交作业,我建议您查看“BatchJobs”包。这是DESCRIPTION文件中的引用:

提供 Map、Reduce 和 Filter 变体以在 PBS/Torque、LSF、SLURM 和 Sun Grid Engine 等批处理计算系统上生成作业。

BatchJobs 似乎比以前的类似软件包(例如 Rsge 和 Rlsf)更复杂。有用于注册、提交和检索作业结果的功能。这是一个简单的例子:

library(BatchJobs)
reg <- makeRegistry(id='test')
batchMap(reg, sqrt, x=1:10)
submitJobs(reg)
y <- loadResults(reg)

您需要配置 BatchJobs 以使用您的批处理排队系统。submitJobs “resource” 参数可用于为作业请求适当的资源。

如果您的集群不允许长时间运行的作业,或者它严重限制了长时间运行的作业的数量,这种方法非常有用。BatchJobs 允许您通过将工作分解为多个作业来绕过这些限制,同时隐藏与手动执行相关的大部分工作。

文档和示例可在项目网站上获得。

于 2014-04-14T14:29:09.300 回答
4

对于我们的大部分工作,我们确实使用 qsub(而不是)并行运行多个 R 会话。

如果是针对多个文件,我通常会这样做:

while read infile rest
do
qsub -v infile=$infile call_r.sh 
done < list_of_infiles.txt

call_r.sh:

...
R --vanilla -f analyse_file.R $infile
...

分析文件.R:

args <- commandArgs()
infile=args[5]
outfile=paste(infile,".out",sep="")...

然后我把所有的输出组合起来......

于 2013-04-11T11:17:57.200 回答
2

R 包 Rsge 允许将作业提交到 SGE 托管集群。它基本上将所需的环境保存到磁盘,构建作业提交脚本,通过 qsub 执行它们,然后整理结果并将它们返回给您。

因为它基本上包装了对 qsub 的调用,所以它也应该与 PBS 一起工作(尽管由于我不了解 PBS,所以我不能保证)。您可以通过更改 Rsge 关联的全局选项(options()输出中的前缀 sge.)来更改 qsub 命令和使用的选项

它不再在 CRAN 上,但可以从 github 获得:https ://github.com/bodepd/Rsge ,尽管它看起来不再像维护了。

要使用它,请使用随包提供的应用类型函数之一:sge.apply、sge.parRapply、sge.parCapply、sge.parLapply 和 sge.parSapply,它们是 apply、rapply、rapply(t(x) ,...), lapply 和 sapply 分别。除了传递给非并行函数的标准参数之外,还需要几个其他参数:

njobs:             Number of parallel jobs to use

global.savelist:   Character vector giving the names of variables
                   from  the global environment that should be imported.

function.savelist: Character vector giving the variables to save from
                   the local environment.

packages:          List of library packages to be loaded by each worker process
                   before computation is started.

这两个 savelist 参数和 packages 参数基本上指定了在执行代码之前应该将哪些变量、函数和包加载到在集群机器上运行的新 R 实例中。X 的不同组件(列表项或 data.frame 行/列)在 njobs 不同的作业之间划分,并作为作业数组提交给 SGE。每个节点启动一个 R 实例,加载指定的变量、函数和包,执行代码,保存并将结果保存到 tmp 文件。控制 R 实例检查作业何时完成,从 tmp 文件加载数据并将结果重新连接在一起以获得最终结果。

例如计算基因列表的随机样本的统计数据:

library(Rsge)
library(some.bioc.library)

gene.list <- read.delim(“gene.list.tsv”)

compute.sample <- function(gene.list) {
   gene.list.sample <- sample(1000, gene.list)
   statistic <- some.slow.bioc.function(gene.list.sample)
   return (statistic)

}

results <- sge.parSapply(1:10000, function(x) compute.sample,
                         njobs = 100,
                         global.savelist = c(“gene.list”),
                         function.savelist(“compute.sample”),
                         packages = c(“some.bioc.library”))
于 2014-04-15T13:15:16.353 回答
1

如果您想在头节点上使用脚本时将任务发送到从节点,我相信您的选择如下:

  1. 预先分配所有从节点和它们,并在不需要它们时让它们处于待机状态(正如我在第一个答案中所建议的那样)。
  2. 当需要从节点时启动新作业,并让它们将结果保存到磁盘。暂停主进程,直到从属完成任务,然后组装它们的输出文件。

选项 2 绝对是可能的,但需要更长的时间来实现(实际上我自己已经做过好几次了)。@pallevillesen 的回答非常准确。

原始答案,带有误解的问题

我自己从未与 PBS 合作过,但您似乎可以使用它来提交 MPI 作业。在执行 R 脚本之前,您可能需要加载 MPI 模块,将这些行的 shell 脚本发送到qsub.

#!/bin/bash
#PBS -N my_job
#PBS -l cput=10:00:00,ncpus=4,mem=2gb

module load openmpi
module load R
R -f myscript.R

然后,您应该能够使用并行doSNOW执行foraech循环。

n.slaves <- 4

library(doSNOW)
cl <- makeMPIcluster(n.slaves)
registerDoSNOW(cl)

foreach(i=c('file1.csv', 'file2.csv'), pbsoptions = list()) %dopar% read.csv(i)
于 2014-04-11T08:15:35.137 回答