title: MPI C++ Runtime Error: signal 11 (Segmentation fault) with multi-dimensional array creation
body: <h1>Making Mandelbrot with MPI</h1>
  <p>So I've made a Mandelbrot generator and everything worked fine. Now I'm throwing in a speedup from MPI. Process 0 generates a file name <code>mbrot.ppm</code> and adds the appropriate metadata, then divides up the workload into chunks.</p>
  <p>Each process receives the chunk's starting and ending positions and gets to work calculating its portion of the Mandelbrot set. To write to the <code>mbrot.ppm</code> file, each process saves its data in an array so it doesn't write to the file before the previous process finishes.</p>
  <h2>My Problem</h2>
  <p>Its a runtime error that says:</p>
  <pre><code>Primary job terminated normally, but 1 process returned
  a non-zero exit code. Per user-direction, the job has been aborted.
  --------------------------------------------------------------------------
  --------------------------------------------------------------------------
  mpirun noticed that process rank 0 with PID 0 on node Lenovo exited on signal 11 (Segmentation fault).
  </code></pre>
  <p>I believe it comes from the line <code>int data[3][xrange][yrange];</code> (line 120) since the print statement after this line never executes. Would there be an obvious reason I'm missing why this multi-dimensional array is causing me problems?</p>
  <h2>Full Code</h2>
  <pre><code>#include &lt;iostream&gt;
  
  #include &lt;mpi.h&gt;
  
  #include &lt;unistd.h&gt;
  
  #include &lt;stdlib.h&gt;
  
  #include &lt;math.h&gt;
  
  #include &lt;fstream&gt;
  
  #define MCW MPI_COMM_WORLD
  
  using namespace std;
  
  struct Complex {
    double r;
    double i;
  };
  
  Complex operator + (Complex s, Complex t) {
    Complex v;
    v.r = s.r + t.r;
    v.i = s.i + t.i;
    return v;
  };
  
  Complex operator * (Complex s, Complex t) {
    Complex v;
    v.r = s.r * t.r - s.i * t.i;
    v.i = s.r * t.i + s.i * t.r;
    return v;
  };
  
  int rcolor(int iters) {
    if (iters == 255) return 0;
    return 32 * (iters % 8);
  };
  
  int gcolor(int iters) {
    if (iters == 255) return 0;
    return 32 * (iters % 8);
  };
  
  int bcolor(int iters) {
    if (iters == 255) return 0;
    return 32 * (iters % 8);
  };
  
  int mbrot(Complex c, int maxIters) {
  
    int i = 0;
    Complex z;
    z = c;
    while (i &lt; maxIters &amp;&amp; z.r * z.r + z.i * z.i &lt; 4) {
      z = z * z + c;
      i++;
    }
    return i;
  
  };
  
  int main(int argc, char * argv[]) {
  
    int rank, size;
  
    MPI_Init( &amp; argc, &amp; argv);
    MPI_Comm_rank(MCW, &amp; rank);
    MPI_Comm_size(MCW, &amp; size);
  
    if (size &lt; 2) {
      printf(&quot;Not an MPI process if only 1 process runs.\n&quot;);
      exit(1);
    }
    if (size % 2 != 0) {
      printf(&quot;Please use a even number\n&quot;);
      exit(1);
    }
  
    Complex c1, c2, c;
    char path[] = &quot;brot.ppm&quot;;
    int DIM;
    int chunk[4];
    c1.r = -1;
    c1.i = -1;
    c2.r = 1;
    c2.i = 1;
  
    if (rank == 0) { //start the file
      ofstream fout;
      fout.open(path);
      DIM = 2000; // pixel dimensions
      fout &lt;&lt; &quot;P3&quot; &lt;&lt; endl; // The file type .ppm
      fout &lt;&lt; DIM &lt;&lt; &quot; &quot; &lt;&lt; DIM &lt;&lt; endl; // dimensions of the image
      fout &lt;&lt; &quot;255&quot; &lt;&lt; endl; // color depth
      fout.close();
  
      // making dimesions marks
      for (int i = 0; i &lt; size; i++) {
        chunk[0] = 0; // startX
        chunk[1] = DIM; // endX
        chunk[2] = (DIM / size) * i; // startY
        chunk[3] = (DIM / size) * (i + 1); // endY
  
        MPI_Send(chunk, 4, MPI_INT, i, 0, MCW);
      };
  
    };
  
    MPI_Recv(chunk, 4, MPI_INT, 0, 0, MCW, MPI_STATUS_IGNORE);
  
    printf(&quot;Process %d recieved chunk\n\t StartX: %d, EndX: %d\n\t StartY: %d, EndY: %d\n&quot;, rank, chunk[0], chunk[1], chunk[2], chunk[3]);
  
    // do stuff save in array
    // data[3 elements][Xs][Ys]
    int xrange = chunk[1] - chunk[0];
    int yrange = chunk[3] - chunk[2];
    printf(&quot;Process %d, x: %d, y: %d\n&quot;, rank, xrange, yrange);
    int data[3][xrange][yrange];
    printf(&quot;done\n&quot;);
  
    // generate data for mandlebrot
    for (int j = chunk[2]; j &lt; chunk[3]; ++j) {
      for (int i = chunk[0]; i &lt; chunk[1]; ++i) {
        // calculate one pixel of the DIM x DIM image
        c.r = (i * (c1.r - c2.r) / DIM) + c2.r;
        c.i = (j * (c1.i - c2.i) / DIM) + c2.i;
        int iters = mbrot(c, 255);
        data[0][i][j] = rcolor(iters);
        data[1][i][j] = gcolor(iters);
        data[2][i][j] = bcolor(iters);
      }
    }
    printf(&quot;here2\n&quot;);
  
    // taking turns to write their data to file
    for (int k = 0; k &lt; size; k++) {
      if (rank == k) {
        ofstream fout;
        fout.open(path, ios::app);
        fout &lt;&lt; rank &lt;&lt; &quot; was here&quot; &lt;&lt; endl;
  
        for (int j = chunk[2]; j &lt; chunk[3]; ++j) {
          for (int i = chunk[0]; i &lt; chunk[1]; ++i) {
            fout &lt;&lt; data[0][i][j] &lt;&lt; &quot; &quot; &lt;&lt; data[1][i][j] &lt;&lt; &quot; &quot; &lt;&lt; data[2][i][j] &lt;&lt; &quot; &quot;;
          }
          fout &lt;&lt; endl;
        }
        printf(&quot;Process %d done and waiting\n&quot;, rank);
      } else {
        MPI_Barrier(MCW);
      }
    }
  
    MPI_Finalize();
  };
  </code></pre>
  <h3>How to Run</h3>
  <pre><code>$ mpic++ -o mbrot.out mbrot.cpp
  $ mpirun -np 4 mbrot.out
  </code></pre>