Preprocessing and directives(omp/acc)

I’m trying to design code which uses controls OPM or ACC based on a configuration-wide preprocessor symbol.

#ifdef GPU_SOLVE
#  define CPU_Omp NO_omp
#else
#  define CPU_Omp omp
#endif

... <snip> ...

        !$acc wait(31)
        !$CPU_Omp do  PRIVATE_VARS
        !$acc kernels async(41)
        !$acc loop collapse(3) &
        !$acc      private(i_pml,i_x,i_y)
        do i_pml=2,theGrid % n_pml_bounds-1
            do i_y=1+1,theGrid % n_y-1
                do i_x=1+1,theGrid % n_x-1
                    g_z(i_x,i_y,i_pml,1) = g_z(i_x,i_y,i_pml,2)
                enddo
            enddo
        enddo
        !$acc end kernels 
        !$CPU_Omp end do
...<snip>...

This does not behave as I expect: no matter whether GPU_SOLVE is defined or not, (and although I have preprocessing enabled), the !$CPU_omp is not replaced before hitting the directives processing.

(a) Do omp/acc directives get processed before the preprocessor?
(b) If not, why does the preprocessor not replace these instances of the defined symbol?
(c) Is there available documentation on the order of events during pgfort compilation?

(b) If not, why does the preprocessor not replace these instances of the defined symbol?

The Fortran preprocesser wont replace symbols in comments. You can use cpp instead (i.e. add -Mcpp) but this will only preprocess files (.f90 → .f) so you’d need to adapt your build process to separate out the preprocess step from the compile step.

Though, the easiest thing to do would be to simply put the “!$” in your define. Something like:

#ifdef GPU_SOLVE 
#  define CPU_Omp !NO_omp 
#else 
#  define CPU_Omp !$omp 
#endif 

... <snip> ... 

        !$acc wait(31) 
        CPU_Omp do  PRIVATE_VARS 
        !$acc kernels async(41) 
        !$acc loop collapse(3) & 
        !$acc      private(i_pml,i_x,i_y) 
        do i_pml=2,theGrid % n_pml_bounds-1 
            do i_y=1+1,theGrid % n_y-1 
                do i_x=1+1,theGrid % n_x-1 
                    g_z(i_x,i_y,i_pml,1) = g_z(i_x,i_y,i_pml,2) 
                enddo 
            enddo 
        enddo 
        !$acc end kernels 
        CPU_Omp end do 
...<snip>...

Hope this helps,
Mat