Ubuntu 16.04 MPICH应用1——环境搭建与简单编译运行
解决的问题:
1. 安装MPICH
2. 编译程序源码
3. 运行程序前的准备工作
4. 运行程序
安装MPICH
很多网络文档都说需要下载源码包进行编译,实际可以直接apt-get,无需人工编译,命令如下:
sudo apt-get install mpich
编译程序源码
开始学习一个东西,肯定要从hello world开始,最简单的MPI程序如下:
#include <stdio.h>
#include "mpi.h"
int main(int argv,char* argc[]){
MPI_Init(&argv,&argc) ;
printf("hello world\n") ;
MPI_Finalize() ;
return 0 ;
}
按网上的说法,使用mpicxx -o mpi_hello ‘hello_world.c’ 命令编译,报错,报错信息如下:
hello_world.c:2:18: fatal error: mpi: No such file or directory
碰到了最讨厌的找不到头文件的问题,找遍全网未果。遂直接上MPI的user guide。发现如下说明:
A convenient way to compile and link your program is by using scripts
that use the same compiler that MPICH was built with. These are mpicc,
mpicxx, and mpifort, for C, C++, and Fortran programs, respectively. If
any of these commands are missing, it means that MPICH was configured
without support for that particular language.
原来需要使用与语言对应的MPI编译器,使用C代码,就要用mpicc来编译。执行命令:
mpicc -o hello_world 'hello_world.c'
编译成功。
运行程序的准备工作
按照User Guide的说法:
Check that you can reach these machines with ssh or rsh without
entering a password
这里首先安装ssh,相关命令如下:
安装OpenSSH:sudo apt-get install openssh-server
确认ssh已成功运行:ps -e|grep ssh
安装OpenSSL:sudo apt-get install openssl
之后设置无密码访问:
生成RSA密钥对:ssh-keygen -t rsa
提示指定密钥文件和passphrase时都按回车,最终会生成RSA2048的一个图像
之后复制改虚拟机镜像,在每个副本(计算节点)中都执行上述过程,overwrite RSA密钥对文件(公钥存储在/home/ubuntu/.ssh/id_rsa.pub,私钥存储在/home/ubuntu/.ssh/id_rsa)
然后需要在节点间交换公钥。因为虚拟机镜像是复制的,IP、hostname等都是一样的,所以需要进行更改。相关方法如下:
更新IP:dhclient <eth0>
更改hostname:sudo gedit /ect/hostname
更改hosts:sudo gedit /ect/hosts
在更新IP时,需要首先用ifconfig查看网卡标识,然后再重新运行DHCP,或者直接重启系统(如果系统IP是自动获取的,且虚拟机网卡配置为桥接),如果配置为NAT,目前没有考虑怎么弄,建议简单化解决,直接把网卡配置为桥接模式即可;
主机名hostname可以设置为node1或ubuntu1等,随意不冲突即可;
更改了主机名之后会出现sudo gedit /etc/hosts不能运行,提示sudo无法解析新的主机名,因为更改主机名之后,新的主机名与hosts文件的主机名不一致了,这里无需理会,测试中使用sudo vim打开hosts文件即可修改;
hosts文件更改为:
127.0.0.1 localhost
127.0.0.1 <node1>
xx.xx.xx.xx <node2>
......
node1、node2是自己修改的新主机名,前面是对应的IP地址;上述代码是在node1节点上的配置方案,因此node1的IP为127.0.0.1,图省事也可以直接把节点的IP地址写在上面。
note:在DHCP环境下,实验时需要首先查看自己配置的IP是否和当前系统获得的IP一致。
配置好各个计算节点的网络参数,就可以在节点间交换自己的公钥,使计算节点间互为可信状态。交换公钥指令如下:
scp /home/<ubuntu>/.ssh/id_rsa.pub <ubuntu>@<node2>:/home/<ubuntu>/.ssh/authorized_keys
意思是使用scp命令,将id_rsa.pub传输到node2节点的ubuntu用户的指定目录下,并命名为authorized_keys。不同节点的命名应该是不同的,可以参考authorized_keys[1,2,3,…]的命名方式。
使用如下命令,测试无密码ssh是否配置成功:
ssh <hostname> date
都准备好之后,还需要写一个machinefile,User Guide上的说法是:
Test the setup you just created:
mpiexec -f machinefile -n <number> hostname
The machinele contains the list of hosts you want to run the executable on.
% cat machinefile
host1 # Run 1 process on host1
host2:4 # Run 4 processes on host2
host3:2 # Run 2 processes on host3
host4:1 # Run 1 process on host4
但是没有讲这个machinefile到底是自己创建的还是系统本来就有的,做简单测试,结果如下:
1、直接在命令里写machinefile,报错说找不到改文件
2、手工创建machinefile文件,使用mpiexec -f方法依然报错,说找不到主机名的文件
3、直接手工创建machinefile文件,并手工写入每个节点分配的进程数
运行程序
使用User Guide的命令形式:
mpiexec -n 5 -f machinefile ./examples/cpi
假设machinefile路径为/path/machinefile,程序路径为/path/hello_world,那么运行前需要先进入path目录,然后用以下命令运行程序:
mpiexec -n 5 -f machinefile ./hello_world
理论上来说程序是可以不进入path目录,直接将文件地址放在命令中,但是图省事,且安全不会错,进入目录是比较好的选择。
运行结果:hello world输出5次。