MPI_Gather generating: Signal Segmentation Fault

Hi,

I am following the tutorial at:

http://mpitutorial.com/tutorials/mpi-scatter-gather-and-allgather/

I have done MPI_Scatter(...) to distribute data. After that I am doing division using a function computerDivion. computerDivision is returning a pointer and storing it in div_buffer.computeDivison is returning a pointer to array of double values of size num_cols.After that I am calling MPI_Gather(...). I want to store the data returned by each process into a pointer to pointer of 2Darray but this is not working.

My complete code is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include <iostream>
#include <cmath>
#include <mpi.h>
#include <fstream>
#include <ctime>
#include <vector>
#define N 16

int rank, size;
double* computeDivisions(double* recv_buffer, int, int);
void GaussianElimination(double **,double *b ,double *y);
int main(int argc, char * argv[])
{
  double sTime, eTime, rTime;
  std::ifstream inFile;
  int num_rows = 4;
  int num_cols = 4;
  int num_processors =4;
  int cur_control = 0;
  double * send_buffer = NULL;
  double * recv_buffer = NULL;
  double ** data = NULL;
  double determinant;
  double *div_buffer=NULL;
  int irow =0; int icol=0; int iIndex =0;
  std::vector<double> file_buffer;
   double **M_div=NULL;


  double **M_A, *I_A, *I_B, *I_Y, *recv_div;
  double *Output, Pivot;
  I_B = NULL;
  I_B = new double[N];
  if(I_B == NULL){
    std::cout<< " I_A can't be allocated memory";
    return -2;
  }
  I_A = NULL;
  I_A = new double[N];
  if(I_A == NULL){
    std::cout<< " I_A can't be allocated memory";
    return -2;
  }
  I_Y = NULL;
  I_Y = new double[N];
  if(I_Y== NULL){
    std::cout<< " I_B can't be allocated memory";
    return -2;
  }
  
 recv_buffer = new double[N];
 if(recv_buffer== NULL){
    std::cout<< " recv_buffer can't be allocated memory";
    return -2;
  }


  M_A = new double*[num_cols];
  for(int i = 0; i < num_cols; i++){
    M_A[i] = new double[num_rows];
    if(M_A[i]==NULL){
       std::cout<<"M_A can't be allocated";
       MPI_Finalize();
       return 0;
    }
  }
  for(int i = 0; i < num_cols; i++)
  {
    for(int j = 0; j < num_rows; j++)
      M_A[i][j] = 0;
  }

div_buffer = new double[num_rows];
       if(div_buffer== NULL){
          std::cout<< " div_buffer can't be allocated memory";
          return -2;
       }

       
      M_div = new double*[num_cols];
      for(int i = 0; i < num_cols; i++){
         M_div[i] = new double[num_rows];
         if(M_div[i]==NULL){
            std::cut<<"M_div can't be allocated";
            MPI_Finalize();
            return 0;
         }
      }
      for(int i = 0; i < num_cols; i++)
      {
         for(int j = 0; j < num_rows; j++)
         M_div[i][j] = 0;
       }
      //std::cout<< "rank = "<< rank << std::endln;


  // Just get the initialization of the program going.
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &size);

 
  // If the input file is not given, print message and exit.
  /*if(argc < 2)
  {
    std::cout << "No input file given." << std::endl;
    MPI_Finalize();
    return 0;
  }*/
  if(!rank)
  {
    /*inFile.open(argv[1]);
    inFile >> num_rows;
    inFile >> num_cols;
    file_buffer.resize(num_rows);*/

    //Reading the whole file in the Matrix
    /*for(irow = 0; irow < n_size; irow++){
		  
        for(icol = 0; icol < num_rows; icol++)
	        M_A[irow][icol] =1;
	  }*/
       
        std::cout<<"WE have "<<size <<" processors " <<std::endl;
       M_A[0][0] =2.0;M_A[0][1] =1.0; M_A[0][2] = -1.0; M_A[0][3] =2.0;  //A[0][3] = 12.0;
       M_A[1][0] =4.0;M_A[1][1] =5.0; M_A[1][2] =-3.0;   M_A[1][3] = 6.0;//A[1][3] = 0.0;
       M_A[2][0] =-2.0;M_A[2][1] =5.0; M_A[2][2] = -2.0; M_A[2][3]=6.0;//A[0][3] = -9;
       M_A[3][0] =4.0;M_A[3][1] =11.0; M_A[3][2] = -4.0; M_A[3][3]=8.0;//A[0][3] = -9;
       I_B[0] = 5; I_B[1] = 9; I_B[2] = 4; I_B[3]=2;
       //2d to 1d array is giving core dumped
       for(irow=0; irow<num_rows; irow++)
	  	  for(icol=0; icol<num_cols; icol++)
			  I_A[iIndex++] = M_A[irow][icol];

       
   }//if(!rank)

  

   MPI_Bcast (&num_rows, 1, MPI_INT, 0, MPI_COMM_WORLD);
   int iChunkSize = num_rows/size;
   MPI_Scatter(I_A, num_cols, MPI_DOUBLE, recv_buffer, num_cols, MPI_DOUBLE, 0, MPI_COMM_WORLD);//data goes to each process
   //http://mpitutorial.com/tutorials/mpi-scatter-gather-and-allgather/
   
   div_buffer = computeDivisions(recv_buffer, rank, num_cols);
   
   MPI_Gather(M_div, num_cols, MPI_DOUBLE, div_buffer, num_cols, MPI_DOUBLE, 0, MPI_COMM_WORLD);

  
  
  for(int i = 0; i < num_rows; i++)
     delete [] M_div[i];
    delete [ ] M_div;
  
  //delete [ ] div_buffer;
    delete [] I_Y;
    delete [ ]I_B;
    for(int i = 0; i < num_rows; i++)
     delete [] M_A[i];
    delete [ ] M_A;// No need to delete A because A is not created dynamically
    MPI_Finalize();
    return 0;
}

