MPI(一) 基础


基本的MPI函数

MPI_Init(int argc ,char* argv[]);

第一个被调用的MPI函数,用于并行环境初始化,其后至MPI_Finalize()函数之前的代码在每个进程中都会被执行一次。

  • 除MPI_Initialized()外,其余所有的MPI函数应该在其后被调用。
  • MPI系统将通过argc,argv得到命令行参数(也就是说main函数必须带参数,否则会出错)。

MPI_Comm_size(MPI_Comm comm ,int* size);

获得进程个数 size。

  • 指定一个通信子,也指定了一组共享该空间的进程, 这些进程组成该通信子的group(组)。
    - 获得通信子comm中规定的group包含的进程的数量。

MPI_Comm_rank(MPI_Comm comm ,int* rank);

  • 得到本进程在通信空间中的rank值,即在组中的逻辑编号(该 rank值为0到p-1间的整数,相当于进程的ID。)

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

  • void *buff:你要发送的变量。
  • int count:你发送的消息的个数(注意:不是长度,例如你要发送一个int整数,这里就填写1,如要是发送“hello”字符串,这里就填写6(C语言中字符串未有一个结束符,需要多一位))。
  • MPI_Datatype datatype:你要发送的数据类型,这里需要用MPI定义的数据类型
  • int dest:目的地进程号,你要发送给哪个进程,就填写目的进程的进程号。
  • int tag:消息标签,接收方需要有相同的消息标签才能接收该消息。
  • MPI_Comm comm:通讯域。表示你要向哪个组发送消息。

MPI_Recv(void buff, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status status);

  • void *buff:接收到的消息要保存到哪个变量里。
  • int count:接收消息的消息的个数(注意:不是长度,例如你要发送一个int整数,这里就填写1,如要是发送“hello”字符串,这里就填写6(C语言中字符串未有一个结束符,需要多一位))。它是接收数据长度的上界。具体接收到的数据长度可通过调用MPI_Get_count 函数得到。
  • MPI_Datatype datatype:你要接收的数据类型,这里需要用MPI定义的数据类型,可在网上找到,在此不再罗列。
  • int dest:接收端进程号,你要需要哪个进程接收消息就填写接收进程的进程号。
  • int tag:消息标签,需要与发送方的tag值相同的消息标签才能接收该消息。
  • MPI_Comm comm:通讯域。
  • MPI_Status *status:消息状态。接收函数返回时,将在这个参数指示的变量中存放实际接收消息的状态信息,包括消息的源进程标识,消息标签,包含的数据项个数等。

MPI_Finalize(void);

  • 退出MPI系统, 所有进程正常退出都必须调用。 表明并行代码的结束,结束除主进程外其它进程。
  • 串行代码仍可在主进程(rank = 0)上运行, 但不能再有MPI函数(包括MPI_Init())。

代码案例

Hello World

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
    // 初始化 MPI 环境,在 MPI_Init 的过程中,所有 MPI 的全局变量或者内部变量都会被创建。
    // 举例来说,一个通讯器 communicator 会根据所有可用的进程被创建出来,参数是指定的。
    // 然后每个进程会被分配独一无二的秩 rank。
    MPI_Init(NULL, NULL);

    // 通过调用以下方法来得到所有可以工作的进程数量。
    // MPI_Comm_size 会返回 communicator 的大小,也就是 communicator 中可用的进程数量。
    // 在例子中,MPI_COMM_WORLD(MPI生成的),这个变量包含了当前 MPI 任务中所有的进程。
    // 我们的代码里的这个调用会返回所有的可用的进程数目。
    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    // 得到当前进程的秩,即返回 communicator 中当前进程的 rank。 
    // communicator 中每个进程会以此得到一个从0开始递增的数字作为 rank 值。
    // rank 值主要是用来指定发送或者接受信息时对应的进程。
    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);

    // 得到当前进程实际跑的时候所在的处理器名字
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    int name_len;
    MPI_Get_processor_name(processor_name, &name_len);

    // 打印一条带有当前进程名字,秩以及
    // 整个 communicator 的大小的 hello world 消息。
    printf("Hello world from processor %s, rank %d out of %d processors\n",
           processor_name, world_rank, world_size);

    // 清理 MPI 环境
    MPI_Finalize();
}
"C:\Program Files\Microsoft MPI\Bin\mpiexec.exe" -np 4 ./mpi.exe
Hello world from processor LAPTOP-JF5NS2NS, rank 0 out of 4 processors
Hello world from processor LAPTOP-JF5NS2NS, rank 1 out of 4 processors
Hello world from processor LAPTOP-JF5NS2NS, rank 3 out of 4 processors
Hello world from processor LAPTOP-JF5NS2NS, rank 2 out of 4 processors

Process finished with exit code 0

声明:Hello World|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - MPI(一) 基础


我的朋友,理论是灰色的,而生活之树是常青的!