Portable way to check existence of ISO_FORTRAN_ENV intrinsic module

Is there a way to check the existence of ISO_FORTRAN_ENV intrinsic module from inside a Fortran module? I’m writing a portable precision module for my code and would like to use int32, int64, real32, and real64 reliably, or manually define them using the following:

  INTEGER, PARAMETER :: int32 = SELECTED_INT_KIND(5)
  INTEGER, PARAMETER :: int64 = SELECTED_INT_KIND(18)
  INTEGER, PARAMETER :: real32 = SELECTED_REAL_KIND(6,30)
  INTEGER, PARAMETER :: real64 = SELECTED_REAL_KIND(14,100)

I’m open to using #ifdef statements, if needed. I have access to GCC, Intel Fortran classic (ifort), AOCC flang, IBM XL Fortran, and NVIDIA nvfortran (formerly PGI pgfortran). Probably will also try Arm compilers in the near future, if I can figure out how to enable multiarch armhf and aarch64 on my Raspberry Pi.

2 Likes

There are likely many ways to achieve the goal. Preprocessing directives is likely the easiest way. One could write a Fortran main program within CMake to check for the values of the iso_fortran_kinds and if any is negative, disable (set to false) the corresponding preprocessing macro before compiling the main library. AFAIK, the standard only requires default real and double precision kind and there is no mention of real32 and real64 in that context. So, if true portability into the distant future is desired, you would likely want to define real kinds in terms of single and double precision and avoid real32 and real64 kinds. Regarding integers, the standard only requires support for an integer with at least 18 digits. Currently, this translates to support for both int32 and int64, but that is not necessarily mandated by the standard to support two integer kinds.

1 Like

CMake

Unfortunately the code currently only builds using GNU make, so adding CMake support would be a considerable investment of time…

So, if true portability into the distant future is desired, you would likely want to define real kinds in terms of single and double precision and avoid real32 and real64 kinds.

Interesting. I thought DOUBLE PRECISION got deprecated in one of the newer standards? At least that’s what MFE says – it’s placed in Appendix A, “Deprecated features”.

It is using DOUBLE PRECISION as the type name in specifications that is deprecated, not the double precision real kind which is actually required by the standard. The modern way to refer to it is real(kind=kind(0d0)), usually parametrized as something like

integer, parameter :: dp=kind(0d0)
real(dp) :: x,y,z

All that is clearly stated in MFE (2018) section A.6

3 Likes

To expand on my answer, I don’t think if there is any way to check for the existence of the iso_fortran_env module at compile-time, because it has to be there if the compiler is standard-conforming (though I am not sure if the standard requires implementation of iso_fortran_env). Now, this may not be the case with some older compilers. So, you will have to fence the newer features with appropriate preprocessing macros. For example, both gfortran and Intel ifort recognize and predefine compiler-specific macros.

If the compiler is gfortran, a set of macros including __GFORTRAN__ are predefined and available to use to detect gfortran compiler at build time.

If the compiler is Intel ifort, then another set of preprocessor macros are predefined and available to use in the codebase, for example, __INTEL_COMPILER.

I am sure PGI / NVIDIA / NAG / IBM / Cray / … have their own specific predefined macros as well, but I am not quite familiar with those compilers.

2 Likes

Yes, the main problem here is dealing with older compilers. I guess I’ll have to do some research on which versions of each compiler started supporting the module, and fence the code appropriately with the correct #ifdefs.

The macro for PGI pgfortran and NVIDIA nvfortran is __PGI and __NVCOMPILER, respectively. Some versions of NVIDIA nvfortran define both to ease the transition.

The macro for IBM is weirdly called __IBMC__, even though it is the Fortran compiler xlf90_r.

1 Like

It is somewhat similar to the use of selected_int/real_kind function to define a kind parameter, later used in object specification, as in:

integer, parameter :: long=selected_int_kind(20)
integer(kind=long) :: i, j, k

If one requires a non supported range or (for reals) precision, the compiler will just fail with error on a kind parameter of negative value.

@wyphan ,

Please note not only is there is no definitive way to check for the existence of the so-called "standard intrinsic module"s such as ISO_FORTRAN_ENV, its presence itself is no guarantee of support of the named constants you wish to work with.

To add to the confusion, add to the mix the standard intrinsic module, IEEE_ARITHMETIC and interface therein for IEEE_SELECTED_REAL_KIND!

Technically the teams I work with would really want a portable way to bring in IEEE floating point kinds and ensure support toward code that work seamlessly across all Fortran compilers, for almost all, if not absolutely all, the computing is done using IEEE floating-point! This may mean

   use, intrinsic :: IEEE_ARITHMETIC
..
   integer, parameter :: IEEE_Bxx = ieee_selected_real_kind( p=x, r=y, radix=2 ) ! and so forth
..
   use xx .. wp => IEEE_Bxx
..
   real(wp) :: x
..

Moreover, the many a power-that-be and senior technical leaders think the path of Fortran thus far is ridiculous, they would rather wish Fortran offered a built-in type alias for IEEE floating-point reals e.g.

   ieee_fp64 :: x  !<-- as opposed to the long route leading up to real(wp) :: x above!
                   !    where wp points to 64-bit IEEE floating-point kind
1 Like

@msz59 explained well the nuance between the type name and the double precision real kind. In your post I see one more instance of confusion that I also had until recently–the meaning of MFE’s deprecated.

The standard defines obsolescent (considered redundant and subject to deletion in the future) and deleted features. It doesn’t define deprecated features.

MFE defines deprecated features and this “status” is the authors’ choice and unrelated to the the standard. Quoting from A.1:

We note that his decision to group certain features into an appendix and to deprecate their use is ours alone, and does not have the actual or implied approval of either WG5 or J3.

The thread where I asked about this is:

2 Likes