nikos
nikos

Reputation: 13

Why does MPI give segmentation fault when I allocate memory for a second time for a second array?

So here is the code that works with // before the lines that cause the segmentation fault:

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

int main (int argc, char *argv[]) {
  float *delta;
  int size,rank,*arr;

  MPI_Init (&argc, &argv); //initialize MPI library
  MPI_Comm_size(MPI_COMM_WORLD, &size); //get number of processes
  MPI_Comm_rank(MPI_COMM_WORLD, &rank); //get my process id
  
    if (rank==0){
        //MPI_Alloc_mem(2*sizeof(int),MPI_INFO_NULL,arr);
        MPI_Alloc_mem(3* sizeof(float),MPI_INFO_NULL,delta);
        delta[0]=1;
        delta[1]=2;
        //arr[0]=1;
        for (int i=1; i<size; i++){
            MPI_Send(delta,3,MPI_FLOAT,i,4,MPI_COMM_WORLD);
            //MPI_Send(arr,2,MPI_INT,i,4,MPI_COMM_WORLD);
        }
    }
    else{
        MPI_Recv(delta, 3, MPI_FLOAT, 0, 4, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        //MPI_Recv(arr, 2, MPI_INT, 0, 4, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  }
  printf("delta:%f from process: %d\n",delta[0],rank);
  //printf("arr:%d from process: %d\n",arr[0],rank);
  MPI_Finalize(); //MPI cleanup
  return 0;
}

And here is the code that doesn't work:

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

int main (int argc, char *argv[]) {
  float *delta;
  int size,rank,*arr;

  MPI_Init (&argc, &argv); //initialize MPI library
  MPI_Comm_size(MPI_COMM_WORLD, &size); //get number of processes
  MPI_Comm_rank(MPI_COMM_WORLD, &rank); //get my process id
  
    if (rank==0){
        MPI_Alloc_mem(2*sizeof(int),MPI_INFO_NULL,arr);
        MPI_Alloc_mem(3* sizeof(float),MPI_INFO_NULL,delta);
        delta[0]=1;
        delta[1]=2;
        arr[0]=1;
        for (int i=1; i<size; i++){
            MPI_Send(delta,3,MPI_FLOAT,i,4,MPI_COMM_WORLD);
            MPI_Send(arr,2,MPI_INT,i,4,MPI_COMM_WORLD);
        }
    }
    else{
        MPI_Recv(delta, 3, MPI_FLOAT, 0, 4, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        MPI_Recv(arr, 2, MPI_INT, 0, 4, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  }
  printf("delta:%f from process: %d\n",delta[0],rank);
  printf("arr:%d from process: %d\n",arr[0],rank);
  MPI_Finalize(); //MPI cleanup
  return 0;
}

Why does allocating memory for a second time cause this? I also tried this with malloc instead of MPI_Alloc_mem just in case but didn't really change anything.

Upvotes: 1

Views: 391

Answers (2)

Dariyoush
Dariyoush

Reputation: 508

I am not familiar with MPI_Alloc_mem so I am using malloc. As @Victore Eijkhout mentioned, you need to allocate the same amount of memory for your array on every process. here is a working version of your code:

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

int main (int argc, char *argv[]) {
  float *delta;
  int *arr;
  int size,rank;
  int tag;
  MPI_Status status;
  MPI_Init (&argc, &argv); //initialize MPI library
  MPI_Comm_size(MPI_COMM_WORLD, &size); //get number of processes
  MPI_Comm_rank(MPI_COMM_WORLD, &rank); //get my process id
  
    if (rank==0){
        arr = malloc(2 * sizeof(int));
        delta = malloc(3 * sizeof(float));
        //MPI_Alloc_mem(2*sizeof(int),MPI_INFO_NULL,arr);
        //MPI_Alloc_mem(3*sizeof(float),MPI_INFO_NULL,delta);

        delta[0]=1;
        delta[1]=2;
        arr[0]=10;
        arr[1] = 20;
        for (int i=1; i<size; i++){
            MPI_Send(delta,3,MPI_FLOAT,i, 4,MPI_COMM_WORLD);
            MPI_Send(arr,2,MPI_INT,i, 4, MPI_COMM_WORLD);
        }
    }
    else{
        arr = malloc(2 * sizeof(int));
        delta = malloc(3 * sizeof(float));
        MPI_Recv(delta, 3, MPI_FLOAT, 0, 4, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        MPI_Recv(arr, 2, MPI_INT, 0, 4, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  }
  printf("Process %d: arr:[%d, %d] | delta:[%f, %f]\n", rank, arr[0], arr[1], delta[0], delta[1]);

  MPI_Finalize(); //MPI cleanup
  return 0;
}

output:

Process 3: arr:[10, 20] | delta:[1.000000, 2.000000]
Process 0: arr:[10, 20] | delta:[1.000000, 2.000000]
Process 2: arr:[10, 20] | delta:[1.000000, 2.000000]
Process 1: arr:[10, 20] | delta:[1.000000, 2.000000]

Upvotes: 1

Victor Eijkhout
Victor Eijkhout

Reputation: 5794

You allocate your buffers only on process zero: on the other processes there is no buffer. Maybe you're confused how send/recv work: they don't send a buffer, but the contents. So the receiver needs to have space allocated to receive the data in. The receive call does not create the buffer, it only puts data in it.

Upvotes: 1

Related Questions