title: How to multiply matrix using parallel computers (MPI)
body: <p>I am trying very hard to get my code to run using MPI. I am trying to achieve matrix multiplication.</p>
  
  <p>My code is like this</p>
  
  <ol>
  <li><p>There are two matrices A and B</p></li>
  <li><p>Scatter the rows of A</p></li>
  <li><p>Broadcast matrix B</p></li>
  <li><p>Compute</p></li>
  <li><p>Gather</p></li>
  </ol>
  
  <p>I have written the code...but the code is not running right... I am getting segmentation fault.</p>
  
  <p>I have no idea why this is happening...I tried tweaking the code a lot ...but it seems something is always wrong.</p>
  
  <p>Could some one go over this code and tell me why the code is not working?</p>
  
  <p>I have added the comments:</p>
  
  <p>"Scattering matrices"</p>
  
  <p>"Gathering answers" and so on...so even if you could just go through the scatter part of the program and tell me why it is not right, I'll be thankful!</p>
  
  <pre><code>#define N 512
  #include &lt;stdio.h&gt;
  #include &lt;math.h&gt;
  #include &lt;sys/time.h&gt;
  #include "mpi.h"
  void print_results(char *prompt, float result[N][N]);
  int main(int argc, char *argv[])
  {
  int i, j, k;
  MPI_Status status;
  int process_rank;//rank of a process
  int no_of_processes;//no. of processes
  
  int Master_To_Slave = 0;
  int Slave_To_Master = 5;
  
  float a[N][N], b[N][N], c[N][N];
  char *usage = "Usage: %s file\n";
  FILE *fd;
  double elapsed_time, start_time, end_time;
  struct timeval tv1, tv2;
  if (argc &lt; 2) {
  fprintf (stderr, usage, argv[0]);
  return -1;
  }
  if ((fd = fopen (argv[1], "r")) == NULL) {
  fprintf (stderr, "%s: Cannot open file %s for reading.\n",
  argv[0], argv[1]);
  fprintf (stderr, usage, argv[0]);
  return -1;
  }
  // Read input from file for matrices a and b.
  // The I/O is not timed because this I/O needs
  // to be done regardless of whether this program
  // is run sequentially on one processor or in
  // parallel on many processors. Therefore, it is
  // irrelevant when considering speedup.
  for (i = 0; i &lt; N; i++)
  {
      for (j = 0; j &lt; N; j++)
          {
              fscanf (fd, "%f", &amp;a[i][j]);
  
          }
  }
  for (i = 0; i &lt; N; i++)
      for (j = 0; j &lt; N; j++)
          fscanf (fd, "%f", &amp;b[i][j]);
  
  int num_of_rows_A = N;
  int num_of_cols_A = N;
  
  int num_of_rows_B = N;
  int num_of_cols_B = N;
  
  int lower_index_of_A;
  int upper_index_of_A;
  
  //TODO: Add a barrier prior to the time stamp.
  MPI_Init(&amp;argc, &amp;argv); //initialize MPI operations
  MPI_Barrier(MPI_COMM_WORLD); //Added Barrier
  
  
  // Take a time stamp
  gettimeofday(&amp;tv1, NULL);
  
  //TODO: Scatter the input matrices a and b.
  
  
      MPI_Comm_rank(MPI_COMM_WORLD, &amp;process_rank); //get the rank
      MPI_Comm_size(MPI_COMM_WORLD, &amp;no_of_processes); //get number of processes
  
      if(process_rank==0){
          fprintf (stderr, "Main process started");
          fprintf (stderr, "No. of process %d",no_of_processes);
          fprintf (stderr, "\n\n");
          fprintf (stderr, "\n\n");
  
      for( i=1; i&lt;no_of_processes;i++)
      {
          int rows_per_process = num_of_rows_A/(no_of_processes-1);
  
           lower_index_of_A = (i-1)*rows_per_process;
         // fprintf (stderr, "Current lower Index of A %s",lower_index_of_A);
  
          if(i+1==no_of_processes &amp;&amp;((num_of_rows_A%(no_of_processes-1))!=0))
          {
              upper_index_of_A=num_of_rows_A; 
             // fprintf (stderr, "Current upper Index of A %s",upper_index_of_A);
          }
          else
          {         
              upper_index_of_A=lower_index_of_A+rows_per_process;
             // fprintf (stderr, "Current upper Index of A %s",upper_index_of_A);
          }
          fprintf (stderr, "Lower index of A %d", lower_index_of_A);
          fprintf (stderr, "Upper index of A %d", upper_index_of_A);
          fprintf (stderr, "\n\n");
  
          MPI_Send(&amp;lower_index_of_A,1,MPI_INT,i,Master_To_Slave,MPI_COMM_WORLD); //send lower index
          MPI_Send(&amp;upper_index_of_A,1,MPI_INT,i,Master_To_Slave+1,MPI_COMM_WORLD);//send upper  index
  
          MPI_Send(&amp;a[lower_index_of_A][0],(upper_index_of_A-lower_index_of_A)*num_of_cols_A,MPI_DOUBLE,i,Master_To_Slave+2,MPI_COMM_WORLD);//send rows of A
          fprintf (stderr, "Scatter done");
  
      }
      MPI_Bcast(&amp;b, num_of_rows_A*num_of_cols_B, MPI_DOUBLE, 0, MPI_COMM_WORLD);
      fprintf (stderr, "Broadcast done");
      }
      else
      {
  
  
          MPI_Recv(&amp;lower_index_of_A, 1, MPI_INT, 0, Master_To_Slave,MPI_COMM_WORLD, &amp;status);
  
          MPI_Recv(&amp;upper_index_of_A, 1, MPI_INT, 0, Master_To_Slave+1,MPI_COMM_WORLD,&amp;status);
  
          MPI_Recv(&amp;a[lower_index_of_A], (upper_index_of_A-lower_index_of_A)*num_of_cols_A, MPI_DOUBLE,0, Master_To_Slave+2,MPI_COMM_WORLD, &amp;status);
  
          //TODO: Add code to implement matrix multiplication (C=AxB) in parallel.
  
  
          for( i=lower_index_of_A;i&lt;upper_index_of_A;i++)
          {
              for( j=0;j&lt;num_of_cols_B;j++)
              {
                  for( k=0;k&lt;num_of_rows_B;k++)
                  {
  
                      c[i][j]+=(a[i][k]*b[k][j]);
  
                  }
              }
          }
  
          MPI_Send(&amp;lower_index_of_A, 1, MPI_INT, 0, Slave_To_Master,MPI_COMM_WORLD);
          MPI_Send(&amp;upper_index_of_A, 1, MPI_INT, 0, Slave_To_Master+1,MPI_COMM_WORLD);
          MPI_Send(&amp;c[lower_index_of_A], (upper_index_of_A-lower_index_of_A)*num_of_cols_B, MPI_DOUBLE,0, Slave_To_Master+2,MPI_COMM_WORLD);
      }
  
  
  
  
  //TODO: Gather partial result back to the master process.
      if(process_rank==0)
      {   
          for(i=1;i&lt;no_of_processes;i++)
          {
  
              MPI_Recv(&amp;lower_index_of_A, 1, MPI_INT, i, Slave_To_Master, MPI_COMM_WORLD, &amp;status);
              //receive upper bound from a slave
              MPI_Recv(&amp;upper_index_of_A, 1, MPI_INT, i, Slave_To_Master + 1, MPI_COMM_WORLD, &amp;status);
              //receive processed data from a slave
              MPI_Recv(&amp;c[lower_index_of_A][0], (upper_index_of_A - lower_index_of_A) * num_of_cols_B, MPI_DOUBLE, i, Slave_To_Master + 2, MPI_COMM_WORLD, &amp;status);
          }
  
      }
  
  
  
  
  // Take a time stamp. This won't happen until after the master
  // process has gathered all the input from the other processes.
  gettimeofday(&amp;tv2, NULL);
  elapsed_time = (tv2.tv_sec - tv1.tv_sec) +
  ((tv2.tv_usec - tv1.tv_usec) / 1000000.0);
  printf ("elapsed_time=\t%lf (seconds)\n", elapsed_time);
  // print results
  print_results("C = ", c);
  }
  void print_results(char *prompt, float result[N][N])
  {
  int i, j;
  printf ("\n\n%s\n", prompt);
  for (i = 0; i &lt; N; i++) {
  for (j = 0; j &lt; N; j++) {
  printf(" %.2f", result[i][j]);
  }
  printf ("\n");
  }
  printf ("\n\n");
  }
  </code></pre>