环境: CentOS 7 x86_64 当前 下到的MPICH是 3.2 版本。
对于我的需求, mpich 与 openmpi 都可以满足,只是很久以前用过mpich 所以这次还是选择 mpich。二者的差异的讨论,可以参阅 mpich-vs-openmpi。
网上有些文章,都比较旧,大致09-12年的比较多,当时比较研究的比较热吧。
后来决定使用 安装文档 的简单步骤。额外的步骤,可能需要配置 SSH 无密码访问,这个已经很常见了。我共有三台机器,不同机器间可无密码互访,并且均可以无密码访问自己。这里贴下文件的权限:
-rw-------. 1 mpi mpi 1189 May 27 02:22 authorized_keys
-r--------. 1 mpi mpi 243 May 27 01:58 config
-rw-------. 1 mpi mpi 1679 May 27 01:49 id_mpich_rsa
-rw-r--r--. 1 mpi mpi 407 May 27 01:49 id_mpich_rsa.pub
authroized_keys 为 600,config 为 400,私钥和公钥文件为自动生成的权限,私钥 600,公钥 644。
这里用到 config 用来指定不同的服务器所使用的私钥文件,内容示例如下:
Host mpihost0
HostName mpihost0
IdentityFile ~/.ssh/id_mpich_rsa
User mpi
Host mpihost1
HostName mpihost1
IdentityFile ~/.ssh/id_mpich_rsa
User mpi
Host mpihost2
HostName mpihost2
IdentityFile ~/.ssh/id_mpich_rsa
User mpi
三台机器均安装了 mpich,安装在相同的路径 /home/mpi/mpich 目录下,三台机器均创建了名字为 mpi 的用户。安装过程使用普通用户权限,基本步骤为:
$cd mpich-3.2/
$./configure -prefix=/home/mpi/mpich |& tee c.txt
$make 2>&1 | tee m.txt
$make install |& tee mi.txt
每个步骤所显示的信息分别输出到 c.txt、 m.txt、 mi.txt 中,方便查看错误。
安装完成后将,mpi 相关二进制可执行文件加入PATH变量,我使用的是普通用户,所以我加入到 ~/.bash_profile
,然后 source ~/.bash_profile
使其在当前 bash 环境中生效。
使用
which mpicc
which mpiexec
可以检测是否设置成功
接下来要运行示例,首先要设置参与分配运行的机器列表。如 文件 machinefile
mpihost0:4
mpihost1:2
mpihost2:2
:
前对应机器,其后对应在该机器上进程数量。
运行源码包中所带示例
mpiexec -n 5 -f machinefile ./examples/cpi
运行结果:
Process 4 of 5 is on node1
Process 0 of 5 is on localhost.localdomain
Process 1 of 5 is on localhost.localdomain
Process 2 of 5 is on localhost.localdomain
Process 3 of 5 is on localhost.localdomain
pi is approximately 3.1415926544231230, Error is 0.0000000008333298
wall clock time = 0.020632
使用了 mpihost0 上的四个进程和mpihost1上的一个进程。
在运行下个示例前,我配置了 nfs。
nfs-server 是 CentOS 7 x86_64 装系统时装上去的。使用 root 权限开启 nfs-server:
#systemctl start nfs-server
并使其随机启动
#systemctl enable nfs-server
其中 server 端的配置方法为,修改 /etc/exports
/home/mpi/publicsrc 192.168.188.0/24(rw,async,no_root_squash)
依次为共享目录,所允许的客户端 IP 范围,最后是权限相关的。server 端的生效方法为 exportfs -a
,并重启 nfs-server, systemctl restart nfs-server
客户端修改 /etc/fstab
, 追加:
mpihost0:/home/mpi/publicsrc /home/mpi/publicsrc nfs defaults 0 0
依次为服务端共享目录,本地挂载点,类型,权限相关。客户端生效使用 root 权限运行 mount -t nfs -a
我这里遇到的问题是,服务端的UID/GID 和客户端的不一样。
比如 服务器端的用户
mpi:x:1002:1002:/home/mpi:/bin/bash
客户端
hadoop:x:1002:1002:/home/hadoop:/bin/bash
mpi:x:1004:1004:/home/mpi:/bin/bash
这样造成的问题是共享配置好后,在nfs的客户端所看到的共享目录属主为uid1002即hadoop,这样不符合我的预期,我要求的是三台机器全部使用mpi用户进行操作以及共享。这样mpi用户访问属主为hadoop用户的共享目录就有权限问题。最后通过修改server 端mpi用户的UID/GID 为1004 才解决,参照方法:
usermod -u <NEWUID> <LOGIN>
groupmod -g <NEWGID> <GROUP>
find / -user <OLDUID> -exec chown -h <NEWUID> {} \;
find / -group <OLDGID> -exec chgrp -h <NEWGID> {} \;
usermod -g <NEWGID> <LOGIN>
修改后:
服务器端的用户
mpi:x:1004:1004:/home/mpi:/bin/bash
客户端
hadoop:x:1002:1002:/home/hadoop:/bin/bash
mpi:x:1004:1004:/home/mpi:/bin/bash
示例程序 hello.c 放在nfs 共享目录中:
#include "mpi.h"
#include <stdio.h>
#include <math.h>
int main(int argc, char *argv[])
{
int myid, numprocs;
int namelen;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init (&argc, &argv);
MPI_Comm_rank (MPI_COMM_WORLD, &myid);
MPI_Comm_size (MPI_COMM_WORLD, &numprocs);
MPI_Get_processor_name(processor_name, &namelen);
fprintf(stderr, "Hello World! Process %d of %d on %s\n", myid, numprocs, processor_name);
MPI_Finalize();
return 0;
}
编译:
cd publicsrc
mpicc hello.c -o hello
两种方式运行
1. mpiexec -n 5 -f publicsrc/machinefile publicsrc/hello
2. mpirun -n 5 -f publicsrc/machinefile publicsrc/hello
结果:
Hello World! Process 4 of 5 on node1
Hello World! Process 0 of 5 on localhost.localdomain
Hello World! Process 3 of 5 on localhost.localdomain
Hello World! Process 1 of 5 on localhost.localdomain
Hello World! Process 2 of 5 on localhost.localdomain
另外看到很多教程使用 mpd,mpiboot 之类的,我下载的安装包没有生成这两个程序,现在好像已经过时了。
I have installed MPICH2 package on beowulf cluster and after executing mpdboot -n 2 -f mpd.hosts file, it returned me an error like:
there is no mpdboot any longer necessary in the actual package, as it was replaced by the Hydra startup without the need for any pre-started daemons. Just start the application with mpiexec.