Re: [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-02-20 Thread Ilmir Usmanov

Hi Tobias!

On 20.02.2014 03:51, Tobias Burnus wrote:

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.

I agree.




+  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:


After your notice about namespaces, I tested !$acc declare attribute. 
Viola, it fails. However, other directives work.




Side question: Do we also need to unset implicit_pure for OpenMP?
 As you can see in decode_omp_directive function, the flag is already 
unset.


--
Ilmir.



Re: [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-02-19 Thread Ilmir Usmanov

Hi Tobias!

Thanks a lot for your review!

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


If I made a mistake and you've collected results which differ from mine 
(whether you compiler is one of the above or not), please, let me know.


Unfortunally, neither PGI nor CAPS don't support Fortran 2008.

These are results:

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=).



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.




Talking about !$acc loop: I vaguely remember that OpenACC 1.0's spec 
doesn't have !$acc end loop while I have seen OpenACC programs which 
use it. How do you handle !$acc end loop?
Looking at parse.c, it seems to simply error out. I wonder whether one 
should be a bit more graceful. For instance, the following examples 
use !$acc end loop: 
http://devblogs.nvidia.com/parallelforall/openacc-example-part-2/ [If 
I remember correctly, pgf95 and Cray ftn silently accepts end loop 
while pathf95 accepts it with a warning.]


And looking at the spec of OpenACC 1.0 and 2.0a, the end loop seems 
to be invalid. How about following PathScale's ENZO and accepting end 
loop with a warning? Or at least error out with a good error message.


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

PGI: silently accepts.
CAPS: Syntax error: expecting ('parallel' ('loop' or end)) or 
(('kernels' or 'dfkernels') ('loop' or end)) or 'data' or 'host_data'

!$acc  end loop
My implementation also errors out, but I agree, we should accept this 
with warning.





