From patchwork Wed Oct 2 09:59:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tobias Burnus X-Patchwork-Id: 1170556 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-510044-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="oBQhdwlc"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46js8d3SF2z9sPh for ; Wed, 2 Oct 2019 20:00:49 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=naR/4X5uINLWzDeVaAwGIa25iLDygsz1HCCBFDtoUlpbo9oDRb 2CBWfiNc4guI6pkz4mJ8vckvS74YroC5bvotZpjUw9VYlk7wSA9F90B13aB8TsGI JNHYDwtUNLix/h8HDXSgZ3Uv7OgEAhxwrAV9/RApS9rSkyaMEWhhPPtUc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=UVBg2RmOKa/hQgWLaJnrKOM4meE=; b=oBQhdwlci54jFIaXaSCL JBkXawg4YbTvuJ6fzhZLJT4f/SgZwzXpafCnYIIWCsvGIkEAS6yBlWfcE60MLlaF eYEZirVS3FwhvCqNGn/cVsdGKEcF4l4kGJpq9I8VfLzHrzLAN01Pvd/846DuNivb cYGnssALSZxGDwrjDOJ3cxg= Received: (qmail 96912 invoked by alias); 2 Oct 2019 10:00:37 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 96733 invoked by uid 89); 2 Oct 2019 10:00:27 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SUBJ_OBFU_PUNCT_FEW autolearn=ham version=3.3.1 spammy= X-HELO: esa3.mentor.iphmx.com Received: from esa3.mentor.iphmx.com (HELO esa3.mentor.iphmx.com) (68.232.137.180) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 02 Oct 2019 10:00:15 +0000 IronPort-SDR: 4y6ZuHx1WHehMl9HCpnqdAI3GYl2S4/pCHUyJ+R+ScJnv4eTzn+wGMpYISQN33kmLbcZlHLBhr j5BQB62sn6qBtgTO6KXbv4QAEyDbIn8yKMLtAvWutn9wJiHawniyESrMhGVLV7JJruwzr7V3nZ SMQFqy1tS2fx8PO9F/Y2bDZKc4i7CWOC+6VYVDnPgV9CZjacyW79qUVWmyhY0TdIwtJHXhD0sh XLCIeUGK4xyTW+mAiriRPnm4dQH0EfcjyfBD3VnIh/lfdZlulYl/+NYWQdIJNL6dwK/o8bF+oP grM= Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa3.mentor.iphmx.com with ESMTP; 02 Oct 2019 01:59:55 -0800 IronPort-SDR: L8UE9wOh1X2C3puAZCxcuda2zkxeREpnXLVVeu8LGf4bXQX/qyVuHV/lsYN8461pDwo/rXYIED siAI5SAf8BGexHZ/WSbreZqrt7XrwHEwt3F+SlBLDbbIcGaYNIVJpb75hmuofHFk3zRufOmgzj b5OdtqkYSkQCbpwCAHiu/u0cis2vGk8P4PS+wPwtgJ0Anuo5oVt5QPFFBLzUtWzBlktDJ89w5z VGoo/xDzOLlvTjQLVKIm8DNqaIojjBQBvp7glD2Y/ejklDxGvJMmZ4VW/MtzM4elph2IdycXv6 6io= To: Jakub Jelinek , gcc-patches , fortran CC: From: Tobias Burnus Subject: [Patch, Fortran, OpenMP] Support OpenMP 5.0's use_device_addr Message-ID: Date: Wed, 2 Oct 2019 11:59:46 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.1.0 MIME-Version: 1.0 X-IsSubscribed: yes This patch adds the first OpenMP 5 feature to gfortran – which is trivial as it justs adds some parsing, the heavy lifting is already done in the middle end. (Minus bugs.) Additionally, I add a check for "is_device_ptr" – which is explicitly is specified in the OpenMP 4.5/5.0 spec. (i.e. dummy argument w/o pointer/allocatable/value attribute; C/C++ have the requirement pointer or array - or (C++) reference to those.) – I am not sure whether the Fortran restrictions make sense, but that's a OpenMP spec issue (for OpenMP 5.x?). I am a bit unsure about checks for use_device_…. The spec has no explicit rules, only some with can be deduced from the semantic. For C/C++, gcc/g++ has for OpenMP 4.5 (_ptr) and for OpenMP 5 (_addr): only accept pointer or array type and C++ additionally for references to those. OpenMP 5 for _ptr accepts only POINTER_TYPE (C++: plus refs to it). The current omp-low.c implementation has in any case issues with use_device_ptr and nonallocatable, nonpointer scalars, which are locally defined or have the value attribute. Build and regtested on x86_64-gnu-linux. OK for the trunk? Tobias * dump-parse-tree.c (show_omp_clauses): Handle OMP_LIST_USE_DEVICE_ADDR. * gfortran.h (enum): Add OMP_LIST_USE_DEVICE_ADDR. * openmp.c (omp_mask1): Likewise. (gfc_match_omp_clauses): Match 'use_device_addr'. (OMP_TARGET_DATA_CLAUSES): Add OMP_LIST_USE_DEVICE_ADDR. (resolve_omp_clauses): Add it; add is_device_ptr checks. * gfortran.dg/gomp/is_device_ptr-1.f90: New. diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c index 513f211b68b..9d7b26f5f6a 100644 --- a/gcc/fortran/dump-parse-tree.c +++ b/gcc/fortran/dump-parse-tree.c @@ -1507,6 +1507,7 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses) case OMP_LIST_CACHE: type = "CACHE"; break; case OMP_LIST_IS_DEVICE_PTR: type = "IS_DEVICE_PTR"; break; case OMP_LIST_USE_DEVICE_PTR: type = "USE_DEVICE_PTR"; break; + case OMP_LIST_USE_DEVICE_ADDR: type = "USE_DEVICE_ADDR"; break; default: gcc_unreachable (); } diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 6f7717d1134..a70978bf49b 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1263,6 +1263,7 @@ enum OMP_LIST_CACHE, OMP_LIST_IS_DEVICE_PTR, OMP_LIST_USE_DEVICE_PTR, + OMP_LIST_USE_DEVICE_ADDR, OMP_LIST_NUM }; diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index bda7f288989..17b0461276a 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -780,6 +780,7 @@ enum omp_mask1 OMP_CLAUSE_SIMD, OMP_CLAUSE_THREADS, OMP_CLAUSE_USE_DEVICE_PTR, + OMP_CLAUSE_USE_DEVICE_ADDR, /* Actually, OpenMP 5.0. */ OMP_CLAUSE_NOWAIT, /* This must come last. */ OMP_MASK1_LAST @@ -1849,6 +1850,11 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, ("use_device_ptr (", &c->lists[OMP_LIST_USE_DEVICE_PTR], false) == MATCH_YES) continue; + if ((mask & OMP_CLAUSE_USE_DEVICE_ADDR) + && gfc_match_omp_variable_list + ("use_device_addr (", + &c->lists[OMP_LIST_USE_DEVICE_ADDR], false) == MATCH_YES) + continue; break; case 'v': /* VECTOR_LENGTH must be matched before VECTOR, because the latter @@ -2477,7 +2485,7 @@ cleanup: | OMP_CLAUSE_IS_DEVICE_PTR) #define OMP_TARGET_DATA_CLAUSES \ (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \ - | OMP_CLAUSE_USE_DEVICE_PTR) + | OMP_CLAUSE_USE_DEVICE_PTR | OMP_CLAUSE_USE_DEVICE_ADDR) #define OMP_TARGET_ENTER_DATA_CLAUSES \ (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \ | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT) @@ -4006,7 +4014,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED", "COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP", "TO", "FROM", "REDUCTION", "DEVICE_RESIDENT", "LINK", "USE_DEVICE", - "CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR" }; + "CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR", "USE_DEVICE_ADDR" }; if (omp_clauses == NULL) return; @@ -4563,7 +4571,25 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, } break; case OMP_LIST_IS_DEVICE_PTR: + if (!n->sym->attr.dummy) + gfc_error ("Non-dummy object %qs in %s clause at %L", + n->sym->name, name, &n->where); + if (n->sym->attr.allocatable + || (n->sym->ts.type == BT_CLASS + && CLASS_DATA (n->sym)->attr.allocatable)) + gfc_error ("ALLOCATABLE object %qs in %s clause at %L", + n->sym->name, name, &n->where); + if (n->sym->attr.pointer + || (n->sym->ts.type == BT_CLASS + && CLASS_DATA (n->sym)->attr.pointer)) + gfc_error ("POINTER object %qs in %s clause at %L", + n->sym->name, name, &n->where); + if (n->sym->attr.value) + gfc_error ("VALUE object %qs in %s clause at %L", + n->sym->name, name, &n->where); + break; case OMP_LIST_USE_DEVICE_PTR: + case OMP_LIST_USE_DEVICE_ADDR: /* FIXME: Handle these. */ break; default: diff --git a/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-1.f90 b/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-1.f90 new file mode 100644 index 00000000000..18211df0ea4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-1.f90 @@ -0,0 +1,24 @@ +! { dg-do compile } +subroutine test(b,c,d) + implicit none + integer, value, target :: b + integer, pointer :: c + integer, allocatable, target :: d + + integer, target :: a(5) + + !$omp target is_device_ptr(a) ! { dg-error "Non-dummy object .a. in IS_DEVICE_PTR clause" } + !$omp target is_device_ptr(b) ! { dg-error "VALUE object .b. in IS_DEVICE_PTR clause" } + !$omp target is_device_ptr(c) ! { dg-error "POINTER object .c. in IS_DEVICE_PTR clause" } + !$omp target is_device_ptr(d) ! { dg-error "ALLOCATABLE object .d. in IS_DEVICE_PTR clause" } + !$omp end target + !$omp end target + !$omp end target + !$omp end target + + !$omp target data map(a) use_device_addr(a) ! Should be okay + !$omp end target data + + !$omp target data map(c) use_device_ptr(c) ! Should be okay + !$omp end target data +end subroutine test