[patch] Fortran: Add OpenMP 'interop' directive parsing support
This patch adds Fortran parsing support for OpenMP's 'interop' directive (which stops with a 'sorry' in trans-openmp.cc as the middle end support is still missing). Tested on x86-64-gnu-linux. Comments, suggestions, remarks? * * * Background: 'interop' makes it easier to call, e.g., a CUDA-BLAS function directly as it permits to map an OpenMP device number (→ "target" modifier required) to the "foreign runtime" device number or to get directly a stream object (→ if "targetsync" modifier specified) with dependency tracking. Just calling '!$omp interop init(obj)' works but that leaves the decision which type of object should be returned to the run time. Using 'prefer_type', the user can ask for a specific type. Permits is a string such as "hip" or an integer constant such as omp_ifr_cuda_driver – and the old-style syntax is 'prefer_type(string> [ , ...])'. [Note thatn a constant integer expression is permitted.] The new syntax permits additional attributes like for 'sycl' requesting an 'in-order' queue (instead of the default 'out-of-order' queue when obtaining a stream. The new syntax is 'prefer_type( {...} [, {...} ... } ) where '{ ... }' is a list of either 'attr("ompx_...")' (i.e. 'attr(...)' with literal string arg that starts with ompx_ and does not contain a ',') or 'fr()' where the identifier is an integer constant. 'fr' can be present or not, but only once per {...} while multiple 'attr' may be used. [Note that as non-string only an identifier is permitted (i.e. a integer parameter).] I decided for the used way to encode the string – but I am open to other representations as well. In my WIP/RFC patch is is used as shown in plugin-*.c in the patch https://gcc.gnu.org/pipermail/gcc-patches/2024-August/661207.html The available foreign runtimes and values that can be returned values are hidden in that patch and more readable in the documentation patch at https://gcc.gnu.org/pipermail/gcc-patches/2024-August/661365.html If someone wants to delve into the details of the 'interop' feature: Have a look at OpenMP 5.1 (5.2) *and* TR13 and the additional definition document at https://www.openmp.org/specifications/ ('hsa': publishing pending). * * * Tobias PS: In the dump, I am a bit lazy and add spurious tailing ','. As it is only a dump, I decided adding a bunch of checks to ensure that a ',' only gets printed if needed is not really required. If you think otherwise, I can surely add a bunch of 'if' an only print it conditionally. PPS: In order to to use 'interop', mainly the part in middle is missing, i.e. some middle-end gimplification with a call into libgomp – and the libgomp function. A stub version of the latter and some (loosely) tested plugin handling does exist as WIP/RFC patch, see patch link above. - Besides gimplify and the libgomp function, a bunch of tests and, obviously, the C and C++ FE counterpart to this patch have to be implemented. Fortran: Add OpenMP 'interop' directive parsing support Parse OpenMP's 'interop' directive but stop with a 'sorry, unimplemented' after resolving. Additionally, it moves some clause dumping away from the end directive as that lead to 'nowait' not being printed when it should as some cases were missed. gcc/fortran/ChangeLog: * dump-parse-tree.cc (show_omp_namelist): Handle OMP_LIST_INIT. (show_omp_clauses): Handle OMP_LIST_{INIT,USE,DESTORY}; move 'nowait' from end-directive to the directive dump. (show_omp_node, show_code_node): Handle EXEC_OMP_INTEROP. * gfortran.h (enum gfc_statement): Add ST_OMP_INTEROP. (OMP_LIST_INIT, OMP_LIST_USE, OMP_LIST_DESTROY): Add. (enum gfc_exec_op): Add EXEC_OMP_INTEROP. (struct gfc_omp_namelist): Add interop items to union. (gfc_free_omp_namelist): Add boolean arg. * match.cc (gfc_free_omp_namelist): Update to free interop union members. * match.h (gfc_match_omp_interop): New. * openmp.cc (gfc_omp_directives): Uncomment 'interop' entry. (gfc_free_omp_clauses, gfc_match_omp_allocate, gfc_match_omp_flush, gfc_match_omp_clause_reduction): Update call. (enum omp_mask2): Add OMP_CLAUSE_{INIT,USE,DESTROY}. (OMP_INTEROP_CLAUSES): Use it. (gfc_match_omp_clauses): Match those clauses. (gfc_match_omp_prefer_type, gfc_match_omp_init, gfc_match_omp_interop): New. (resolve_omp_clauses): Handle interop clauses. (omp_code_to_statement): Add ST_OMP_INTEROP. (gfc_resolve_omp_directive): Add EXEC_OMP_INTEROP. * parse.cc (decode_omp_directive): Parse 'interop' directive. (next_statement, gfc_ascii_statement): Handle ST_OMP_INTEROP. * st.cc (gfc_free_statement): Likewise * resolve.cc (gfc_resolve_code): Handle EXEC_OMP_INTEROP. * trans.cc (trans_code): Likewise. * trans-openmp.cc (gfc_trans_omp_directive): Print 'sorry' for EXEC_OMP_INTEROP. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/interop-1.f90: New test. * gfortran.dg/gomp/interop-2.f90: New test. * gfortran.dg/gomp/interop-3.f90: New test. gcc/fortran/dump-parse-tree.cc | 61 +
[PATCH, pushed] Fortran: fix ICE with use with rename of namelist member [PR116530]
Dear all, the attached simple & obvious patch fixes a NULL pointer dereference when USEing with rename a namelist member and reading/writing the namelist. Patch was OK'ed in the PR by Steve and is pushed to mainline as: r15-3308-g6bfeba12c86b4d0dae27d99b484f64774dd49398 As this is a 14/15 regression, I plan to backport when it has successfully passed the testers. Thanks, Harald From 6bfeba12c86b4d0dae27d99b484f64774dd49398 Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Thu, 29 Aug 2024 21:21:39 +0200 Subject: [PATCH] Fortran: fix ICE with use with rename of namelist member [PR116530] gcc/fortran/ChangeLog: PR fortran/116530 * trans-io.cc (transfer_namelist_element): Prevent NULL pointer dereference. gcc/testsuite/ChangeLog: PR fortran/116530 * gfortran.dg/use_rename_12.f90: New test. --- gcc/fortran/trans-io.cc | 3 ++- gcc/testsuite/gfortran.dg/use_rename_12.f90 | 27 + 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/use_rename_12.f90 diff --git a/gcc/fortran/trans-io.cc b/gcc/fortran/trans-io.cc index 7ab82fa2f5b..c0baa718ef6 100644 --- a/gcc/fortran/trans-io.cc +++ b/gcc/fortran/trans-io.cc @@ -1692,7 +1692,8 @@ transfer_namelist_element (stmtblock_t * block, const char * var_name, gcc_assert (sym || c); /* Build the namelist object name. */ - if (sym && !sym->attr.use_only && sym->attr.use_rename) + if (sym && !sym->attr.use_only && sym->attr.use_rename + && sym->ns->use_stmts->rename) string = gfc_build_cstring_const (sym->ns->use_stmts->rename->local_name); else string = gfc_build_cstring_const (var_name); diff --git a/gcc/testsuite/gfortran.dg/use_rename_12.f90 b/gcc/testsuite/gfortran.dg/use_rename_12.f90 new file mode 100644 index 000..0447d5fe150 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/use_rename_12.f90 @@ -0,0 +1,27 @@ +! { dg-do compile } +! PR fortran/116530 - ICE with member of namelist renamed by use module +! +! Reported by philippe.wautelet at cnrs.fr + +module mod_nml1 + implicit none + logical :: ldiag + namelist /nam_nml1/ldiag +end module mod_nml1 + +module mod_interm + use mod_nml1 +end module mod_interm + +program ice_nml + use mod_nml1,ldiag_nml1 => ldiag + use mod_nml1, only : ldiag_only => ldiag + use mod_interm + implicit none + integer :: ilu = 10 + read(unit=ilu,nml=nam_nml1) + write(unit=*,nml=nam_nml1) + print *, ldiag + print *, ldiag_nml1 + print *, ldiag_only +end program ice_nml -- 2.35.3
Re: [PATCH, pushed] Fortran: fix ICE with use with rename of namelist member [PR116530]
Thanks for the patch. If you have not already opened a new PR for the other issue with C8107, I'll open one later today. It's likely that we need to check the namelist-group-name for USE association in match.cc:gfc_match_namelist. Hmmm, it seems we already catch the error, but accept it as an extension. % gfcx -o z -std=f2023 a.f90 && ./z a.f90:11:23: 11 |namelist /nam_nml1/j | 1 Error: GNU Extension: Namelist group name 'nam_nml1' at (1) already is USE associated and cannot be respecified. In hindsight, I wish GNU extensions had warnings associated with them. -- steve On Thu, Aug 29, 2024 at 09:31:37PM +0200, Harald Anlauf wrote: > Dear all, > > the attached simple & obvious patch fixes a NULL pointer dereference > when USEing with rename a namelist member and reading/writing the > namelist. > > Patch was OK'ed in the PR by Steve and is pushed to mainline as: > > r15-3308-g6bfeba12c86b4d0dae27d99b484f64774dd49398 > > As this is a 14/15 regression, I plan to backport when it has > successfully passed the testers. > > Thanks, > Harald > > From 6bfeba12c86b4d0dae27d99b484f64774dd49398 Mon Sep 17 00:00:00 2001 > From: Harald Anlauf > Date: Thu, 29 Aug 2024 21:21:39 +0200 > Subject: [PATCH] Fortran: fix ICE with use with rename of namelist member > [PR116530] > > gcc/fortran/ChangeLog: > > PR fortran/116530 > * trans-io.cc (transfer_namelist_element): Prevent NULL pointer > dereference. > > gcc/testsuite/ChangeLog: > > PR fortran/116530 > * gfortran.dg/use_rename_12.f90: New test. > --- > gcc/fortran/trans-io.cc | 3 ++- > gcc/testsuite/gfortran.dg/use_rename_12.f90 | 27 + > 2 files changed, 29 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gfortran.dg/use_rename_12.f90 > > diff --git a/gcc/fortran/trans-io.cc b/gcc/fortran/trans-io.cc > index 7ab82fa2f5b..c0baa718ef6 100644 > --- a/gcc/fortran/trans-io.cc > +++ b/gcc/fortran/trans-io.cc > @@ -1692,7 +1692,8 @@ transfer_namelist_element (stmtblock_t * block, const > char * var_name, >gcc_assert (sym || c); > >/* Build the namelist object name. */ > - if (sym && !sym->attr.use_only && sym->attr.use_rename) > + if (sym && !sym->attr.use_only && sym->attr.use_rename > + && sym->ns->use_stmts->rename) > string = gfc_build_cstring_const > (sym->ns->use_stmts->rename->local_name); >else > string = gfc_build_cstring_const (var_name); > diff --git a/gcc/testsuite/gfortran.dg/use_rename_12.f90 > b/gcc/testsuite/gfortran.dg/use_rename_12.f90 > new file mode 100644 > index 000..0447d5fe150 > --- /dev/null > +++ b/gcc/testsuite/gfortran.dg/use_rename_12.f90 > @@ -0,0 +1,27 @@ > +! { dg-do compile } > +! PR fortran/116530 - ICE with member of namelist renamed by use module > +! > +! Reported by philippe.wautelet at cnrs.fr > + > +module mod_nml1 > + implicit none > + logical :: ldiag > + namelist /nam_nml1/ldiag > +end module mod_nml1 > + > +module mod_interm > + use mod_nml1 > +end module mod_interm > + > +program ice_nml > + use mod_nml1,ldiag_nml1 => ldiag > + use mod_nml1, only : ldiag_only => ldiag > + use mod_interm > + implicit none > + integer :: ilu = 10 > + read(unit=ilu,nml=nam_nml1) > + write(unit=*,nml=nam_nml1) > + print *, ldiag > + print *, ldiag_nml1 > + print *, ldiag_only > +end program ice_nml > -- > 2.35.3 > -- Steve
Re: [PATCH, pushed] Fortran: fix ICE with use with rename of namelist member [PR116530]
Hi Steve, Am 29.08.24 um 21:53 schrieb Steve Kargl: Thanks for the patch. If you have not already opened a new PR for the other issue with C8107, I'll open one later today. It's likely that we need to check the namelist-group-name for USE association in match.cc:gfc_match_namelist. Hmmm, it seems we already catch the error, but accept it as an extension. % gfcx -o z -std=f2023 a.f90 && ./z a.f90:11:23: 11 |namelist /nam_nml1/j | 1 Error: GNU Extension: Namelist group name 'nam_nml1' at (1) already is USE associated and cannot be respecified. ah, I overlooked this. In hindsight, I wish GNU extensions had warnings associated with them. Should we downgrade this extension to GFC_STD_LEGACY? Not sure when it was implemented or where it was used. Current NAG and Intel reject it hard; Nvidia and Flang accept it. Harald
[PATCH] Fortran: default-initialization of derived-type function results [PR98454]
Dear all, the attached, rather simple patch adds the missing default-initialization of non-pointer, non-allocatable derived-type function results. Regtested ok on x86_64-pc-linux-gnu, but needed two adjustments in the testsuite. One of them is easily explained by the fix, but the other one to gfortran.dg/pdt_26.f03 makes me scratch my head. The patch adds default-initialization and thus changes the count of __builtin_malloc in the tree dump, but not the __builtin_free count. Running the testcase under valgrind shows that no memleak occurs at -O1 and higher, but I get a minor leak at -O0 and -Og. The dump tree is the same at -O0 and -O1, which is nice. Any suggestions how to proceed? And is the patch OK for mainline? The PDT implementation may have latent issues, but that is just a guess. Thanks, Harald From b75d3cb8321018f68b39e1799113bf7815bfab19 Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Thu, 29 Aug 2024 22:17:07 +0200 Subject: [PATCH] Fortran: default-initialization of derived-type function results [PR98454] gcc/fortran/ChangeLog: PR fortran/98454 * resolve.cc (resolve_symbol): Add default-initialization of non-allocatable, non-pointer derived-type function results. gcc/testsuite/ChangeLog: PR fortran/98454 * gfortran.dg/alloc_comp_class_4.f03: Remove bogus pattern. * gfortran.dg/pdt_26.f03: Adjust expected count. * gfortran.dg/derived_result_3.f90: New test. --- gcc/fortran/resolve.cc| 3 + .../gfortran.dg/alloc_comp_class_4.f03| 2 +- .../gfortran.dg/derived_result_3.f90 | 158 ++ gcc/testsuite/gfortran.dg/pdt_26.f03 | 2 +- 4 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/derived_result_3.f90 diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index 5db327cd12b..a78e9b7daf7 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -17262,6 +17262,9 @@ resolve_symbol (gfc_symbol *sym) /* Mark the result symbol to be referenced, when it has allocatable components. */ sym->result->attr.referenced = 1; + else if (a->function && !a->pointer && !a->allocatable && sym->result) + /* Default initialization for function results. */ + apply_default_init (sym->result); } if (sym->ts.type == BT_CLASS && sym->ns == gfc_current_ns diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03 b/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03 index 3118b552a30..4a55d73b245 100644 --- a/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03 +++ b/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03 @@ -71,7 +71,7 @@ contains allocatable :: t_init end function - type(t) function static_t_init() ! { dg-warning "not set" } + type(t) function static_t_init() end function end module test_pr58586_mod diff --git a/gcc/testsuite/gfortran.dg/derived_result_3.f90 b/gcc/testsuite/gfortran.dg/derived_result_3.f90 new file mode 100644 index 000..4b28f7e28c9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/derived_result_3.f90 @@ -0,0 +1,158 @@ +! { dg-do run } +! PR fortran/98454 - default-initialization of derived-type function results + +program test + implicit none + type t + integer :: unit = -1 + end type t + type u + integer, allocatable :: unit(:) + end type u + type(t) :: x, x3(3) + type(u) :: y, y4(4) + + ! Scalar function result, DT with default initializer + x = t(42) + if (x% unit /= 42) stop 1 + x = g() + if (x% unit /= -1) stop 2 + x = t(42) + x = f() + if (x% unit /= -1) stop 3 + x = t(42) + x = h() + if (x% unit /= -1) stop 4 + x = t(42) + x = k() + if (x% unit /= -1) stop 5 + + ! Array function result, DT with default initializer + x3 = t(13) + if (any (x3% unit /= 13)) stop 11 + x3 = f3() + if (any (x3% unit /= -1)) stop 12 + x3 = t(13) + x3 = g3() + if (any (x3% unit /= -1)) stop 13 + x3 = t(13) + x3 = h3() + if (any (x3% unit /= -1)) stop 14 + x3 = t(13) + x3 = k3() + if (any (x3% unit /= -1)) stop 15 + + ! Scalar function result, DT with allocatable component + y = u() + if (allocated (y% unit)) stop 21 + allocate (y% unit(42)) + y = m() + if (allocated (y% unit)) stop 22 + allocate (y% unit(42)) + y = n() + if (allocated (y% unit)) stop 23 + allocate (y% unit(42)) + y = o() + if (allocated (y% unit)) stop 24 + allocate (y% unit(42)) + y = p() + if (allocated (y% unit)) stop 25 + + ! Array function result, DT with allocatable component + y4 = u() + if (allocated (y4(1)% unit)) stop 31 + allocate (y4(1)% unit(42)) + y4 = m4() + if (allocated (y4(1)% unit)) stop 32 + y4 = u() + allocate (y4(1)% unit(42)) + y4 = n4() + if (allocated (y4(1)% unit)) stop 33 + + y4 = u() + allocate (y4(1)% unit(42)) + y4 = o4() + if (allocated (y4(1)% unit)) stop 34 + y4 = u() + allocate (y4(1)% unit(42)) + y4 = p4() + if (allocated (y4(1)% unit)) stop 35 + +contains + + ! Function result not referenced within function body + function f() +type(t
Re: Installing gfortran-14
Hi Thomas & Damian Thank you. I'm running Ubuntu 24.04 in an x86_64 system. I do have dpkg and it said (lf) john:~/Gcc-build$ dpkg -S libc-header-start.h libc6-dev:amd64: /usr/include/x86_64-linux-gnu/bits/libc-header-start.h So I tried $ sudo apt install libc6-dev $ ../Gcc/gcc-14.2.0/configure --prefix=$HOME --enable-multilib --enable-languages=c,c++,fortran $ make -j4 but I still got the same error message from make. John On Thu, 29 Aug 2024, Thomas Koenig wrote: Date: Thu, 29 Aug 2024 06:25:23 + From: Thomas Koenig To: John Harper Cc: Damian Rouson , "fortran@gcc.gnu.org" Subject: Re: Installing gfortran-14 Resent-Date: Thu, 29 Aug 2024 18:25:38 +1200 (NZST) Resent-From: [You don't often get email from tkoe...@netcologne.de. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ] Hi John, /usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory 27 | #include I'm not sure what system you are running. On my Ubuntu system, which is Debian-based, you can search for the package that provides a file with $ dpkg -S libc-header-start.h which, for me, returns libc6-dev. You can then install that with $ apt install libc6-dev If your system does not provide dpkg and apt, you'll have to use whatever tool there is. Best regards Thomas -- John Harper, School of Mathematics and Statistics Victoria Univ. of Wellington, PO Box 600, Wellington 6140, New Zealand. e-mail john.har...@vuw.ac.nz
Re: Installing gfortran-14
On 8/29/24 7:53 PM, John Harper wrote: Hi Thomas & Damian Thank you. I'm running Ubuntu 24.04 in an x86_64 system. I do have dpkg and it said (lf) john:~/Gcc-build$ dpkg -S libc-header-start.h libc6-dev:amd64: /usr/include/x86_64-linux-gnu/bits/libc-header-start.h So I tried $ sudo apt install libc6-dev $ ../Gcc/gcc-14.2.0/configure --prefix=$HOME --enable-multilib --enable-languages=c,c++,fortran $ make -j4 but I still got the same error message from make. John I am reminded. When using --enable-multilib you need both the 32-bit and the 64-bit libraries. Possibly libc6-i386 libc6-dev-i386. Jerry