FORTRAN Species Confusion

I have been writing FORTRAN code for the numerical simulation of applied physics for more than two years, and I tried to implement the conventions described in Fortran Best Practices .

In particular, I defined the parameter as

integer, parameter:: dp=kind(0.d0) 

and then used it for all doubles in my code.

However, I found out (in this forum) that using the KIND options does not necessarily give you the same accuracy if you compile your code using other compilers. In this question, I read that a possible solution uses SELECTED_REAL_KIND and SELECTED_INT_KIND, which, as I understand it, comply with some conventions.

Subsequently, I found out about ISO_FORTRAN_ENV , which defines the parameters REAL32, REAL64 and REAL128 KIND.

I think they are really portable, and since they are FORTRAN 2008 standard (although supported by GNU), I assume that I should use them?

Therefore, I would be very grateful if someone with more knowledge and experience would eliminate the confusion.

Also, I have the following question about using these KINDs in HDF5. I used H5T_NATIVE_DOUBLE and it really worked fine (as far as I know). However , this document states that this is an obsolete feature and should not be used. Instead, they provide a function

 INTEGER(HID_T) FUNCTION h5kind_to_type(kind, flag) RESULT(h5_type) . 

When I use it and print out the exact numeric value of the integer HID_T corresponding to REAL64 gives me 50331972, while H5T_NATIVE_DOUBLE gives me 50331963, which is different.

If I try to use the value calculated by H5kind_to_type, the HDF5 library will work just as well and, using XDMF , I can output the result in VisIt or Paraview without changing the attached .xmf file.

So my second question will be (again): Is this the correct use?

+5
source share
1 answer

The double precision type and the corresponding kind(1.d0) well defined by the standard. But they are also not quite fixed. Indeed, there have been many computers in history, and different types of native formats have been used for their floating point numbers, and the standard should allow this!

So double precision is a type of real that has higher precision than the default value of real . The real default is also not fixed, it must correspond to what computers can use.

We now have the standard for floating point numbers IEEE_754 , which defines the double types IEEE (binary) and IEEE (binary 64) and some others. If computer hardware implements this standard, since almost all computers are under 20 years old, it is very likely that the compiler chooses these two as real and double precision .

The Fortran 2008 standard provides two constants of the form real32 and real64 (and others). They allow you to request real views, the storage size of which is 32 and 64 bits. It is not guaranteed to be IEEE types, but it is almost certainly on modern computers.

To request IEEE types (if available), use the built-in function ieee_selected_real_kind() from the ieee_arithmetic module.

IEEE types are the same for all computers (excluding endianness!), But the compiler should not support them, because you may have a computer that does not support them at the hardware level. This is only a theoretical possibility; all modern computers support them.

Now, to your HDF constants, these are apparently only some indices for any table, no matter if they are different or not, the important thing is whether they matter the same thing and in your case they do.

As I wrote above, it is highly likely that on a computer that supports IEEE 754, double precision will be identical to IEEE double. Perhaps this is not the case if you use some compiler options that change this behavior. There are compiler options that double the default value of real and, in addition, can increase the accuracy of double precision to four-point accuracy (128 bits) to preserve standard semantics that require double precision have more precision and storage size.

Conclusion: You can use both methods or any other way to select your view constants (you can also use iso_c_binding c_float and c_double ), but you should know why these methods are different and what they really mean.

+6
source

All Articles