Showing posts with label fortran. Show all posts
Showing posts with label fortran. Show all posts

Friday, 24 July 2015

Raising a negative number to a non-integer power

It is undefined to raise a negative number to a non-integer power. However, Fortran compilers differ in their handling of the case when the power is an integer represented as a floating point number. Consider the following code:

      program test
      implicit double precision(a-h,o-z)
      a=-26.5227750387574375d0
      b=1.0000000000000000d0
      write(6,*)a**(b-0.01d0)
      write(6,*)a**b
      write(6,*)a**(b+0.01d0)
      end

With Intel compiler this is the result:

> ifort test.f
> ./a.out 
                     NaN
  -26.5227750387574     
                     NaN

But with NAG compiler all of the results are NaN:

> nagfor -ieee=full test.f
> ./a.out 
                     NaN   
                     NaN
                     NaN

Wednesday, 2 July 2014

The Fortran makefile dependency problem

For a project comprising of C/C++ code and header files, to simply compile once there is often no need for dependencies. Assuming that none of the header files are generated as part of the build process, it doesn't matter which order the source files are compiled in.

When developing a piece of code it is inefficient to recompile all the source files when a file has changed. Instead just the files which depend on those changes need to be recompiled. For example, when modifying a single C file only that file need be recompiled, or in the case of modifying a header file, all source files which include the header should be recompiled.

For a while standalone tools such as makedepend were used to generate these dependencies, but these have largely been superceded by the compilers themselves, commonly via a '-M' flag. This has great advantages, not least because the compiler itself knows best how to pre-process the file and which defines are internally set. A typical setup would therefore compile all files and then generate dependencies during the initial make. Subsequent makes include those dependencies and only recompiles things that have changed or are newly created, whilst of course also updating any dependencies accordingly.


There is a problem if one attempts to apply such a set-up to a Fortran project, namely F90 module files. Modules are similar to C header files, except that they themselves are source code which must be compiled before they can be used. For a small project one can of course write by hand that file A generates module M which is needed by files B and C. However, for larger projects, where modules are including other modules, which include other modules etc. this quickly becomes complicated. Some Fortran compilers (eg. gfortran) are able to generate dependencies via a '-M' option, but this is of little help since it can't be done until the relevant modules are available, a classic chicken and egg situation.

So unlike C, with Fortran the order in which source files should be compiled matters, and therefore dependencies must be generated before any compilation is done. This has unsurprisingly resulted in a whole series of tools designed to do this, sfmakedepend is the first that google turns up. In truth, many of these tools are actually more complicated than they need be since they often attempt to deal with Fortran and CPP include directives. These could be handled in the same way as C include directives, but of course it has the advantage that one does not need to generate separately module and include dependencies.

In conclusion, with Fortran one needs to generate at least module dependencies for all source files, and then include those dependencies before attempting to compile any source code.

It should be mentioned that for a Fortran project not making use of F90 module files this problem of course does not exist.

Wednesday, 18 June 2014

Fortran module filenames

The Fortran standard does not define a rule as to the filename format of F90 module files. In fact, some (mostly old) compilers don't even use module files at all, instead embedding the modules within the object files.

The autoconf package provides a macro, AC_FC_MODULE_EXTENSION, which can be used to determine the file suffix of module files for a compiler, although currently it only handles cases when the file basename is the module name either in upper or lower case. However, there appears no macro that actually returns the format of the module file. For example a module named test could result in one of:
  • test.mod
  • TEST.mod
  • test.MOD
  • TEST.MOD
being created.

As a result I wrote a new macro MAY_FC_MODULE_FILENAME_FORMAT available here which returns the filename format of module files in the variable FC_MODFMT. For the cases listed above the values of FC_MODFMT returned are:
  • %m.mod
  • %M.mod
  • %m.MOD
  • %M.MOD

As mentioned there are other less common possibilities, these are not currently implemented but will be if I need them or if there is demand.