2010-11-19 88 views
4

我试图在大型计算机集群上运行一段代码以分析数据的不同部分。bash中的matlab批量并行化

我创建了2个循环来将作业分配给不同节点和节点包含的cpu。 我写的分析函数'chnJob()'只需要一个索引来知道需要分析哪部分数据(在这种情况下是shell变量叫'chn')。

循环是这样的:

for NODE in $NODES; do # Loop through nodes 
    for job_idx in {1..$PROCS_PER_NODE}; do # Loop through jobs per node (8 per node) 
     echo "this is the channel $chn" 
     ssh $NODE "matlab -nodisplay -nodesktop -nojvm -nosplash -r 'cd $WORK_DIR; chnJob($chn); quit'" & 
     let chn++ 
     sleep 2 
    done 
done 

即使我看到CHN变量被正确地递增,传递给MATLAB函数的CHN的值总是CHN的最后一个值。

这可能是因为matlab在每个节点上需要花费大量时间打开并且bash完成循环。所以传递给每个matlab实例的值只是最后一个值。

有没有办法规避这种情况?当我调用函数时,可以'烘烤'该变量的值吗?

或者是完全不同的问题?

回答

2

Bash无法处理大括号范围表达式中的变量。他们必须是文字:{1..10}。由于你现在拥有它,所以内循环总是每次迭代外循环时执行一次,而不是八次(或者任何值为PROCS_PER_NODE)。因此,当chnOriginal_chnNODES * PROCS_PER_NODE时,它从初始值变为NODES

使用C风格for循环,而不是:

for ((job_idx=1; job_idx<=$PROCS_PER_NODE; job_idx++)) 

你可以增加在forjob_idxchn(如果不给你的off-by-一个问题):

for ((job_idx=1; job_idx<=$PROCS_PER_NODE; job_idx++, chn++)) 
3

我不认为这是发生了什么事。你可以尝试运行此:

cnt=0 
for a in 1 2; do 
    for b in 1 2; do 
    echo --- $cnt 
    ssh somehost "echo result: '$cnt'" & 
    let cnt++ 
    done 
done 

替换,某一些主机,你必须sshd运行。这将打印从echo result: '$cnt'远程执行的数字0 - 3。因此,执行本身工作正常。

我可以建议的一件事是让您将命令(matlab ...)移动到已知文件夹中的某个脚本中,然后通过给出该脚本的完整路径在上述循环中运行该脚本。喜欢的东西:

ssh $NOTE "/path/to/script.sh $cnt" 

在脚本中,$1会给你你想要的值(即$cnt从循环)。您可以在脚本的开头使用echo $1 >> /tmp/values来收集文件/tmp/values中的所有值。当然,rm /tmp/values开始之前。这将确认你是否获得了所有你想要的值。

0

如果$ PBS_NODEFILE包含节点列表(每行一个)的文件名,那么这应该工作:

seq 1 100 | parallel --slf $PBS_NODEFILE "matlab -nodisplay -nodesktop -nojvm -nosplash -r 'cd $WORK_DIR; chnJob({}); quit'" 

了解更多:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1