【问题标题】:specifying job arrays in LSF在 LSF 中指定作业数组
【发布时间】:2015-12-22 18:46:39
【问题描述】:

我的目标是重复运行一个 R 脚本,每次使用一组不同参数。

为此,我一直在使用 bash 脚本通过循环输入文件将命令行参数传递给 R 脚本,其中每一行包含 7 个参数的不同组合。

输入文件如下所示:

10 food 0.00005 0.002 1 OBSERVED 0
10 food 0.00005 0.002 1 OBSERVED 240
10 food 0.00005 0.002 1 OBSERVED 480
10 food 0.00005 0.002 1 OBSERVED 720
10 food 0.00005 0.002 1 OBSERVED 960
10 food 0.00005 0.002 1 OBSERVED 1200

命令行参数传递到的 R 脚本的开头如下:

commandArgs(trailingOnly=FALSE)
A <- as.numeric (commandArgs()[as.numeric(length(commandArgs()) -6 )]) 
B <-             commandArgs()[as.numeric(length(commandArgs()) -5 )]  
C <- as.numeric (commandArgs()[as.numeric(length(commandArgs()) -4 )]) 
D <- as.numeric (commandArgs()[as.numeric(length(commandArgs()) -3 )]) 
E <- as.numeric (commandArgs()[as.numeric(length(commandArgs()) -2 )])
F <-             commandArgs()[as.numeric(length(commandArgs()) -1 )]  
G <- as.numeric (commandArgs()[as.numeric(length(commandArgs())    )]) 

读取这些内容并分派 R 脚本的 bash 循环如下;

#!/bin/bash
N=0
cat Input.txt | while read LINE ; do
N=$((N+1))
echo "R --no-save < /home/trichard/Script.R" "$LINE" |  bsub  -N -q priority -R "select[model==Xeon5450]"  
done

但是,问题在于 Input.txt 中有数百万行,所以这种方法太慢了(它会阻止其他 LSF 用户提交他们自己的作业)。

那么,问题来了,如何使用 LSF 数组进行上述操作?

【问题讨论】:

    标签: r cluster-computing jobs hpc lsf


    【解决方案1】:

    主要技巧是从输入文件中提取nth 行。假设你在一个类 Unix 系统上,你可以使用“sed”命令来做到这一点。这是一个例子:

    N=$(wc -l < input.txt)
    echo 'R --no-save -f Script.R --args $(sed "${LSB_JOBINDEX}q;d" input.txt)' |
      bsub -J "R_Job[1-$N]" -N -q priority -R "select[model==Xeon5450]"
    

    在这个例子中,正确的参数引用有点棘手而且非常重要。

    请注意,这使用 R "--args" 选项来避免有关无法识别的参数的警告消息。我还建议在 R 脚本中使用 commandArgs(trailingOnly=TRUE),这样您就只能看到感兴趣的参数。

    【讨论】:

      【解决方案2】:

      也许您应该考虑将其全部放入 R 中并使用具有适当并行化框架的“foreach”循环构造,例如“doMPI”(如果您真的有动力,也可以使用纯 Rmpi​​ ;-))。因此集群上的作业管理系统具有完全控制权,您基本上是在提交一个单个作业。

      而不是提示,而不是针对您的特定问题的解决方案。

      【讨论】:

        【解决方案3】:

        Steve Westson 的回答效果很好;谢谢!

        但是,在 LSF 系统中,单个阵列中的最大 N 个作业被限制为 ~1000。这意味着当您有 >1000 个作业时,您需要提交多个作业数组,如下所示:

        #!/bin/bash
        increment=1000
        startvalue=1
        stopvalue=$(wc -l < Col_Treat_BETA_MU_RAND_METHOD_part1.txt)                           
        stopvalue=$((  ($increment*((stopvalue+999)/$increment))+$increment ))                 
        end=$increment
        
        for ((s=$startvalue,e=$end ; e<$stopvalue; s+=$increment,e+=$increment)); do
          echo $s "-" $e
         echo 'R --no-save -f script.R --args $(sed "${LSB_JOBINDEX}q;d" input.txt)' |  bsub -J "R_Job[$s-$e]"  -N -q normal
        done
        

        因此,这会立即成功提交所有作业,而没有原来的逐个作业循环基本上会阻止其他用户,并且会惹恼您的系统管理员。再次感谢!

        我将其发布为答案,因为它超过了评论的最大长度。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-18
          相关资源
          最近更新 更多