Hi Ilmir,

thanks for your reply; I am looking forward to your updated patch.

Ilmir Usmanov wrote:
I have tested your notes on two compilers which support OpenACC: PGI 14.1 and CAPS 3.4.1.

I can add Cray ftn results, if you want me to cross-check something.

On 10.02.2014 02:22, Tobias Burnus wrote:

a) Does this part work well when both -fopenmp and -fopenacc is used? I mean: "!$acc loop" followed/preceded by "!$omp do"? I could imagine that there could be clashes, especially when - e.g. - collapse doesn't match.
PGI: Silently ignores OpenMP pragmas.
CAPS: Ignored option '--define' (_OPENMP=).

I like how Cray handles it: It permits both - but neither OpenMP -> OpenACC nesting nor vice versa. (It might not always detectable.)

ERROR:
The !$OMP PARALLEL DO directive cannot be specified within a !$ACC PARALLEL region.

And adding OpenACC to an OpenMP loop fails with:

ERROR:
The !$ACC LOOP directive cannot be specified within a !$OMP PARALLEL DO region.

(One gets the same error independent whether one tries to place the pragma on the same loop or just nested in the parallel pragma or on different loops.)

I think doing likewise would be best. A simpler approach is to reject using -fopenmp and -fopenacc simultaneously.

b) Do you also handle DO CONCURRENT - either by rejecting it or by accepting it? Namely,

!$acc loop
do concurrent(i=1:5)
end do
!$acc end loop
end
Side remark, with -fopenmp, it does ICE: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60127

My implemetation also fails, will fix. By the way, should we support these loops? I think we should, since DO CONCURRENT loops are parallelizable.

I think one should at least error out and not ICE.

The long-term solution should be to support DO CONCURRENT with both OpenMP and OpenACC; although one option would be to wait until the specs officially support it.

If you want to support it, please recall that do concurrent also permits a mask argument, which makes everything a bit more complicated. (Cf. gcc/fortran/trans-stmt.c's gfc_trans_forall_1 function.)

No, the spec doesn't specify !$acc end loop. However, compilers handle this construction differently:
PGI: silently accepts.

Which is not surprising given that NVidia's and PGI's example often use "!$acc end loop". [Cray ftn also accepts it silently.]

+  if (gfc_pure (NULL))
+    {
+ gfc_error_now ("OpenACC directives at %C may not appear in PURE "
+                     "or ELEMENTAL procedures");
...
In any case, either drop "or ELEMENTAL" or also check for the elemental attribute.

I think I should drop "or ELEMENTAL" since OpenMP also accepts directives in IMPURE ELEMENTAL procecdures.

Fine with me.

+  if (gfc_implicit_pure (NULL))
+    gfc_current_ns->proc_name->attr.implicit_pure = 0;

I believe that will fail with BLOCK - cf. gfc_implicit_pure()
Fortunally, it doesn't.

Are you sure that it works? A block starts a new namespace, hence, gfc_implicit_pure() does:

----------------------cut---------------
      /* Check if the current procedure is implicit_pure.  Walk up
         the procedure list until we find a procedure.  */
      for (ns = gfc_current_ns; ns; ns = ns->parent)
        {
          sym = ns->proc_name;
          if (sym == NULL)
            return 0;

          if (sym->attr.flavor == FL_PROCEDURE)
            break;
        }
    }

  return sym->attr.flavor == FL_PROCEDURE && sym->attr.implicit_pure
    && !sym->attr.pure;
----------------------cut---------------

But you set "gfc_current_ns->proc_name->attr.implicit_pure = 0". If gfc_current_ns is the BLOCK, the procedure might still have the "implict_pure" attribute set.

Side question: Do we also need to unset implicit_pure for OpenMP?

Tobias

Reply via email to