MPI基本函数

本文详细介绍了MPI的基本函数和编程规范,包括MPI_Init和MPI_Finalize的使用,通信器的概念及其相关函数如MPI_Comm_rank和MPI_Comm_size,以及数据发送接收函数MPI_Send和MPI_Recv的参数解析。

MPI基本函数

MPI 编程规范

  • 所有的常量,变量和函数以MPI_开始编写

  • MPI的C接口是一个函数(值传递)

  • 除下划线外,所有常量均以大写字母定义

  • 功能和数据类型的定义,

      MPI_后跟的第一个字母为大写,其余为小写,形式为MPI_Xxxx_XXx
    
  • MPI程序从MPI_Init开始

  • MPI程序以MPI_Finalize结尾
    (分别初始化和终止MPI)

  • 除MPI Wtime和MPI Wtick之外的所有函数调用都返回一个错误信息代码

  • 由于 C 语言的函数调用机制是值传递,所以 MPI 的所有 C 函数中的输出参数用的都是指针

基本的MPI程序

#include "mpi.h" 
int main (int argc,char **argv)
{
	int rank,size,tag=1;//进程号,进程个数,进程标记
	int senddate,recvdata;//发送数据,接受数据
	MPI_Status status;//通信状态
	MPI_Init(&argc,&argv);//MPI 初始化
	MPI_Comm_rank(MPI_COMM_WORLD,&rank);//进程的编号
	MPI_Comm_size(MPI_COMM_WORLD,&size)//进程数
	if(rank==0){
		senddata=9999;
		MPI_Send(&senddata,1,MPI_INT,1,tag,MPI_COMM_WORLD);
		//发送地址 ,发送数据类型 ,发送标志,哪个范围内发送
	}
	if(rank==1){
		MPI_Recv(&recvdata,1,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
	}
	MPI_Finalize();
	return 0;
}

MPI_Init

  • 告诉系统进行初始化操作该函数初始化 MPI并行程序的执行环境。例如,系统可能需要为消息缓冲区分配存储空间,为进程指定进程号等。
  • 它必须在调用所有其它MPI函数之前被调用(除MPI_INITIALIZED)
  • 在一个MPI程序中,只能被调用一次
#返回一个int型错误码(大部分时候忽略)
int MPI_Init(
     #指向argc的指针,不使用设置为NULL
     int *  argc_p /*in/out*/,
     #指向argv的指针,不使用设置为NULL
     char *** argv_p /*in/out*/ )

MPI_Finalize

int MPI_Finalize(void)
该函数清除 MPI环境的所有状态
它被调用后,所有MPI 函数都不能再调用,包括 MPI_INIT
标志并行代码的结束,结束除主进程外其它进程。
之后串行代码仍可在主进程(rank = 0)上运行(如果必须).

communicator(通信器/通信子)

a collection of processes that can send messages to each other
(一组可以互相发送消息的进程集合)

MPI 程序启动时自动建立两个通信器:
MPI_COMM_WORLD :包含程序中所有MPI进程
MPI_COMM_SELF:由单个进程独自构成,仅包含自己

进程号是在通信器被创建时赋予的,相对通信器而言;
同一进程在不同的通信器中可以有不同的进程号;

MPI_Comm_rank

  • 作用:获得进程号(我是在哪一个进程)
    Get the number of the current process in the specified communication domain
    (获取指定通信域中当前进程的编号)
    used to distinguish itself from other programs
    (用于区别其他程序)
    它的函数形式:
    int MPI_Comm_rank(MPI_Comm_comm(自定的群), int * rank )
    进程号与通信器相关

MPI_Comm_size

解决问题:任务由多少个进程来进行并行计算
获得特定通信器的进程个数p
函数格式:

int MPI_Comm_size(
          MPI_Comm_comm     /*in*/,
          int*      size     /*out*/);

MPI_Send

mpi send(buf,counter,datatype,dest,tag,comm):
buf:发送缓冲区的起始地址,可以是数组或结构指针;
count:非负整数,发送的数据个数;
datatype:发送数据的数据类型;
dest:整型,目的的进程号;
tag:整型,消息标志;//用来表示不同的需求
comm:MPI进程组所在的通信域
在这里插入图片描述

在这里插入图片描述

MPI_Recv

在这里插入图片描述

### MPI六大基本函数及其用法 MPI(Message Passing Interface)是一种广泛应用于并行计算的消息传递接口标准,提供了丰富的函数库来支持分布式内存编程。以下是MPI中六大基本函数的介绍及用法: --- #### 1. **MPI_Init** `MPI_Init` 是MPI程序的初始化函数,必须在任何MPI调用之前执行。它负责初始化MPI运行环境,并解析命令行参数。 - **C语言声明**: ```c int MPI_Init(int *argc, char ***argv); ``` - **功能**: 初始化MPI环境。 - **注意事项**: - 参数 `argc` 和 `argv` 可以为 `NULL`,但通常建议传递 `main` 函数的参数[^2]。 - 必须在所有MPI调用之前执行[^1]。 --- #### 2. **MPI_Finalize** `MPI_Finalize` 是MPI程序的终止函数,标志着MPI程序的结束。它负责清理MPI资源并退出MPI环境。 - **C语言声明**: ```c int MPI_Finalize(void); ``` - **功能**: 终止MPI环境。 - **注意事项**: - 必须是MPI程序最后一条可执行语句[^5]。 - 在此之后不能再进行任何MPI调用。 --- #### 3. **MPI_Comm_rank** `MPI_Comm_rank` 用于获取当前进程在其通信域中的唯一标识号(rank)。 - **C语言声明**: ```c int MPI_Comm_rank(MPI_Comm comm, int *rank); ``` - **功能**: 获取调用进程在指定通信域中的标识号。 - **参数**: - `comm`: 指定的通信域(通常是 `MPI_COMM_WORLD`)。 - `rank`: 返回当前进程的标识号。 - **示例代码**: ```c #include <mpi.h> #include <stdio.h> int main(int argc, char *argv[]) { MPI_Init(&argc, &argv); int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); printf("Hello from process %d\n", rank); MPI_Finalize(); return 0; } ``` --- #### 4. **MPI_Comm_size** `MPI_Comm_size` 用于获取指定通信域中的进程总数。 - **C语言声明**: ```c int MPI_Comm_size(MPI_Comm comm, int *size); ``` - **功能**: 获取指定通信域中的进程总数。 - **参数**: - `comm`: 指定的通信域。 - `size`: 返回通信域中的进程总数。 - **示例代码**: ```c #include <mpi.h> #include <stdio.h> int main(int argc, char *argv[]) { MPI_Init(&argc, &argv); int size; MPI_Comm_size(MPI_COMM_WORLD, &size); printf("Total processes: %d\n", size); MPI_Finalize(); return 0; } ``` --- #### 5. **MPI_Send** `MPI_Send` 用于发送消息到另一个进程。 - **C语言声明**: ```c int MPI_Send(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm); ``` - **功能**: 向目标进程发送数据。 - **参数**: - `buf`: 发送数据的缓冲区地址。 - `count`: 发送数据的数量。 - `datatype`: 数据类型(如 `MPI_INT`, `MPI_DOUBLE` 等)。 - `dest`: 目标进程的标识号。 - `tag`: 消息标签,用于区分不同类型的消息。 - `comm`: 通信域。 - **示例代码**: ```c #include <mpi.h> #include <stdio.h> int main(int argc, char *argv[]) { MPI_Init(&argc, &argv); int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { int data = 42; MPI_Send(&data, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); } else if (rank == 1) { int recv_data; MPI_Recv(&recv_data, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); printf("Process 1 received: %d\n", recv_data); } MPI_Finalize(); return 0; } ``` --- #### 6. **MPI_Recv** `MPI_Recv` 用于接收来自其他进程的消息。 - **C语言声明**: ```c int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status); ``` - **功能**: 接收来自指定进程的消息。 - **参数**: - `buf`: 接收数据的缓冲区地址。 - `count`: 接收数据的最大数量。 - `datatype`: 数据类型。 - `source`: 消息来源进程的标识号(或 `MPI_ANY_SOURCE` 表示任意来源)。 - `tag`: 消息标签(或 `MPI_ANY_TAG` 表示任意标签)。 - `comm`: 通信域。 - `status`: 存储接收到的消息信息(如实际来源和标签)。 - **示例代码**: ```c #include <mpi.h> #include <stdio.h> int main(int argc, char *argv[]) { MPI_Init(&argc, &argv); int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { int data = 42; MPI_Send(&data, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); } else if (rank == 1) { int recv_data; MPI_Recv(&recv_data, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); printf("Process 1 received: %d\n", recv_data); } MPI_Finalize(); return 0; } ``` --- ### 总结 以上六个函数MPI中最基础且常用的函数,涵盖了MPI程序的初始化、终止、进程标识与数量获取以及消息的发送与接收功能[^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值