广播后其他处理器的数组中的错误元素(MPI)

Wrong elements in the array for other processors after broadcasting (MPI)

我正在尝试将指向 x 的指针广播给其他处理器。它与 errnum 一起声明为全局变量。但是在广播之后,除了 rank 0 之外,所有处理器的数组内容都不正确,而 errnum 被正确读取。

我在大写部分添加了评论以指出我在上面所指的内容。底部打印循环在广播后给出 errnum 的正确值,而不管等级如何,但 x 的内容仅在等级为 0 时才是正确的。有人知道为什么吗?

注意:我不太熟悉 C,但数组的元素似乎已正确填充,因为进程 0 能够访问数组并从中读取正确的元素。

示例输入...

3 
5.05
2 3 4

如果我将等级设置为 0 的输出...

3
0.010000
0 2.000000
1 3.000000
2 4.000000

如果我将排名设置为 1 的输出...

3
0.010000
0 1209010463764815312582472227618816.000000
1 18988728894356880079764586496.000000
2 78657026497739634549916490384015360.000000

和代码..

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


float err; 
float *x;  // DECLARING X HERE
int num;

void get_input();  


void get_input(FILE* fp, int process_rank, int comm_size)
{
    if(process_rank == 0)
    {
        x = (float *)malloc(num * sizeof(float));

        for(int i = 0; i < num; i++) {
            fscanf(fp, "%f", &x[i]);
        }

        // BROADCASTING X
        MPI_Bcast(&x, num, MPI_FLOAT, 0, MPI_COMM_WORLD);

        fclose(fp);
    }
}


int main(int argc, char *argv[])
{
    FILE* fp;

    fp = fopen(argv[1], "r");
    if (!fp)
    {
        printf("Cannot open file %s\n", argv[1]);
        exit(1);
    }    
    fscanf(fp, "%d ", &num);
    fscanf(fp, "%f ", &err);

    int comm_size;
    int process_rank;
    x = (float *)malloc(num * sizeof(float));  /* The unknowns */

    MPI_Init(NULL, NULL);
    MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
    MPI_Comm_rank(MPI_COMM_WORLD, &process_rank);

    MPI_Bcast(&num, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&err, 1, MPI_FLOAT, 0, MPI_COMM_WORLD);

    get_input(fp, process_rank, comm_size);

    // CHECKING X
    if(process_rank == 1) {
        printf("%d\n", num);
        printf("%f\n", err);
        for(int i = 0; i < num; i++) {
            printf("%d %f\n", i, x[i]);
        }
    }

    MPI_Finalize();

    return(0);
}

MPI_Bcast()的第一个参数是指向缓冲区的指针,而不是指向缓冲区的指针的地址。

因此您需要将 MPI_Bcast(&x, ...); 替换为 MPI_Bcast(x, ...);

您还需要将 xMPI_Bcast() 分配给 所有 行列。 这是更正后的 get_input() 函数

void get_input(FILE* fp, int process_rank, int comm_size)
{
    x = (float *)malloc(num * sizeof(float));

    if(process_rank == 0)
    {
        for(int i = 0; i < num; i++) {
            fscanf(fp, "%f", &x[i]);
        }
    }

    // BROADCASTING X
    MPI_Bcast(x, num, MPI_FLOAT, 0, MPI_COMM_WORLD);

    fclose(fp);
}

话虽这么说,您可能想要修改代码,以便仅对输入文件进行 0 open/read/close 排名。