Search code examples
cmpiopenmpi

Number of processes changes midway


I wrote a simple MPI program that takes an input file and take the first 99 numbers inside it, and sum them up. It's actually a slight modified version of this. This programs works.

#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();

}

I then tried to make the same program takes argument (how many numbers it read and sums up) by simply commenting out line 5, and uncomment line 8 and 14. This program runs just fine with any argument, but passing 80 or above gives it weird behaviors. I did printf-style debugging, and found out that numprocs's value, originally 4, will change to 1 in the middle of the process.

What happened here?


Solution

  • Weird behaviour can be due to the line 10 where int data[MAXSIZE] is declared with MAXSIZE set in line 8 (which is 6). This is because line 15 again sets MAXSIZE. If it's greater than the initial MAXSIZE then it can lead to undefined behaviour (probably also segmentation fault) because data array will now be accessed with new MAXSIZE. So move int data[MAXSIZE] from line 10 to line 16.

    As far as changing the value of numprocs in the middle of the execution, it shouldn't happen at all. The only instance where value of numprocs is assigned (write) is during the MPI call and rest of the time it is only accessed (read). So in theory it shouldn't happen.