title: MPI Matrix Multiplication with scatter gather
body: <p>I'm trying to do matrix multiplication using MPI in C and we have to do a version that sequential and one parallel version.  My parallel version is not giving the correct answers and I'm not sure why.  I think I'm not sending the right communications to the processes but I can't be sure.  The professor just went over the different send/receive/gather etc messages, but didn't really get into much detail...  I've seen a lot of different examples but none complete and none using scatter/gather.  If anyone can take a look at my code and tell me if anything pops out at them I'd appreciate it.  I'm pretty sure my problem is in the scatter/gather messages or the actual calculation of the c matrix.</p>
  
  <pre><code>#define N 512
  
  #include &lt;stdio.h&gt;
  #include &lt;math.h&gt;
  #include &lt;sys/time.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;stddef.h&gt;
  #include "mpi.h"
  
  
  print_results(char *prompt, float a[N][N]);
  
  int main(int argc, char *argv[])
  {
      int i, j, k, rank, size, tag = 99, blksz, sum = 0;
      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;
  
      MPI_Init(&amp;argc, &amp;argv);
      MPI_Comm_size(MPI_COMM_WORLD, &amp;size);
      MPI_Comm_rank(MPI_COMM_WORLD, &amp;rank);
  
      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;
      }
  
      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]);
  
      MPI_Barrier(MPI_COMM_WORLD);
  
      gettimeofday(&amp;tv1, NULL);
  
      MPI_Scatter(a, N*N/size, MPI_INT, a, N*N/size, MPI_INT, 0,
                                                      MPI_COMM_WORLD);
      MPI_Bcast(b, N*N, MPI_INT, 0, MPI_COMM_WORLD);
  
  
      if (rank != 0) {
              for (i = 0; i &lt; N; i++)
              {
                      for (j = 0; j &lt; N; j++)
                      {
                              for (k = 0; k &lt; N; k++)
                              {
                                      sum = sum + a[i][k] * b[k][j];
                              }
                              c[i][j] = sum;
                              sum = 0;
                      }
              }
      }
  
      MPI_Gather(c, N*N/size, MPI_INT, c, N*N/size, MPI_INT, 0,
                                                       MPI_COMM_WORLD);
      MPI_Finalize();
  
      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("C = ", c);
  }
  
  print_results(char *prompt, float a[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", a[i][j]);
              }
              printf ("\n");
      }
      printf ("\n\n");
  }
  </code></pre>
  
  <p>updated part of code:</p>
  
  <pre><code>for (i=0;i&lt;size; i++)
              {
                      if (rank == i)
                      {
                              for (i = rank*(N/size); i &lt; (rank*(N/size)+(N/size)); i++)
                              {
                                      for (j = rank*(N/size); j &lt; (rank*(N/size)+(N/size)); j++)
                                      {
                                              for (k = rank*N; k &lt; rank*N+N; k++)
                                              {
                                                      sum = sum + a[i][k] * b[k][j];
                                              }
                                              c[i][j] = sum;
                                              sum = 0;
                                      }
                              }
                      }
              }
  </code></pre>