double* computeDivisions(double* recv_buffer, int rank, int num_cols){
    
    std::cout<<"Inside ComputeDivision "<<std::endl;
     for(int j=0;j<num_cols;++j)
              std::cout<<recv_buffer[j]<<" ";
     std::cout<<std::endl;
   
         
            for(int j= rank+1; j <=num_cols-1; ++j)
            recv_buffer[j] = recv_buffer[j]/recv_buffer[rank];
              
// std::cout<<"rb=["<<j<<"]="<<recv_buffer[j]<<" and"<<"rb=["<<rank<<"]="<<recv_buffer[rank]<<std::endl;
             
           
            // std::cout<<"After division Recvbuffer["<<j<<"]= "<<recv_buffer[j];
             
            for(int j=0;j<num_cols;++j)
              std::cout<<recv_buffer[j]<<" ";

           
}

I am getting following error messages:

$ mpirun -np 4 ./a.out
WE have 4 processors
Inside ComputeDivision
2 1 -1 2
Inside ComputeDivision
[lc2530hz:08832] *** Process received signal ***
[lc2530hz:08832] Signal: Segmentation fault (11)
[lc2530hz:08832] Signal code: Address not mapped (1)
[lc2530hz:08832] Failing at address: 0x4
4 5 -3 6
[lc2530hz:08833] *** Process received signal ***
[lc2530hz:08833] Signal: Segmentation fault (11)
[lc2530hz:08833] Signal code: Address not mapped (1)
[lc2530hz:08833] Failing at address: (nil)
Inside ComputeDivision
Inside ComputeDivision
[lc2530hz:08832] [ 0] 4 11 -4 8
-2 5 -2 6
/lib/x86_64-linux-gnu/libc.so.6(+0x3ef20)[0x7fd217e1ff20]
[lc2530hz:08832] [ 1] [lc2530hz:08833] [ 0] [lc2530hz:08835] *** Process received signal ***
[lc2530hz:08835] Signal: Segmentation fault (11)
[lc2530hz:08835] Signal code: Address not mapped (1)
[lc2530hz:08835] Failing at address: (nil)
[lc2530hz:08834] *** Process received signal ***
[lc2530hz:08834] Signal: Segmentation fault (11)
[lc2530hz:08834] Signal code: Address not mapped (1)
[lc2530hz:08834] Failing at address: (nil)
/lib/x86_64-linux-gnu/libc.so.6(+0x18eaed)[0x7fd217f6faed]
[lc2530hz:08832] [ 2] /lib/x86_64-linux-gnu/libc.so.6(+0x3ef20)[0x7fdde2be5f20]
[lc2530hz:08833] [ 1] /usr/lib/x86_64-linux-gnu/libopen-pal.so.20(+0x3a103)-gnu/libmpi.so.20(PMPI_Gather+0x1a0)[0x7fd2187d4fd0]


[lc2530hz:08835] [ 5] +0xe7)[0x7fd217e02b97]
[lc2530hz:08832] [ 8] ./a.out(+0xb7ca)[0x55f26dfb07ca]
/usr/lib/x86_64-linux-gnu/openmpi/lib/openmpi/mca_pml_ob1.so(mca_pml_ob1_send+0xea)[0x7f2222f4566a]
[lc2530hz:08835] [ 6] ]
[lc2530hz:08834] [ 5] /usr/lib/x86_64-linux-gnu/openmpi/lib/openmpi/mca_pml_ob1.so(mca_pml_ob1_send+0xea)[0x7fee0b3d066a]
[lc2530hz:08834] [ 6] c1b5)[0x55e1bc2081b5]
[lc2530hz:08833] [ 8] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7fdde2bc8b97]

[lc2530hz:08834] *** End of error message ***
[lc2530hz:08835] *** End of error message ***
--------------------------------------------------------------------------
mpirun noticed that process rank 3 with PID 0 on node lc2530hz exited on signal 11 (Segmentation fault).
--------------------------------------------------------------------------


Note, I have deleted some of the messages.

If I comment the MPI_Gather, these errors won't generate.
Some body please guide.
Zulfi.
Last edited on
No idea, but computeDivisions doesn't return the pointer (or array) that it promised, so div_buffer won't be set, so MPI_Gather won't work.

@zak100, your code is becoming incredibly difficult to read.
Hi,
You are right. Because I was gettingthe error when i was trying to delete div_buffer because it was not initialized.

I would remove the comments. This would make the code simpler. And I would also indent it.
Thanks for comments and for helping me.

God bless you.

Zulfi.
Last edited on
new doesn't ever return a null pointer.
new can be used to initialize your memory (to zero) for you.

Why aren't you using std::vector?
Registered users can post here. Sign in or register to post.