Following this best practices guide, I have a module in my Fortran code that defines a double precision type,
module kind_parameters
implicit none
public
! Double precision real numbers, 15 digits, range 10^-307 to 10^307-1; 64 bits
integer, parameter :: dp = selected_real_kind(15, 307)
end module kind_parameters
My code, which uses this double precision type for all floating point operations, makes regular use of MKL. Here I always use the double precision version of MKL subroutines, i.e. DGEMM and DSYEVD.
It is not clear to me that my user defined type is consistent with the double precision type expected by MKL. In all my testing so far (with ifort/ifx) this seems to have worked fine, but are there potential pitfalls with my way of doing things? Is there a better way?
In theory, inconsistency might occur if you are working on a platform where double precision means something else than the IEEE double floating point type. For example, if the compiler, including the compiler that compiled MKL, is set to use the 64-bit floats as the default type and 128-bit as double. In that case, as Ian wrote, there is nothing wrong in using kind(1.d0)
for your kind. The important style recommendation is to use a named constant for your kinds, how exactly you set the value of the constant is less important.
If you need double precision, you set it to double precision as kind(1.d0)
, if you need compatibility with the C double, you set it to c_double
, if you want the 64-bit storage, you set it to real64
. In practice, all these methods will normally give you the same result. You can also use selected_real_kind
, but in my opinion, it somewhat did not fulfill the expectations and is practically obsolete, despite not officially. In this point I clearly do not agree with the fortran-lang.org recommendation. It is my personal opinion.