我们在学习并行这门课的时候使用MPI来讲解课程实例的,我是在VMware下安装了CentOS来跑的,root权限有风险,操作需谨慎,所以我是在用户下安装的。
MPICH3是MPI(Message-Passing Interface)的一个应用实现。所以这篇文章简单记录一下安装MPICH3的过程,最后的目的是实现在一台linux机器下模仿集群的功能的程序:三个Slave向一个Master打招呼。
1.下载
这里是MPICH下载的官网,进去后选择Downloads选择想安装的版本下载即可,但在官网下载速度牛慢,我是在其他地方找的安装包,我安装的是mpich-3.1.tar.gz,我刚开始不会挂载什么的,没法下这个安装包,就使用图形界面的浏览器下载,下载的安装包默认在用户的Downloads文件夹下(希望你linux里已经有了C++的编译环境,因为之后安装过程中会用到)。
[gg@localhost ~]$ cd /home/gg/Downloads
[gg@localhost Downloads]$ ls
mpich-3.1.tar.gz
2.解压
将安装包拷贝到另一个文件夹,比如新建一个temp文件夹,准备在这里进行解压
[gg@localhost ~]$ mkdir temp
[gg@localhost ~]$ cp ~/Downloads/mpich-3.1.tar.gz ~/temp
[gg@localhost ~]$ cd temp
[gg@localhost temp]$ ls
mpich-3.1.tar.gz
[gg@localhost temp]$ tar -zxvf mpich-3.1.tar.gz
…
[gg@localhost temp]$ ls
mpich-3.1 mpich-3.1.tar.gz
运行了tar命令后,开始解压,出来一大串解压信息,这样就将安装包解压到了temp目录下,temp下多了一个解压后的文件mpich-3.1,进入这个文件夹,我们可以找到configure这个文件。再然后运行命令./configure -prefix=/home/gg/mpich3进行软件配置与检查(这里出来一大串检查信息,直到出现Configuration completed.),这里的路径就是下一步的安装目录,也就是软件会安装在mpich3下,在检查阶段如果你没有安装gcc一类的编译器他会提醒,这就需要你安装C++的编译环境,网上优秀的教程文章很多,这里就不说了。
[gg@localhost temp]$ cd mpich-3.1
[gg@localhost mpich-3.1]$ ./configure -prefix=/home/gg/mpich3
…
Configuration completed.
[gg@localhost mpich-3.1]$
注:prefix参数是表示安装路径
3.安装
运行make && make install(当然也可以先执行make命令编译,再执行make install命令安装,作用一样。)也是一大串安装命令。
[gg@localhost mpich-3.1]$ make && make install
…
[gg@localhost mpich-3.1]$
安装完成了,接着就要配置环境变量了。
4.环境配置
使用过javac,java的朋友都知道,这两个命令经常使用,他俩的实质是运行文件,我们只有配置了环境变量,才能直接使用,当然不配置也行,那么要使用这两个运行文件就必须写绝对路径系统才能找到,这里也同理。如果是Ubuntu的就在~目录下修改.bashrc文件,我们的CentOS是修改.bash_profile文件,用vi编辑该文件,在文件的末尾跟上:
export MPI_ROOT=/home/gg/mpich
export PATH=$MPI_ROOT/bin:$PATH
export MANPATH=$MPI_ROOT/man:$
先返回到~目录下:
[gg@localhost mpich-3.1]$ cd ~
[gg@localhost ~]$ vi ./.bash_profile
…
~export MPI_ROOT=/home/gg/mpich
~export PATH=$MPI_ROOT/bin:$PATH
~export MANPATH=$MPI_ROOT/man:$
[gg@localhost ~]$ source .bash_profile
保存文件退出,使用source .bash_profile命令更新使配置文件生效。
至此大功告成,测试一下。
5.测试
5.1我们先用一个hellow.c程序来演示,这个程序在刚才解压缩包里有个examples文件,用mpicc来编译c文件,-o后面的名字是编译成的可执行文件的名字,hellow(注意什么后缀也没有哈)就是可执行文件了;可以直接运行hellow(注意这里加上”./”),也可以用mpirun或mpiexec跟上参数-np 4,表示模拟4个进程来运行。
[gg@localhost ~]$ cd temp/mpich-3.1/examples
[gg@localhost examples]$ mpicc -o hellow hellow.c
[gg@localhost examples]$ ./hellow
Hello World from process 0 of 1
[gg@localhost examples]$ mpirun -np 4 ./hellow
Hello World from process 3 of 4
Hello World from process 2 of 4
Hello World from process 1 of 4
Hello World from process 0 of 4
[gg@localhost examples]$ mpiexec -np 4 ./hellow
Hello World from process 3 of 4
Hello World from process 1 of 4
Hello World from process 2 of 4
Hello World from process 0 of 4
[gg@localhost examples]$
这里每次运行的结果不尽相同,大家应该知道。
5.2再来一个问候的程序,从进程向主进程问候,主进程自己表明身份。我们可以在~下新建一个codes文件夹来放自己写的代码,新建一个greetings.c的文件,用vi编辑器编辑。
[gg@localhost ~]$ mkdir codes
[gg@localhost ~]$ cd codes
[gg@localhost codes]$ vi greetings.c
…
[gg@localhost codes]$ mpicc -o greetings greetings.c
[gg@localhost codes]$ mpirun -np 5 ./greetings
Hello,everyone,I am master,my rank is : 0
Greeting from process 1 of 5 !
Greeting from process 2 of 5 !
Greeting from process 3 of 5 !
Greeting from process 4 of 5 !
代码如下:
#include<stdio.h>
#include<string.h>
#include<mpi.h>
const int MAX_STRING = 100;
int main(void)
{
char greeting[MAX_STRING];
int comm_sz;
int my_rank;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if(my_rank != 0)//These are slave proceses
{
sprintf(greeting, "Greeting from process %d of %d !", my_rank, comm_sz);
MPI_Send(greeting, strlen(greeting) + 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
}
else//This is master process
{
printf("Hello,everyone,I am master,my rank is : %d\n", my_rank);
int q;//Must pre-state before block "for" using the "q",because of gcc perform the stander c99
for(q = 1; q < comm_sz; q++)
{
MPI_Recv(greeting, MAX_STRING, q, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("%s\n", greeting);
}
}
MPI_Finalize();
return 0;
}