title: OpenMP parallel for loop issue with shared pointer to pointers
body: <p>I am just learning OpenMP and am having a problem parallelizing a for loop that I"m pretty sure meets the criteria for parallelization.  Below is a <a href="http://www.sscce.org/" rel="nofollow">SSCCE</a> that exhibits the issue I'm having in my actual code.</p>
  
  <p>The problem is that when I compile and run this with OpenMP the contents of <strong>wr[i][j]</strong> and <strong>wi[i][j]</strong> are always 1.00 and 0.00 respectively.  If I comment out the pragma and run the code serially then <strong>wr</strong> and <strong>wi</strong> contain the values that I expect.  The code still exhibits the problem even if I run it with just 1 thread after being compiled with OpenMP.  The pragma has to be commented out to run it serially.</p>
  
  <p>I think my problem is related to the fact that <strong>wr</strong> and <strong>wi</strong> are pointers to pointers.  If that's the case, how do I work around it?  If that's not the problem what is?  Any insights are greatly appreciated.</p>
  
  <pre><code>// compilation gcc -fopenmp -o test test.c -lm 
  // usage ./test &lt;Problem Size (Must be a power of 2)&gt; &lt;Num Threads&gt;
  #include &lt;omp.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;math.h&gt;
  
  int main (int argc, char *argv[]){
      double **wr, **wi;  
      double *data;
      double wtemp, wpr, wpi, theta;
      int i, j, n, nn, mmax, istep, num_mmax_iterations, T;
      const int isign = -1;
  
      if(argc &lt; 3){
          printf("ERROR, usage: %s &lt;N (must be a power of 2)&gt; &lt;T&gt;\n", argv[0]);
          exit(1);
      } else {
          n = atoi(argv[1]);
          T = atoi(argv[2]);
      }
  
      num_mmax_iterations = log2(n);
      wr = malloc(sizeof(double *) *num_mmax_iterations);
      wi = malloc(sizeof(double *) *num_mmax_iterations);
  
      mmax = 2;
      for(i = 0; i &lt; num_mmax_iterations; i++) {
          wr[i] = malloc(sizeof(double) * (mmax &gt;&gt; 1));
          wi[i] = malloc(sizeof(double) * (mmax &gt;&gt; 1));
          wr[i][0] = 1.0;
          wi[i][0] = 0.0;
          mmax &lt;&lt;= 1;
      }
  
      mmax = 2;
      #pragma omp parallel for private(i, j, theta, wtemp, wpr, wpi) firstprivate(mmax) shared(num_mmax_iterations, wr, wi) num_threads(T)
      for(i = 0; i &lt; num_mmax_iterations; i++) {
          theta = isign * (6.28318530717959 / mmax);
          wtemp = sin(0.5 * theta);
          wpr = -2.0 * wtemp * wtemp;
          wpi = sin(theta);       
  
          for(j = 1; j &lt; (mmax &gt;&gt; 1); j++) {
              wr[i][j] = wr[i][j - 1] * wpr - wi[i][j - 1] * wpi + wr[i][j - 1];
              wi[i][j] = wi[i][j - 1] * wpr + wr[i][j - 1] * wpi + wi[i][j - 1];
          }
  
          mmax &lt;&lt;= 1;
      }
  
      for(i = 0; i &lt; num_mmax_iterations; i++) {      
          for(j = 0; j &lt; (mmax &gt;&gt; 1); j++) {
              printf("%.2f | %.2f\n", wr[i][j], wi[i][j]);
          }
      }
  
      for(i = 0; i &lt; num_mmax_iterations; i++) {
          free(wr[i]);
          free(wi[i]);
      }
      free(wr);
      free(wi);
      return 0;
  }
  </code></pre>
  
  <p><strong>Edit</strong></p>
  
  <p>Expected output with the pragma removed running ./test 8 1</p>
  
  <pre><code>1.00 | 0.00
  0.00 | 0.00
  0.00 | 1.00
  0.00 | -0.00
  1.00 | 0.00
  -0.00 | -1.00
  0.00 | 1.00
  -1.00 | 0.71
  1.00 | -0.00
  0.71 | -0.71
  -0.00 | 0.00
  -0.71 | -0.71
  0.00 | -1.00
  -0.71 | -0.71
  -1.00 | 1.00
  -0.71 | 0.92
  1.00 | 0.00
  -0.00 | -1.00
  0.00 | 1.00
  -1.00 | 0.71
  1.00 | -0.00
  0.71 | -0.71
  -0.00 | 0.00
  -0.71 | -0.71
  0.00 | -1.00
  -0.71 | -0.71
  -1.00 | 1.00
  -0.71 | 0.92
  1.00 | 0.71
  0.92 | 0.38
  0.71 | -0.00
  0.38 | -0.38
  1.00 | 0.00
  0.71 | -0.71
  -0.00 | -1.00
  -0.71 | -0.71
  0.00 | 1.00
  -0.71 | 0.92
  -1.00 | 0.71
  -0.71 | 0.38
  1.00 | -0.00
  0.92 | -0.38
  0.71 | -0.71
  0.38 | -0.92
  -0.00 | 0.00
  -0.38 | -0.38
  -0.71 | -0.71
  -0.92 | -0.92
  1.00 | 0.00
  0.92 | -0.38
  0.71 | -0.71
  0.38 | -0.92
  -0.00 | -1.00
  -0.38 | -0.92
  -0.71 | -0.71
  -0.92 | -0.38
  0.00 | 0.00
  -0.38 | 0.00
  -0.71 | 0.00
  -0.92 | 0.00
  -1.00 | 0.00
  -0.92 | 0.00
  -0.71 | 0.00
  -0.38 | 0.00
  </code></pre>
  
  <p>Actual output with the pragma left intact running ./test 8 (any number of threads)</p>
  
  <pre><code>1.00 | 0.00
  1.00 | 0.00
  1.00 | 0.00
  </code></pre>
  
  <p>Note: The actual problem sizes are much larger and the expected data usually varies more than it does above.</p>