使用 MPI_MAXLOC 的 MPI_Reduce 函数时 MPI 程序出错

Error in MPI program when using MPI_Reduce function of MPI_MAXLOC

我想用MPI_Reduce函数同时求最大值和它的PID(rank),但是结果显示不是真的,不知道怎么解决,结果:

PID:1, loc_num:2 
PID:2, loc_num:3 
PID:3, loc_num:4 
global data: 1 
coresponding PID: 0

我的程序:

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

int main(int argc, char *argv[])
{
    //init MPI
    int PID, P;
    MPI_Init(&argc, &argv);      
    MPI_Comm_size(MPI_COMM_WORLD, &P);
    MPI_Comm_rank(MPI_COMM_WORLD, &PID);
    struct{
        int value;
        int PID;
    } in, out;
    int value = 1;
    in.value = value;
    in.PID = PID;

   for(int i = 1; i <= P; i++){
        if (PID == i){                
            value = value + i;
            printf("PID:%d, loc_num:%d \n",PID, value);
        }

    } 
    MPI_Reduce(&in, &out, 1, MPI_2INT, MPI_MAXLOC, 0, MPI_COMM_WORLD);
    int max_PID = out.PID;
    int max_num = out.value;

    if (PID == 0){

        printf("global data: %d \n", max_num);
        printf("coresponding PID: %d \n",max_PID);
    }
    MPI_Finalize();
    return 0;       
}

我只是按照in.value= value and in.PID=PID and then,every PID calculate value=value+PID的结构所以答案是当PID=1, loc=2;when PID=2, loc=3 ...接下来将它们全部与max进行比较,然后将它们发送到PID=0

您的示例 MPI_Reduce 中没有错误。正如 @Gilles 指出的那样,问题是您没有将新计算的 value 分配给 in.value.

如果你像下面这样在计算之后放置赋值语句,那么一切都会按预期工作。

   for(int i = 1; i <= P; i++){
        if (PID == i){
            value = value + i;
            printf("PID:%d, loc_num:%d \n",PID, value);
        }

    }
    in.value = value;
    in.PID = PID;
    MPI_Reduce(&in, &out, 1, MPI_2INT, MPI_MAXLOC, 0, MPI_COMM_WORLD);

在下面的示例中,您没有将计算值分配给 in 结构对象。

    in.value = value; // value is set as 1
    in.PID = PID;
    for(int i = 1; i <= P; i++){
    if (PID == i){
        value = value + i; // calculating the value but not assigning to in.value
        printf("PID:%d, loc_num:%d \n",PID, value);
       }
     }
    // uses the old value for in.value (i.e 1) for reduction
    MPI_Reduce(&in, &out, 1, MPI_2INT, MPI_MAXLOC, 0, MPI_COMM_WORLD);