title: MPI Gather Corrupting Arrays
body: <p>I have written an MPI code in C++ for my Raspberry Pi cluster, which generates an image of the Mandelbrot Set. What happens is on each node (excluding the master, processor 0) part of the Mandelbrot Set is calculated, resulting in each node having a 2D array of ints that indicates whether each xy point is in the set.</p>
  
  <p>It appears to work well on each node individually, but when all the arrays are gathered to the master using this command:
  MPI_Gather(&amp;inside, 1, MPI_INT, insideFull, 1, MPI_INT, 0, MPI_COMM_WORLD);
  it corrupts the data, and the result is an array full of garbage.
  (inside is the nodes' 2D arrays of part of the set. insideFull is also a 2D array but it holds the whole set)
  Why would it be doing this?</p>
  
  <p>(This led to me wondering if it corrupting because the master isn't sending its array to itself (or at least I don't want it to). So part of my question also is is there an MPI_Gather variant that doesn't send anything from the root process, just collects from everything else?)</p>
  
  <p>Thanks</p>
  
  <p>EDIT: here's the whole code. If anyone can suggest better ways of how I'm transferring the arrays, please say.</p>
  
  <pre><code>#include &lt;mpi.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  
  
  // ONLY USE MULTIPLES OF THE NUMBER OF SLAVE PROCESSORS
  #define ImageHeight  128
  #define ImageWidth   128
  
  double MinRe = -1.9;
  double MaxRe = 0.5;
  double MinIm = -1.2;
  double MaxIm = MinIm + (MaxRe - MinRe)*ImageHeight / ImageWidth;
  
  double Re_factor = (MaxRe - MinRe) / (ImageWidth - 1);
  double Im_factor = (MaxIm - MinIm) / (ImageHeight - 1);
  unsigned n;
  
  unsigned MaxIterations = 50;
  
  int red;
  int green;
  int blue;
  
  // MPI variables ****
  int processorNumber;
  int processorRank;
  //*******************//
  
  int main(int argc, char** argv) {
  
    // Initialise MPI
    MPI_Init(NULL, NULL);
  
    // Get the number of procesors
    MPI_Comm_size(MPI_COMM_WORLD, &amp;processorNumber);
  
    // Get the rank of this processor
    MPI_Comm_rank(MPI_COMM_WORLD, &amp;processorRank);
  
    // Get the name of this processor
    char processorName[MPI_MAX_PROCESSOR_NAME];
    int name_len;
    MPI_Get_processor_name(processorName, &amp;name_len);
  
    // A barrier just to sync all the processors, make timing more accurate
    MPI_Barrier(MPI_COMM_WORLD);
  
    // Make an array that stores whether each point is in the Mandelbrot Set
    int inside[ImageWidth / processorNumber][ImageHeight / processorNumber];
  
    if(processorRank == 0) {
      printf("Generating Mandelbrot Set\n");
    }
  
    // We don't want the master to process the Mandelbrot Set, only the slaves
    if(processorRank != 0) {
      // Determine which coordinates to test on each processor
      int xMin = (ImageWidth / (processorNumber - 1)) * (processorRank - 1);
      int xMax = ((ImageWidth / (processorNumber - 1)) * (processorRank - 1)) - 1;
      int yMin = (ImageHeight / (processorNumber - 1)) * (processorRank - 1);
      int yMax = ((ImageHeight / (processorNumber - 1)) * (processorRank - 1)) - 1;
  
      // Check each value to see if it's in the Mandelbrot Set
      for (int y = yMin; y &lt;= yMax; y++) {
        double c_im = MaxIm - y  *Im_factor;
        for (int x = xMin; x &lt;= xMax; x++) {
          double c_re = MinRe + x*Re_factor;
          double Z_re = c_re, Z_im = c_im;
          int isInside = 1;
          for (n = 0; n &lt;= MaxIterations; ++n) {
            double Z_re2 = Z_re * Z_re, Z_im2 = Z_im * Z_im;
            if (Z_re2 + Z_im2 &gt; 10) {
              isInside = 0;
              break;
            }
            Z_im = 2 * Z_re * Z_im + c_im;
            Z_re = Z_re2 - Z_im2 + c_re;
          }
          if (isInside == 1) {
            inside[x][y] = 1;
          }
          else{
            inside[x][y] = 0;
          }
        }
      }
    }
  
    // Wait for all processors to finish computing
    MPI_Barrier(MPI_COMM_WORLD);
  
    int insideFull[ImageWidth][ImageHeight];
  
    if(processorRank == 0) {
      printf("Sending parts of set to master\n");
    }
  
    // Send all the arrays to the master
    MPI_Gather(&amp;inside[0][0], 1, MPI_INT, &amp;insideFull[0][0], 1, MPI_INT, 0, MPI_COMM_WORLD);
  
    // Output the data to an image
    if(processorRank == 0) {
      printf("Generating image\n");
      FILE * image = fopen("mandelbrot_set.ppm", "wb");
      fprintf(image, "P6 %d %d 255\n", ImageHeight, ImageWidth);
      for(int y = 0; y &lt; ImageHeight; y++) {
        for(int x = 0; x &lt; ImageWidth; x++) {
          if(insideFull[x][y]) {
            putc(0, image);
            putc(0, image);
            putc(255, image);
          }
          else {
            putc(0, image);
            putc(0, image);
            putc(0, image);
          }
          // Just to see what values return, no actual purpose
          printf("%d, %d, %d\n", x, y, insideFull[x][y]);
        }
      }
      fclose(image);
      printf("Complete\n");
    }
  
    MPI_Barrier(MPI_COMM_WORLD);
  
    // Finalise MPI
    MPI_Finalize();
  }
  </code></pre>