我有一个简单的问题。
我最近尝试使用我学校的服务器运行mpi程序,并遇到以下“奇怪”问题:
为了执行'mpirun'命令,我必须将其路径放入我在.bashrc中的默认路径,然后输入:
mpirun -n 16 ./myprogram
只是为了得到一个名为:libmpi.so.0
的缺失库的错误但是,如果我尝试使用如下所示的完整mpirun路径运行程序
/usr/lib64/openmpi/bin/mpirun -n 16 ./myprogram
一切都很好。
我检查了openmpi的FAQ,它说我需要将以下行放入我的.bashrc
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/openmpi/lib
这对我来说实际上是固定的,但我的问题仍未得到解决:
为什么会这样?
提前感谢您的时间。
答案 0 :(得分:1)
因为Open MPI的包装编译器在编译/链接myprogram时不会自动-rpath libmpi.so所在位置(我们在OMPI包装器编译器中传递的标志中采用极简主义方法 - 如果它们'不是需要,我们不会把它们放在那里。)
具体来说,当您在Linux中运行可执行文件时,运行时链接程序将查找该可执行文件所需的所有库(运行“ldd myprogram”,您将看到所需库的列表为myprogram)。它将查看所有系统默认位置(它们本身可由sysadmins配置)。它还会查看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条目中的“not found”。
您可以设置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)