Linux下MPI环境的安装配置及MPI程序的编译运行

Linux下MPI环境的安装配置及MPI程序的编译运行,step by step。

  • 下载MPI安装包
    这里下载一个适合的安装包。
  • 安装包的解压
    安装包所在的目录下,运行tar xzvf mpich-x.x.x.tgz
  • 切换到解压出来的包目录下
    cd mpich-x.x.x
  • configure配置编译环境,我这里为它选择了一个安装路径。
    ./configure --prefix=/usr/local/mpich-x.x.x

这里可能会有一些出错提示,缺少编辑器啥的,按需求确认安装C、C++、F77和F90编译器即可。sudo apt-get install fort77sudo apt-get install gfortran

  • 安装
sudo make
sudo make install
  • 可能还需要添加环境变量,设置用户权限等等,大概就像下面这样。不同的Linux系统不一样,不要照抄呀。参考参考就行。其实主要就是你要扒拉到你的安装文件夹下,看哪些文件夹比较重要的,要想办法添加到PATH中去。比如/usr/local/mpi/bin这个文件夹等等。

1、创建文件/etc/profile.d/user.sh,包含以下内容:

export PATH=$PATH:/usr/local/mpi/bin
export MANPATH=$MANPATH:/usr/local/mpi/man

2、创建文件/etc/ld.so.conf.d/mpi.conf,包含以下内容:

/usr/local/mpi/lib
/usr/local/mpi/lib/shared

3、执行以下命令,使两个文件生效:

source  /etc/profile.d/user.sh
source /sbin/ldconfig

4、在/etc/profile文件中添加库共享路径
执行sudo gedit /etc/profile,然后在其中加入一行

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

5.使该配置文件生效

source /etc/profile

至此,Linux下MPI环境的安装配置就算完成了。接下来可以来使用这个接口了。

在解压出来的MPI安装目录下有个examples文件夹,里面有若干示例程序可供测试。

  • 编译测试
    使用cd命令切换到示例程序文件夹下,使用mpicc hellow.c -o hellow进行编译。
  • 运行测试
mpirun -np N hellow
这里的N改成一个常数,表示你要用来运行这个并行程序的节点。当然,如果不是在集群环境上,你一个CPU就一个节点,进程数也就是一个最多,本地机子默认的编号就是0。你N的不同无异于就是把程序跑N遍而已。

MPI:英文全称是Message Passing
Interface,这个就很明了了,信息传递接口,是独立于语言的通信协议(标准),是一个库。不是一个编程语言,它有自己的实现。

在MPICH中,mpirun是MPI程序的启动脚本,它简化了并行进程的启动过程,尽可能屏蔽了底层的实现细节,从而为用户提供了一个通用的MPI并行机。在用mpirun命令执行并行程序时,参数-np指明了需要并行运行的进程个数。mpirun首先在本地结点上启动一个进程,然后根据/usr/local/share/machines.LINUX文件中所列出的主机,为每个主机启动一个进程。若进程数比可用的并行节点数多,则多余的进程将重新按照上述规则进行。按这个机制分配好进程后,一般会给每个节点分一个固定的标号,类似于身份证了,到时再消息传递中会用到。

节点之间传递消息,一般要先认证身份,每次传递都要认证身份比较麻烦。所以,可以搞一个“通行证”一样的东西,使得传递消息变得更加便捷。示例命令行代码如下:

ssh-keygen -t dsa
cp id˙dsa.pub authorized˙keys
chmod go-rwx authorized˙keys
ssh-agent  $SHELL
ssh-add

看一个简单的MPI程序:

#include <stdio.h>
#include <mpi.h>
int main(int argc, char * argv[])
{int myrank, nprocs;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
printf("rank%dof%d:Hello,world!\n",myrank, nprocs);
MPI_Finalize();
return 0;
}
  • 初始化MPI环境:

MPI_Init(&argc, &argv);

  • 获取并行环境参数(总进程数、本地进程编号等):

MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

  • 执行计算、通信等操作:

printf(”rank %d of %d: Hello, world!\n”, myrank, nprocs);

  • 结束MPI环境:

MPI_Finalize();

收发消息函数:

#include <mpi.h>
int main (int argc, char *argv[])
{
int myrank, a;
MPI_Status stat;
MPI_Init (&argc, &argv);
MPI_Comm_rank (MPI_COMM_WORLD, &myrank);
a = myrank  +  10;
if (myrank == 0)
MPI_Send (&a, 1, MPI_INT, 1, 9, MPI_COMM_WORLD);
else (myrank == 1)
MPI_Recv (&a, 1, MPI_INT, 0, 9, MPI_COMM_WORLD, &stat);
MPI_Finalize (); 
return 0;
}

这里写图片描述

通俗地说,MPI_Send的六个元素的大概意思就是,我要从内存的那个位置开始,连续取多少个某种类型的数据,这就是消息数据。信封上写上这是要送给序号为多少的节点的第几封信,指明这是申通快递寄过去,这就是消息信封的三个元素。反之亦然,MPI_Recv就要开辟从某个位置开始的多少个这种类型的数据内存,然后去找对方寄送给自己的第N封消息,要是申通的,如果收到了,反馈一个状态。

如何理解并行计算的计算流程呢?我是这样想的。按并行的方式写一段并行的程序,然后在集群环境里主机上运行apirun的时候指定需要的进程数。接着,计算机在集群环境下尽可能找到对应 的节点,分配进程任务并给他们编号。此后,将程序拷贝一份给每一个节点,每个节点在这个共同的工作中都担任着一份角色。接着,他们就按程序中设计的方式,各自运行着由自己编号决定的自己的那一段代码,相互之间进行通讯,最后共同完成这项任务。那么,不同节点程序进行有早晚,如何保证协调一致有序进行呢?比如说,你可以等呀,可以找个地方先寄存一下你给别人的消息之类的。这就涉及到了MPI通讯的阻塞型和非阻塞型通讯模式。

注意权限不足的引起的错误,有时候并不会明显地报给你,多加sudo跑命令总是没错。

©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页