Команда mpirun, показывающая странное поведение в bash - PullRequest
1 голос
/ 30 марта 2012

У меня быстрый вопрос.

Недавно я пытался запустить программу mpi, используя сервер моей школы, и столкнулся со следующей «странной» проблемой:

Чтобы выполнить команду 'mpirun', мне пришлось поместить ее путь в путь по умолчанию в .bashrc, который я сделал, а затем набрал:

mpirun -n 16 ./myprogram

только для получения сообщения об отсутствующей библиотеке с именем: libmpi.so.0

Однако, если я попытался запустить программу, используя полный путь mpirun, как показано ниже

/usr/lib64/openmpi/bin/mpirun -n 16 ./myprogram

все было хорошо.

Я проверил часто задаваемые вопросы openmpi, и там было сказано, что мне нужно поместить следующую строку в мой .bashrc

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/openmpi/lib

, который на самом деле исправил все для меня, но мой вопрос все еще остается нерешенным:

Почему это случилось?

Заранее спасибо за ваше время.

1 Ответ

1 голос
/ 30 марта 2012

Поскольку компиляторы обертки Open MPI не автоматически -rpath расположения, в котором находится libmpi.so, при компиляции / компоновке myprogram (мы применяем минималистский подход к флагам, которые передаются компиляторам обертки OMPI - если они ' не нужен , мы их туда не кладем).

В частности, когда вы запускаете исполняемый файл в Linux, компоновщик времени выполнения будет искать все библиотеки, необходимые для этого исполняемого файла (запустите «ldd myprogram», и вы увидите список библиотек, которые необходимы для моей программы). Он будет выглядеть во всех системных местоположениях по умолчанию (которые сами по себе настраиваются системными администраторами). Он также просматривает все каталоги, указанные в LD_LIBRARY_PATH - LD_LIBRARY_PATH - это фактически метод для каждого пользователя, расширяющий список каталогов для компоновщика, который ищет для поиска общих библиотек.

Я предполагаю, что libmpi.so не находится ни в одном из системных расположений по умолчанию, и поэтому вам нужно указать его каталог в LD_LIBRARY_PATH.

В качестве альтернативы, вы можете добавить предложение -rpath при связывании myprogram. Например:

mpicc myprogram.c -o myprogram -Wl,-rpath /opt/openmpi/lib

Это добавит местоположение / opt / openmpi / lib в сам бинарный файл myprogram, и компоновщик также будет искать в этом месте файл libmpi.so (и любые другие библиотеки, которые необходимо разрешить). Например:

# Without an rpath clause:
[8:45] svbu-mpi:~/mpi % mpicc hello.c -o hello
[8:45] svbu-mpi:~/mpi % ldd hello
linux-vdso.so.1 =>  (0x00007ffff7ffe000)
libmpi.so.0 => not found
libdl.so.2 => /lib64/libdl.so.2 (0x0000003d58c00000)
libm.so.6 => /lib64/libm.so.6 (0x0000003d59c00000)
libnuma.so.1 => /usr/lib64/libnuma.so.1 (0x00007ffff7ddf000)
libpci.so.3 => /lib64/libpci.so.3 (0x00007ffff7bd2000)
librt.so.1 => /lib64/librt.so.1 (0x0000003d5a000000)
libnsl.so.1 => /lib64/libnsl.so.1 (0x0000003d5c000000)
libutil.so.1 => /lib64/libutil.so.1 (0x0000003d5a800000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003d59400000)
libc.so.6 => /lib64/libc.so.6 (0x0000003d59000000)
/lib64/ld-linux-x86-64.so.2 (0x0000003d58800000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x0000003d5b000000)

Обратите внимание на "not found" в записи libmpi.so.

Вы можете установить LD_LIBRARY_PATH и найти его:

[8:45] svbu-mpi:~/mpi % setenv LD_LIBRARY_PATH /home/jsquyres/bogus/lib
[8:45] svbu-mpi:~/mpi % ldd hello
linux-vdso.so.1 =>  (0x00007ffff7ffe000)
libmpi.so.0 => /home/jsquyres/bogus/lib/libmpi.so.0 (0x00007ffff7b06000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003d58c00000)
libm.so.6 => /lib64/libm.so.6 (0x0000003d59c00000)
libnuma.so.1 => /usr/lib64/libnuma.so.1 (0x00007ffff78e8000)
libpci.so.3 => /lib64/libpci.so.3 (0x00007ffff76db000)
librt.so.1 => /lib64/librt.so.1 (0x0000003d5a000000)
libnsl.so.1 => /lib64/libnsl.so.1 (0x0000003d5c000000)
libutil.so.1 => /lib64/libutil.so.1 (0x0000003d5a800000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003d59400000)
libc.so.6 => /lib64/libc.so.6 (0x0000003d59000000)
/lib64/ld-linux-x86-64.so.2 (0x0000003d58800000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x0000003d5b000000)

Или вы можете использовать предложение -rpath (и тогда настройка в LD_LIBRARY_PATH становится неактуальной):

[8:45] svbu-mpi:~/mpi % mpicc hello.c -o hello -Wl,-rpath /home/jsquyres/bogus/lib
[8:45] svbu-mpi:~/mpi % ldd hello
linux-vdso.so.1 =>  (0x00007ffff7ffe000)
libmpi.so.0 => /home/jsquyres/bogus/lib/libmpi.so.0 (0x00007ffff7b06000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003d58c00000)
libm.so.6 => /lib64/libm.so.6 (0x0000003d59c00000)
libnuma.so.1 => /usr/lib64/libnuma.so.1 (0x00007ffff78e8000)
libpci.so.3 => /lib64/libpci.so.3 (0x00007ffff76db000)
librt.so.1 => /lib64/librt.so.1 (0x0000003d5a000000)
libnsl.so.1 => /lib64/libnsl.so.1 (0x0000003d5c000000)
libutil.so.1 => /lib64/libutil.so.1 (0x0000003d5a800000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003d59400000)
libc.so.6 => /lib64/libc.so.6 (0x0000003d59000000)
/lib64/ld-linux-x86-64.so.2 (0x0000003d58800000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x0000003d5b000000)
...