====== 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 并行计算}}