0

I am trying to create three matrices a,b,c where c = a*b with using MPI. Also, I am taking the length of these matrices as N (common for all) as it I have to create a square matrix. However, whenever I enter the value of N in runtime, I am getting a segmentation fault error and if I put I gave the value of N in the program, then it works fine.

I have tried this with scatter and gather as given it in here: matrix multiplication using Mpi_Scatter and Mpi_Gather . Now I have to di dynamically, so that can check the time consumption done by the program to execute it. Just want to inform that I have done this OpenMP, and which was great, but want to compare which one is really good i.e. OpenMP or MPI.

#include <iostream>
#include <math.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stddef.h>
#include "mpi.h"


int main(int argc, char *argv[])
{
    int i, j, k, rank, size, tag = 99, blksz, sum = 0,N=0;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    int aa[N],cc[N];
    if(rank ==0)
    {
      std::cout << "input value of N" << '\n';
      std::cin >> N;
    }
    MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);

    int **a = new int*[N];
    for (int i = 0; i < N; i++)
        a[i] = new int[N];

    int **b = new int*[N];
    for (int i = 0; i < N; i++)
        b[i] = new int[N];

    int **c = new int*[N];
    for (int i = 0; i < N; i++)
        c[i] = new int[N];

        if (rank == 0)
        {

            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                        a[i][j] =rand() % 10;
                        std::cout << a[i][j];
                }
                std::cout << '\n';
            }

            std::cout << '\n';

            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                        b[i][j] =rand() % 10;
                        std::cout << b[i][j];
                }
                std::cout << '\n';
            }
        }

    MPI_Scatter(a, N*N/size, MPI_INT, aa, N*N/size, MPI_INT,0,MPI_COMM_WORLD);

    //broadcast second matrix to all processes
    MPI_Bcast(b, N*N, MPI_INT, 0, MPI_COMM_WORLD);

    MPI_Barrier(MPI_COMM_WORLD);

          //perform vector multiplication by all processes
          for (i = 0; i < N; i++)
          {
                    for (j = 0; j < N; j++)
                    {
                            sum = sum + aa[j] * b[j][i];  //MISTAKE_WAS_HERE
                    }
                    cc[i] = sum;
                    sum = 0;
            }

    MPI_Gather(cc, N*N/size, MPI_INT, c, N*N/size, MPI_INT, 0, MPI_COMM_WORLD);

    MPI_Barrier(MPI_COMM_WORLD);

    MPI_Finalize();


    if (rank == 0)                         //I_ADDED_THIS
    {
      for (i = 0; i < N; i++) {
              for (j = 0; j < N; j++)
              {
                      std::cout << a[i][j]<< '\n';
              }
              std::cout << '\n';
      }
      std::cout << '\n' << '\n';

    }
    delete *a;
    delete *b;
    delete *c;
}


The error which I am getting is:

mpirun noticed that process rank 3 with PID 3580 on node localhost exited on signal 11 (Segmentation fault).

I just wanted here that matrix multiplication to be done.

Saurabh Bade
  • 162
  • 2
  • 15
  • 1
    You need to allocate your arrays in contiguous memory(you are using jagged arrays instead). A quick search on SO will point you to brilliantly answered similar questions. – Gilles Gouaillardet Jul 16 '19 at 22:06

1 Answers1

1

Declaring array like this

 int **a = new int*[N];
    for (int i = 0; i < N; i++)
        a[i] = new int[N]; 

will not allocate it in contiguous memory location. Replacing above declaration with one of the following will make the application work.

 int a[N][N]; // or
 int **a=malloc(N*N*sizeof(int));

MPI_Scatter, Gather etc works on arrays with contiguous memory location.

#include <iostream>
#include <math.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stddef.h>
#include "mpi.h"


int main(int argc, char *argv[])
{
    int i, j, k, rank, size, tag = 99, blksz, sum = 0,N=0;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    if(rank ==0)
    {
      std::cout << "input value of N" << '\n';
      std::cin >> N;
    }
    MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
int size_array=(N*N)/size;
int aa[size_array],cc[size_array]; // Declare arrays here since value of N is 0 otherwise 
    int a[N][N];
    int b[N][N];
    int c[N][N];
    for (int i = 0; i < N; i++)
        c[i] = new int[N];

        if (rank == 0)
        {

            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                        a[i][j] =rand() % 10;
                        std::cout << a[i][j];
                }
                std::cout << '\n';
            }

            std::cout << '\n';

            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                        b[i][j] =rand() % 10;
                        std::cout << b[i][j];
                }
                std::cout << '\n';
            }
        }

    MPI_Scatter(a, N*N/size, MPI_INT, aa, N*N/size, MPI_INT,0,MPI_COMM_WORLD);

    //broadcast second matrix to all processes
    MPI_Bcast(b, N*N, MPI_INT, 0, MPI_COMM_WORLD);

    MPI_Barrier(MPI_COMM_WORLD);

          //perform vector multiplication by all processes
          for (i = 0; i < N; i++)
          {
                    for (j = 0; j < N; j++)
                    {
                            sum = sum + aa[j] * b[j][i];  //MISTAKE_WAS_HERE
                    }
                    cc[i] = sum;
                    sum = 0;
            }

    MPI_Gather(cc, N*N/size, MPI_INT, c, N*N/size, MPI_INT, 0, MPI_COMM_WORLD);

    MPI_Barrier(MPI_COMM_WORLD);

    MPI_Finalize();


    if (rank == 0)                         //I_ADDED_THIS
    {
      for (i = 0; i < N; i++) {
              for (j = 0; j < N; j++)
              {
                      std::cout << a[i][j]<< '\n';
              }
              std::cout << '\n';
      }
      std::cout << '\n' << '\n';

    }
}

Also declare the array int aa[N],cc[N]; after the scanf.

j23
  • 3,139
  • 1
  • 6
  • 13
  • I was trying to do this in C++, however, I go back and will do it in C. Thank you so much. – Saurabh Bade Jul 19 '19 at 04:19
  • Just want to inform that it is not working, getting **segmentation fault ** error. – Saurabh Bade Jul 20 '19 at 23:24
  • @SaurabhBade it's working without segmentation fault for me. Let me try with some other input values to see whether I get any errors or not. – j23 Jul 22 '19 at 08:47
  • 1
    @SaurabhBade Segmentation fault was due to the declaration of array aa and cc with size N. Size should be N*N/size i.e Total number of elements divided by the number of processes. I have changed it in the code. – j23 Jul 22 '19 at 09:19