Real kinds and interoperability?

This blog refers to Dr Fortran blog and states

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.

That’s a whole load of baloney by @everythingfunctional !! The Dr Fortran blog was published on March 27, 2017, there was an “ecosystem” of libraries, even in the programming language of interest here, going back at least to 1967, fifty years prior!

1 Like

There are some very stupid compiler flags in many compilers that cause DOUBLE PRECISION to not match C double, and so forth. See Fortran Dialect Options (The GNU Fortran Compiler) where it says -fdefault-real-{8,10,16}, etc.

I think these options change the value of the intrinsic function kind(1E0) and kind(1D0), but they do not change the values of selected_real_kind() or ieee_selected_real_kind() or the constants defined in the intrinsic modules iso_fortran_env, iso_c_binding, or ieee_arithmetic. I’m unsure about the stdlib module, but I think those values remain unchanged too.

I would say that if one wants C interoperability, one has to use the iso_c_binding kind constant and not rely on assumption that a REAL is a float, etc…

Nonetheless, these are dangerous flags, as they make the processor non standard conformant, as a REAL no longer occupies a single numeric storage unit.

Thank you for all your comments. It seems that purely based on interoperability, one should indeed go for the kinds defined in iso_c_binding. However, a colleague remarked that most of the C libraries that we are using, actually already have a Fortran interface … so, we shouldn’t need to worry about C interoperability, just interoperability with those Fortran layers. Good point. So, how do those Fortran layers define their kinds? Via iso_c_binding? Nope … focussing on just the “double” equivalent they define it as follows

PetSc: selected_real_kind(10)
netCDF 4: selected_real_kind(P=13, R=307)
BMI 2: double precision
Our own API: c_double … but then passes a pointer to any internal double precision array …

Just to complete the list here, stdlib uses selected_real_kind(15).

What to conclude? Well, I conclude that it’s a mess, but in the end it probably doesn’t matter too much how you define the kinds since hardware seems to have converged sufficiently to allow these definitions to be effectively equivalent. Fortran allows for far more fine grained specification of the desired precision than any other programming language that I know of, but in the end it’s seems to barely matter. This conclusion is mainly based on the observation that two widely used libraries PetSc and netCDF implemented in C/C++ both don’t use the iso_c_binding (yet) and use quite different definitions for the double equivalent. I guess that this implies that we can just choose any reasonable selected_real_kind definition, e.g. the one coming from stdlib, and it’s going to be unlikely that we’ll run into any issues on the current generation of (laptop to supercomputer) hardware.

The current hardware “standardization” make people lazy when it comes to selecting the kinds :slight_smile: … When interfacing with C routines (without any Fortran wrapper in between) I can’t see any good reason for not using the c_xxx kinds that are defined in iso_c_binding.

One possibility is to define interface blocks with the constants from iso_c_binding, but then use your own convention for real kinds in your fortran code. If there is a mismatch, the compiler must detect them at compile time. This doesn’t require an actual fortran wrapper, just the fortran interface block.