## Tuesday, November 28, 2006

### More on modern Fortran

From the echo on my earlier post about why we use Fortran for number crunching applications, I gather that many people still associate Fortran with the worst features of the now mostly obsolete FORTRAN 77 standard (fixed source form, implicit typing) and are mostly unaware of the great strides the development of the Fortran standard has made in the past 30 (sic!) years. So I feel that this might be a good opportunity to talk a little about the advanced features that make Fortran 95 so convenient for developping computational physics applications. [Note that in the following Fortran 95 will be referred to simply as "Fortran" for the sake of brevity.]

To start with, there are Fortran's superior array features which greatly facilitate working with vectors, matrices and tensors: Being able to write vector addition as
`a = b + c`
instead of some kind of `for`-loop is a great boon in terms of code legibility. Having the `sum`, `product`, `dot_product` and `matmul` intrinsic functions available to perform common mathematical operations on arrays using a (hopefully) efficient vendor-supplied math library also helps.

But where Fortran's array features really shine is when it comes to defining `elemental` functions and subroutines, which save a huge amount of coding. An elemental function or subroutine is one which is defined with scalar dummy arguments, but which fulfils certain technical conditions that allow it to be called with an array passed as the actual argument. When called in this way, an elemental function is evaluated on each element of the passed array argument, and the results are assembled into an array of the same shape. Most of the mathematical functions Fortran provides as intrinsics are elemental. So one can do something like
`Pi = 4.*atan(1.)x = (/ (i*Pi/n,i=0,n) /) ! array constructor with implied do-loopy = sin(x) ! an elemental assignment operation`
to load `y(i)` with `sin(x(i))` for all i. And better yet, user-defined functions can also be elementary, so you only ever need to write the overloaded operators for your automatically-differentiating spinor type as scalars, and Fortran will take care of dealing with the arrays of those spinors that occur in your code.

Next in usefulness and importance comes the already mentioned support for overloading operators and intrinsic functions on user-defined types. Again, this provides a lot of convenience in terms of maintaining a coding style that stays as close to standard mathematical notation as possible, and of keeping the gory details of complex type operations (such as multiplying two automatically-differentiating spinors) transparent to the programmer/user on the next higher level. The ability to have public and private procedures and variables in modules also helps with this kind of encapsulation.

And that isn't all: `namelist` I/O provides a cheap kind of configuration files; `selected_int_kind` and `selected_real_kind` allow testing whether the system provides sufficient range/precision at compile time; the `forall` construct allows some measure of parallelization on parallel processors where the compiler supports it.

The next incarnation of the Fortran standard, Fortran 2003, exists only as a standard document at this time, although compiler vendors are beginning to add features from Fortran 2003 to their compilers in a piecewise fashion. Major new features include object orientation (single inheritance, polymorphism and deferred binding) and C interoperability (so you can call C system libraries from Fortran programs, and/or call your Fortran matrix-crunching code from a C application).

And after that, the future Fortran 2008 standard is expected to include co-arrays to support parallel and distributed computing, a bitfield type, a Fortran-specific macro preprocessor, among other things.

Advanced programmers keen to learn about Fortran 2003's new features may want to have a look at the Fortran 95/2003 book by Cohen, Metcalf and Reid. This is the successor to Metcalf and Reid's Fortran 90/95 book, which is still probably the best reference to modern Fortran, as most of the Fortran 2003 features aren't available on most platforms yet, whereas standard Fortran 95 is very portable.

For beginning programmers, or people who have never worked with any flavour of Fortran before, the book by Chapman (which I haven't read personally) may be a better idea from the reviews I've seen, but the reviews also indicate that it is not useful as a reference, so you may have to get the Metcalf et.al. book(s) anyway.

Oleg said...

I totally agree that there should be some language for calculations and fortran 90 arrays and elementary functions are great, but for me it seems that fortran is too overweighted with old and odd constructs.

I dont have f77 experience, but lots of C/C++/Java/Python/...

1) allocatable, pointer, target - do these mean something on supercomputers? I used to C pointers which were much simpler to understand.

2) IO seems to be bound to printers and other devices: records, markers. Formatters even better than in printf, but some parts are frustrating.

3) There could be some kind of templating (ok probably overkill, but specifying the same algorithm function several times is NOT nice)

4) Real constructors and destructors, otherwise you may loose memory with overloaded operators in A+B*C

I dont have experience with supercomputers, so I may miss something here, but looking forward to fortran 2003 and hope it will remove some odd features (still preserving linking compatibility with old f77 libraries)

Georg said...

Allocatable arrays are a very useful feature and take the place of C pointers in a lot of cases. Fortran pointer are a completely different kind of beast from C pointers; personally, I try to stay away from them as much as possible.

Formatted I/O is a strong area of Fortran, but you are right that the burden of its heritage is particularly obvious in that area.

Some aspects of templating are addressed in Fortran 2003 with parametrised data types, and many other aspects will be addressed by the 'smart macros' that are to come with Fortran 2008.

Memory leaks are rarely a problem in Fortran, since local variables without the "save" attribute are automatically deallocated on return from a subroutine or function.