1
votes

I'm trying to calculate the difference between the speedup and efficiency of broadcasting an array of 1 million integers to all processes using MPI_Bcast and the usual MPI_send and MPI_Recv. But I don't understand why I'm getting this segmentation fault, any help would be greatly appreciated. here is my code:

#define num_of_ints 1000000
int *create_random_array(int);
int main(int argc, char *argv[]){
int size=0, my_rank =0, i=0;
int tag =99;
double start, end;
int *array = NULL;
srand(time(NULL));

MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

if(my_rank ==0)
    array = create_random_array(size*num_of_ints);
MPI_Barrier(MPI_COMM_WORLD);
start = MPI_Wtime();
MPI_Bcast(&array, num_of_ints, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
end = MPI_Wtime();
printf("time of broadcast using Bcast is %f seconds", end - start);

MPI_Barrier(MPI_COMM_WORLD);
start = MPI_Wtime();
if (my_rank == 0){
    for (i = 1; i < size; i++)
        MPI_Send(&array, num_of_ints, MPI_INT, i,tag, MPI_COMM_WORLD);
}else{
    MPI_Recv(&array, num_of_ints, MPI_INT, 0,tag,MPI_COMM_WORLD, &status);
}
MPI_Barrier(MPI_COMM_WORLD);
end = MPI_Wtime();

printf("time of broadcast using send/recv is %f seconds", end - start);
MPI_Finalize();
return 0;
}
 int *create_random_array(int size){
int i=0;
int *random_arr = (int*)malloc(size*sizeof(int));
for(i=0;i<size;i++)
    random_arr[i] = (rand()/(int)RAND_MAX);
return random_arr;
 }
2
Use a debugger, and find out where it segfaults, you can't expect us to do this for you. Indent your code properly. Don't cast the return of malloc and friends.Jens Gustedt

2 Answers

3
votes

There is a very common mistake in your code that has nothing to do with MPI itself but with the proper use of pointers in C/C++. All MPI communication calls in C expect a pointer to the data and most examples are shown like MPI_Somecall(&var, ...) but there var is usually a scalar integer or floating-point variable. While &var also works if var is a static array, it doesn't work if var is a pointer since &var then gives the location of the pointer itself and not the address that it points to.

In a nutshell:

MPI_Somecall(&var, ...)

when var is:

  • scalar global/static or automatic variable, e.g. int var;
  • a global/static or an automatic instance of a structure, e.g. struct foo var;

Otherwise:

MPI_Somecall(var, ...)

when var is:

  • a static array, e.g. int var[10];
  • a pointer to a heap variable or array, e.g. int *var = malloc(...);
  • a pointer in general, e.g. int *var = &some_int_var;
  • a function argument of a pointer type, e.g. void func(..., int *var, ...);

Replace all instances of &array in your code with array.

2
votes

Besides the & error reported by @HristoLLiev, you code is flawed with regard to memory management, and will not work unless you fix it.

Indeed, at the beginning the array variable is NULL for all of the processes involved, but is allocated in the call to create_random_array() ONLY by the process with rank zero. All of the other process do not allocate the memory. Therefore, you experience the segmentation fault. In order for your code to work, EVERY process must allocate properly the array.