我的大学运行一个condor计算网格(计算节点正在运行Linux),我想用它来在R中运行模拟。问题是只有一些网格上的机器安装了R。 到目前为止,我看到两个选项,但我不知道如何实现任何一个,所以我希望你能帮助我(请记住,我不是一个系统pipe理员,不能做太多改变设置计算节点):
1)在用我的神鹰提交文件出去的ClassAds中进行检查,要求在具有/usr/bin/R
节点上计算作业。
2)将R及其所有依赖包打包到一个独立的目录中,这个目录可以发送到计算节点,并且可以运行我的仿真。 我已经尝试了几个小时来做到这一点,但Linux版本的R(与OSX和Windows版本不同)似乎针对分布在整个文件系统中的库运行,而且我想不出一个实际的方法来收集它们都进入了R可以find它们的位置。
有任何想法吗? 提前致谢。
最终为我工作的是提出的解决方案(1)。 在这里,我将讨论如何在我的condor提交文件和我的worker shell脚本中实现(1)。
这是shell脚本。 重要的改变是通过if [ -f /usr/bin/R ]
检查R是否安装在计算节点上。 如果找到了R,我们沿着一条以返回值0结束的路径。如果找不到R,我们返回1(这就是exit 0
行和exit 1
行的含义)。
mkdir output if [ -f /usr/bin/R ] then if $(uname -m |grep '64') then Rscript code/simulations-x86_64.r $* else Rscript code/simulations-i386.r $* fi tar -zcvf output/output-$1-$2.tgz2 output/*.csv exit 0 else exit 1 fi
现在神鹰提交文件。 关键的变化是倒数第二行( on_exit_remove = (ExitBySignal == False) && (ExitCode == 0)
)。 它检查来自计算节点的每个作业的返回值 – 如果返回值不是零(即,如果在计算节点上找不到R),则作业将被放回到队列中以重新运行。 否则,该作业将被视为已完成并从队列中删除。
universe = vanilla log = logs/log_$(Cluster)_$(Process).log error = logs/err_$(Cluster)_$(Process).err output = logs/out_$(Cluster)_$(Process).out executable = condor/worker.sh arguments = $(Cluster) $(Process) requirements = (Target.OpSys=="LINUX" && regexp("stat", Machine)) should_transfer_files = YES when_to_transfer_output = ON_EXIT_OR_EVICT transfer_input_files = code, R-libs, condor, seeds.csv transfer_output_files = output notification = Never on_exit_remove = (ExitBySignal == False) && (ExitCode == 0) queue 1800
哇,好吧,这比我想象的要难。 我们从建议的解决方案(2)开始:
在哈德利的建议下,我用Renv把R安装到一个已知的本地目录(也使用R-build来构建R-2.15.2)。 不幸的是,这个本地安装仍然依赖于像/usr/lib
这样的系统级库。
MvG建议把当地的R装置拔出来。 这是一个包含所有必要系统库的本地副本的方法,可能适用于大多数面对我情况的人。 但是,我的R
代码依赖于几个仅与R
> = 2.15兼容的R
包。
于是我把所有的库从圣人的lib
目录中取出,并把它们复制到Renv的R-2.15.2安装中。 这可能会奏效,但是我的大学神鹰网格上的一些机器必须有一个奇怪的架构,因为大约有十分之一的作业回来了,并且错误地尝试着使用错误版本的libc.so
在这一点上,我放弃了提出的解决方案(2),并转向提出的解决方案(1)。