2012-03-29 57 views
1

我有一個快速的問題。mpirun命令在bash中顯示奇怪的行爲

我最近嘗試使用我的學校的服務器來運行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

由於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) 
+0

So..if的問題在於你建議的庫路徑,那麼如果我運行mpirun給出它的完整路徑,那麼究竟發生了什麼變化?換句話說,在這種情況下發生了什麼,圖書館被閱讀? – kstratis 2012-03-30 19:52:38

+1

(不知何故,當添加新評論時,SO不會郵寄給我;對於延遲抱歉)當您提供mpirun的完整路徑時,它會自動爲您在遠程節點上設置LD_LIBRARY_PATH,這意味着它不依賴於.bashrc設置LD_LIBRARY_PATH。有關更多信息,請參見mpirun.1的手冊頁。 – 2012-04-27 14:47:28

+1

現在更有意義。但之後:爲什麼LD_LIBRARY_PATH會在我提供完整路徑時自動設置,但是當我不需要手動指定它時?這與mpirun命令有關還是與bash相關?再次感謝。 – kstratis 2012-05-01 17:45:13