2012-03-29 56 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