MPI

from b站视频 超算小白-灵犀学院 click

(一)基本框架

头文件 mpi.h

#include "mpi.h"

初始化函数:MPI_Init( )

MPI_Init(int *argc, char ***argv)

完成MPI程序初始化工作,通过获取main函数的参数,让每一个MPI进程都能获取到main函数
MPI_Init函数要在调用其他MPI函数之间调用
指示系统完成所用函数初始化工作(mpi库)

通信域概念

通信域提供了在进程之间传递消息的环境
world是最大的一个通信域,且是系统默认的一个通信域

在一个通信域中进程的序号是有序的,一个进程的序号是它在整个排序过程中的位置
eg.一个通信域包含了p个进程,编号 0~p-1

获取进程标号:MPI_Comm_rank( )

MPI_Comm_rank(MPI_Comm comm, int *rank) //通信域  返回值

用于获取调用进程在给定的通信域中的进程标识号

序号决定计算哪个过程

返回进程总数:MPI_Comm_size( )

MPI_Comm_size(MPI_Comm comm,int *size)

调用返回给定的通信域中所包含的进程总数

清除函数:MPI_Finalize(void)

MPI程序的最后一个调用,清除全部MPI环境

mpi程序编译:

mpicc -O2 -o helloworld helloworld.c (gcc)
mpiicc -O2 -o helloworld helloworld.c (intel)
    
mpicxx -O2 -o helloworld helloworld.cpp (gcc)
mpiicpc -O2 -o helloworld helloworld.cpp (intel)

mpi程序运行命令:

mpirun (mpiexec) -np 进程数 可执行文件

集群mpi上运行
集群作业调度系统特定参数 + 可执行文件

use: (linux)

mpicc -o test mpitest.c
mpirun -np 4 ./test

在这里插入图片描述
在这里插入图片描述

(二)通信函数

1.MPI点对点通信函数

在一对进程之间传递数据
类型:阻塞(消息从本地发出之后才执行后面的语句)和非阻塞(通信于计算的重叠,但调用的返回不保证资源的可在用性)

发送函数:MPI_Send( )

MPI_Send(void* buf,int count,MPI_Datatype datatype,int dest,int tag,MPI_Comm comm)

将发送缓冲区buf中count个datatype数据类型的数据,发送给comm通信域中的标识为dest,消息标志为tag的进程

buffer发送缓冲区的一个起始地址

datatype: eg.int double float…

接收函数:MPI_Recv( )

MPI_Recv(void* buf,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm comm,MPI_Status *status)

从comm通信域中标识号为source的进程,接收消息标记为tag,消息数据类型为datatype,个数为count消息并存储在buf缓冲区中,并将该过程的状态信息写入status中

多了一个mpi状态的一个参数 status

ps. 在C语言中,status是一个结构体,包含 MPI_SOURCE、MPI_TAG、MPI_ERROR信息

非阻塞通信:
在这里插入图片描述

发送函数(非阻塞): int MPI_Isend( )

int MPI_Isend(void* buf,int count,MPI_Datatype datatype,int dest,int tag,MPI_Comm comm,MPI_Request *request)

在这里插入图片描述

与MPI_Send相比多了一个请求的操作,OUT request用于判读非阻塞通信是否完成

接收函数(非阻塞):int MPI_Irecv( )

int MPI_Irecv(void* buf,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm comm,MPI_Request *request)

在这里插入图片描述

栗子:
在这里插入图片描述

2.MPI集合通信函数

请添加图片描述

广播函数:MPI_Bcast( )

MPI_Bcast(*buffer,count,datatype,root,comm)

从指定的一个跟进程中把数据广播发送给组中的所有其他进程

MPI_Bcast{
    void *data_p;
    int cout;
    MPI_Datatype datatype;
    int source_proc;
    MPI_Comm comm;
}

影响data缓冲区中的数据
请添加图片描述

收集函数:MPI_Gather( )

MPI_Gather(*sendbuf,sentcnt,sendtype,*recvbuf,recvcount,recvtype,root,comm)

在组中指定一个进程收集组中所有进程发来的消息,这个函数操作与 MPI_Scatter函数操作相反

MPI_Gather{
    void *send_data;   //数据起始位置
    int send_count;    //取出的数据量
    MPI_Datatype send_datatype;  //类型
//发送到根节点接收进程的地方
    void *recv_data;
    int recv_count;
    MPI_Datatype recv_datatype;
    int root;          // 根结点
    MPI_Comm communicator;  //通信域
}

请添加图片描述ps.根的缓冲区要大

分发函数:MPI_Scatter( )

MPI_Scatter(*sendbuf,sendcnt,sendtype,*recvcnt,recvtype,root,comm)

mpi 分发函数,把指定进程中的数据分散发送给组中的所有进程(包括自己)

MPI_Scatter{
    void *send_data;
    int send_count;
    MPI_Datatype send_datatype;
    void *recv_data;
    int recv_count;
    MPI_Datatype recv_datatype;
    int root;
    MPI_Comm communicator;
}

在这里插入图片描述

规约函数:MPI_Reduce( )

MPI_Reduce(*sendbuf,*recvbuf,count,datatype,op,root,comm)

在组内所有进程中,执行一个规约操作,并把结果存在指定的一个进程中

MPI_Reduce{
    void *send_data;
    void *recv_data;
    int count;
    MPI_Datatype datatype;
    MPI_Op op;          // new
    int root; 
    MPI_Comm communicator;
}

在这里插入图片描述

规约操作中可以包含很多操作

在这里插入图片描述

聚集函数:MPI_Allgather( )

MPI_Allgather(*sendbuf,sendcnt,sendtype,*recvbuf,recvcount,recvtype,comm)

将各进程的向量数据聚集为一个大向量,并分发到各个进程中,相当于各进程同步该大向量的各部分分量。
相比于MPI_Gather(),只是少了一个root参数

MPI_Allgather{
    void *send_data;   
    int send_count;   
    MPI_Datatype send_datatype;  
    void *recv_data;
    int recv_count;
    MPI_Datatype recv_datatype;
    MPI_Comm communicator;  
}

在这里插入图片描述

计时函数:double MPI_Wtime(void)

在这里插入图片描述

(三)summary

在这里插入图片描述在这里插入图片描述在这里插入图片描述

OTHERS:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Logo

汇聚原天河团队并行计算工程师、中科院计算所专家以及头部AI名企HPC专家,助力解决“卡脖子”问题

更多推荐