bash中的matlab批量并行化

时间:2010-11-19 23:51:29

标签: bash matlab batch-file pbs parallel-processing

我正在尝试在大型计算机集群上运行一段代码,以便分析数据的不同部分。

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

循环是这样的:

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实例的值只是最后一个值。

有没有办法规避这个?我在调用函数时可以'烘焙'变量的值吗?

或问题完全不同?

3 个答案:

答案 0 :(得分: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

将somehost替换为运行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。这将确认您是否获得了所需的所有值。

答案 1 :(得分:2)

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

改为使用C风格的for ((job_idx=1; job_idx<=$PROCS_PER_NODE; job_idx++)) 循环:

job_idx

您可以在chn中增加forfor ((job_idx=1; job_idx<=$PROCS_PER_NODE; job_idx++, chn++)) (如果这不会给您一个一个问题):

{{1}}

答案 2 :(得分: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