In November 2014, I led a session at SC14 (the event formerly known as “Supercomputing”) titled “The Future of Fortran”. I invited representatives from other vendors and members of the Fortran standards committee to participate, and had some accept, but when it came time for the session, I was up there alone. Oh well…

I had prepared a short, vendor-neutral presentation on the current state of the Fortran standard and what was coming in the next standard, currently called Fortran 2015. (I expect this name to stick.) After that I opened it up for questions from the audience, which was more substantial than I expected (about 70-80 people, despite an awful time slot.) At the end invited attendees to participate in an online survey of Fortran usage, and the results were interesting (see the end of this post).

First, I spoke about the current standard, Fortran 2008 (2010) and the previous one, Fortran 2003 (2004). There is one vendor supporting all of Fortran 2008 (Cray) and three supporting Fortran 2003 (IBM, Intel, PGI/NVidia).

Fortran 2015 was envisioned as a minor revision with only two major feature sets plus corrections of inconsistencies (referred to as “wart removal”). As is usually the case, a bunch of small features have crept in, but the result is still manageable. If you want the complete list, the Introduction to the new standard lists all the changes. The current draft is here, but it doesn't yet reflect all the changes.

The current schedule calls for the “technical work” to be done in 2015, hence the name. The expectation is that the new standard would be published sometime in 2017, but it may get pushed out further, as I discuss later.

In the following sections I will highlight the major changes, but won’t go into full detail. You can look at the draft (see above) for that.

The "Interop TS"

The first big feature set was defined in a separate Technical Specification TS29113 “Further Interoperability with C”. This was approved in 2012 with the intent that vendors could implement the features now with reasonable assurance that the final standard would not be incompatible. A big driver of the “Interop TS”, as it is often called, was the needs of MPI 3.0. As is hinted by the title, Fortran 2015 extends the C interoperability features that first appeared in Fortran 2003 as follows:

Assumed-type and assumed-rank make it easier to interoperate with C’s “void *”

ALLOCATABLE, POINTER, assumed-shape and CHARACTER(*) arguments can be passed to and from C, communicated with a new data structure called a “C descriptor”

New ISO_Fortran_binding.h C header file declares C descriptors and routines for manipulating them

OPTIONAL arguments are now interoperable

ASYNCHRONOUS was extended to more than I/O

Relaxed restrictions on dummy arguments

Assumed-type variables are declared with the new syntax TYPE(*) and are allowed only as dummy arguments. Assumed-type variables have no type (are effectively unlimited polymorphic, so you can pass any type to one of these), but unlike ordinary polymorphic variables you can’t do a SELECT TYPE on them. In Fortran code if you want to use these at all you have to “cast” them to a Fortran pointer type using C_LOC and C_F_POINTER. Assumed-type variables may not have the ALLOCATABLE, CODIMENSION, INTENT(OUT), POINTER or VALUE attributes.

Assumed-rank variables are declared with the new syntax DIMENSION(..); DIMENSION(*) already had a meaning, so you’re supposed to think of this as a colon on its side. Again, only dummy variables may have assumed-rank. You can pass an item of any rank, including scalar, to an assumed-rank dummy argument. (If the item is assumed-type, it must also be assumed-shape or assumed-rank to pass to an assumed-rank dummy.) The rank of an assumed-rank dummy is assumed from the actual argument, which may be 0 if the actual was a scalar. These are passed by descriptor (C descriptor if the procedure is BIND(C) - see below). An assumed-rank dummy may not have the CODIMENSION or VALUE attributes. A new RANK intrinsic returns the rank of its argument.

At the February 2015 standards meeting, we accepted a proposal for a new SELECT RANK construct which is similar in concept to SELECT TYPE. It can be used on assumed-rank variables only and within each select block, the “associate variable” has the rank specified. This hasn't yet been accepted by the ISO committee, but I expect that to happen at our meeting in August 2015. Without SELECT RANK, it is difficult to do much with an assumed-rank variable in Fortran code.

C descriptors are an invention of the Fortran standard – they define a standard-conforming way to communicate extended information about procedure arguments such as shape, type, ALLOCATABLE/POINTER attributes and more. The standard specifies that the Fortran implementation provide a C header file named ISO_Fortran_binding.h that declares the typedefs for C descriptors, macros for values of various members, and definitions of functions for accessing and manipulating C descriptors. Any changes to the descriptor must be made through one of these functions. All the typedefs, macros and functions have names beginning with “CFI_”. An important point is that while the standard defines some restrictions on the layout of C descriptors, there is room for implementation-dependent members and member order, so C descriptors are not necessarily interchangeable among different Fortran implementations. Nonetheless, they allow mixed Fortran-C applications to do away with dependencies on vendor extensions.

Here’s a short example of a Fortran-C program that uses C descriptors.

