C语言 在MPI编程中,如何计算根进程中所有平均值的总和,以及从其他进程接收的局部平均值?

eqqqjvef  于 2023-10-16  发布在  其他
关注(0)|答案(1)|浏览(105)

给出的问题陈述是编写一个MPI程序(使用C),在根进程中将整数值M和NXM个元素读入一个1D数组,其中N是进程数。根进程向每个进程发送M个元素。每个进程找到它收到的M个元素的平均值,并将这些平均值发送给根。Root收集所有的值并找到总平均值。使用集体通信例程。(注意:不允许使用MPI_Reduce函数)
我的解决方案是

#include<stdio.h>
#include<stdlib.h>
#include<mpi.h>
int main(int argc, char *argv[]){
    int rank,size,m,arr[10],ans[10];
    float avg = 0,sum=0;
    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    MPI_Comm_size(MPI_COMM_WORLD,&size);

    if (rank == 0){
        fprintf(stdout,"Enter m:\n");
        fflush(stdout);
        fprintf(stdout,"Enter %d elements:\n",size*m);
        fflush(stdout);
        for (int i = 0; i < size*m; i++)
            scanf("%d",&arr[i]);
    }
    
    MPI_Bcast(&m,1,MPI_INT,0,MPI_COMM_WORLD);
    MPI_Scatter(arr, m, MPI_INT, ans, m, MPI_INT, 0, MPI_COMM_WORLD);
    for (int i = 0; i < m; i++)
        sum += ans[i];
    avg = sum/m;
    MPI_Gather(&avg, 1, MPI_FLOAT, ans, 1, MPI_FLOAT, 0, MPI_COMM_WORLD);
    if (rank == 0){
        for (int i = 0; i < m; i++)
            avg += ans[i];
        avg = avg/m;
        fprintf(stdout,"The  average of all values %f\n",avg);
        fflush(stdout);
    }
    MPI_Finalize();
    return 0;
}

生成的输出:

Enter m:
Enter 0 elements:
The  average of all values -1.#IND00

我无法理解如何进一步修复错误。在调用MPI_Gather函数之后,它应该能够计算根进程中的平均值。使用MPI_Reduce可以大大简化这个问题,但我不允许使用它。

6ovsh4lw

6ovsh4lw1#

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

int main(int argc, char *argv[]) {
    int rank, size, arr[10], recv[20],n;
    float avg = 0, sum = 0, tot_sum = 0, tot_avg = 0, ans[20];

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    if (rank == 0) {
        fprintf(stdout, "Enter n:\n");
        fflush(stdout);
        scanf("%d", &n);
        fprintf(stdout, "Enter %d array elements:\n", n * size);
        fflush(stdout);
        for (int i = 0; i < n * size; i++) {
            scanf("%d", &arr[i]);
        }
    }

    MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Scatter(arr, n, MPI_INT, recv, n, MPI_INT, 0, MPI_COMM_WORLD);

    for (int i = 0; i < n; i++) {
        sum += recv[i];  
    }
    avg = sum / n;
    
    fprintf(stdout, "Process (rank %d) has average %f\n", rank, avg);
    fflush(stdout);
    
    MPI_Gather(&avg, 1, MPI_FLOAT, ans, 1, MPI_FLOAT, 0, MPI_COMM_WORLD);

    if (rank == 0) {
        for (int i = 0; i < size; i++) {  
            tot_sum += ans[i];
        }
        tot_avg = tot_sum / size;  
        fprintf(stdout, "Total average: %f\n", tot_avg);
        fflush(stdout);
    }

    MPI_Finalize();
    return 0;
}

Generated output
Enter n:
1
Enter 4 array elements:
1 2 3 4
Process (rank 0) has average 1.000000
Process (rank 2) has average 3.000000
Process (rank 1) has average 2.000000
Process (rank 3) has average 4.000000
Total average: 2.500000

这个解决方案解决了我们得到垃圾值的问题。之前的解决方案有一个问题,我在计算平均值时使用了错误的变量。

相关问题