====== OpenMPI并行环境的模拟 ======
[[http://www.open-mpi.org|OpenMPI]]是MPI的一个开源实现,MPI是Message Passing Interface(消息传递接口)的缩写,是一个得到广泛支持的并行标准库。本文讲述用几台虚拟机来搭建一个OpenMPI并行计算环境的过程。
===== 测试环境 =====
并行集群的结点数一般是2的n次方,这里先使用4台虚拟机来搭建(后期可以扩展),第一个结点兼做控制结点。系统均使用[[http://www.slackware.com|slackware64 14.0]],软件都是完全安装,只启用ssh服务,保证一个纯粹的平台。
机器网络配置如下:
^ 域名 ^ IP地址 ^
| slk-op1.example.org | 192.168.176.81/24 |
| slk-op2.example.org | 192.168.176.82/24 |
| slk-op3.example.org | 192.168.176.83/24 |
| slk-op4.example.org | 192.168.176.84/24 |
===== 初始安装 =====
集群规模很小,故暂不采用NFS等网络集中管理方案,下面这些操作在每台机器上都要做。
==== 安装OpenMPI ====
这里使用[[http://slackbuilds.org|SlackBuilds.org]]提供的脚本来编译OpenMPI,以生成二进制安装包,这样就只需在一台机器上编译,其他机器可以获得生成的安装包,直接安装。
解开脚本:
tar xzvf openmpi.tar.gz
将OpenMPI的源代码包放在脚本目录下,进行编译打包:
cd openmpi/
cp ~/downloads/openmpi-1.4.2.tar.bz2 .
./openmpi.SlackBuild
安装(生成的安装包在/tmp下):
cd /tmp
installpkg openmpi-1.4.2-x86_64-1_SBo.tgz
其他机器获得openmpi-1.4.2-x86_64-1_SBo.tgz后,执行installpkg安装即可。
==== 添加用户 ====
我们新建一个普通账户openmpi,而不是直接用root:
useradd -m -s /bin/bash openmpi
==== 配置域名解析 ====
由于网络规模很小,故暂不采用集中的DNS域名解析机制,直接编辑/etc/hosts文件,添加其余所有节点的IP信息。
比如slk-op1的内容如下:
127.0.0.1 localhost
192.168.176.81 slk-op1.example.org slk-op1
192.168.176.82 slk-op2.example.org slk-op2
192.168.176.83 slk-op3.example.org slk-op3
192.168.176.84 slk-op4.example.org slk-op4
===== 集群配置 =====
接下来的操作只在控制结点,即slk-op1上进行。
==== ssh登录配置 ====
配置ssh,让控制结点(slk-op1)能采用无密码的方式ssh登录到其他结点。
首先生成一对密钥:
ssh-keygen
接下来把密钥中的公钥附加到要登录节点的.ssh/authorized_keys文件里,通过ssh-copy-id命令完成:
ssh-copy-id slk-op2
ssh-copy-id slk-op3
ssh-copy-id slk-op4
进行一次登录测试,确保可以无交互的登录:
ssh slk-op2
ssh slk-op3
ssh slk-op4
==== hostfile配置文件 ====
要在集群的多个结点上运行任务,需要一个包含各结点信息的配置文件,运行时通过命令行参数-hostfile指定。文件内容很简单,每个结点一行:
slk-op1
slk-op2
slk-op3
slk-op4
如果想让某个结点运行不止一个process,可用slots属性指定(缺省为1),如:
slk-op1 slots=1
slk-op2 slots=2
slk-op3 slots=3
slk-op4 slots=4
===== 集群测试 =====
==== 初始测试 ====
配置完毕,先运行hostname程序来验证集群是否能正常工作。hostname是一个显示或设置系统主机名的命令,根据执行结果可以判断程序是否真的在多个结点上运行:
openmpi@slk-op1:~$ mpirun -hostfile hostfile hostname
slk-op1
slk-op3
slk-op3
slk-op3
slk-op2
slk-op2
slk-op4
slk-op4
slk-op4
slk-op4
接下来我们编译一个样例C代码hello_c.c(在OpenMPI源代码包的examples目录下):
mpicc hello_c.c -o hello_c
编译生成的目标程序必须存在于每个参与运算的结点上。由于没有使用NFS等集中的管理方案,需要手工拷贝到其余结点上:
scp hello_c slk-op2:
scp hello_c slk-op3:
scp hello_c slk-op4:
现在可以运行了:
openmpi@slk-op1:~$ mpirun -hostfile hostfile -np 8 hello_c
Hello, world, I am 0 of 8
Hello, world, I am 5 of 8
Hello, world, I am 3 of 8
Hello, world, I am 4 of 8
Hello, world, I am 2 of 8
Hello, world, I am 1 of 8
Hello, world, I am 7 of 8
Hello, world, I am 6 of 8
==== Makefile ====
当程序越来越多时,每次都敲命令编译是很繁琐的事,可以用Make来管理。下面是一个Makefile样例:
MPICC := mpicc
LDLIBS :=
TARGETS := hello_c
all: $(TARGETS)
hello_c: hello_c.o
.PHONY: all clean
%: %.o
$(MPICC) -o $@ $^ $(LDLIBS)
echo "cp $@ to slk-op2:"; \
scp $@ slk-op2:; \
echo "cp $@ to slk-op3:"; \
scp $@ slk-op3:; \
echo "cp $@ to slk-op4:"; \
scp $@ slk-op4:
%.o: %.c
$(MPICC) -Wall -g -c $<
clean:
rm -rf $(TARGETS) *.o
编译的同时也完成了复制程序到其他结点的工作。
当结点数增多时,可以用for循环代替目前的逐条拷贝的方法。当然,那时,也许应该考虑集中的网络管理方案了。
{{tag>OpenMPI 并行计算}}