mpi程序出现不可预知的错误-主进程运行了两次

There is an unpredictable error in the mpi program-The main process runs twice

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

int main(int argc, char *argv[])
{
    int rank, value, size,count;
    MPI_Status status;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    count=2*size-1;
    while(count>0){
        if (rank==0) {
            // fprintf(stderr, "\nPlease give new value=");
            printf("please input value= ");
            scanf("%d",&value);
            // fprintf(stderr, "%d read <-<- (%d)\n",rank,value);
            printf("%d read <-<- (%d)\n",rank,value);
            count-=1;
    
            if (size>1) {
                MPI_Send(&value, 1, MPI_INT, rank+1, 0, MPI_COMM_WORLD);
                // fprintf(stderr, "%d send (%d)->-> %d\n", rank,value,rank+1);
                printf("%d send (%d)->-> %d\n",rank,value,rank+1);
                count-=1;
            }
        }
        else {
            MPI_Recv(&value, 1, MPI_INT, rank-1, 0, MPI_COMM_WORLD, &status);
            // fprintf(stderr, "%d receive(%d)<-<- %d\n",rank, value, rank-1);
            printf("%d receive(%d)<-<- %d\n",rank, value, rank-1);
            count-=1;
            if (rank<size-1) {
                MPI_Send(&value, 1, MPI_INT, rank+1, 0, MPI_COMM_WORLD);
                fprintf(stderr, "%d send (%d)->-> %d\n", rank, value, rank+1);
            count-=1;
            }
        }
        MPI_Barrier(MPI_COMM_WORLD);
    }
    MPI_Finalize();
}

这个程序的作用是在进程之间传递数字。 现在我打开两个传递数字 4

的进程

但是0进程运行两次,不符合预期。

然后我用gdb调试

这个问题困扰我很久了,我不太擅长从命令行观察变量。请帮助我。

TL;DR : 运行s 两次因为 while 循环执行了两次。

But the 0 process ran twice, which is not as expected.

你的印象是进程 0 运行s 两次,因为在进入 while 循环之前 count 变量的值为 3 来自 count=2*size-1;size 是 2,因为你是 运行 2 个进程)。

在你的循环中:

while(count>0){
        if (rank==0) {
            ...
            count-=1;
    
            if (size>1) {
                ...
                count-=1;
            }
        }
        else {
            ...
            count-=1;
            if (rank<size-1) {
               ...
            count-=1;
            }
        }
        MPI_Barrier(MPI_COMM_WORLD);
    }

count变量对于(进程0)递减了两次,所以count是1,由于while循环条件是count>0所以又是退出前执行。因此,处理0“再次运行s”。

进程 0count 变量递减两次,而进程 1 仅递减一次,因此很可能这是一个错误。您可以 运行 遇到进程 1 阻塞等待从进程 0 接收消息但进程 0 已经在循环之外的情况。

要测试从进程 0 发送和接收消息,请尝试以下操作:

int main(int argc, char *argv[])
{
    int rank, value, size,count;
    MPI_Status status;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    if (rank==0) 
    {
       printf("please input value= ");
       scanf("%d",&value);
       for(int i = 1; i < size; i++){
           MPI_Send(&value, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
           printf("%d send (%d)->-> %d\n",rank, value, i);
      }
    }
    else 
    {
       MPI_Recv(&value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
       printf("%d receive(%d)<-<- %d\n",rank, value, rank-1);
    }
    MPI_Finalize();
}

进程0向所有剩余进程发送一个值:

   for(int i = 1; i < size; i++){
       MPI_Send(&value, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
       printf("%d send (%d)->-> %d\n",rank, value, i);
  }

并且所有剩余进程从进程0:

接收消息
MPI_Recv(&value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);