由於Open MPI的包裝編譯器不會在編譯/鏈接myprogram時自動地清除libmpi.so所在的位置(我們在OMPI包裝器編譯器中傳遞的標誌中採用了最低限度的方法 - 如果它們'不是需要,我們不把它們放在那裏)。
具體而言,當您在Linux中運行可執行文件時,運行時鏈接程序將查找找到該可執行文件所需的所有庫(運行「ldd myprogram」,您將看到一系列庫myprogram需要)。它會查看所有系統默認位置(它們本身可以由系統管理員配置)。它還會查看由LD_LIBRARY_PATH指定的所有目錄 - LD_LIBRARY_PATH實際上是擴展鏈接程序目錄列表的每用戶方法,以便搜索以查找共享庫。
我猜libmpi.so不在任何系統默認位置,因此您需要在LD_LIBRARY_PATH中指定其目錄。
或者,您可以在鏈接myprogram時添加-rpath子句。例如:
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)
請注意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)
So..if的問題在於你建議的庫路徑,那麼如果我運行mpirun給出它的完整路徑,那麼究竟發生了什麼變化?換句話說,在這種情況下發生了什麼,圖書館被閱讀? – kstratis 2012-03-30 19:52:38
(不知何故,當添加新評論時,SO不會郵寄給我;對於延遲抱歉)當您提供mpirun的完整路徑時,它會自動爲您在遠程節點上設置LD_LIBRARY_PATH,這意味着它不依賴於.bashrc設置LD_LIBRARY_PATH。有關更多信息,請參見mpirun.1的手冊頁。 – 2012-04-27 14:47:28
現在更有意義。但之後:爲什麼LD_LIBRARY_PATH會在我提供完整路徑時自動設置,但是當我不需要手動指定它時?這與mpirun命令有關還是與bash相關?再次感謝。 – kstratis 2012-05-01 17:45:13