[gomp4] openacc kernels directive support

Tom de Vries Tom_deVries@mentor.com
Wed Aug 6 15:10:00 GMT 2014


Jakub,

I've looked into how to implement the openacc kernels directive in gcc.

In order to map the loopnests marked by the kernels directive efficiently on 
accelerator hardware, we need parallelization and vectorization.

Focussing on paralellization for the moment, a possibility for paralellization 
is to use the parloops pass. The parloops pass identifies loops that can be 
parallelized with a factor n, splits off the n-reduced loop into a function and 
issues the function in n parallel threads.

A problem with using parloops for the kernels directive is that the parloops 
pass is placed after lto's gimple-stream read/write point, so the parloops pass 
is executed during the accelerator-specific compilation. So while the resulting 
function with the reduced loop is compiled for the accelerator as required, also 
the code issuing the function in parallel threads is generated for the 
accelerator. While f.i. newer cuda with dynamic parallelism supports launching 
accelerator kernels from within accelerator kernels, I guess that that might not 
hold in general.

I've investigated moving the parloops pass up in the pass list, using attached 
example kernels.c.  It contains 4 loops; 2 loops that set arrays, one loop that 
does a vector addition, and one loop that does a reduction

First, I compile the example using upstream trunk:
...
$ gcc -ftree-parallelize-loops=32 -fdump-tree-all-all -O2 kernels.c -std=c99 
-Wl,-rpath,$(pwd -P)/lean-c/install/lib64
$ ./a.out ; echo $?
sum: 4293394432
0
...

All 4 loops are recognized as parallel by parloops:
...
$ egrep 'SUCCES|FAIL' kernels.c.*parloops
    SUCCESS: may be parallelized
    SUCCESS: may be parallelized
    SUCCESS: may be parallelized
    SUCCESS: may be parallelized
...

Using attached patch, I manage the same with parloops placed after 
pass_build_ealias, with some additional passes inbetween:
...
           NEXT_PASS (pass_build_ealias);
           NEXT_PASS (pass_ch);
           NEXT_PASS (pass_ccp);
           NEXT_PASS (pass_lim_aux);
           NEXT_PASS (pass_parallelize_loops);
  ...

The pass_lim_aux in front is needed because otherwise the loads of pointers a, b 
and c stay in the loop and prevent parallelization.

The pass_ccp is to get rid of:
...
phi is i_5 = PHI <0(3)>
arg of phi to exit:   value 0 used outside loop
   checking if it a part of reduction pattern:
   FAILED: it is not a part of reduction.
...

The pass_tree_ch is to get rid of:
...
phi is sum_3 = PHI <sum_1(4)>
arg of phi to exit:   value sum_1 used outside loop
   checking if it a part of reduction pattern:
   FAILED: it is not a part of reduction.
...

The place after build_ealias is early enough to be before the lto-stream 
write/read. I don't see how we can do this earlier. Before ealias, there's no 
alias info, and one of the loops fails to be recognized as parallel. 
Furthermore, pass_ch, pass_ccp, pass_lim_aux and pass_parloops are written to 
work on cfg/ssa code, which we don't have at omp_low/omp_exp time.

We could insert a pass-group here that only deals with functions that have the 
kernels directive, and do the auto-par thing in a pass_oacc_kernels (which 
should share the majority of the infrastructure with the parloops pass):
...
           NEXT_PASS (pass_build_ealias);
           INSERT_PASSES_AFTER/WITHIN (passes_oacc_kernels)
              NEXT_PASS (pass_ch);
              NEXT_PASS (pass_ccp);
              NEXT_PASS (pass_lim_aux);
              NEXT_PASS (pass_oacc_par);
           POP_INSERT_PASSES ()
...

Any comments, ideas or suggestions ?

Thanks,
- Tom

-------------- next part --------------
A non-text attachment was scrubbed...
Name: kernels.c
Type: text/x-csrc
Size: 812 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20140806/bc2820eb/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: move-parloops.patch
Type: text/x-patch
Size: 4847 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20140806/bc2820eb/attachment-0001.bin>


More information about the Gcc mailing list