From Zero to Hero:MPICH2,OPENMPI函数使用——高性能计算

MPI环境安装、配置SSH免密登录

一、安装MPI

1、安装MPI库

sudo yum install mpich mpich-devel

2、 配置环境变量
编辑~/.bashrc文件,在文件末尾添加如下两行:
在这里插入图片描述

在普通用户模式下输入vim ~/bashrc

export PATH=$PATH:/usr/lib64/mpich/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64/mpich/lib

然后:

source ~/.bashrc

3、 测试MPI环境

mpirun -np 2 hostname

如果输出了两个主机名,则MPI环境配置成功。

二、安装openmp环境

1、 安装GCC/G++
CentOS中安装GCC可以使用yum命令:

sudo yum install gcc
sudo yum install gcc-c++

2、配置环境变量:
编辑~/.bashrc文件,在文件末尾添加如下一行:

export OMP_NUM_THREADS=4

其中4可以根据实际需要修改。

3、测试OpenMP环境
新建一个文件test.c,写入以下代码:

#include <stdio.h>
#include <omp.h>

int main() {
    
    
    #pragma omp parallel
    {
    
    
        int tid = omp_get_thread_num();
        printf("Hello, world! This is thread %d\n", tid);
    }
    return 0;
}

在终端输入以下命令编译并运行程序:

gcc -fopenmp test.c -o test
./test

在这里插入图片描述

三、配置ssh免密登录

修改映射

vim /etc/hosts

node1:192.168.79.133
node2:192.168.79.134
添加:

192.168.79.133 node1
192.168.79.134 node2

生成公钥、私钥

ssh-keygen -t rsa

配置ssh
在node01机器上输入命令

ssh-copy-id -i Node1

然后输入对应密码,再输入

ssh-copy-id -i Node2

node02同理

四、多节点程序

编辑hostfile文件,确认每个机器发起进程的上限

node1:2
node2:3 
(1)多节点单程序

如果执行中用到的-n number,number中的前2个会在node1中执行,接下来的会在node2中执行

mpirun -f hostfile -n 10 ./mpi

在这里插入图片描述

(2)多节点多程序

mpi的前10个rank执行hello程序,接下来的20个rank执行world程序

mpirun -f hostfile -n 10 ./hello : -n 20 ./world

注意事项:

上述执行方式中,在node1和node2中必须有相同路径、相同名称的可执行文件,否则程序会报错,找不到文件。
可能会提示需要安装ssh-askpass,按照提示安装即可
最好都加上具体路径 “./mpi”的形式,直接使用“mpi”可能会报错,报错如下图
在这里插入图片描述

bcast广播函数使用

代码文件:test5.c

#include "mpi.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv)
{
    
    
    int                    rank,size,i;
    int                    *arr = NULL;
    int                    len = 6;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    arr = (int*)malloc(len*sizeof(int));
    memset(arr, 0, sizeof(int)*len);

    if(rank == 0)
    {
    
    
        for(i = 0; i < len; i++)
                arr[i] = i + 1;
    }

    MPI_Bcast(arr, len, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Barrier(MPI_COMM_WORLD);

    if(rank != 0)
    {
    
    
        printf("In process %d...\n", rank);
        for(i = 0; i < len; i++)
            printf("arr[%d]=%d\t", i, arr[i]);
    }

    free(arr);
    MPI_Finalize();
    return 0;
}

1)在语义上,可以认为MPI_Bcast是一个“多次发送”的过程,这是没有错误的,但在语法上,不可以将MPI_Bcast等同为多个MPI_Send语句,因此,在MPI程序中,就不能用MPI_Recv去和MPI_Bcast相匹配。
2)MPI_Bcast是组操作,在每一个进程中都必须有相应的MPI_Bcast语句,而不是MPI_Recv语句。
3)由上面的程序,可以看出MPI_Bcast函数处于所有进程的执行流程中。且对于所有进程来说,广播进程(0进程)和其他进程之间的发送/接收缓冲区名字是一致的,如本程序中都是arr,看过的其他程序中也仍然存在这种一致性,这也许是MPI中对MPI_Bcast的一种约定俗成?

带着3)中的疑问,我们不妨将程序test5.c中对数组arr分配内存的部分放到主进程(0进程)中,即:

if(rank == 0)
{
    
    
    arr = (int*)malloc(len*sizeof(int));
    memset(arr, 0, sizeof(int)*len);
    for(i = 0; i < len; i++)
            arr[i] = i + 1;
}
然后编译,运行程序,启动两个进程,然后输出的运行结果为:

==================================================================================== 
=   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
=   EXIT CODE: 11
=   CLEANING UP REMAINING PROCESSES
=   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
=====================================================================================
APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11)

程序运行错误,错误字串为:Segmentation fault(根据经验,这是引用了未分配的内存所造成的)
因为,将对数组arr内存分配的代码放到主进程(0进程)中后,从进程将无法对arr分配内存,而又要执行MPI_Bcast函数接收主进程发送过来的数据而引用未分配的内存空间,所以产生Segmentation fault错误

更新中…

猜你喜欢

转载自blog.csdn.net/weixin_39589455/article/details/139002213