Note that there are some explanatory texts on larger screens.

plurals
  1. POhow to use orphaned for loop in OpenMP?
    primarykey
    data
    text
    <p><strong>SOLVED: see EDIT 2 below</strong></p> <p>I am trying to parallelise an algorithm which does some operation on a matrix (lets call it blurring for simplicity sake). Once this operation has been done, it finds the biggest change between the old and new matrix (max of absolute difference between old and new matrix on a per element basis). If this maximum difference is above some threshold, then do another iteration of the matrix operation.</p> <p>So my main program has the following loop:</p> <pre><code>converged = 0; for( i = 1; i &lt;= iteration_limit; i++ ){ max_diff = update( &amp;data_grid ); if( max_diff &lt; tol ) { converged = 1; break; } } </code></pre> <p><code>update( &amp;data_grid )</code> then calls the actual implementation of the blurring algorithm. The blurring algorithm then iterates over the matrix, it is this loop that I am trying to parallelise:</p> <pre><code>for( i = 0; i &lt; width; i++ ) { for( j = 0; j &lt;= height; j++ ) { g-&gt;data[ update ][ i ][ j ] = ONE_QUARTER * ( g-&gt;data[ update ][ i + 1 ][ j ] + g-&gt;data[ update ][ i - 1 ][ j ] + g-&gt;data[ update ][ i ][ j + 1 ] + g-&gt;data[ update ][ i ][ j - 1 ] + ); diff = fabs( g-&gt;data[ old ][ i ][ j ] - g-&gt;data[ update ][ i ][ j ] ); maxdiff = maxdiff &gt; diff ? maxdiff : diff; } } </code></pre> <p>I could just stick a parallel region inside <code>update(&amp;data_grid)</code> but that would mean threads would be created and destroyed on each iteration which I am trying to avoid.:</p> <pre><code>#pragma omp parallel for private(i, j, diff, maxdg) shared(width, height, update, g, dg, chunksize) default(none) schedule(static, chunksize) </code></pre> <p>I have 2 copies of the grid and write the new answer in the "other one" on every iteration by switching <code>old</code> and <code>update</code> between <code>0</code> and <code>1</code>.</p> <p><strong>EDIT:</strong></p> <p>So I've made an orphaned omp for loop as per Jonathan Dursi's suggestion, but for some reason, can't seem to find the maximum value between threads...</p> <p>Here is my "outer" code:</p> <pre><code> converged = 0; #pragma omp parallel shared(i, max_iter, g, tol, maxdg, dg) private(converged) default(none) { for( i = 1; i &lt;= 40; i++ ){ maxdg = 0; dg = grid_update( &amp;g ); printf("[%d] dg from a single thread: %f\n", omp_get_thread_num(), dg ); #pragma omp critical { if (dg &gt; maxdg) maxdg = dg; } #pragma omp barrier #pragma omp flush printf("[%d] maxdg: %f\n", omp_get_thread_num(), maxdg); if( maxdg &lt; tol ) { converged = 1; break; } } } </code></pre> <p>And the result:</p> <pre><code> [11] dg from a single thread: 0.000000 [3] dg from a single thread: 0.000000 [4] dg from a single thread: 0.000000 [5] dg from a single thread: 0.000000 [0] dg from a single thread: 0.166667 [6] dg from a single thread: 0.000000 [7] dg from a single thread: 0.000000 [8] dg from a single thread: 0.000000 [9] dg from a single thread: 0.000000 [15] dg from a single thread: 0.000000 [10] dg from a single thread: 0.000000 [1] dg from a single thread: 0.166667 [12] dg from a single thread: 0.000000 [13] dg from a single thread: 0.000000 [14] dg from a single thread: 0.000000 [2] maxdg: 0.000000 [3] maxdg: 0.000000 [0] maxdg: 0.000000 [8] maxdg: 0.000000 [9] maxdg: 0.000000 [4] maxdg: 0.000000 [5] maxdg: 0.000000 [6] maxdg: 0.000000 [7] maxdg: 0.000000 [1] maxdg: 0.000000 [14] maxdg: 0.000000 [11] maxdg: 0.000000 [15] maxdg: 0.000000 [10] maxdg: 0.000000 [12] maxdg: 0.000000 [13] maxdg: 0.000000 </code></pre> <p><strong>EDIT 2:</strong> Made some mistakes with the private/shared classifiers and forgot a barrier. This is the correct code:</p> <pre><code> #pragma omp parallel shared(max_iter, g, tol, maxdg) private(i, dg, converged) default(none) { for( i = 1; i &lt;= max_iter; i++ ){ #pragma omp barrier maxdg=0; /*#pragma omp flush */ dg = grid_update( &amp;g ); #pragma omp critical { if (dg &gt; maxdg) maxdg = dg; } #pragma omp barrier /*#pragma omp flush*/ if( maxdg &lt; tol ) { converged = 1; break; } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload