A discussion starting on the Fortran Discourse, got me thinking about how Fortran libraries should support multiple kinds of floating point numbers? I immediately recalled Dr. Fortran’s blog post, but that didn’t really consider the idea from a library developer’s perspective, just a standalone application developer. That’s understandable since at that time there wasn’t an ecosystem of Fortran libraries, so pretty much all Fortran developers were writing standalone applications. So the question remains.
For the history lesson, the aforementioned Dr. Fortran blog post does a great job. For a quick recap though, let’s take a look at what the Fortran Standard currently has to say about floating point type/kind. But first, a quick note about how the standard defines a processor. The definition in the standard reads:
combination of a computing system and mechanism by which programs are transformed for use on that computing system
So in the majority of cases that means a combination of compiler (although an interpreter would technically be possible), operating system and hardware. Thus, in theory anything that is allowed to differ between “processors” could be different if any of those things are changed.
Given the following excerpt:
The real type has values that approximate the mathematical real numbers. The processor shall provide two or more approximation methods that define sets of values for data of type real.
And given that type declarations that must be supported are
real (with an optional kind parameter) and
double precision, and that:
The type specifier for the real type uses the keyword REAL. The keyword DOUBLE PRECISION is an alternative specifier for one kind of real type.
If the type keyword REAL is used without a kind type parameter, the real type with default real kind is specified and the kind value is KIND (0.0). The type specifier DOUBLE PRECISION specifies type real with double precision kind; the kind value is KIND (0.0D0). The decimal precision of the double precision real approximation method shall be greater than that of the default real method.
The decimal precision of double precision real shall be at least 10, and its decimal exponent range shall be at least 37. It is recommended that the decimal precision of default real be at least 6, and that its decimal exponent range be at least 37.
We can see that there are only guaranteed to be two kinds of real supported by a processor. Furthermore, what exactly the precision or storage size of those kinds are is very open-ended. But what about the
iso_fortran_env module and the values
real128? For a given processor it is guaranteed that the kind values corresponding to default real and double precision will be in the
real_kinds array, but it is not guaranteed that either will be one of
real128, nor is it guaranteed that any of
real128 be valid.
So what is a library developer supposed to do? Well, the library is only guaranteed to be usable everywhere if they stick to default real and double precision. But users of the library (the application developers) want to be able to take advantage of the hardware they’re running on, and chances are pretty good the kinds mapping to the hardware representation won’t correspond to default real or double precision, and possibly not even to
For now, the workaround I’ve heard described amounts to something like the following. Note that this must all be done on the system on which the application is intended to be executed.
- Compile a program to output the contents of the
- Execute that program to determine what kind values are available
- Use those outputs to execute a preprocessor on the library to generate code for all the available kinds
- compile the library
- link the library with the application
At this point it is clear, this is a very brutal thorn in the side of Fortran library developers. I was discussing this with a colleague and he said to me he thought this was the most compelling example he had heard motivating the development of the generics facility slated for inclusion in the 202Y (the one after next) edition of the standard. If it does nothing else, allowing library developers to write kind agnostic code will alleviate a major pain point.