3

我的目标是重复运行一个 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 数组来完成上述操作?

4

3 回答 3

3

主要技巧是n从输入文件中提取第 th 行。假设你在一个类 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" 选项来避免有关无法识别的参数的警告消息。我还建议commandArgs(trailingOnly=TRUE)在 R 脚本中使用,这样您就只能看到感兴趣的参数。

于 2015-12-23T19:14:37.710 回答
0

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

而是提示然后解决您的具体问题。

于 2015-12-23T20:15:47.533 回答
0

史蒂夫韦斯特森的回答很好;谢谢!

但是,在 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

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

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

于 2015-12-26T00:45:06.097 回答