Following the publication of the Fortran 90 standard in 1991, two things happened. The first was that the High Performance Fortran Forum (HPFF) was set up to define a set of extensions to Fortran, to make it possible to write portable code when using parallel computers for handling problems involving large sets of data that can be represented by regular grids. This version of Fortran is known as High Performance Fortran (HPF), and is based on Fortran 90, mainly because of its array features. HPF is of a superset of Fortran 90, the main extensions being in the form of directives that take the form of Fortran 90 comment lines, and are thus recognized as directives only by an HPF processor. However, it did become necessary also to add some additional syntax, as not all the desired features could be accommodated in the form of such directives (see also High Performance Fortran, CERN/CN/95/11).
The second happening was that the standards committees, X3J3 and WG5, decided on a strategy whereby a minor revision of Fortran 90 would be prepared by the mid-1990s - Fortran 95 - and a further revision by about the year 2000. At the same time, it was clearly desirable to include the new syntax defined by HPFF in Fortran 95 and, indeed, the HPF features are the most significant new features that it introduces.
The other changes consist mainly of what are known as `corrections, clarifications and interpretations'. These came about as it was discovered that the text of the Fortran 90 standard contained a number of errors that required correction, some obscure wording that required further textual clarification, and ambiguous statements that required interpretation. Apart from the HPF syntax and the corrections, only a small number of other pressing but minor language changes were made. Fortran 95 is almost completely backwards compatible with Fortran 90.
A draft of the Fortran 95 standard was published in 1995, (ACM Fortran Forum, June, 1995). It was finalized in November 1995, and the expected schedule is for a new ISO standard, replacing Fortran 90, to be published in October 1996. This article is a summary of what is new in Fortran 95; the final version is completely described in Fortran 90/95 Explained, by John Reid and myself, (Oxford U. Press, March, 1996).
This section describes new features for parallel computing, based on HPF. They are designed to make Fortran a still better language for applications on parallel architectures.
Within FORALL statements or constructs (see below), the possibility that a function might have side effects is a severe impediment to optimization on a parallel processor - the order of execution of the assignments could affect the results. To control this situation, it is possible for the programmer to specify that a procedure has no side-effects by adding the PURE keyword to the SUBROUTINE or FUNCTION statement. In practical terms, this is an assertion that the procedure alters no global variable, performs no I/O, has no saved variables, and does not alter its INTENT(IN) arguments. These requirements are so formulated that a compiler can check that this is the case. An example is
PURE FUNCTION calculate (x)All the intrinsic functions are pure.
Elemental procedures are those with scalar dummy arguments that may be called with array actual arguments provided that the array arguments have the same shape. For a function, the shape of the result is the shape of the array arguments. Many intrinsic functions are elemental and Fortran 95 extends this to non-intrinsic procedures. It requires an ELEMENTAL prefix on the FUNCTION or SUBROUTINE statement. This is very useful to the programmer who can get the same effect in Fortran 90 only by writing 22 versions, for ranks 0-0, 0-1, 1-1, 0-2, 2-0, 2-2, ... 7-7, and is an aid to optimization on parallel processors. An elemental procedure must satisfy all the requirements of a pure procedure, as it automatically has the PURE attribute. All dummy arguments and function results must be scalar variables without the pointer attribute. For an elemental subroutine, if any argument is array valued, all the arguments with intent INOUT or OUT must be arrays. For example, we can make a subroutine, swap, perform its task on arrays of any shape or size:
ELEMENTAL SUBROUTINE swap(a, b) REAL, INTENT(INOUT) :: a, b REAL work work = a a = b b = work END SUBROUTINE swap
When a DO construct is executed, the processor is required to perform each successive iteration in order and one after the other. This represents a potential impediment to optimization on a parallel processor so, for this purpose, Fortran 95 has the FORALL statement, for example
FORALL(i = 1:n) a(i, i) = x(i)which specifies that the individual assignments may be carried out in any order, and even simultaneously. The FORALL statement may be considered to be an array assignment expressed with the help of indices. In this particular example, this operation could not otherwise be represented as a simple array assignment. Another example of the FORALL statement is
FORALL(i=1:n, j=1:n, y(i,j)/=0.) & x(j,i)=1.0/y(i,j)where the masking condition ensures that the assignment is not carried out for zero elements of Y.
The FORALL construct also exists. It allows several assignment statements to be executed in order. The FORALL equivalent of the array assignments
a(2:n-1,2:n-1) = a(2:n-1,1:n-2) & + a(2:n-1,3:n) & + a(1:n-2,2:n-1) & + a(3:n,2:n-1) b(2:n-1,2:n-1) = a(2:n-1,2:n-1)is
FORALL(i = 2:n-1, j = 2:n-1) a(i,j) = a(i,j-1) + a(i,j+1) & + a(i-1,j) + a(i+1,j) b(i,j) = a(i,j) END FORALLThis sets each internal element of A equal to the sum of its four nearest neighbours and copies the result to B. The FORALL version is more readable. Each assignment in a FORALL is like an array assignment; the effect is as if all the expressions were evaluated in any order, held in temporary storage, then all the assignments performed in any order. The first statement must fully complete before the second can begin.
A FORALL statement or construct may contain pointer assignments, may be nested, and may include a WHERE statement or construct. Procedures may be referenced within a FORALL, both in the logical scalar expression that forms the optional mask or, directly or indirectly, in the body of the construct. All such procedures must be pure.
For full details of this important new feature, please see the references above.
It is permitted in Fortran 95 to mask not only the WHERE statement of the WHERE construct, but also any ELSEWHERE statement that it contains. A WHERE construct may contain any number of masked ELSEWHERE statements but at most one ELSEWHERE statement without a mask, and that must be the final one. In addition, WHERE constructs may be nested within one another, just like FORALL constructs. A WHERE assignment statement is permitted to be a defined assignment, provided that it is elemental. Finally, a WHERE construct may be named in the same way as other constructs.
Many processors distinguish at the hardware level between a negative real zero value and a positive real zero value, and the IEEE standard for binary floating-point arithmetic (IEEE 754 or IEC 559-1989) makes use of this where possible. In order to be able to distinguish between the two cases in Fortran 95, the function SIGN has been generalized such that the sign of the second argument may be taken into account even if its value is zero. On a processor that has IEEE arithmetic, the value of SIGN(2.0, -0.0) is -2.0.
In Fortran 90, an allocated array that does not have the save attribute has an undefined allocation status on return from a subprogram. In Fortran 95, such an array is automatically deallocated. This feature not only avoids inadvertent memory leakage, but prevents the very undesirable undefined allocation status. For allocatable arrays defined in modules, see the references.
Any of the intrinsic functions defined by the standard may now be used in a specification expression. In addition, a non-intrinsic pure function may be so used provided that certain simple conditions are fulfilled. Such functions are called specification functions. This feature will be a convenience for specification expressions that cannot be written as simple expressions.
allows pointers to be given the initial status of disassociated in a
type declaration statement such as
REAL, POINTER, DIMENSION(:) :: vector => NULL()
NULL is a new intrinsic function and may be used in an executable
vector => NULL()It is very useful in avoiding memory leaks.
Fortran 95 allows us to specify that any object of a derived type is
given a default initial value for a component.
The value is
specified when the component is declared as part of the type definition.
If the component is not a pointer, this is done in the
If the component is a pointer, the only
initialization allowed is to NULL().
Initialization does not have to apply to all components of a
given derived type:
REAL :: value = 0.0
TYPE(node), POINTER :: next => NULL()
END TYPE node
Given an array declaration such as
TYPE(node), DIMENSION(100) :: arrsubobjects such as arr(3)%value will have the initial value 0.0, and the value false will be returned by the reference ASSOCIATED(arr(3)%next).
The implications for nested definitions, the interaction with the SAVE attribute, overriding default values, and dynamic object creation are all described in the references above.
For consistency with similar functions, the numeric intrinsic functions CEILING and FLOOR may now take an optional KIND keyword argument.
The transformational array location functions MAXLOC and MINLOC are extended with an optional argument DIM like those for the functions MAXVAL and MINVAL. The functions MAXVAL, MINVAL, PRODUCT, and SUM already have a DIM argument, but for consistency with MAXLOC and MINLOC, are extended to allow their MASK argument as the second positional argument.
There is a new intrinsic subroutine that returns the processor time, CPU_TIME.
There are minor changes concerning comments in NAMELIST input, minimal field width editing, and allowing an optional generic specification on the END INTERFACE statement.
There are six additions to Fortran's list of obsolescent features: fixed source form, computed GO TO, CHARACTER* form of character specification, DATA statements amongst executable statements, statement functions, and assumed character length of function results. Also, for the first time, the standard contains a list of five features that were formerly obsolescent but are now deleted. The references above describe what they are and, for both categories, what to use instead.
This article has set out the briefly the changes that Fortran 95 brings to the language, with their justifications. But standardization continues, and Fortran 2000, planned for the year 2001 and whose contents are still speculative, will certainly be described at the appropriate time in these pages.