Parameterized Derived Types make first appearance in gfortran 8.0.0

1175 views
Skip to first unread message

paul.rich...@gmail.com

unread,
Sep 9, 2017, 11:35:51 AM9/9/17
to
Dear All,

I have just applied a patch to GNU Fortran (GCC) 8.0.0 20170909 (experimental) which implements Parameterized Derived Types.

This implementation is still somewhat rough around the edges and so I would greatly appreciate bug reports, preferably to gcc Bugzilla with the title prefaced by "PDT" or directly to me.

The five testcases pdt_[1-5].f03 will give an impression of the state of implementation.

Regards

Paul


paul.rich...@gmail.com

unread,
Sep 9, 2017, 2:30:29 PM9/9/17
to
I forgot to add an appreciation to the Sourcery Institute and Damian Rouson, in particular, for support for this work.

Thanks guys!

Paul

FortranFan

unread,
Sep 9, 2017, 4:25:35 PM9/9/17
to
On Saturday, September 9, 2017 at 11:35:51 AM UTC-4, paul.rich...@gmail.com wrote:

> ..
>
> I have just applied a patch to GNU Fortran (GCC) 8.0.0 20170909 (experimental) which implements Parameterized Derived Types.
>
> ..

@Paul,

Mighty congratulations!

Thank you for your great effort, it is a wonderful achievement, bringing GNU Fortran (GCC) ever closer to a full-feature Fortran 2003 compiler if at all there are any aspects still pending from that iconic standard revision following your latest work on PDTs!

If you and your GCC colleagues can conjure up extra magic and effort, GNU Fortran can be a full-feature Fortran 2015 compiler next year, just when the standard is 'officially' published during August 2018 (per https://wg5-fortran.org/f2015.html). That is, once you have "climbed the mountain" in terms of Coarrays, PDTs, and SUBMODULEs, the pending features from the two supposed minor revisions of 2008 and 2015 will not faze you!

Wow, 2015 by 2018! Now that's a target to shoot for!

Many thanks,

FortranFan

unread,
Sep 9, 2017, 4:31:49 PM9/9/17
to
On Saturday, September 9, 2017 at 2:30:29 PM UTC-4, paul.rich...@gmail.com wrote:

> ..
>
> I forgot to add an appreciation to the Sourcery Institute and Damian Rouson, in particular, for support for this work.
>
> Thanks guys!
> ..

Kudos to Damian Rouson and the Sourcery Institute, great contribution to the advancement of Fortran.

Much appreciated,

FortranFan

unread,
Sep 9, 2017, 5:00:37 PM9/9/17
to
On Saturday, September 9, 2017 at 11:35:51 AM UTC-4, paul.rich...@gmail.com wrote:

> ..
> I have just applied a patch to GNU Fortran (GCC) 8.0.0 20170909 (experimental) which implements Parameterized Derived Types. ..

@Paul,

Will it possible for you to share your experiences - the issues and challenges - you faced while implementing the PDT feature in GNU Fortran? How difficult was it, especially the length-type parameter? If you can put together a brief report or a summary of some sort that you can place online, it will be of great help to other implementations. It can also be useful with features in future revisions of the Fortran standard.

Thanks,

Damian Rouson

unread,
Sep 10, 2017, 12:04:10 PM9/10/17
to
Many thanks for your tireless efforts on this, Paul. I have a sense of how much thought and preparation went into this over the years. And thanks for the acknowledgement, especially given that your actual effort greatly exceeds the resources available for financial support. You've done a great service to the Fortran community.

Damian

FortranFan

unread,
Sep 11, 2017, 4:54:31 PM9/11/17
to
On Saturday, September 9, 2017 at 11:35:51 AM UTC-4, paul.rich...@gmail.com wrote:

>.. I would greatly appreciate bug reports, preferably to gcc Bugzilla with the title prefaced by "PDT" or directly to me. ..

@Paul,

If you wish I can send you a simple initial case directly but I thought it will be useful for readers to know of this as well: here's a quick test I tried of what I think is a standard-conforming program and which works as I expect with Intel Fortran:

--- begin PDT example ---
program p

use, intrinsic :: iso_fortran_env, only : CK => character_kinds

implicit none

type :: pdt_t(k,l)
integer, kind :: k = CK(1)
integer, len :: l
character(kind=k,len=l) :: s
end type

type(pdt_t(l=12)) :: foo

foo%s = "Hello World!"
print *, "foo%s = ", foo%s
print *, "len(foo%s) = ", len(foo%s), "; expected is foo%l = ", foo%l
print *, "foo%k = ", foo%k

stop

end program
--- end example ---

Upon compilation with GNU Fortran (gfortran) 8.0.0 20170909 (experimental), the output with errors is

p.f90:10:22:
character(kind=k,len=l) :: s
1
Error: Constant expression required at (1)
p.f90:15:8:
foo%s = "Hello World!"
1
Error: 's' at (1) is not a member of the 'pdtpdt_t_1' structure
p.f90:16:29:
print *, "foo%s = ", foo%s, "
1
Error: 's' at (1) is not a member of the 'pdtpdt_t_1' structure
p.f90:17:38:
print *, "len(foo%s) = ", len(foo%s), "; expected is foo%l = ", foo%l
1
Error: 's' at (1) is not a member of the 'pdtpdt_t_1' structure

The code compiles with no errors or warnings with Intel Fortran and upon execution, the output is as I expect:

foo%s = Hello World!
len(foo%s) = 12 ; expected is foo%l = 12
foo%k = 1

FortranFan

unread,
Sep 11, 2017, 5:12:21 PM9/11/17
to
On Monday, September 11, 2017 at 4:54:31 PM UTC-4, FortranFan wrote:

> .. here's a quick test I tried ..
> Upon compilation with GNU Fortran (gfortran) 8.0.0 20170909 (experimental), the output with errors ..

@Paul,

By the way, as you probably have realized, the following variation with length-type parameter only works fine:

--- begin example ---
program p

use, intrinsic :: iso_fortran_env, only : compiler_version

implicit none

type :: pdt_t(l)
integer, len :: l
character(len=l) :: s
end type

type(pdt_t(l=12)) :: foo

print *, "Compiler Version: ", compiler_version()

foo%s = "Hello World!"
print *, "foo%s = ", foo%s
print *, "len(foo%s) = ", len(foo%s), "; expected is foo%l = ", foo%l

stop

end program p
--- end example ---

Upon execution,

Compiler Version: GCC version 8.0.0 20170910 (experimental)

paul.rich...@gmail.com

unread,
Sep 12, 2017, 3:21:22 PM9/12/17
to
Hi,

Thanks for this - it looks as if I have not implemented the insertion of the KIND expression for characters. I'll take a look later on.

Cheers

Paul

paul.rich...@gmail.com

unread,
Sep 13, 2017, 2:04:28 PM9/13/17
to
Since you provided me with a rather useful testcase later in this thread, which is now fixed and 8.0.0 update this evening, I would be more than happy to oblige :-)

