------------------------------------------------------------------------ ------------------------------------------------------------------------ Fortran 90 in Scientific Computing Juha Haataja and Jussi Rahola, CSC ------------------------------------------------------------------------ This article was originally published in the CSC News magazine (Vol. 8, No 4, December 1996). ------------------------------------------------------------------------ History of Fortran The development of the Fortran programming language was started in 1954 at IBM. A report containing the words "FORmula TRANslator" gave the name to the language, and thus the first ever high-level programming language was born. Fortran was also the first programming language to be standardized. The first standard is known as Fortran 66 because it was finalized in 1966. The next evolutionary step was Fortran 77 which was accepted in 1978 and 1979 to be the new ANSI and ISO standard. The development of Fortran 90 is a logical continuation of the Fortran standardization and development effort, although this revision of the standard is much larger than the previous ones. This is due to the general developments in the theory and practice of programming languages in the 1970's and 1980's. The most well known programming languages from this era are Pascal and C. These languages offer many features not included in Fortran 77. On the other hand, none of these new languages was developed specially for numerical computing, and therefore Fortran 77 is today still widely used in science and engineering. The Fortran 90 standard The current version of the Fortran standard is know as Fortran 90. This standard was accepted as ANSI and ISO standards in 1991. The first Fortran 90 compiler installed at CSC in the summer of 1992 was the NAGWare f90 compiler. Today all the compute servers at CSC offer a Fortran 90 compiler, and Fortran 77 is slowly being phased out. The developments in other programming languages strongly affected the development of Fortran 90. In addition to the modernization of the language, compability and portability of Fortran codes had to be taken into account. Also, the most important shortcomings of the Fortran 77 standard had to be corrected. For example, Fortran 90 offers many new features for better error checking and programming safety. Fortran 90 contains the Fortran 77 language as a subset, with minor exceptions. Some features of Fortran 77 are declared as "obsolescent", which means that these features should not be used in new codes. Instead the new and better features of the language should be used. In future standards some features may be marked as "deleted". This way the Fortran standard can be cleaned of some features of mainly historical interest. At this point it should be noted that many programmers who say they are using the old Fortran 77 standard are actually not doing so. Many "Fortran 77" codes use, e.g., names longer than six letters, the IMPLICIT NONE statement, or the END DO statement. None of these features are included in the Fortran 77 standard, but all are contained in Fortran 90. The future of Fortran The development of Fortran has not ceased. The next revision of the language is called Fortran 95. This is a minor revision of the standard, where some ambiguities of the Fortran 90 standard are cleared and a few extensions are added. The first compilers for this standard will appear in the beginning of 1997. DEC, for example, already supports some features of the Fortran 95 standard. The High-Performance Fortran (HPF) language is a data-parallel extension to the Fortran 90 programming language. The HPF standard contains directives and structures for data-parallel computation. In fact, most of the extensions included in the Fortran 95 revision come from the HPF standard. Unfortunately, there are few HPF compilers available at the moment. Also, the efficiency of the generated code is usually not very good, depending on the application. In addition to the HPF superset of Fortran 90, there are some compilers for subsets of the Fortran 90 language: the F language compiler, and the Elf90 compiler (Essential Lahey Fortran). Both offer a modern subset of the language, suitable for teaching and educational purposes. On the other hand, old Fortran codes can not be compiled using either one of these compilers. The next major development in the Fortran language is the so-called "Fortran 2000 project". This revision of the language is a major one, though maybe not as big as the Fortran 90 revision was. At this point, there are no final decisions on what the Fortran language will look like in the year 2000. However, we are certain that Fortran will be alive and well. New and improved features in Fortran 90 The Fortran 90 language looks like a totally new programming language although it maintains compatibility with the Fortran 77 standard. Below we describe the major new and improved features of Fortran 90. The most visible change is the introduction of a new free source form, which discards the column-oriented fixed Fortran 77 format inherited from punched cards. In the free format, statements can begin in any column and an ampersand (&) in the end of the line implies that the line is continued on the next line. The maximum length of the line is 132 characters. Another visible change is a new variable declaration scheme where the variable attributes and names are separated by two colons (::). Of course, the older way of using, for example, separate type and DIMENSION declarations is still legal Fortran. However, the new syntax makes it easy to use many of the advanced features of Fortran 90. Fortran 90 allows long names of up to 31 characters for variables and procedures. This feature has been used in many Fortran 77 compilers as a standard extension. Another widely used Fortran 77 extension that is now part of the Fortran 90 standard is the DO ... END DO construct. Besides this, the Fortran 90 language offers also the SELECT CASE, DO WHILE, EXIT and CYCLE control structures and statements. The accuracy of the intrinsic numerical data types of Fortran can now controlled by kind parameters, which makes writing portable code a lot easier. Intrinsic types can be combined in derived type declarations, which is familiar to users of Pascal or C languages. Fortran programs can now contain modules, which encapsulate data structures and the corresponding algorithms to a single package. The modules replace COMMON blocks and provide an elegant and portable way of using global variables. The new array syntax allows the programmer to manipulate arrays as single entities using an efficient and compact array notation. This makes it easier to vectorize and parallelize codes. For example, it is easy to compute the elementwise sum or product of two matrices. Matrix intrinsic functions are available to compute the dot product of two vectors and matrix-vector products. Used with restrain, the array syntax makes codes easier to read and maintain. One of the serious drawbacks of the Fortran 77 language was the lack of dynamic memory management. Fortran 90 fixes this with the introduction of allocatable arrays and pointer variables. The language also incorporates a number of minor improvements. For example, recursive procedures are now supported and the collection of intrinsic functions has been enlarged. Advanced features of Fortran 90 The Fortran 90 language supports abstract data types (ADT). This means that a datatype and the operations on that datatype are public, but the implementation details are private. This way the programmer is free to change the implementation of an ADT while the user of the ADT module does not have to change his or her code. Using the PUBLIC and PRIVATE attributes it is also possible to implement data hiding, whereby only the necessary details are made public to the user of a module. This encourages modularity on the source code level, and also as a programming strategy. This makes it easier to develop, test, and maintain codes in large software development projects. The Fortran 90 array syntax also works with derived types. In addition, you can overload procedures and operators, which makes it possible to develop your own compact notation. In this way, a module for, e.g., tensor operations is relatively straightforward to develop. Portability of Fortran 90 programs Fortran 90 contains several new features which make it easier to develop portable codes. The use of parametrized data types is especially useful when writing codes to be used on different platforms. Using the so-called KIND parameters it is possible to declare for example REAL variables, which have at least a precision of 12 decimal numbers wherever the code is compiled. Also included are functions like PRECISION, EPSILON and HUGE, which return information about the selected numeric type. The Fortran 90 standard discourages the use of the storage association model. Storage association means using the EQUIVALENCE or COMMON statements or mapping two-dimensional arrays to one-dimensional arrays etc. It the old days the storage association was the only way to do certain operations - now there are much better alternatives in the language. Fortran 90 contains pointers and allocatable arrays, which make it easy and safe to do things the EQUIVALENCE statement was (mis)used to do. Modules can be used to declare global data, instead of the error-prone COMMON blocks. The old features such as COMMON and EQUIVALENCE should not be used, because codes using these features are difficult to understand and maintain. Also, you can't use the compiler for checking errors in these statements. In addition, codes using these features are very difficult to parallelize: on a parallel computer, the storage association model does not apply. How to start using Fortran 90 As the Fortran 90 standard includes the Fortran 77 standard, one can just recompile old programs using new compilers. However, to increase the readability and maintainability of old codes, certain old Fortran anachronisms should be replaced by new and better features. For example, character constants should not be written using the Hollerith notation, and the computed GOTO construct should be avoided. The most important rule in converting old Fortran programs to Fortran 90 is: "if it works, don't fix it". However, the new language features can gradually be introduced to old programs to enhance their usability. There are a number of automatic converters available to help the user to modernize his or her code. These converters translate codes from the old fixed source form to the new free format. The converters can also be used to change short variable names to more meaningful ones. Although it is not enforced by the standard, all variables should be explicitly declared in order to minimize the risk of typing errors. To get rid of workspace limitations, one can easily introduce the memory allocation features of Fortran 90. For example, a subroutine can allocate a local work array just by declaring it with a dimension given in the subroutine parameter list. Loops involving matrix manipulation can be replaced with array constructs, which makes the code more readable and compact. Common blocks should be replaced by variables declared in modules. Experiences with Fortran 90 Some Fortran 90 features, such as array syntax, have been available on the Cray and Convex compilers for many years. Native Fortran 90 compilers have lately become available on all the hardware platforms at CSC. The compilers are for the most part robust and efficient, and can produce even faster code than the Fortran 77 compilers. Some of the hardware vendors now supply only a Fortran 90 compiler, which can of course be used to compile standard-conforming Fortran 77 programs. According to CSC's recent user survey, 28% of our customers used the Fortran 77 programming language, 7% used Fortran 90, 10% used C, and 5% used C++. However, 46% of the customers did not do any programming. Note that a user could specify multiple choices. Of the people who did program development themselves, 64% used Fortran 77 or 90, and 29% used C or C++. At CSC, we have been extensively using the Fortran 90 language and most of its new features. The language contains many elegant new features which allows one to write clear, efficient, portable and robust code. However, some of the declaration statements could have been written more clearly if the language did not have to be compatible with older Fortran versions. New Fortran 90 programs should be written in a totally new programming style. A good style is suggested by the F language, which is a subset of the Fortran 90 standard targeted for educational purposes. In the CSC textbook on Fortran 90 a uniform and clear programming style is also used and encouraged. In our opinion, Fortran 90 programs are less error-prone than corresponding programs written in the C or C++ languages. This is due to the strict typing and more restricted use of pointers in Fortran 90. For developing user interfaces or operating system services, the C or C++ languages are still preferred. However, the Fortran 90 language provides just the right level of abstraction for writing numerical algorithms and at the same time maintaining a good performance, which is not always true for C++ programs. Further reading CSC has published a textbook on Fortran 90, written in Finnish. You can find information about the CSC textbook at the World Wide Web (WWW) address http://www.csc.fi/oppaat/f90/. The Fortran Market is a useful collection of Fortran information on the WWW system. The address is http://www.fortran.com/fortran/market.html. An example of Fortran 90 code The following Fortran codes read a vector of a given length, and calculate the corresponding normalized vector. The Fortran 90 version of the code uses allocatable arrays and array syntax. Fortran 77 version: PROGRAM VECNOR INTEGER MAX, N, I PARAMETER (MAX = 25) REAL X(MAX), NORM, EUCNOR, MINNOR PARAMETER (MINNOR = 1.E-25) READ (*,*) N IF (N .GT. MAX) STOP 'Array too big!' DO 100 I = 1, N READ (*,*) X(I) 100 CONTINUE WRITE (*,*) 'Original vector:' DO 200 I = 1, N WRITE (*,*) X(I) 200 CONTINUE WRITE (*,*) NORM = EUCNOR(X, N) WRITE (*,*) 'Normalized vector:' IF (NORM .LE. MINNOR) THEN DO 300 I = 1, N WRITE (*,*) 0.0 300 CONTINUE ELSE DO 400 I = 1, N WRITE (*,*) X(I) / NORM 400 CONTINUE END IF END REAL FUNCTION EUCNOR(X, N) INTEGER N, I REAL X(N), SQSUM SQSUM = 0.0 DO 100 I = 1, N SQSUM = SQSUM + X(I)**2 100 CONTINUE EUCNOR = SQRT(SQSUM) END Fortran 90 version: PROGRAM vector_norm IMPLICIT NONE REAL, ALLOCATABLE, DIMENSION(:) :: x REAL :: norm REAL, PARAMETER :: min_norm = 1.e12*TINY(x) INTEGER :: n, allocstat, i READ (*,*) n ALLOCATE(x(n), STAT=allocstat) IF (allocstat /= 0) STOP 'Memory allocation failed!' READ (*,*) x WRITE (*,*) 'Original vector:' WRITE (*,*) x WRITE (*,*) norm = SQRT(SUM(x**2)) WRITE (*,*) 'Normalized vector:' IF (norm <= min_norm) THEN WRITE (*,*) (0.0, i = 1, n) ELSE WRITE (*,*) x / norm END IF END PROGRAM vector_norm ------------------------------------------------------------------------