Re: [PATCH 2/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
Hi Tobias! On 10.02.2014 03:10, Tobias Burnus wrote: Shouldn't you also reject polymorphic types (BT_CLASS and BT_ASSUMED)? [BT_CLASS = class(derived_type_name) or class(*); BT_ASSUMED = type(*)] + if (n-sym-attr.pointer) +gfc_error (POINTER object '%s' in %s clause at %L, + n-sym-name, name, code-loc); Actually, here and probably elsewhere: Do you need to take care of derived-type components? I mean something like clause(derived_type%comp) Do you also need to reject AS_ASSUMED_RANK (new since Fortran Technical Specification ISO/IEC TS 29113:2012)? I mean code like: subroutine foo(x) integer, DIMENSION(..) :: x ... openacc_clause(x) Side note: One should also check how OpenMP handles those. I think we should reject assumed size, assumed shape and assumed rank variables, as OpenMP does. + case OMP_LIST_DEVICEPTR: +if (n-sym-attr.pointer) + gfc_error (POINTER object '%s' in %s clause at %L, + n-sym-name, name, code-loc); Talking about pointers, you probably also want to reject Cray pointers (attr.cray_pointee - and cray_pointee). [One should also check what OpenMP does; I think it does handle it correctly.] I agree, currently my implementation does not handle Cray pointers correctly, will fix. And another point: I think you have to check whether the argument is a named constant (PARAMETER, attr.flavor == FL_PARAMETER), I think those you cannot put them there either. What happens if you try to use a literal such as deviceptr(5)? Both parameter and literal are rejected. By the way, PGI compiler accepts parameters with warning, CAPS silently accepts. I think, we also should support parameters with warning. + resolve_oacc_positive_int_expr (el-expr, TILE); + if (el-expr-expr_type != EXPR_CONSTANT) +gfc_error (TILE requires constant expression at %L, code-loc); Is the following permitted: tile(4+5)? If so, do you need to call gfc_simplify_expr() as some point? (Or is this already done at some point?) Yes, the syntax is allowed, but ... CAPSCompilers-3.4.1/bin/hmpp: [Error HP0112] tile.f95:30: Syntax error: expecting ')' !$acc parallel loop collapse(1+ 1) CAPS compiler doesn't support this. But PGI does. There is no need to simplify expression since it is constant anyway. The simplification is done during match stage (gfc_match_expr calls gfc_add). -- Ilmir.
Re: [PATCH 2/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
Hi! On Mon, 10 Feb 2014 00:10:26 +0100, Tobias Burnus bur...@net-b.de wrote: Ilmir Usmanov wrote: OpenACC 1.0 fortran FE support -- matching and resolving. +static void +resolve_oacc_cache (gfc_code *) +{ + //TODO: resolve subarrays +} ;-) Just to clarify: I'm fine with incomplete changes being committed to the gomp-4_0-branch, which is a development branch, as long as such changes don't largely break the existing (working) code, as determined by the testsuite for example. Occasional small breakage should be fine, if it is understood, and will be fixed later, like in the case where a recent merge that I did from trunk into gomp-4_0-branch caused a regression in one C++ OpenMP test case, which I could pinpoint to one gomp-4_0-branch-specific patch, which Ilya Tocar by now has fixed (pending commit). What I'd generally like to see added are markers à la: /* TODO: resolve subarrays */ gcc_unreachable (); This makes it obvious both to the reader/reviewer and user of GCC ;-) that this code path has not yet been implemented. This is of course not acceptable for released versions of GCC, but I think it's fine for the gomp-4_0-branch, in this early OpenACC development stage. Grüße, Thomas pgp1UsgK6EtuJ.pgp Description: PGP signature
Re: [PATCH 2/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
Ilmir Usmanov wrote: OpenACC 1.0 fortran FE support -- matching and resolving. + return MATCH_ERROR; +} + +static match +match_oacc_clause_gang (gfc_omp_clauses *cp) +{ For consistency, can you add another empty line before the function? +#define OMP_CLAUSE_SEQ (1ll 32) I think you should use 1LL instead of 1ll - that should be more readable and matches gcc/{configure,fold-const.c,glimits.h,simplify-rtx.c} +static void +resolve_oacc_scalar_int_expr (gfc_expr *expr, const char *clause) +{ + if (!gfc_resolve_expr (expr) + || expr-ts.type != BT_INTEGER || expr-rank != 0) +gfc_error (%s clause at %L requires a scalar INTEGER expression, + clause, expr-where); +} I'd use integer instead of INTEGER as it is not a 'reserved' word +gfc_warning (INTEGER expression of %s clause at %L must be positive, + clause, expr-where); +} Ditto. @@ -800,10 +1366,14 @@ resolve_omp_clauses (gfc_code *code) static const char *clause_names[] = { PRIVATE, FIRSTPRIVATE, LASTPRIVATE, COPYPRIVATE, SHARED, - COPYIN, REDUCTION }; + COPYIN, COPY, COPYIN, COPYOUT, CREATE, DELETE, +PRESENT, PRESENT_OR_COPY, PRESENT_OR_COPYIN, PRESENT_OR_COPYOUT, +PRESENT_OR_CREATE, DEVICEPTR, USE_DEVICE, DEVICE_RESIDENT, +HOST, DEVICE, CACHE, REDUCTION}; Indention: Should be a tab not spaces. @@ -933,8 +1503,43 @@ resolve_omp_clauses (gfc_code *code) else gcc_unreachable (); + if (list = OMP_LIST_DATA_CLAUSE_FIRST + list = OMP_LIST_DATA_CLAUSE_LAST) +{ + if (n-sym-ts.type == BT_DERIVED + n-sym-attr.allocatable) +gfc_error (ALLOCATABLE object '%s' of DERIVED type in %s clause at %L, + n-sym-name, name, code-loc); + if (n-sym-ts.type == BT_DERIVED + n-sym-attr.pointer) +gfc_error (POINTER object '%s' of DERIVED type in %s clause at %L, + n-sym-name, name, code-loc); I'd use derived type for the same reason as above. Shouldn't you also reject polymorphic types (BT_CLASS and BT_ASSUMED)? [BT_CLASS = class(derived_type_name) or class(*); BT_ASSUMED = type(*)] + if (n-sym-attr.pointer) +gfc_error (POINTER object '%s' in %s clause at %L, + n-sym-name, name, code-loc); Actually, here and probably elsewhere: Do you need to take care of derived-type components? I mean something like clause(derived_type%comp) If so, note that symtree-n.sym-attr.pointer only checks for derived_type - even if you are interested in comp's attributes. You probably should use gfc_expr_attr() in this and similar cases. + if (n-sym-as n-sym-as-type == AS_ASSUMED_SIZE) +gfc_error (Assumed size array '%s' in %s clause at %L, + n-sym-name, name, code-loc); +} Do you also need to reject AS_ASSUMED_RANK (new since Fortran Technical Specification ISO/IEC TS 29113:2012)? I mean code like: subroutine foo(x) integer, DIMENSION(..) :: x ... openacc_clause(x) Side note: One should also check how OpenMP handles those. + case OMP_LIST_DEVICEPTR: + if (n-sym-attr.pointer) + gfc_error (POINTER object '%s' in %s clause at %L, +n-sym-name, name, code-loc); Talking about pointers, you probably also want to reject Cray pointers (attr.cray_pointee - and cray_pointee). [One should also check what OpenMP does; I think it does handle it correctly.] And another point: I think you have to check whether the argument is a named constant (PARAMETER, attr.flavor == FL_PARAMETER), I think those you cannot put them there either. What happens if you try to use a literal such as deviceptr(5)? +} + +static void +resolve_oacc_params_in_parallel (gfc_code *code, const char *clause) +{ Another empty line for consistency. + if (oacc_is_parallel (code)) +gfc_error (LOOP %s in PARALLEL section allows no argument or static at %L, + clause, code-loc); I am not sure whether I understand the error - in particular what static means. (It might be obvious after looking at the spec - if not, the error message should be improved.) In any case, I think you want to use nor instead of or. + if (code-ext.omp_clauses-seq) +{ + if (code-ext.omp_clauses-independent) +gfc_error (Both SEQ and INDEPENDENT are not allowed in %L, code-loc); Somehow, I don't like the wording; it sounds to me a bit as if SEQ is not permitted and INDEPENDENT is not permitted while you mean that only using them simultaneously is wrong. I don't have a very good suggestion, but here are some: SEQ clause conflicts with INDEPENDENT at %L, SEQ shall not be used together with INDEPENDENT at %L or ... + resolve_oacc_positive_int_expr (el-expr, TILE); + if (el-expr-expr_type != EXPR_CONSTANT) +gfc_error (TILE requires constant expression at %L,
Re: [PATCH 2/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
OpenACC 1.0 fortran FE support -- matching and resolving. * openmp.c (gfc_free_omp_clauses): Remove also OpenACC clauses. (gfc_free_exprlist): New function to clear expression list. (match_oacc_exprlist): New function to match expression list. (match_oacc_clause_gang): New function to match OpenACC 2.0 gang clauses. (OMP_CLAUSE_ASYNC, OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS, OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_COPY, OMP_CLAUSE_OACC_COPYIN, OMP_CLAUSE_COPYOUT, OMP_CLAUSE_CREATE, OMP_CLAUSE_PRESENT, OMP_CLAUSE_PRESENT_OR_COPY, OMP_CLAUSE_PRESENT_OR_COPYIN, OMP_CLAUSE_PRESENT_OR_COPYOUT, OMP_CLAUSE_PRESENT_OR_CREATE, OMP_CLAUSE_DEVICEPTR, OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, OMP_CLAUSE_SEQ, OMP_CLAUSE_INDEPENDENT, OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE_HOST, OMP_CLAUSE_DEVICE_RESIDENT, OMP_CLAUSE_DEVICE, OMP_CLAUSE_DEFAULT, OMP_CLAUSE_WAIT, OMP_CLAUSE_DELETE, OMP_CLAUSE_AUTO, OMP_CLAUSE_TILE): New clauses. (OACC_PARALLEL_CLAUSES, OACC_KERNELS_CLAUSES, OACC_DATA_CLAUSES, OACC_LOOP_CLAUSES, OACC_PARALLEL_LOOP_CLAUSES, OACC_KERNELS_LOOP_CLAUSES, OACC_HOST_DATA_CLAUSES, OACC_DECLARE_CLAUSES, OACC_UPDATE_CLAUSES, OACC_ENTER_DATA_CLAUSES, OACC_EXIT_DATA_CLAUSES): New defines. From 64b05eeeadf25fca4f92f083cc11aaad1a7a692a Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Fri, 31 Jan 2014 13:26:13 +0400 Subject: [PATCH 2/6] OpenACC fortran front-end -- part 2 --- gcc/fortran/openmp.c | 942 ++- 1 file changed, 940 insertions(+), 2 deletions(-) diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index dff3ab1..d4e3ebd 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -69,11 +69,36 @@ gfc_free_omp_clauses (gfc_omp_clauses *c) gfc_free_expr (c-final_expr); gfc_free_expr (c-num_threads); gfc_free_expr (c-chunk_size); + gfc_free_expr (c-async_expr); + gfc_free_expr (c-gang_expr); + gfc_free_expr (c-worker_expr); + gfc_free_expr (c-vector_expr); + gfc_free_expr (c-num_gangs_expr); + gfc_free_expr (c-num_workers_expr); + gfc_free_expr (c-vector_length_expr); + gfc_free_expr (c-non_clause_wait_expr); + for (i = 0; i OMP_LIST_NUM; i++) gfc_free_namelist (c-lists[i]); + + gfc_free_exprlist (c-waitlist); + free (c); } +/* Free expression list. */ +void +gfc_free_exprlist (gfc_exprlist *list) +{ + gfc_exprlist *n; + + for (; list; list = n) +{ + n = list-next; + free (list); +} +} + /* Match a variable/common block list and construct a namelist from it. */ static match @@ -169,6 +194,87 @@ cleanup: return MATCH_ERROR; } +static match +match_oacc_exprlist (const char *str, gfc_exprlist **list, bool allow_asterisk) +{ + gfc_exprlist *head, *tail, *p; + locus old_loc; + gfc_expr *expr; + match m; + + head = tail = NULL; + + old_loc = gfc_current_locus; + + m = gfc_match (str); + if (m != MATCH_YES) +return m; + + for (;;) +{ + m = gfc_match_expr (expr); + if (m == MATCH_YES || allow_asterisk) +{ + p = gfc_get_exprlist (); + if (head == NULL) +head = tail = p; + else +{ + tail-next = p; + tail = tail-next; +} + if (m == MATCH_YES) +tail-expr = expr; + else if (gfc_match ( *) != MATCH_YES) +goto syntax; + goto next_item; +} + if (m == MATCH_ERROR) +goto cleanup; + goto syntax; + +next_item: + if (gfc_match_char (')') == MATCH_YES) +break; + if (gfc_match_char (',') != MATCH_YES) +goto syntax; +} + + while (*list) +list = (*list)-next; + + *list = head; + return MATCH_YES; + +syntax: + gfc_error (Syntax error in OpenACC expression list at %C); + +cleanup: + gfc_free_exprlist (head); + gfc_current_locus = old_loc; + return MATCH_ERROR; +} + +static match +match_oacc_clause_gang (gfc_omp_clauses *cp) +{ + if (gfc_match_char ('(') != MATCH_YES) +return MATCH_NO; + if (gfc_match ( num :) == MATCH_YES) +{ + cp-gang_static = false; + return gfc_match ( %e ), cp-gang_expr); +} + if (gfc_match ( static :) == MATCH_YES) +{ + cp-gang_static = true; + if (gfc_match ( * )) != MATCH_YES) +return gfc_match ( %e ), cp-gang_expr); + return MATCH_YES; +} + return gfc_match ( %e ), cp-gang_expr); +} + #define OMP_CLAUSE_PRIVATE (1 0) #define OMP_CLAUSE_FIRSTPRIVATE (1 1) #define OMP_CLAUSE_LASTPRIVATE (1 2) @@ -186,11 +292,40 @@ cleanup: #define OMP_CLAUSE_FINAL (1 14) #define OMP_CLAUSE_MERGEABLE (1 15) +/* OpenACC 2.0 clauses. */ +#define OMP_CLAUSE_ASYNC(1 16) +#define OMP_CLAUSE_NUM_GANGS(1 17) +#define OMP_CLAUSE_NUM_WORKERS (1 18) +#define OMP_CLAUSE_VECTOR_LENGTH(1 19) +#define OMP_CLAUSE_COPY (1 20) +#define