The basic process was one of on-and-off contemplation of how to do this over a period of nearly five years, followed by 6 weeks of coding and testing, which was interspersed with daytime work and eclipse chasing.

It was obvious that instances of the PDTs corresponding to kind parameters would have to be emitted. I looked at all sorts of possibilities to do this using macros or simply producing all the valid combinations straight off.

The light bulb moment came when I realised that all the mechanics to do the job were already present in the gfortran frontend. The treatment of the decl_param_name_list was so similar to that of formal arguments that this was a no-brainer. A namespace, attached to derived types, had already been introduced years ago; partly to take typebound procedures but also with PDT parameters in mind. Symbols, corresponding to each of the type parameters, are put in this namespace.

The next step was the recognition that the type_param_spec_list is sufficiently similar to actual arguments that the associated code was easily modified to accept them. The parameterized expressions associated with each of the components are then walked and the parameter symbols substituted for by the corresponding expressions in the type_param_spec_list.

Finally, LEN parameters were dispatched using the machinery for allocatable derived type components. This turned out to be very straight forward. In fact, looking at it now, it might be a future subject of simplification since, I think, I have repeated some of the parameter substitution unnecessarily.

The principal difficulty that I had, apart from waiting for inspiration, was gleaning from the standard the constraints on the use of the type parameters; most especially deferred and assumed parameters. In fact, there are some corners where I do not think that I have them right even now.

Conclusions:
(i) 5 years of wandering round in circles, 24 hours of inspiration and 6 weeks of perspiration.
(ii) For future new features, if they are this complication, it would be helpful to gather all the relevant changes to the standard, including constraints in one place. For PDTs they are scattered all over the place. John Reid's notes are helpful but not complete enough for this purpose.

Regards

Paul

Damian Rouson

unread,
Sep 13, 2017, 4:52:13 PM9/13/17
to
On Wednesday, September 13, 2017 at 11:04:28 AM UTC-7, paul.rich...@gmail.com wrote:
> Conclusions:
> (i) 5 years of wandering round in circles, 24 hours of inspiration and 6 weeks of perspiration.

Wow. What an incredible journey and a Herculean task.

