0

i am learning MPI and i am new, i have been trying this problem of matrix vector multiplication and i am stuck. please any help i can get, i would appreciate.so this is how it is: my program is compile and executing, with some dimension of matrix is working and failing for the other with a segmentation fault and i can't figure out why. bellow is a program and the result for 2 cases:

 #include <iostream>
    #include <cmath>
    #include <cstdlib>
    #include <chrono>
    #include <mpi.h>
    float genA (int row, int col) {
    
        if (row > col)
            return 1.;
          else
            return 0.;
    
    }
    
    float genx0 (int i) {
      
    
        return 1.;
    
    }
    
    
    void checkx (int iter, long i, float xval) {
     
    
         if (iter == 1) {
            float shouldbe = i;
            if (fabs(xval/shouldbe) > 1.01 || fabs(xval/shouldbe) < .99 )
              std::cout<<"incorrect : x["<<i<<"] at iteration "<<iter<<" should be "<<shouldbe<<" not "<<xval<<std::endl;
    
      }
    
      
    
        if (iter == 2) {
            float shouldbe =(i-1)*i/2;
            if (fabs(xval/shouldbe) > 1.01 || fabs(xval/shouldbe) < .99)
              std::cout<<"incorrect : x["<<i<<"] at iteration "<<iter<<" should be "<<shouldbe<<" not "<<xval<<std::endl;
          }
    
    }
    
    //perform dense y=Ax on an n \times n matrix
    void matmul(float*A, float*x, float*y, long n) {
     
    
         int rank;
          int size;
        
            MPI_Comm_rank (MPI_COMM_WORLD, &rank);
            MPI_Comm_size (MPI_COMM_WORLD, &size); 
            float* localresult = new float[n / size]{};
            float matrix [n][n];   //local matrix
            MPI_Barrier(MPI_COMM_WORLD);
            MPI_Scatter(A, (n*n)/size, MPI_FLOAT, matrix, (n*n)/size, MPI_FLOAT, 0, MPI_COMM_WORLD); //Scatter the Matrix
            MPI_Bcast(x, n, MPI_FLOAT, 0, MPI_COMM_WORLD);
          for (long row = 0; row<n/size; row++) {
          //  float sum = 0;
            
            for (long col = 0; col<n; ++col) {
              //sum += x[col] *A[row][col]
           //    sum += x[col] * A[row*n+col];
                localresult[row]+=x[col]*matrix[row][col];
            }
            
          }
        MPI_Gather(localresult,(n)/size,MPI_FLOAT,y,(n)/size,MPI_FLOAT,0,MPI_COMM_WORLD);
    
    }
    
    int main (int argc, char*argv[]) {
    
      
    
        if (argc < 3) {
            std::cout<<"usage: "<<argv[0]<<" <n> <iteration>"<<std::endl;
          }
        
          bool check = true;
          
          long n = atol(argv[1]);
        
          long iter = atol(argv[2]);
         int my_rank;
         int nprocs;
        
         MPI_Init(&argc,&argv);
         MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
         MPI_Comm_rank(MPI_COMM_WORLD,&my_rank); 
        
         MPI_Barrier(MPI_COMM_WORLD);
         
         float* A = new float[n*n];
        
          for (long row = 0; row<n; row++) {
            for (long col=0; col<n; col++) {
              A[row*n+col] = genA(row, col);
            }
          }
        
          float* x = new float[n];
        
          for (long i=0; i<n; ++i)
            x[i] = genx0(i);
          float* y = new float[n];
        
          std::chrono::time_point<std::chrono::system_clock> start = std::chrono::system_clock::now();
        
         // MPI_Allgather(local_vec, local_vec_size, MPI_INT,x, local_vec_size, MPI_INT, MPI_COMM_WORLD);
    
    
      for (int it = 0; it<iter; ++it) {
      
      
    
          matmul(A, x, y, n);
        
            {
              float*t = x;
              x=y;
              y=t;
            }
        
        
            if (check)
              for (long i = 0; i<n; ++i)
            checkx (it+1, i, x[i]);
          }
          
          std::chrono::time_point<std::chrono::system_clock> end = std::chrono::system_clock::now();
        
          std::chrono::duration<double> elapsed_seconds = end-start;
        
          std::cerr<<elapsed_seconds.count()<<std::endl;
        
          
          
          delete[] A;
          delete[] x;
          delete[] y;
          MPI_Finalize();
          return 0;
    
    }

case #1: mpirun -np 1 ./mpi_matmul 720 1

i get expected result

case #2: mpirun -np 1 ./mpi_matmul 2880 1

result:
===================================================================================
=   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
=   PID 1623250 RUNNING AT stage
=   EXIT CODE: 139
=   CLEANING UP REMAINING PROCESSES
=   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11)
This typically refers to a problem with your application.
Please see the FAQ page for debugging suggestions

can anyone point me on what i am doing wrong please. thank you

talonmies
  • 70,661
  • 34
  • 192
  • 269
  • You should remove all unnecessary blank lines from your code to make it more readable. – Daniel Langr Dec 02 '21 at 09:16
  • Also, I would suggest to use `std::vector` instead of `new[]`. – Daniel Langr Dec 02 '21 at 09:17
  • `float matrix [n][n];` This is not allowed in C++ and, even if supported by your implementation, may easily result in stack overflow (typically manifested as segfault). See: https://stackoverflow.com/q/1887097/580083 and https://stackoverflow.com/q/1847789/580083. In you case, `matrix` requires over 33 MB, which likely exceeds the limit of the stack. – Daniel Langr Dec 02 '21 at 09:19
  • Thank you guys for your help. i appreciate . – patrick sano Dec 02 '21 at 13:11

0 Answers0