进程数中途变化

Number of processes changes midway

我写了一个简单的 MPI 程序,它接受一个输入文件并获取其中的前 99 个数字,然后将它们相加。它实际上是 this 的一个轻微修改版本。这个程序有效。

#include "mpi.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#define MAXSIZE 99 //line 5

void main(int argc, char **argv){
        //int MAXSIZE = 6; //line 8
        int myid, numprocs;
        int data[MAXSIZE], i, x, low, high, myresult, result;
        char fn[255];
        FILE *fp;

        //if (argc > 1) MAXSIZE = atoi(argv[1]); //line 14
        MPI_Init (&argc, &argv);
        MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
        MPI_Comm_rank (MPI_COMM_WORLD, &myid);

        if (myid == 0){ //Open input file and initialize data
                strcpy(fn, getenv("HOME"));
                strcat (fn, "/MPI/rand_data.txt");
                if ((fp = fopen(fn, "r")) == NULL){
                        printf("Can't open the input file: %s\n\n", fn);
                        exit (1);
                }
                for(i = 0; i < MAXSIZE; i++){
                        fscanf(fp,"%d", &data[i]);
                }
        }

        //broadcast data
        MPI_Bcast (data, MAXSIZE, MPI_INT, 0, MPI_COMM_WORLD);
        //Add my portion Of data

        x = MAXSIZE/numprocs; //must be an integer
        low = myid * x;
        high = low + x;
        myresult = 0;

        for(i = low; i < high; i++){
                myresult += data[i];
        }
        if (MAXSIZE % numprocs > myid)
                myresult += data[x*numprocs+myid];
        printf("I got %d from %d\n", myresult, myid);

        //Compute global sum
        MPI_Reduce(&myresult, &result, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
        if (myid == 0) printf("The sum is %d.\n", result);
        MPI_Finalize();

}

然后我尝试通过简单地注释掉第 5 行并取消注释第 8 行和第 14 行来使同一个程序接受参数(它读取和总结了多少数字)。这个程序运行任何参数都很好,但是通过80 或以上给它奇怪的行为。我做了 printf 风格的调试,发现 numprocs 的值,原本是 4,会在过程中间变成 1。

这里发生了什么?

奇怪的行为可能是由于第 10 行声明了 int data[MAXSIZE],而第 8 行(即 6)设置了 MAXSIZE。这是因为第 15 行再次设置 MAXSIZE。如果它大于初始的 MAXSIZE 那么它会导致未定义的行为(也可能是分段错误),因为现在将使用新的 MAXSIZE 访问 data 数组。所以将 int data[MAXSIZE] 从第 10 行移动到第 16 行。

就在执行过程中更改 numprocs 的值而言,根本不应该 发生。分配 numprocs 值 (write) 的唯一实例是在 MPI 调用期间,其余时间仅访问它 (read)。所以理论上它不应该发生。