Openmpi并行环境冲突解决一例
2015-11-24 03:59阅读:
有个朋友在ubuntu
12.04/多核工作站上编译并行版本cpmd(4.1),mpirun运行时总是碰到如下错误:
'an error occurred in
MPI_Comm_set_errhandler on communicator in MPI_COMM_WORLD
MPI_ERR_COMM'
无输出文件。疑似mpirun的问题。经询问后得知,前后安装过多个并行编译软件,包括openmpi,
mpich(手动编译make install),以及intel
编译的openmpi,可能内部互相冲突。但将其它版本的并行编译器完全删除,甚至将下载的mpich完全删除后,问题仍然没有解决,mpirun运行显示同样的错误提示。包括反复从源安装删除openmpi希望覆盖原先安装的版本都没有解决问题(sudo
apt-get install openmpi-bin
libopenmpi-dev)。之后静下心来首先确认是编译器的问题还是cpmd的问题,在确认是mpirun的问题之后,很快发现系统中在/usr/bin和/usr/local/bin
下分别存在两套相同的mpirun/mpicc/mpif77/mpif90,确认他们之间互相冲突,然后将/usr/local/bin下与mpi相关的文件全部删除,问题解决,重新编译cpmd可顺利运行。
下面是解决问题的一些过程。
1.
首先,如何确定是mpirun的问题,而不是cpmd的问题?这是通过运行一个mpirun测试,一个并行编译的Hello
world,如果mpirun没有问题,则返回每个处理器的rank #;
$
mpirun -n 4 ./mpi_hello_world
Hello world from processor Lab, rank 1 out
of 4 processors
Hello world from processor Lab, rank 2 out
of 4 processors
Hello world from processor Lab, rank 3 out
of 4 processors
Hello world from processor Lab, rank 4 out
of 4 processors
如果mpirun存在多个可执行版本(冲突),则返回的所有rank
#都是0.
$ mpirun -n 4
./mpi_hello_world
Hello world from processor Lab, rank 0 out
of 4 processors
Hello world from processor Lab, rank 0 out
of 4 processors
Hello world from processor Lab, rank 0 out
of 4 processors
Hello world from processor Lab, rank 0 out
of 4 processors
其中hello world并行版源文件mpi_hello_world.c如下
#include
#include
int main(int argc, char** argv)
{
// Initialize the
MPI environment
MPI_Init(NULL,
NULL);
// Get the number of
processes
int
world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
// Get the rank of
the process
int
world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
// Get the name of
the processor
char
processor_name[MPI_MAX_PROCESSOR_NAME];
int
name_len;
MPI_Get_processor_name(processor_name,
&name_len);
// Print off a hello
world message
printf('Hello world
from processor %s, rank %d'
' out of %d processors',
processor_name, world_rank,
world_size);
// Finalize the MPI
environment.
MPI_Finalize();
}
编译上述文件的Makefile如下:
EXECS=mpi_hello_world
MPICC?=mpicc
all:
${EXECS}
mpi_hello_world:
mpi_hello_world.c
${MPICC} -o mpi_hello_world mpi_hello_world.c
clean:
rm
${EXECS}
在同一路径下建立上述两个文件,运行make即可得到mpi_hello_world。
注意,在makefile中,缩进必须用tab。因此,如果make有错,则将缩进前的空格删掉,改用tab缩进。
2. 其次,是使用哪个并行编译器的问题,openmpi还是mpich?
openmpi和mpich是不同组织开发的并行编译器,在使用上没有区别。即对于同一源代码,二者均可使用。因为之前在另外的机器ubuntu
14.04/openmpi成功过,因此,决定仍然使用openmpi而将mpich删除掉。mpich是手动安装的,则在源文件路径下执行:
$ sudo make uninstall
3. 解决mpirun互相冲突
首先,如何发现两个版本的mpirun的。运行如下命令:
$ whereis mpicc
mpicc: /usr/local/bin/mpicc /usr/bin/mpicc
/usr/bin/mpicc.openmpi /usr/bin/X11/mpicc
/usr/bin/X11/mpicc.openmpi
/usr/share/man/man1/mpicc.1.gz
(whereis mpirun和whereis
f77结果类似。)上面显示了所有存在的mpicc的可供运行文件。你会发现,mpicc存在于/usr/local/bin和/usr/bin两个不同的路径下,区别如下:
- /usr/bin/mpicc
系统从ubunutu源安装的openmpi,
- /usr/local/bin/mpicc
之前覆盖安装,或者手动编译安装的mpich的mpicc,在用户目录下。但是make
uninstall删除不干净。只能手动删除。
因为上述两个路径同时存在于变量$PATH中,所以互相冲突。解决方法
$ sudo rm
/usr/local/bin/*mpi*
之后系统中只剩下从源安装的openmpi,冲突解决。
4. 其它:dpkg卸载软件包
如果通过源安装,或者手动安装了软件包,可以通过dpkg找到和删除
(1)寻找名字中包含mpich的软件包
$ dpkg -i | grep mpich
mpich2
(2) 删除好到的软件包
$ dpkg -r mpich2
【总结】
遇到由于反复安装不同版本mpirun而造成的冲突问题,直接用whereis
mpicc检查系统内是否在不同路径下存在多份安装,然后保留一个,卸载其它(用sudo dpkg -r或sudo apt-get
remove)。