Я пишу программу (назову ее «пусковой») на C ++, используя MPI для «порождения» второго исполняемого файла («ведомого»). В зависимости от того, сколько узлов в кластере доступно для модуля запуска, он будет запускать ведомые на каждом узле, и подчиненное устройство будет связываться с модулем запуска также через MPI. Когда ведомое устройство выполнено с его математикой, оно сообщает программе запуска, что узел теперь доступен, и программа запуска порождает другого ведомого в свободный узел. Смысл в том, чтобы выполнить 1000 независимых вычислений, которые зависят от второго исполняемого файла, на разнородной группе машин.
Это работает на моем собственном компьютере, где я создаю «поддельный» машинный файл (или хост-файл), дающий программе два узла: localhost и localhost. Модуль запуска порождает двух рабов, и когда один из них заканчивается, запускается другой раб. Это говорит мне о том, что процесс порождения работает правильно.
Когда я перемещаю его в кластер в моей лаборатории (где для управления им используется крутящий момент / мауи), он также работает, если я запрашиваю 1 (один) узел. Если я попрошу больше, я получу пропущенную библиотечную ошибку (точнее, libimf.so. Библиотека от компиляторов intel). Там есть библиотека, и узел ее видит, так как программа запускается, если я запрашиваю только один узел.
Моя PBS, которая работает, выглядит так:
#!/bin/bash
#PBS -q small
#PBS -l nodes=1:ppn=8:xeon
#PBS -l walltime=1:00:00
#PBS -N MyJob
#PBS -V
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/mpich2.shared.exec/lib/:/opt/intel/composerxe-2011.3.174/compiler/lib/intel64/:/usr/local/boost/lib/
log_file="output_pbs.txt"
cd $PBS_O_WORKDIR
echo "Beginning PBS script." > $log_file
echo "Executing on hosts ($PBS_NODEFILE): " >> $log_file
cat $PBS_NODEFILE >> $log_file
echo "Running your stuff now!" >> $log_file
# mpiexec is needed in order to let "launcher" call MPI_Comm_spawn.
/usr/local/mpich2.shared.exec/bin/mpiexec -hostfile $PBS_NODEFILE -n 1 /home/user/launhcer --hostfile $PBS_NODEFILE -r 1 >> $log_file 2>&1
echo "Fim do pbs." >> $log_file
Когда я пробую два или более узлов, программа запуска не запускает никаких исполняемых файлов.
Я получаю вывод, как это:
Beginning PBS script.
Executing on hosts (/var/spool/torque/aux//2742.cluster):
node3
node3
node3
node3
node3
node3
node3
node3
node2
node2
node2
node2
node2
node2
node2
node2
Running your stuff now!
(Bla bla bla from launcher initialization)
Spawning!
/usr/local/mpich2.shared.exec/bin/hydra_pmi_proxy: error while loading shared libraries: libimf.so: cannot open shared object file: No such file or directory
Я нашел еще одного человека с такой проблемой, как моя, в списке рассылки, но не нашел решения. (http://lists.mcs.anl.gov/pipermail/mpich-discuss/2011-July/010442.html). Единственный ответ предлагал попытаться найти, может ли узел видеть библиотеку (если каталог, в котором хранилась библиотека, был смонтирован на узле), поэтому я попытался
ssh node2 ls /opt/intel/composerxe-2011.3.174/compiler/lib/intel64/libimf.so >> $log_file
внутри моего сценария PBS, и библиотека существует в папке, которую может видеть узел.
На мой взгляд, кажется, что Torque / Maui не экспортирует переменные окружения во все узлы (хотя я не знаю, почему это не так), поэтому, когда я пытаюсь использовать MPI_Spawn для запуска другого исполняемого файла в другом узле, он не могу найти библиотеку.
Имеет ли это смысл? Если да, не могли бы вы предложить решение?
Кто-нибудь может предложить какие-то другие идеи?
Заранее спасибо,
Marcelo
РЕДАКТИРОВАТЬ:
Следуя предложению в одном из ответов, я установил OpenMPI для проверки опции «-x VARNAME» с mpiexec. В сценарии PBS я изменил строку выполнения на следующую:
/usr/local/openmpi144/bin/mpiexec -x LD_LIBRARY_PATH -hostfile $PBS_NODEFILE -n 1 /var/dipro/melomcr/GSAFold_2/gsafold --hostfile $PBS_NODEFILE -r 1 >> $log_file 2>&1
но получил следующие сообщения об ошибках:
[node5:02982] [[3837,1],0] ORTE_ERROR_LOG: A message is attempting to be sent to a process whose contact information is unknown in file rml_oob_send.c at line 105
[node5:02982] [[3837,1],0] could not get route to [[INVALID],INVALID]
[node5:02982] [[3837,1],0] ORTE_ERROR_LOG: A message is attempting to be sent to a process whose contact information is unknown in file base/plm_base_proxy.c at line 86
Из интернета я понял, что эта ошибка обычно возникает из-за выполнения mpiexec более чем один раз, как в /path/to/mpiexec mpiexec -n 2 my_program
это не мой случай.
Полагаю, я должен добавить, что порожденная «подчиненная» программа связывается с программой «запуска» через порт. Модуль запуска открывает порт с помощью MPI_Open_port и MPI_Comm_accept, затем он ожидает подключения подчиненной программы, когда ведомое устройство выполняет MPI_Comm_connect.
Как я уже говорил выше, все это работает (с MPICH2), когда я запрашиваю только один узел. С OpenMPI я получаю вышеуказанную ошибку четное когда я прошу только один узел.
Ты прав. Удаленные вызовы намного ниже программного обеспечения кластеризации не передают переменные среды.
Вы можете использовать опцию -x, чтобы mpiexec передавал переменные окружения другим узлам.