пакетное распараллеливание в Matlab в Bash - PullRequest
4 голосов
/ 20 ноября 2010

Я пытаюсь запустить фрагмент кода на большом компьютерном кластере, чтобы проанализировать различные части данных.

Я создал 2 цикла для назначения заданий различным узлам и процессорам, которые содержат узлы. Функция анализа, которую я написал, 'chnJob ()', просто должна взять индекс, чтобы знать, какую часть данных она должна анализировать (в данном случае это переменная оболочки, называемая '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 правильно увеличивается, значение chn, которое передается функции matlab, всегда является последним значением chn.

Вероятно, это связано с тем, что matlab занимает много времени для открытия каждого узла, а bash к тому времени завершает циклы. Таким образом, значение, которое передается каждому экземпляру matlab, является только последним значением.

Есть ли способ обойти это? Могу ли я «запечь» значение этой переменной при вызове функции?

Или проблема совсем в другом?

Ответы [ 3 ]

3 голосов
/ 20 ноября 2010

Я не думаю, что это то, что происходит. Можете ли вы попробовать запустить это:

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. Это печатает числа 0 - 3, возвращаясь из echo result: '$cnt', выполняемого удаленно. Таким образом, выполнение себя работает нормально.

Одна вещь, которую я могу предложить, это переместить вашу команду (matlab ...) в какой-либо скрипт в известной папке, а затем запустить этот скрипт в вышеуказанных циклах, указав полный путь к этому скрипту. Что-то вроде:

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

В сценарии $1 даст вам желаемое значение (т. Е. $cnt из цикла). Вы можете использовать echo $1 >> /tmp/values в начале вашего скрипта, чтобы собрать все значения в файле /tmp/values. Конечно, rm /tmp/values перед тем, как начать. Это подтвердит, получаете ли вы все значения так, как вы хотите.

2 голосов
/ 20 ноября 2010

Bash не может обрабатывать переменные в выражениях диапазона скобок.Они должны быть литералами: {1..10}.Из-за того, что у вас сейчас есть, внутренний цикл всегда выполняется ровно один раз за итерацию внешнего цикла, а не восемь раз (или независимо от значения PROCS_PER_NODE).В результате chn переходит от своего начального значения к этому плюс NODES, когда оно должно перейти от Original_chn до NODES * PROCS_PER_NODE.

Вместо этого используйте цикл for в стиле C:

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

Вы можете увеличить как job_idx, так и chn в for (если это не доставляет вам неприятностей):

for ((job_idx=1; job_idx<=$PROCS_PER_NODE; job_idx++, chn++))
0 голосов
/ 03 февраля 2013

Если $ 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...