由于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