Changes between Version 10 and Version 11 of OpenMPTransformation


Ignore:
Timestamp:
04/20/14 18:14:33 (12 years ago)
Author:
siegel
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • OpenMPTransformation

    v10 v11  
    118118    int _nthreads = 1+$choose_int(THREAD_MAX);
    119119    $proc _threads[_nthreads];
     120    $omp_gws _gws = $omp_gws_create($here, _nthreads);
    120121    void _thread(int _tid) {
     122      $omp_ws = $omp_ws_create(_gws, _tid);
     123
    121124      translate(S)
    122125    }
     
    134137
    135138Try to determine whether the loop iterations are independent.  In that case, they can all be executed by one thread.
    136 
    137 Otherwise, iterations must be distributed among the threads in some nondeterministic way.  This could blow up rapidly!  Also, a thread does not have to execute its iterations in increasing order.  It can execute them in any order.
    138 
    139 Trying a few different things for now: picking a particular scheduling policy like round-robin (status with chunk size 1).  Of course you can always do this if schedule is specified to be static.
    140 
    141 The question is do we ever want to try to explore these interleavings?
    142 
    143 Is there any loss of generality  by just running all iterations concurrently?
    144 
    145 One approach: assume you have a function or macro `CIVL_owns(n, t, i)`.  It takes three ints and returns a boolean.  The arguments are `n`: the number of threads; `t`: a thread ID between 0 and `n`-1 (inclusive); and `i`, an iteration index.
    146 
    147 {{{
     139Otherwise:
     140
     141{{{
     142// location 23:
    148143#pragma omp parallel for
    149   for (i...)
     144for (i=0; i<n; i++) 
    150145  S
    151146}}}
     
    154149
    155150{{{
    156 for (i...) {
    157   if (CIVL_owns(_nthreads, _tid, i)) {
    158     translate(S)
    159   }
    160 }
    161 barrier (unless no wait)
    162 }}}
    163 
    164 
    165 More general way:
    166 
    167 {{{
    168 
    169   {
    170 
    171 //use distributions
    172   }
    173 
    174 
     151{
     152  $int_iter iter = $omp_ws_arrive_loop(_ws, 23, 0, n-1, 1);
     153
     154  while ($int_iter_hasNext(iter)) {
     155    int i = $int_iter_next(iter);
     156
     157    translate(S);
     158  }
     159}
    175160}}}
    176161
     
    181166
    182167{{{
     168// location 42:
    183169#pragma omp sections
    184   {
    185   #pragma omp section
    186   ...
    187   #pragma omp section
    188   ...
    189   }
    190 }}}
    191 
    192 =>
    193 
    194 {{{
    195   {
    196     void section0() {
    197       ...
    198     }
    199     void section1() {
    200       ...
     170#pragma omp section
     171  S0
     172#pragma omp section
     173  S1
     174...
     175}}}
     176
     177=>
     178
     179{{{
     180{
     181  $int_iter iter = $omp_ws_arrive_sections(ws, 42);
     182
     183  while ($int_iter_hasNext(iter)) {
     184    int _i = $int_iter_next(iter);
     185
     186    switch (_i) {
     187    case 0: {
     188      translate(S0);
     189      break;
     190    }
     191    case 1: {
     192      translate(S1);
     193      break;
    201194    }
    202195    ...
    203     if (CIVL_owns(_nthreads, _tid, 0)
    204       section0();
    205     if (CIVL_owns(_nthreads, _tid, 1)
    206       section1();
    207     ...
    208     barrier unless nowait;
    209   }
    210 }}}
     196    }
     197  }
     198}}}
     199
    211200
    212201=== Translating `single` ===
    213202
    214 Nondeterministically choose a thread, i.e, `$choose_int(threads)`.   That thread executes the code, the rest skip it.
    215 The question is, which thread does the choosing?  The first thread to arrive at that construct?
    216 
    217 Once again, try to determine if it matters.  If the modifications and reads do not involve any private data, it doesn't matter which thread does it, so make it thread 0.
    218 
    219 There is a barrier at the end.
     203{{{
     204// location 33:
     205#pragma omp single
     206S
     207}}}
     208
     209=>
     210
     211{{{
     212if ($omp_arrive_single(ws, 33)) {
     213  translate(S);
     214}
     215}}}
    220216
    221217
    222218=== Translating `barrier` ===
    223219
    224 Provide some system functions for this.   All the threads in the team (threads[i]) register with a barrier object and partake in the barrier.  Can re-use that barrier object for multiple barriers.
     220{{{
     221// location 58:
     222#pragma omp barrier
     223}}}
     224
     225=>
     226
     227{{{
     228$omp_barrier_arrive(ws, 58);
     229$barrier...
     230}}}
    225231
    226232=== Translating `critical` ===