This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[OT] cure for nasty #ifdef's?


I'm pretty sure this is off-topic for this list (feel free to point me
toward something more generally about fortran), but I figure folks on
this list are likely to have answers (esp multi-platform coders):

I work on an atmospheric model (now a family of models--more below),
the code for which long predates me. (We've not yet gotten it to F90.)
Like most Earth-system models it defines a 3-space over the surface of
an Earth region, and various variables of interest within each "box" in
that space, and then solves differential equations over discrete
"timesteps."

One area in which we advance is by creating "instrumented models" (IMs)
derived from our "base model." E.g., we have a sensitivity model which
essentially calculates derivatives of change in one quantity vs
change(s) in one or more other quantities, in each box over each
timestep. (E.g., one might be interested in the sensitivity of
production of ozone to concentrations of other chemical species at
various spacetimes.) Currently, this IM is developed as a separate
body of code, in a separate repository: its developer takes the current
version of the "base model", and adds necessary data structures and
calculations.

The other instrumented models (I believe we currently have 5) proceed
similarly. Note each IM has well-separated concerns:

* our IMs are purely additive: they only add code to the base model,
  never subtract.

* our IMs are orthogonal: users can't (yet :-) simultaneously run a
  combination of 2 or more IMs.

Separate development means each IM developer spends most of her/his
time "catching up" to changes in the base model. So we'd like to,
jointly,

* have all the developers work on one set of codes

but

* (continue to) have users run only the model of interest

* pay no runtime performance penalty

How best to do this? My group seems to concur that

1 We should make the model-choice @ compiletime. I.e., the user builds
  only the model(s) of interest.

2 The only way to do this (of which we're aware, in fortran--more
  below) in one set of code is to use the preprocessor. E.g., for
  IMs={foo, bar},

#ifdef foo
      SUBROUTINE VDIFF ( CGRID, JDATE, JTIME, TSTEP,
     &                   SENGRID, NPMAX, IPT, IPARM, ISPLIT,
     &                   ILAYER, STDATE, IDATE, ITIME, SEN_PAR )
#elif bar
      SUBROUTINE VDIFF ( CGRID, JDATE, JTIME, TSTEP,
     &                   HGGRID, HGMAX, HGMIN, HGDATE, HGTIME, HGPAR )
#else
C the base model
      SUBROUTINE VDIFF ( CGRID, JDATE, JTIME, TSTEP )
#endif

3 For all but the most trivial blocks (like the above), using the
  preprocessor would tend to degrade maintainability, e.g., the code
  would quickly get unreadable.

I'd appreciate "second opinions" from outside my group about how to do
this. (And feel free to say, "your analysis is flawless--you're
totally screwed" :-)

Regarding 1: can one make the choice of model/code @ runtime, without
paying a penalty at either buildtime (these models already require
nontrivial time and expertise to build) or runtime (e.g., bloating the
executable)?

Regarding 2: is there an alternative to the preprocessor? E.g.:
I spent a long time coding java; in a similar circumstance there,
I'd try AspectJ or other vehicle for aspect-oriented programming.
I believe there are attempts at AOP for C++, but know of nothing for
fortran. Am I missing something?

Regarding 3: is the readability concern warranted? or will we "just
get over it"?

Again, if there's a better vehicle for questions like this, please
pass a pointer; otherwise,

your assistance is appreciated, Tom Roche <Tom_Roche@pobox.com>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]