与 MPI_SEND 在循环中排名和在 MPI 中不循环发送有什么不同

What is different from MPI_SEND with rank in a loop and sending without loop in MPI

我正在尝试这些逻辑代码,但我不知道它们之间有什么不同。我正在尝试在我的程序中使用 MPI_Send()MPI_Recv()。据我了解,在 MPI 中,进程通过每个处理器的等级和每条消息的标签进行通信。那么,如果我尝试

有什么不同

逻辑 1:

int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);

int number;
if (world_rank == 0) {
    number = -1;
    MPI_Send(&number, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
} else if (world_rank == 1) {
    MPI_Recv(&number, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
             MPI_STATUS_IGNORE);
    printf("Process 1 received number %d from process 0\n",
           number);
}

逻辑 2:

int world_rank;
  MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
  int world_size;
  MPI_Comm_size(MPI_COMM_WORLD, &world_size);
  int number;
      if (world_rank == 0) {
        number = -1;
        int i =0;
        for(i = 1 ; i< world_size;i++){
           MPI_Send(&number, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
        }
      }else{
        MPI_Recv(&number, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
         printf("Process 1 received number %d from process 0\n",
           number);
      }

我试试:mpirun -np 100 ./test <arguments>

我认为这两种逻辑都会获得进程的等级,并将其解析为 MPI_Send 上的参数。有什么不同???

我正在使用 OpenMPI 1.8 开发 Debian Kali Linux。 我是 MPI 的新手。感谢您的帮助。

这是非常不同的。

一方面,在逻辑 1 中,单个消息从进程 0 发送到进程 1。另一方面,在逻辑 2 中,world_size-1 条消息由进程 0 和每个剩余进程发送从 0 收到一条消息。第二种情况可以通过调用 MPI_Bcast().

来代替

如果您尝试过 mpirun -np 2 ./test <arguments> 这些代码会做同样的事情...但这是唯一的情况!

两个代码摘要似乎都是正确的。第一种情况的失败可能是因为整数number没有在进程2到world_size上初始化。例如,如果 number 是数组的长度,它会触发分段错误。如果 numberfor 循环中停止条件的一部分,它可以触发无限循环(或非常长的循环)。

已编辑

由于我们缺少完整的源代码,因此无法确定 initialization/finalization 函数是否被正确使用。

这里我们有与初始答案相同的源代码 + 正确 运行 mpi 应用程序所需的内容:

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

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

    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    int number;
    if (world_rank == 0) {
        number = -1;
        MPI_Send(&number, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
    } else if (world_rank == 1) {
        MPI_Recv(&number, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
                 MPI_STATUS_IGNORE);
        printf("Process 1 received number %d from process 0\n",
               number);
    }

    MPI_Finalize();
}

编译:

> mpicc -std=c99 -O2 -g -Wall -I. -o app app.c -lm

运行:

> mpirun -n 10 app
Process 1 received number -1 from process 0
>

基本上一切正常,所以我猜问题可能与 initialization/finalization.

有关

初步反应

您的应用程序以逻辑 1 挂起,因为有 99 个进程在等待一条消息,但主进程只将消息发送给排名为 1 的进程。

当您使用阻塞函数时(即 MPI_Send 与 MPI_Isend),有 98 个进程永远等待直到消息来自排名为 0、标记=0 且通讯器 MPI_COMM_WORLD.