Writing robust and "modern" Fortran code

Blklight picture Blklight · May 3, 2010 · Viewed 14.6k times · Source

In some scientific environments, you often cannot go without FORTRAN as most of the developers only know that idiom, and there is lot of legacy code and related experience. And frankly, there are not many other cross-platform options for high performance programming (C++ would do the task, but the syntax, zero-starting arrays, and pointers are not compatible with some people).

So, let's assume a new project must use Fortran 90, but I want to build the most modern software architecture out of it, while being compatible with most recent compilers (Intel ifort, but also including the Sun/HP/IBM compilers)

So I'm thinking of imposing stuff that is widely known as common good sense, but not yet a standard in my environment:

  • global variable forbidden, no gotos, no jump labels, implicit none, etc.
  • "object-oriented programming" (modules with datatypes and related subroutines)
  • modular/reusable functions, well documented, reusable libraries
  • assertions/preconditions/invariants (implemented using preprocessor statements)
  • unit tests for all (most) subroutines and "objects"
  • an intense "debug mode" (#ifdef DEBUG) with more checks and all possible Intel compiler checks possible (array bounds, subroutine interfaces, etc.)
  • uniform and enforced legible coding style, using code processing tool helpers.

The goal with all that is to have trustworthy, maintainable and modular code. Whereas, in lot of legacy codes, re-usability was not a important target.

I searched around for references about object-oriented Fortran, programming-by-contract (assertions/preconditions/etc.), and found only ugly and outdated documents, syntaxes and papers done by people with no large-scale project involvement, and dead projects.

Any good URLs, advice, reference paper/books on this subject?

Answer

High Performance Mark picture High Performance Mark · May 3, 2010

I suggest that OP drops the attitude that Fortran is something nasty to be endured in high-performance scientific computing and dives into it enthusiastically. If OP retains that rather dismissive mindset then his/her entire Fortran coding career is going to be a struggle. And really, there's nothing you can do with Fortran that you can't do with C++ so why bother if you really don't want to ?

There is nothing in OP's list of bullets that a lot of us who have been working with Fortran for the last 30 years haven't been doing (since the widespread availability of Fortran 90 compilers but some of it before then too). Yes, there are computational scientists, and scientific software engineers, who understand pointers, know that a lot of (misguided) people start counting at 0 and that global variables are A BAD THING.

Like @MSB I'd recommend Metcalf et al's book as a source of information on the capabilities and features of modern Fortran. And, like @MSB, I raise an eyebrow at the idea of using C or C++ to wrap libraries for which there are either Fortran equivalents or better approaches entirely. The 2003 standard's interoperability with C features, which are implemented in Intel Fortran, make it easier than ever to call C libraries directly.

I'd take issue with OP that having modular code is a goal in its own right. The goals are, I suggest, correct, verifiable and validatable, robust, reliable code. Modularity is one way of supporting the achievement of those goals but it's a tactic, not an end point. If I thought that we could write good (in the foregoing senses) programs comprising 10^6 lines of code without modularity, I wouldn't bother with modularity.

OK, now some concrete tips to add to what OP already intends to do or has been told:

  • use KINDs on variable declarations to enforce the precision you require; don't leave this to compiler options or guesses about what this compiler might do on that processor;
  • use array operations wherever possible rather than explicit loops; this helps to make code safer -- sometimes at the expense of performance but you need to check this on a case-by-case basis;
  • write PURE functions;
  • don't depend on pre-processors or other non-Fortran approaches to code correctness (etc), write your assertions and preconditions (etc) in Fortran; the pre-processors (etc) will not survive as long as well-written Fortran programs and will be a major barrier to portability now and in the future;
  • if you have access to Intel Fortran get access to Intel MKL (and IPP) and use those libraries rather than writing your own code;
  • plan to tackle OpenMP and MPI for parallelisation, they both fit Fortran very well; oh, and plan to go parallel as soon as possible, it's a lot more fun than serial programming;
  • this set of Fortran Coding Standards is a good start, but probably no more than that; the 1st edition of Code Complete had a lot more about Fortran (77) programming than the current edition, but most of its advice can be applied whatever language you write in.

And, finally, these days I think that Fortran programs and programmers are better informed by ideas from functional programming than ideas from object-oriented programming.