Damian

FortranFan

unread,
Sep 14, 2017, 2:05:58 PM9/14/17
to
On Wednesday, September 13, 2017 at 2:04:28 PM UTC-4, paul.rich...@gmail.com wrote:

> ..
> Conclusions:
> (i) 5 years of wandering round in circles, 24 hours of inspiration and 6 weeks of perspiration.
> (ii) For future new features, if they are this complication, it would be helpful to gather all the relevant changes to the standard, ..

@Paul,

Thank you very much for your feedback on this, great summary and very valuable.

Re: "i) 5 years of wandering round in circles, 24 hours of inspiration and 6 weeks of perspiration"

- I wonder what the Fortran community kinds about this level of effort. I personally find parameterized derived types to be a valuable addition to the standard: I believe they can serve as part of the broad foundation on which the language can provide improved support for generics, at least toward scientific/technical computing needs. Also, with robust and reliable implementations of PDTs in compilers, I feel one can create more 'convenient' code designs of simulation programs and compute libraries toward, what I call, N-body problems i.e., the computations involved largely make use of data objects whose sizes are some functions of [N], a set of problem sizes ascertained during the initial stages (or the very beginning) of a simulation/calculation, a simple example being a solver class for the solution to N equations. All in all, I will say the value of PDTs in the language far exceeds the level of effort required for GNU Fortran, but that's my opinion only. What do readers think? Can Fortran bring in new features, whatever they be, if the effort was similar to that of PDT implementation in GNU Fortran? I earnestly hope the answer will remain yes.

Re: "ii) For future new features, if they are this complicat(ed), it would be helpful to gather all the relevant changes to the standard, including constraints in one place".

- yes it sounds like a good suggestion. Actually it will be most helpful if the "What's new in Fortran XXXX' document by WG5 following a new revision were to be appreciably more detailed with information on why the features were added, what are the envisioned use cases, detailed code examples that can serve as a necessary (if not sufficient) test suite for all compiler implementations, all this in addition to a compilation of the changes to the standard brought on by the feature. But given the supposedly limited resources, all this appears impossible to achieve.

FortranFan

unread,
Oct 27, 2017, 11:00:03 AM10/27/17
to
On Wednesday, September 13, 2017 at 2:04:28 PM UTC-4, paul.rich...@gmail.com wrote:

>..
> Since you provided me with a rather useful testcase later in this thread, which is now fixed and 8.0.0 update this evening ..

@Paul,

Thanks again for your follow-up earlier. Here's another case involving parameterized derived types that gfortran fails to compile. If you're interested in following up, you can check the code against the standard; I believe it's conforming and gfortran is wrong to issue the error.

--- begin case ---
module m
type :: t(k)
integer, kind :: k = 1
contains
procedure, pass(this) :: p1
procedure, pass(this) :: p2
generic :: p => p1, p2
end type
contains
subroutine p1( this )
class(t(k=1)), intent(inout) :: this
end subroutine
subroutine p2( this )
class(t(k=2)), intent(inout) :: this
end subroutine
end module
--- end case ---

Compilation output with gfortran, the output is

--- begin output ---
generic :: p => p1, p2
1
Error: 'p1' and 'p2' for GENERIC 'p' at (1) are ambiguous
C:\dev\Fortran\temp\sor\m.f90:5:15:
procedure, pass(this) :: p1
1
Error: Argument 'this' of 'p1' with PASS(this) at (1) must be of the derived-type 't'
C:\dev\Fortran\temp\sor\m.f90:6:15:
procedure, pass(this) :: p2
1
Error: Argument 'this' of 'p2' with PASS(this) at (1) must be of the derived-type 't'
Process terminated with status 1 (0 minute(s), 0 second(s))
3 error(s), 0 warning(s) (0 minute(s), 0 second(s))
--- end output ---

paul.rich...@gmail.com

unread,
Oct 27, 2017, 1:57:35 PM10/27/17
to
Thanks for the report. This is now bug #82753.

Paul

FortranFan

unread,
Oct 31, 2017, 4:23:43 PM10/31/17
to
On Wednesday, September 13, 2017 at 2:04:28 PM UTC-4, paul.rich...@gmail.com wrote:

> ..
>
> Since you provided me with a rather useful testcase later in this thread ..


@Paul,

Here's another issue, a nastier one involving an internal compiler error, from a case tried by James Van Buskirk:
https://groups.google.com/d/msg/comp.lang.fortran/7QJAwoKN4Jw/kLuSid-VCgAJ

--- begin code ---
type :: t(ell)
integer, len :: ell
character(len=1) :: s(ell)
end type

