【问题标题】:Submit jobs to a slave node from within an R script?从 R 脚本中向从节点提交作业?
【发布时间】:2012-10-30 15:55:27
【问题描述】:

使用作业调度程序让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 命令的替代解决方案是从myscript.R 的第一行中删除#/usr/bin/Rscript 并直接调用它,正如@Josh 指出的那样

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

【问题讨论】:

  • 您可以编写一个 R 函数来构造对 qsub 的系统调用(即您将在 bash 命令行中键入的内容),然后使用 system() 执行它们。您可能希望也可能不想让 qsub 调用 Rscript 作为让 R 执行您的 myscript.R 的一种方式。
  • @JoshO'Brien 在我的原始示例中这是一个很好的观点,myscript.R 的第一行称为 Rscript;但我可以删除它并在 qsub 命令中将/bin/bash 替换为/usr/bin/Rscript ...qsub -S /usr/bin/Rscript ... ,类似的功能但更简洁,因为它不调用bash,然后调用Rscript。
  • 您使用的 qsub 参数表明您使用的是 SGE 而不是 PBS/Torque。

标签: r parallel-processing hpc qsub torque


【解决方案1】:

如果您想从 R 脚本中提交作业,我建议您查看“BatchJobs”包。以下是说明文件中的引述:

提供 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 允许您通过将工作分解为多个作业,同时隐藏与手动执行相关的大部分工作来绕过这些限制。

文档和示例可在the project website 获得。

【讨论】:

    【解决方案2】:

    对于我们的大部分工作,我们确实使用 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="")...
    

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

    【讨论】:

      【解决方案3】:

      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”))
      

      【讨论】:

        【解决方案4】:

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

        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)
        

        【讨论】:

        • 谢谢,但这并不能解决我的问题 - 我希望能够从 R 脚本中提交作业,而不是将 R 脚本作为单个作业提交。
        猜你喜欢
        • 2014-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多