MPI_Recv 没有收到所有 MPI_Send 请求

MPI_Recv not receiving all MPI_Send requests

我的代码中有一个错误。我有多个进程都处理来自二叉树的数据。最后,他们应该将结果发送到将处理结果的主节点(节点 0)。但是,由于某些原因,一些 MPI_Sends 没有收到。

int *output=(int*) malloc(sizeof(int)*(varNum+2)); //contains all variable values and maxSAT and assignNum

if(proc_id!=0 && proc_id<nodeNums){
    output[0]=maxSAT;
    output[1]=assignNum;
    for(i=2;i<varNum+2;i++){
        output[i]=varValues[i-2];
    }
    MPI_Send(output,varNum+2,MPI_INT,0,TAG,MPI_COMM_WORLD);
    printf("proc %d sent data\n",proc_id);
}
else if(proc_id==0){
    for(i=1;i<nodeNums;i++){
        printf("receiving data from %d\n",i);
        MPI_Recv(output,varNum+2,MPI_INT,i,TAG,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
        if(output[0]>maxSAT){
            maxSAT=output[0];
            assignNum=output[1];
            for(i=0;i<varNum;i++){
                varValues[i]=output[i+2];
            }   
        }
        else if(output[0]==maxSAT){
            assignNum+=output[1];
        }
    }
}

当我运行它有8个进程(nodeNums=8)时,这是输出。

proc 2 sent data
receiving data from 1
proc 5 sent data
proc 6 sent data
proc 3 sent data
proc 7 sent data
proc 1 sent data
proc 4 sent data

出于某种原因,所有进程都在发送数据,但它只从 1 接收数据。但是,如果我 运行 它有 4 个进程,一切都是 sent/received。有人知道为什么会这样吗?

这不是真正使用 MPI 的方法。你在这里想要的是MPI_Gather(),这是所有进程(包括根)发送数据块并且收集进程接收所有数据的地方。像这样:

rbuf = (int *)malloc(nodeNums*(varNum+2)*sizeof(int));
MPI_Gather(output, varNum+2, MPI_INT, rbuf, varNum+2, MPI_INT, 0, MPI_COMM_WORLD);

你所有的进程都应该在它们执行的同一部分执行上面的内容。所有数据将在 rbuf.

中结束

在你的情况下,如果根不想发送任何东西,只要让它发送它可以简单地忽略的空数据(毕竟,它不需要物理 "send" 给自己,所以这不是很低效)。

问题与MPI无关。您的错误是在两个不同但嵌套的循环中使用了相同的变量:

else if(proc_id==0){
    for(i=1;i<nodeNums;i++){ <----------------- (1)
        ...
            for(i=0;i<varNum;i++){ <----------- (2)
                varValues[i]=output[i+2];
            }
        ...
    }
}

内循环完成后,i的值等于varNum,如果恰好varNum大于等于nodeNums,则外循环循环也终止。更改内层循环的循环变量名称。