integer, parameter :: N = 2
type(t(ell=:)), allocatable :: foo

allocate( t(ell=N) :: foo )
foo%s = transfer(source=repeat("x",ncopies=N), mold=[ character(len=1) :: ], size=N)

end
--- end code ---

Compilation output:

gfortran.exe -c p.f90 -o p.o
f951.exe: internal compiler error: Segmentation fault
libbacktrace could not find executable to open
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.

FortranFan

unread,
Oct 31, 2017, 5:30:51 PM10/31/17
to
On Wednesday, September 13, 2017 at 2:04:28 PM UTC-4, paul.rich...@gmail.com wrote:

> ..
> Since you provided me with a rather useful testcase later in this thread ..


And a couple more in case they catch your interest:

--- begin case 1 ---
type :: t(k)
integer, kind :: k
end type

type(t(k=1)), allocatable :: foo

foo = t(k=1)()

end
--- end case 1 ---

gfortran.exe -c p.f90 -o p.o
foo = t(k=1)()
1
Error: Invalid character in name at (1)


--- begin case 2 ---
type :: t(ell)
integer, len :: ell
end type

type(t(ell=:)), allocatable :: foo

foo = t(ell=2)()

end
--- end case 2 ---

gfortran.exe -c p.f90 -o p.o
p.f90:7:16:
foo = t(ell=2)()
1
Error: Invalid character in name at (1)

Per my read of the standard, both the above cases are standard-conforming and compile ok with Intel Fortran.

FortranFan

unread,
Oct 31, 2017, 11:41:42 PM10/31/17
to
On Tuesday, October 31, 2017 at 5:30:51 PM UTC-4, FortranFan wrote:

> On Wednesday, September 13, 2017 at 2:04:28 PM UTC-4, paul.rich...@gmail.com wrote:
>
> > ..
> > Since you provided me with a rather useful testcase later in this thread ..
>
>
> And a couple more in case they catch your interest:
> ..

And another one to try once the earlier cases are resolved:

--- begin case ---
type :: t(ell)
integer, len :: ell
end type

type :: u
type(t(ell=:)), allocatable :: x
end type

type(t(ell=:)), allocatable :: foo
type(u) :: bar

allocate( t(ell=1) :: foo )

bar = u( x=foo )

end
--- end case ---

gfortran.exe -c p.f90 -o p.o
p.f90:14:14:
bar = u( x=foo )
1
Error: Can't convert TYPE(Pdtt) to TYPE(t) at (1)

paul.rich...@gmail.com

unread,
Nov 5, 2017, 8:08:10 AM11/5/17
to
This is a problem with the simplification of transfer:

integer, parameter :: N = 2
character(len=1) :: chr(N)
chr = transfer(source=repeat("x",ncopies=N), mold=[ character(len=1) :: ], size=N)
end

fails in the same way.

I will post it on Bugzilla.

Thanks

Paul

paul.rich...@gmail.com

unread,
Nov 5, 2017, 8:21:41 AM11/5/17
to
This is Bug #82842.

I will be having a blitz on PDT bugs the week after next. This one will certainly be squashed.

Thanks

Paul

paul.rich...@gmail.com

unread,
Nov 5, 2017, 8:36:31 AM11/5/17
to
This is Bug #82843.

Thanks

Paul

FortranFan

unread,
Nov 18, 2017, 11:43:44 PM11/18/17
to
On Wednesday, September 13, 2017 at 2:04:28 PM UTC-4, paul.rich...@gmail.com wrote:

> ..
>
> Since you provided me with a rather useful testcase ..


@Paul,

Fyi - in the other on the ICE with allocatable character type, I just posted a long outstanding issue with gfortran:
https://groups.google.com/d/msg/comp.lang.fortran/Lg8tBwlkS6A/XsR5sxVmAwAJ

And now here's another problem with gfortran, this time with parameterized derived types and one that also involves a structure constructor:

--- begin case ---
type :: t(ell)
integer, kind :: ell
character(len=ell) :: s
end type t

type(t(ell=42)), parameter :: foo = t(ell=42)( s="a" )

print *, "length of foo%s = ", len(foo%s), ", expected length is foll%ell: ", foo%ell

end
--- end case ---

Compilation output with gfortran:

--- begin output ---
gfortran.exe -c p.f90 -o p.o
p.f90:6:38:
type(t(ell=42)), parameter :: foo = t(ell=42)( s="a" )
1
Error: No initializer for component 's' given in the structure constructor at (1)
p.f90:8:42:
print *, "length of foo%s = ", len(foo%s), ", expected length is foll%ell: ", foo%ell
1
Error: Symbol 'foo' at (1) has no IMPLICIT type