+  if (gfc_pure (NULL))
+{
+  gfc_error_now (OpenACC directives at %C may not appear in PURE 
+ or ELEMENTAL procedures);


Using gfc_pure() you do not check for ELEMENTAL: Since Fortran 2008, 
there are also IMPURE ELEMENTAL procedures. I don't know the spec, but 
I don't really see a reason why OpenACC shouldn't be permitted in 
IMPURE ELEMENTAL procedures. (BTW: ELEMENTAL implies PURE unless an 
explicit IMPURE is used.)


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.



+  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()

real function foo(n)
  integer, value :: n
  BLOCK
 integer i
 real sum
 !$acc loop reduce(+:sum)
 do i=1, n
sum += sin(real(i))
 end do
  END BLOCK
end


Fortunally, it doesn't.

--
Ilmir.


Re: [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-02-19 Thread Tobias Burnus

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


Re: [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-02-09 Thread Tobias Burnus

Ilmir Usmanov wrote:

OpenACC 1.0 support to fortran FE -- core.
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -1031,9 +1031,22 @@ show_omp_node (int level, gfc_code *c)
  {
gfc_omp_clauses *omp_clauses = NULL;
const char *name = NULL;
+  bool is_oacc = false;


I'd also update the comment before the function and mention OpenACC 
there. It currently reads:



/* Show a single OpenMP directive node and everything underneath it
   if necessary.  */



+  fprintf (dumpfile, !$%s %s, is_oacc?ACC:OMP, name);


Add spaces around ? and :


@@ -1215,7 +1334,7 @@ show_omp_node (int level, gfc_code *c)
-  fprintf (dumpfile, !$OMP END %s, name);
+  fprintf (dumpfile, !$%s END %s, is_oacc?ACC:OMP, name);


Ditto.


--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h

+/* Likewise to gfc_namelist, but contains expressions.  */
+typedef struct gfc_exprlist
+{
+  struct gfc_expr *expr;
+  struct gfc_exprlist *next;
+}
+gfc_exprlist;


I don't feel strong about it, but I think it is more GCC / gfortran 
style to use gfc_expr_list instead of gfc_exprlist.



+  /* OpenACC. */
+  struct gfc_expr *async_expr;
+  struct gfc_expr *gang_expr;
+  struct gfc_expr *worker_expr;
+  struct gfc_expr *vector_expr;
+  struct gfc_expr *num_gangs_expr;
+  struct gfc_expr *num_workers_expr;
+  struct gfc_expr *vector_length_expr;
+  struct gfc_expr *non_clause_wait_expr;
+  gfc_exprlist *waitlist;
+  gfc_exprlist *tilelist;
+  bool async, gang, worker, vector, seq, independent;
+  bool wait, par_auto, gang_static;


I wonder whether it would make sense to use bit fields here.


--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -2595,6 +2595,33 @@ match_exit_cycle (gfc_statement st, gfc_exec_op op)
if (cnt  0
 o != NULL
 o-state == COMP_OMP_STRUCTURED_BLOCK
+   (o-head-op == EXEC_OACC_LOOP
+  || o-head-op == EXEC_OACC_PARALLEL_LOOP))
+{
+  int collapse = 1;
+  gcc_assert (o-head-next != NULL
+   (o-head-next-op == EXEC_DO
+  || o-head-next-op == EXEC_DO_WHILE)


Two questions:

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.


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



Talking about !$acc loop: I vaguely remember that OpenACC 1.0's spec 
doesn't have !$acc end loop while I have seen OpenACC programs which 
use it. How do you handle !$acc end loop?


Looking at parse.c, it seems to simply error out. I wonder whether one 
should be a bit more graceful. For instance, the following examples use 
!$acc end loop: 
http://devblogs.nvidia.com/parallelforall/openacc-example-part-2/ [If I 
remember correctly, pgf95 and Cray ftn silently accepts end loop while 
pathf95 accepts it with a warning.]


And looking at the spec of OpenACC 1.0 and 2.0a, the end loop seems to 
be invalid. How about following PathScale's ENZO and accepting end 
loop with a warning? Or at least error out with a good error message.




+  if (st == ST_EXIT  cnt = collapse)
+{
+  gfc_error (EXIT statement at %C terminating !$ACC LOOP loop);
+  return MATCH_ERROR;
+}
+  if (st == ST_CYCLE  cnt  collapse)
+{
+  gfc_error (CYCLE statement at %C to non-innermost collapsed
+  !$ACC LOOP loop);
+  return MATCH_ERROR;
+}
+}


I wonder whether one should include for OpenMP and OpenACC some 
additional checks as done for DO CONCURRENT or whether those aren't 
required. I think image controll statements like Fortran 2008's CRITICAL 
block might cause problems with OpenACC/OpenMP concurrency. (Given that 
OpenACC/OpenMP likely ignores Fortran 2008's coarrays, one might defer 
this until OpenACC/OpenMP has been updated for Fortran 2008.)




+  if (gfc_pure (NULL))
+{
+  gfc_error_now (OpenACC directives at %C may not appear in PURE 
+ or ELEMENTAL procedures);


Using gfc_pure() you do not check for ELEMENTAL: Since Fortran 2008, 
there are also IMPURE ELEMENTAL procedures. I don't know the spec, but I 
don't really see a reason why OpenACC shouldn't be permitted in IMPURE 
ELEMENTAL procedures. (BTW: ELEMENTAL implies PURE unless an explicit 
IMPURE is used.)


In any case, either drop or ELEMENTAL or also check for the elemental 
attribute.



+  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()

real function foo(n)
  integer, value :: n
  BLOCK
 integer i
 real sum
 !$acc loop reduce(+:sum)
 do i=1, n
sum += sin(real(i))
 end do
  END BLOCK
end


Re: [PING] [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-02-03 Thread Ilmir Usmanov

Hi Jakub!

On 31.01.2014 15:45, Ilmir Usmanov wrote:

Hi Jakub!

Thank you for review and quick answer.

The above are OpenACC specific clauses, so they should have OACC_LIST_*?

I just followed Thomas's style recomendations:

If we're adding new names for implementing OpenACC things, maybe we
should also name these OMP_*, to keep things simple to read in the code
that uses them.

And I agree with him.

+  case OMP_LIST_DEVICE: type = DEVICE; break;
This one is in OpenMP 4.0 too (though, I didn't get to OpenMP 4.0 / 
fortran

support yet), so this should be OMP_LIST_DEVICE.
As far as I know, OpenMP device clause requires integer-expression, 
not variable-list, so, I think, we can use OMP_LIST_DEVICE to 
represent OpenACC device clause.




So, what should I do? Is current naming OK? Or you think it's better to 
use OACC_ prefix for OpenACC specific stuff in Fortran front-end and 
OMP_ prefix in middle-end?


--
Ilmir.


Re: [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-01-31 Thread Ilmir Usmanov

OpenACC 1.0 support to fortran FE -- core.

gcc/fortran/
* dump-parse-tree.c
(show_omp_node): Dump also OpenACC executable statements.
(show_code_node): Call it.
* gfortran.h
(ST_OACC_PARALLEL_LOOP, ST_OACC_END_PARALLEL_LOOP, ST_OACC_PARALLEL,
ST_OACC_END_PARALLEL, ST_OACC_KERNELS, ST_OACC_END_KERNELS,
ST_OACC_DATA, ST_OACC_END_DATA, ST_OACC_HOST_DATA,
ST_OACC_END_HOST_DATA, ST_OACC_LOOP, ST_OACC_DECLARE, ST_OACC_UPDATE,
ST_OACC_WAIT, ST_OACC_CACHE, ST_OACC_KERNELS_LOOP,
ST_OACC_END_KERNELS_LOOP, ST_OACC_ENTER_DATA,
ST_OACC_EXIT_DATA): New statements.
(gfc_exprlist): New structure to hold list of expressions.
(OMP_LIST_COPY, OMP_LIST_DATA_CLAUSE_FIRST,
OMP_LIST_OACC_COPYIN, OMP_LIST_COPYOUT, OMP_LIST_CREATE, 
OMP_LIST_DELETE,

OMP_LIST_PRESENT, OMP_LIST_PRESENT_OR_COPY,
OMP_LIST_PRESENT_OR_COPYIN, OMP_LIST_PRESENT_OR_COPYOUT,
OMP_LIST_PRESENT_OR_CREATE, OMP_LIST_DEVICEPTR,
OMP_LIST_DATA_CLAUSE_LAST, OMP_LIST_USE_DEVICE,
OMP_LIST_DEVICE_RESIDENT, OMP_LIST_HOST, OMP_LIST_DEVICE,
OMP_LIST_CACHE): New types of list, allowed in clauses.
(gfc_omp_clauses): Add OpenACC clauses.
(gfc_namespace): Add OpenACC declare directive clauses.
(EXEC_OACC_KERNELS_LOOP, EXEC_OACC_PARALLEL_LOOP, EXEC_OACC_PARALLEL,
EXEC_OACC_KERNELS, EXEC_OACC_DATA, EXEC_OACC_HOST_DATA, EXEC_OACC_LOOP,
EXEC_OACC_UPDATE, EXEC_OACC_WAIT, EXEC_OACC_CACHE, 
EXEC_OACC_ENTER_DATA,

EXEC_OACC_EXIT_DATA): New executable statements.
(gfc_free_exprlist): New function declaration.
(gfc_resolve_oacc_directive): Likewise.
(gfc_resolve_oacc_parallel_loop_blocks): Likewise.
(gfc_resolve_oacc_blocks): Likewise.
* match.c (match_exit_cycle): Add support of OpenACC regions and loops.
* match.h (gfc_match_oacc_cache): New function declaration.
(gfc_match_oacc_wait, gfc_match_oacc_update): Likewise.
(gfc_match_oacc_declare, gfc_match_oacc_loop): Likewise.
(gfc_match_oacc_host_data, gfc_match_oacc_data): Likewise.
(gfc_match_oacc_kernels, gfc_match_oacc_kernels_loop): Likewise.
(gfc_match_oacc_parallel, gfc_match_oacc_parallel_loop): Likewise.
(gfc_match_oacc_enter_data, gfc_match_oacc_exit_data): Likewise.
* parse.c (decode_oacc_directive): New function.
(verify_token_free, verify_token_fixed): New helper functions.
(next_free, next_fixed): Decode !$ACC sentinel.
(case_executable): Add ST_OACC_UPDATE, ST_OACC_WAIT, ST_OACC_CACHE,
ST_OACC_ENTER_DATA and ST_OACC_EXIT_DATA directives.
(case_exec_markers): Add ST_OACC_PARALLEL_LOOP, ST_OACC_PARALLEL,
ST_OACC_KERNELS, ST_OACC_DATA, ST_OACC_HOST_DATA, ST_OACC_LOOP and
ST_OACC_KERNELS_LOOP directives.
(push_state): Initialize OpenACC declare clauses.
(gfc_ascii_statement): Dump names of OpenACC directives.
(verify_st_order): Verify OpenACC declare directive as declarative.
(parse_spec): Push clauses to state stack when declare directive is
parsed.
(parse_oacc_structured_block, parse_oacc_loop): New functions.
(parse_executable): Call them.
(parse_progunit): Move declare clauses from state stack to namespace.
* parse.h (gfc_state_data): Add declare directive's clauses.
* resolve.c (gfc_resolve_blocks): Resolve OpenACC directives.
(resolve_code): Likewise.
* scanner.c (openacc_flag, openacc_locus): New static variables.
(skip_oacc_attribute, skip_omp_attribute): New helper functions.
(skip_free_comments, skip_fixed_comments): Don't skip !$ACC sentinel.
(gfc_next_char_literal): Support OpenACC directives.
* st.c (gfc_free_statement): Free also OpenACC directives.
From f8f10537d2555e596bdd1655990150d45ef08f9b Mon Sep 17 00:00:00 2001
From: Ilmir Usmanov i.usma...@samsung.com
Date: Fri, 31 Jan 2014 13:25:42 +0400
Subject: [PATCH 1/6] OpenACC fortran front-end -- part 1

---
 gcc/fortran/dump-parse-tree.c | 135 +-
 gcc/fortran/gfortran.h|  59 ++
 gcc/fortran/match.c   |  27 +++
 gcc/fortran/match.h   |  15 ++
 gcc/fortran/parse.c   | 425 ++
 gcc/fortran/parse.h   |   1 +
 gcc/fortran/resolve.c |  36 
 gcc/fortran/scanner.c | 376 ++---
 gcc/fortran/st.c  |  12 ++
 9 files changed, 980 insertions(+), 106 deletions(-)

diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
index b1343bc..9ef9db4 100644
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -1031,9 +1031,22 @@ show_omp_node (int level, gfc_code *c)
 {
   gfc_omp_clauses *omp_clauses = NULL;
   const char *name = NULL;
+  bool is_oacc = false;
 
   switch (c-op)
 {
+case EXEC_OACC_PARALLEL_LOOP: name = PARALLEL LOOP; is_oacc = true; break;
+case EXEC_OACC_PARALLEL: name = PARALLEL; is_oacc = true; break;
+case EXEC_OACC_KERNELS_LOOP: name = KERNELS LOOP; is_oacc = true; break;
+case 

Re: [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-01-31 Thread Jakub Jelinek
On Fri, Jan 31, 2014 at 03:10:59PM +0400, Ilmir Usmanov wrote:
 @@ -1182,6 +1281,26 @@ show_omp_node (int level, gfc_code *c)
 {
   switch (list_type)
 {
 +  case OMP_LIST_COPY: type = COPY; break;
 +  case OMP_LIST_OACC_COPYIN: type = COPYIN; break;
 +  case OMP_LIST_COPYOUT: type = COPYOUT; break;
 +  case OMP_LIST_CREATE: type = CREATE; break;
 +  case OMP_LIST_DELETE: type = DELETE; break;
 +  case OMP_LIST_PRESENT: type = PRESENT; break;
 +  case OMP_LIST_PRESENT_OR_COPY: 
 +type = PRESENT_OR_COPY; break;
 +  case OMP_LIST_PRESENT_OR_COPYIN: 
 +type = PRESENT_OR_COPYIN; break;
 +  case OMP_LIST_PRESENT_OR_COPYOUT: 
 +type = PRESENT_OR_COPYOUT; break;
 +  case OMP_LIST_PRESENT_OR_CREATE: 
 +type = PRESENT_OR_CREATE; break;
 +  case OMP_LIST_DEVICEPTR: type = DEVICEPTR; break;
 +  case OMP_LIST_USE_DEVICE: type = USE_DEVICE; break;
 +  case OMP_LIST_DEVICE_RESIDENT: type = USE_DEVICE; break;
 +  case OMP_LIST_HOST: type = HOST; break;

The above are OpenACC specific clauses, so they should have OACC_LIST_*?

 +  case OMP_LIST_DEVICE: type = DEVICE; break;

This one is in OpenMP 4.0 too (though, I didn't get to OpenMP 4.0 / fortran
support yet), so this should be OMP_LIST_DEVICE.

 +  case OMP_LIST_CACHE: type = ; break;

Again, this is OpenACC specific.

Jakub


Re: [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-01-31 Thread Ilmir Usmanov

Hi Jakub!

Thank you for review and quick answer.

The above are OpenACC specific clauses, so they should have OACC_LIST_*?

I just followed Thomas's style recomendations:

If we're adding new names for implementing OpenACC things, maybe we
should also name these OMP_*, to keep things simple to read in the code
that uses them.

And I agree with him.

+  case OMP_LIST_DEVICE: type = DEVICE; break;

This one is in OpenMP 4.0 too (though, I didn't get to OpenMP 4.0 / fortran
support yet), so this should be OMP_LIST_DEVICE.
As far as I know, OpenMP device clause requires integer-expression, not 
variable-list, so, I think, we can use OMP_LIST_DEVICE to represent 
OpenACC device clause.


--
Thanks,
Ilmir.


Re: [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-01-27 Thread Tobias Burnus

Hi,

Thomas Schwinge wrote:

Regarding my comments, please keep in mind that I don't have a lot of
Fortran experience; neither as a user nor as an implementor


How about CC-ing fortran@gcc for Fortran patches - it increases the 
chance that some Fortran maintainer will give some comment on them.


(When doing so, please add a line or so stating that it is for the 
branch and what is OpenACC - it makes it easier for those who haven't 
followed gcc-patches.)


Tobias

PS: I might look at the patches myself; however, I have a huge backlog 
of emails and didn't manage to do anything for GCC in the past month. 
Thus, don't hold your breath and count rather one some other Fortran 
maintainer.


Re: [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-01-24 Thread Thomas Schwinge
Hi!

Regarding my comments, please keep in mind that I don't have a lot of
Fortran experience; neither as a user nor as an implementor ;-) in the
GCC front end, so don't hesitate to tell me if I'm misunderstanding
something.  As I suggested, it may make sense to CC Fortran front end
maintainers for such patches.


When I say again in the following, that refers to things I
asked/suggested in »[PATCH 4/6] OpenACC GENERIC nodes«.

On Thu, 23 Jan 2014 22:03:09 +0400, Ilmir Usmanov i.usma...@samsung.com wrote:
 Subject: [PATCH 1/6] OpenACC fortran FE part 1

 --- a/gcc/fortran/dump-parse-tree.c
 +++ b/gcc/fortran/dump-parse-tree.c
 @@ -1230,6 +1230,194 @@ show_omp_node (int level, gfc_code *c)
  fprintf (dumpfile,  (%s), c-ext.omp_name);
  }
  
 +/* Show a single OpenACC directive node and everything underneath it
 +   if necessary.  */
 +
 +static void
 +show_oacc_node (int level, gfc_code *c)

Is this something that accurately needs to reproduce valid Fortran code?
Or, could we again re-use more of the existing OpenMP code, and get
nearly-valid Fortran, that differs in how some of the data clauses are
displayed, for example?

 --- a/gcc/fortran/gfortran.h
 +++ b/gcc/fortran/gfortran.h

 @@ -1025,16 +1031,29 @@ gfc_namelist;

  enum
  {
OMP_LIST_PRIVATE,
 +  OACC_LIST_PRIVATE = OMP_LIST_PRIVATE,
OMP_LIST_FIRSTPRIVATE,
 +  OACC_LIST_FIRSTPRIVATE = OMP_LIST_FIRSTPRIVATE,

Again, possible to simply re-use the existing OMP_* ones?

 @@ -1047,7 +1066,29 @@ enum
OMP_LIST_IOR,
OMP_LIST_IEOR,
OMP_LIST_REDUCTION_LAST = OMP_LIST_IEOR,
 -  OMP_LIST_NUM
 +  OACC_LIST_REDUCTION_LAST = OMP_LIST_REDUCTION_LAST,
 +  OMP_LIST_NUM,
 +
 +  OACC_LIST_COPY = OMP_LIST_NUM,
 +  OACC_LIST_FIRST = OACC_LIST_COPY,
 +  OACC_LIST_DATA_CLAUSE_FIRST = OACC_LIST_COPY,
 +  OACC_LIST_COPYIN,
 +  OACC_LIST_COPYOUT,
 +  OACC_LIST_CREATE,
 +  OACC_LIST_DELETE,
 +  OACC_LIST_PRESENT,
 +  OACC_LIST_PRESENT_OR_COPY,
 +  OACC_LIST_PRESENT_OR_COPYIN,
 +  OACC_LIST_PRESENT_OR_COPYOUT,
 +  OACC_LIST_PRESENT_OR_CREATE,
 +  OACC_LIST_DEVICEPTR,
 +  OACC_LIST_DATA_CLAUSE_LAST = OACC_LIST_DEVICEPTR,
 +  OACC_LIST_USE_DEVICE,
 +  OACC_LIST_DEVICE_RESIDENT,
 +  OACC_LIST_HOST,
 +  OACC_LIST_DEVICE,
 +  OACC_LIST_CACHE,
 +  OACC_LIST_NUM
  };

Again, for conformity, maybe stick with OMP_LIST_* names
(OMP_LIST_OACC_*?).

Do we still need the OMP_LIST_NUM value if we now got OACC_LIST_NUM to
mark the number of items, and should the latter one in fact be named
OMP_LIST_NUM then?)

Again, can we re-use the existing infrastructure for OpenMP's memory
mapping instead of adding OACC_LIST_COPY* (and similar) here?

 @@ -1077,17 +1118,42 @@ typedef struct gfc_omp_clauses

 +  /* OpenACC. */
 +  bool is_acc;

Can we avoid the is_acc member and instead make it clear from the context
whether this is OpenACC or OpenMP?  (Just an idea.)

 +  [...]
  }
  gfc_omp_clauses;
  
  #define gfc_get_omp_clauses() XCNEW (gfc_omp_clauses)
  
 +typedef gfc_omp_clauses gfc_oacc_clauses;

Again, I'd just use the existing gfc_omp_* name.

 --- a/gcc/fortran/parse.c
 +++ b/gcc/fortran/parse.c

 @@ -3643,6 +3875,113 @@ parse_omp_atomic (void)
  }
  
  
 +/* Parse the statements of an OpenACC structured block.  */
 +
 +static void
 +parse_oacc_structured_block (gfc_statement acc_st)
 +{
 +[...]

 --- a/gcc/fortran/parse.h
 +++ b/gcc/fortran/parse.h
 @@ -29,7 +29,8 @@ typedef enum
COMP_BLOCK_DATA, COMP_INTERFACE, COMP_DERIVED, COMP_DERIVED_CONTAINS,
COMP_BLOCK, COMP_ASSOCIATE, COMP_IF,
COMP_DO, COMP_SELECT, COMP_FORALL, COMP_WHERE, COMP_CONTAINS, COMP_ENUM,
 -  COMP_SELECT_TYPE, COMP_OMP_STRUCTURED_BLOCK, COMP_CRITICAL, 
 COMP_DO_CONCURRENT
 +  COMP_SELECT_TYPE, COMP_OMP_STRUCTURED_BLOCK, COMP_CRITICAL, 
 COMP_DO_CONCURRENT,
 +  COMP_OACC_STRUCTURED_BLOCK
  }
  gfc_compile_state;

In Fortran, how is an OpenACC structured block different from an OpenMP
one?  In C they aren't; see the third patch in
http://news.gmane.org/find-root.php?message_id=%3C87r49kuass.fsf%40kepler.schwinge.homeip.net%3E,
for the C front end/middle end, which is pending approval.  Or is this
something else in the Fortran front end?


Grüße,
 Thomas


pgpCcAPrVfrQA.pgp
Description: PGP signature


[PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-01-23 Thread Ilmir Usmanov


From 84dc72f88c1b23ae995afdda0b946ebd73af102f Mon Sep 17 00:00:00 2001
From: Ilmir Usmanov i.usma...@samsung.com
Date: Thu, 23 Jan 2014 21:04:37 +0400
Subject: [PATCH 1/6] OpenACC fortran FE part 1

---
 gcc/fortran/decl.c|   1 +
 gcc/fortran/dump-parse-tree.c | 203 
 gcc/fortran/gfortran.h|  81 +++-
 gcc/fortran/match.c   |  34 +++-
 gcc/fortran/match.h   |  15 ++
 gcc/fortran/parse.c   | 425 ++
 gcc/fortran/parse.h   |   4 +-
 gcc/fortran/resolve.c |  36 
 gcc/fortran/scanner.c | 382 +
 gcc/fortran/st.c  |  14 +-
 10 files changed, 1082 insertions(+), 113 deletions(-)

diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 0a0f8e0..e988983 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -6000,6 +6000,7 @@ gfc_match_end (gfc_statement *st)
 
 case COMP_CONTAINS:
 case COMP_DERIVED_CONTAINS:
+case COMP_OACC_STRUCTURED_BLOCK:
   state = gfc_state_stack-previous-state;
   block_name = gfc_state_stack-previous-sym == NULL
 		 ? NULL : gfc_state_stack-previous-sym-name;
diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
index 14ff004..74be9ba 100644
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -1230,6 +1230,194 @@ show_omp_node (int level, gfc_code *c)
 fprintf (dumpfile,  (%s), c-ext.omp_name);
 }
 
+/* Show a single OpenACC directive node and everything underneath it
+   if necessary.  */
+
+static void
+show_oacc_node (int level, gfc_code *c)
+{
+  gfc_oacc_clauses *acc_clauses = NULL;
+  const char *name = NULL;
+
+  switch (c-op)
+{
+case EXEC_OACC_PARALLEL_LOOP: name = PARALLEL LOOP; break;
+case EXEC_OACC_PARALLEL: name = PARALLEL; break;
+case EXEC_OACC_KERNELS_LOOP: name = KERNELS LOOP; break;
+case EXEC_OACC_KERNELS: name = KERNELS; break;
+case EXEC_OACC_DATA: name = DATA; break;
+case EXEC_OACC_HOST_DATA: name = HOST_DATA; break;
+case EXEC_OACC_LOOP: name = LOOP; break;
+case EXEC_OACC_UPDATE: name = UPDATE; break;
+case EXEC_OACC_WAIT: name = WAIT; break;
+case EXEC_OACC_CACHE: name = CACHE; break;
+case EXEC_OACC_ENTER_DATA: name = ENTER DATA; break;
+case EXEC_OACC_EXIT_DATA: name = EXIT DATA; break;
+default:
+  gcc_unreachable ();
+}
+  fprintf (dumpfile, !$ACC %s, name);
+  acc_clauses = c-ext.omp_clauses;
+  if (acc_clauses)
+{
+  int list;
+
+  if (acc_clauses-if_expr)
+{
+  fputs ( IF(, dumpfile);
+  show_expr (acc_clauses-if_expr);
+  fputc (')', dumpfile);
+}
+  if (acc_clauses-async)
+{
+  fputs ( ASYNC, dumpfile);
+  if (acc_clauses-async_expr)
+{
+  fputc ('(', dumpfile);
+  show_expr (acc_clauses-async_expr);
+  fputc (')', dumpfile);
+}
+}
+  if (acc_clauses-num_gangs_expr)
+{
+  fputs ( NUM_GANGS(, dumpfile);
+  show_expr (acc_clauses-num_gangs_expr);
+  fputc (')', dumpfile);
+}
+  if (acc_clauses-num_workers_expr)
+{
+  fputs ( NUM_WORKERS(, dumpfile);
+  show_expr (acc_clauses-num_workers_expr);
+  fputc (')', dumpfile);
+}
+  if (acc_clauses-vector_length_expr)
+{
+  fputs ( VECTOR_LENGTH(, dumpfile);
+  show_expr (acc_clauses-vector_length_expr);
+  fputc (')', dumpfile);
+}
+  if (acc_clauses-collapse)
+{
+  fputs ( COLLAPSE(, dumpfile);
+  fprintf (dumpfile, %d, acc_clauses-collapse);
+  fputc (')', dumpfile);
+}
+  if (acc_clauses-gang)
+{
+  fputs ( GANG, dumpfile);
+  if (acc_clauses-gang_expr)
+{
+  fputc ('(', dumpfile);
+  show_expr (acc_clauses-gang_expr);
+  fputc (')', dumpfile);
+}
+}
+  if (acc_clauses-worker)
+{
+  fputs ( WORKER, dumpfile);
+  if (acc_clauses-worker_expr)
+{
+  fputc ('(', dumpfile);
+  show_expr (acc_clauses-worker_expr);
+  fputc (')', dumpfile);
+}
+}
+  if (acc_clauses-vector)
+{
+  fputs ( VECTOR, dumpfile);
+  if (acc_clauses-vector_expr)
+{
+  fputc ('(', dumpfile);
+  show_expr (acc_clauses-vector_expr);
+  fputc (')', dumpfile);
+}
+}
+  if (acc_clauses-non_clause_wait_expr)
+{
+  fputc ('(', dumpfile);
+  show_expr (acc_clauses-non_clause_wait_expr);
+  fputc (')', dumpfile);
+}
+  if (acc_clauses-seq)
+fputs ( SEQ, dumpfile);
+  if (acc_clauses-independent)
+fputs ( INDEPENDENT, dumpfile);
+  for (list = 0; list