MPI函数总结
决定将代码中出现的MPI函数都总结一下:调用MPI函数,通常要包含头文件#include "mpi.h"or#include <mpi.h>MPI 环境在初始化时会自动创建两个通信器,一个称为 MPI_COMM_WORLD,它包含程序中的所有进程,另一个称为 MPI_COMM_SELF,它是每个进程独自构成的、仅包含自己的通信器。MPI 系统提供了一个特殊进程号 MPI_PROC_NU
决定将代码中出现的MPI函数都总结一下:
调用MPI函数,通常要包含头文件
#include "mpi.h"
or
#include <mpi.h>
MPI 环境在初始化时会自动创建两个通信器,一个称为 MPI_COMM_WORLD,它包含程序中的所有进程,另一个称为 MPI_COMM_SELF,它是每个进程独自构成的、仅包含自己的通信器。MPI 系统提供了一个特殊进程号 MPI_PROC_NULL,它代表空进程 (不存在的进程),与 MPI_PROC_NULL 进行通信相当于一个空操 作,对程序的运行没有任何影响。
有好几个来自这个网页:
MPI 常用函数概述_狂草年糕的博客-CSDN博客_mpi函数
MPI_Comm_rank & MPI_Comm_size
MPI_Comm_size(MPI_COMM_WORLD, &proc.size);
MPI_Comm_rank(MPI_COMM_WORLD, &proc.rank);
rank返回当前进程,size返回rank的个数即processor总个数
MPI_Gather
MPI_Gather(&npeach, 1, MPI_INT, nptotal1, 1, MPI_INT, 0, MPI_COMM_WORLD);
将进程0从通信域中所有进程收集数据npeach存在数组nptotal1里面。
MPI_GATHER(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root , comm)
sendbuf 发送消息缓冲区的起始地址(可变)
sendcount 发送消息缓冲区中的数据个数(整型)
sendtype 发送消息缓冲区中的数据类型(句柄)
recvbuf 接收消息缓冲区的起始地址(可变,仅对于根进程)
recvcount 待接收的元素个数(整型,仅对于根进程)
recvtype 接收元素的数据类型(句柄,仅对于根进程)
root 接收进程的序列号(整型)
comm 通信子(句柄)
函数声明为
int MPI_Gather(void* sendbuf, int sendcount, MPI_Datatype sendtype,
void* recvbuf, int recvcount, MPI_Datatype recvtype,
int root, MPI_Comm comm)
————————————————
版权声明:本段为CSDN博主「坚强的小鱼人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u014247371/article/details/26965185
MPI_Cart_coords
MPI_Cart_coords(MPI_COMM_3D, rank3d, 3, coords)
MPI_Comm_rank(MPI_COMM_3D, &rank3d);
MPI_Cart_coords(MPI_COMM_3D, rank3d, 3, coords);
Determines process coords in cartesian topology given rank in group.
int MPIAPI MPI_Cart_coords(
MPI_Comm comm,
int rank,
int maxdims,
_Out_cap_(maxdims) int *coords
);
通常先用 MPI_Comm_rank
获得当前进程在笛卡尔通信器中的等级,再用 MPI_Cart_coords
获得进程的笛卡尔坐标。
MPI_Barrier()
MPI_Barrier(MPI_COMM_WORLD);
MPI_Allreduce(&prmt.npp, &prmt.npt, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
用于通信子中所有进程的同步,即等前面的步骤所有进程都完成才进行后面的步骤。
MPI_Allreduce()
全局规约函数,将所有发送信息进行同一个操作,所有进程均接收信息。
MPI_Barrier(MPI_COMM_WORLD);
MPI_Allreduce(&prmt.npp, &prmt.npt, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
将所有prmt.npp加和赋值给所有prmt.bpt
MPI_Reduce(
void* send_data,
void* recv_data,
int count,
MPI_Datatype datatype,
MPI_Op op,
int root,
MPI_Comm communicator)
————————————————
版权声明:本文为CSDN博主「Harold Gao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_40255793/article/details/84201243
每个进程发送容量为 count 的数组 send_data,root 进程收到后进行 op 操作,存放在容量也为 count 的数组 recv_data 中。
usleep()
MPI_Barrier(MPI_COMM_WORLD);
usleep(50000 * proc.rank);
usleep功能把进程挂起一段时间, 单位是微秒(百万分之一秒)
MPI_Send & MPI_Recv()
#ifdef __PERIODIC__
MPI_Barrier(MPI_COMM_WORLD);
if (proc.rank == proc.size - 1) {
MPI_Send(&nptf, 1, MPI_INT, 0, dim * 2, MPI_COMM_WORLD);
}
if (proc.rank == 0) {
MPI_Recv(&npfb, 1, MPI_INT, proc.size - 1, dim * 2, MPI_COMM_WORLD,
&proc.status);
}
MPI_Barrier(MPI_COMM_WORLD);
#endif
这两个函数通常一起出现,这个代码是将nptf的值发送给npfb。
MPI_Sendrecv
若单纯的利用MPI_Send, MPI_Recv函数进行通讯的话,容易造成死锁,下面介绍MPI_Sendrecv的来解决这个问题。顾名思义,MPI_Sendrecv表示的作用是将本进程的信息发送出去,并接收其他进程的信息.
MPI_Sendrecv(src, srcsize, MPI_BYTE, proc.fs.x, tag,
dst, dstsize, MPI_BYTE, proc.fr.x, tag,
MPI_COMM_WORLD, &proc.status);
另外,我对tag的理解就是方便debug的时候判断是哪个位置出错了。
MPI_Sendrecv( void *sendbuf //initial address of send buffer
int sendcount //number of entries to send
MPI_Datatype sendtype //type of entries in send buffer
int dest //rank of destination
int sendtag //send tag
void *recvbuf //initial address of receive buffer
int recvcount //max number of entries to receive
MPI_Datatype recvtype //type of entries in receive buffer (这里数目是按实数的数目,若数据类型为MPI_COMPLEX时,传递的数目要乘以2)
int source //rank of source
int recvtag //receive tag
MPI_Comm comm //group communicator
MPI_Status status //return status;
MPI_Status
MPI类型MPI_Status是一个有至少三个成员的结构,MPI_SOURCE,MPI_TAG和MPI_ERROR。假定程序有如下的定义:
#ifdef __USE_MPI__
MPI_Status status;
#endif
将&status
作为最后一个参数传递给MPI_Recv函数并调用它后,可以通过检查以下两个成员来确定发送者和标签。
status.MPI_SOURCE
status.MPI_TAG
接收量不是存储在应用程序可以直接访问到的域内,但是用户可以调用MPI_Get_count函数找到这个值。
int MPI_Get_count(
MPI_Status * status_p,
MPI_Datatype type,
int * count_p
);
MPI_Finalize()
用来清理 MPI 环境的。这个调用之后就没有 MPI 函数可以被调用了。
更多推荐
所有评论(0)