use, intrinsic :: iso_c_binding interface function c_alloc (array) bind(C) import integer(C_INT) :: c_alloc real(C_FLOAT), intent(out), allocatable, dimension(:) :: array end function c_alloc end interface real(C_FLOAT), allocatable, dimension(:) :: my_array if (c_alloc(my_array) == 0) then print *, lbound(my_array), ubound(my_array); print *, my_array end if end

#include "ISO_Fortran_binding.h“ extern int c_alloc (CFI_cdesc_t * descr) { int ret, i; float * array; CFI_index_t lower = 0, upper = 10; ret = CFI_allocate (descr, &lower, &upper, 0); // No elem_len if (ret == CFI_SUCCESS) { array = descr->base_addr; for (i=lower;i<=upper;i++) {array[i] = (float) i;} } return ret; }

The “Coarray TS”

The other major feature set is contained in TS18508, “Additional Parallel Features in Fortran”, generally referred to as the “Coarray TS”. Unlike the “Interop TS”, the Coarray TS is still in flux. When I spoke about this last November, I was not optimistic that things would settle down enough to meet the already ambitious schedule. However, at the February 2015 meeting we made major changes to the most contentious aspect and I am feeling a lot better about its chances now.

There are generally four parts to the Coarray TS: teams, events, atomics and collectives. A “team” is a collection of images in a coarray application that are working together on a particular task. The application may have several (or many) teams working independently and then communicating their results to their parent. The nice thing about teams is that image numbering is relative to the team making it much easier to construct libraries that use coarrays without having to worry about the “coshape” of the entire application. Syntax has been added to allow you to specify a team variable as part of a coindex reference.

Teams can themselves form subteams, and teams can be dissolved and reformed dynamically. One reason to do this is if one of the images fails – as the number of images grows this can become more and more likely. But this was where the arguments raged – how do you know if an image has failed, or perhaps is just taking longer than it should to respond?

Initially, the TS had the notion of “stalling” where an image failed to make progress but was still somehow alive. We spent many, many meetings debating this topic and failed to come up with a solution for expressing in the language how to detect and recover from stalled images. In February we chose to toss the whole idea of stalling. Instead, an image could be deemed to have failed and status arguments were added to synchronization constructs to detect that an image had failed. (The actual mechanism for such detection is implementation dependent, of course.) A caveat is that some of the more vocal participants in the debate weren't at the February meeting, so it remains to be seen how the revised TS is accepted at the August meeting.

Another significant part to the TS is “events”, a way for one image notifying another image that a task has been completed and that it can proceed. This part has been settled for some time now and I don’t expect further changes.

Fortran 2008 added the concept of ATOMIC objects for which operations are done indivisibly, but there was limited support for them. The Coarray TS adds procedures for more atomic operations such as ADD, AND, CAS (Compare and Swap), OR and XOR.

Lastly, collectives are intrinsic procedures for performing some operation across all the images of the current team. New subroutines defined are CO_MAX, CO_MIN, CO_SUM, CO_BROADCAST and CO_REDUCE.

What Else?

In addition to the two Technical Specifications above, Fortran 2015 will have a number of smaller changes intended to improve consistency across the language. Some of these are:

Being able to specify the type and kind of the implied DO variable in an array constructor and in DATA (this was prompted by a suggestion in our user forum!)

SIZE= can be used with advancing input (like our Q format extension)

G0.d can be used with integer, logical and character list items

New intrinsics RANDOM_INIT, COSHAPE, REDUCE, OUT_OF_RANGE

IMPORT is now allowed in a contained procedure and in BLOCK

IMPLICIT NONE(EXTERNAL) requires explicit interfaces for all procedures

All procedures are recursive by default – NON_RECURSIVE may be specified if desired

Finally, what the standards committee giveth, the standards committee can also taketh away. Newly declared “obsolescent” are labeled DO loops (DO 10 I…), EQUIVALENCE, COMMON and BLOCK DATA. Arithmetic IF and the non-block DO construct, where the DO range doesn't end in a CONTINUE or END DO, are finally deleted from the language, having been declared obsolescent for several revisions. Note that none of these will actually be removed from any compiler you are likely to use, but their use will be flagged if you ask for standards checking.

The Survey Says….

As I noted earlier, I invited those attending the SC14 session to respond to a survey about Fortran usage. I didn't get a lot of responses (eleven), but what I did get was interesting:

45% said they were using coarrays now, 64% thought they would be using coarrays in three years

73% were using C interoperability features now and 36% thought they would use DO CONCURRENT within three years

C was the overwhelming (90%) “other language” used in mixed-language applications, but Python came in a surprising second (27%)

90% of the responders use three or more different Fortran compilers in their work

Responders had been programming in Fortran an average of 14 years (range was 4 to 28)

100% thought they would still be using Fortran in five years

Want to take the survey yourself? It’s still open at http://goo.gl/forms/j55wX7EyPs

Feel free to put in your comments here on Fortran 2015 (or the survey). As always, if you need help with the compiler or with the Fortran language, please ask in our user forums. We have one for Windows users and one for Linux/Mac users.