You will find this code compiles just fine with Intel Fortran and the output is:

length of foo%s = 42 , expected length is foll%ell: 42


Cheers,

FortranFan

unread,
Nov 18, 2017, 11:46:37 PM11/18/17
to
On Saturday, November 18, 2017 at 11:43:44 PM UTC-5, FortranFan wrote:

> ..
> And now here's another problem with gfortran, this time with parameterized derived types and one that also involves a structure constructor: ..


And a variant:

type :: t(ell)
integer, kind :: ell
character(len=ell) :: s
end type t

type(t(ell=42)) :: foo

foo = t(ell=42)( s="a" )
print *, "length of foo%s = ", len(foo%s), ", expected length is foll%ell: ", foo%ell

end

gfortran.exe -c p.f90 -o p.o
p.f90:8:16:
foo = t(ell=42)( s="a" )
1

FortranFan

unread,
Dec 2, 2017, 9:53:19 AM12/2/17
to
On Sunday, November 5, 2017 at 8:21:41 AM UTC-5, paul.rich...@gmail.com wrote:

> ..
>
> I will be having a blitz on PDT bugs the week after next. ..


@Paul,

If you or other GNU volunteers haven't given up on PDTs in gfortran yet, here's another issue to consider (and note I still have more gfortran PDT bug cases for you!!):

--- begin code ---
use, intrinsic :: iso_fortran_env, only : I8 => int64
type :: t(ell)
integer(kind=I8), len :: ell
end type
end
--- end code ---

Compilation response:
gfortran.exe -c -Wall p.f90
p.f90:3:30:
integer(kind=I8), len :: ell
1
Error: Component with LEN attribute at (1) must be default integer kind (4)

You will notice in section 4.5.2 Derived-type parameters in WORKING DRAFT
J3/04-007 May 10, 2004 toward Fortran 2003 in lines 12 and 13 say, "Each type parameter is itself of type integer. If its kind selector is omitted, the kind type parameter is default integer." And the same concept is included in the Fortran 2008 revision and the latest committee draft on Fortran 2018.

As far as I can tell, there is no constraint in any revision of the standard the length-type parameter be of default integer kind.

Thanks,

paul.rich...@gmail.com

unread,
Dec 2, 2017, 2:27:49 PM12/2/17
to
Hi FortranFan,

You might want to update your 8.0.0 - I did a retreat in a cottage in Cornwall last week and fixed a substantial number of PDT bugs. I have to confess that that the above was not among them :-( It is trivially fixed though.

In addition to those that I have fixed, you might want to take a look at the PDT meta-bug PR82173 before unleashing those that you have to hand.

PR82649 is the most pressing of the bugs since it will require a partial rewrite of the implementation in order to introduce PDT descriptors. I have a plan.....

Apart from this, there are issues with type matching in interface comparisons and with PDT constructors.

I think that all these issues will be sorted out by the time 8.1.0 is released. Thanks for all your help. Also, I should thank Reinhold Bader and Gerhard Steinmetz for all of their testing to destruction of the current PDT implementation.

Regards

Paul


FortranFan

unread,
Dec 30, 2017, 11:10:14 PM12/30/17
to
On Saturday, December 2, 2017 at 2:27:49 PM UTC-5, paul.rich...@gmail.com wrote:

> ..
> Apart from this, there are issues with type matching in interface comparisons ..

@Paul,

Thanks much for all your effort. Wish you many more retreats to enjoy that lead to many more blessings for the FOSS developers!

Re: your comment above with "issues with type matching in interface comparisons", you may want to consider the test case below as well:

--- begin code snippet ---
module m

type :: t(ell)
integer, len :: ell
integer :: i(ell)
end type

contains

subroutine sub( a )
type(t(ell=*)), intent(inout) :: a
end

end module m
! main program
use m, only : t, sub

type(t(ell=42)) :: foo

call sub( foo )

end
--- end code ---

Upon compilation,
gfortran.exe -c p.f90
p.f90:20:18:
call sub( foo )
1
Error: Type mismatch in argument 'a' at (1); passed TYPE(Pdtt) to TYPE(pdtt)

paul.rich...@gmail.com

unread,
Jan 1, 2018, 1:07:41 PM1/1/18
to
Aaaah, its's the 'only' that has done that. I need to make sure that 't' is expanded to encompass the PDT instances in the USE statement.

This is now PR83646.

Thanks

Paul
Reply all
Reply to author
Forward
0 new messages