0

I want to change a large Fortran 90 program to use double precision instead of single precision. I thought the easiest way to do this is to add the following flag to the compiler:

-fdefault-real-8

However, this does not seem to update the MPI commands. For example, I need to change commands like this:

CALL MPI_RECV(x, n, MPI_REAL, rankstart, tag, comm, stat, ierr)

to

CALL MPI_RECV(x, n, MPI_REAL8, rankstart, tag, comm, stat, ierr)

Do you know if there is a compiler flag to change the default value of MPI_REAL to MPI_REAL8? If not, do you know of another way I can easily change the precision of the program without having the manually adjust all the commands in the code myself?

Peanutlex
  • 169
  • 5
  • 1
    -fdefault-real-8 is never the correct method for porting code. Unfortunately, a quorum of gfortran developer's refuse to remove that option. – steve Apr 19 '21 at 16:41

1 Answers1

1

You can use the same flag when configuring your MPI library for compilation. In that case, provided the library is programmed properly, the default real should correspond to the default kind you chose.

The library may request that the default integers and logicals are of the same storage size as the new enlarged real.

Be aware that MPI is an external library. It is compiled separately. It will NOT react to flags that you supply to the compiler when compiling your program. It only knows about the flags that were used to compile the library.


The easiest way to change the precision in a Fortran 90 program is to use a working kind parameter

integer, parameter :: rp = kind(1.d0)

and to declare your real variables as

real(rp) :: x

You can later change the parameter value to any other value as shown at Fortran 90 kind parameter

  • Thank you. I am a big noob when it comes to MPI. How do I change the flags used by MPI? The code uses the command `INCLUDE "mpif.h"` at the start. Do I need to edit a file somewhere called `mpif.h`? – Peanutlex Apr 19 '21 at 12:57
  • 1
    @Peanutlex That would not help in any way. You would have to recompile the library. See, e.g., https://www.open-mpi.org/faq/?category=building https://wiki.mpich.org/mpich/index.php/Getting_And_Building_MPICH – Vladimir F Героям слава Apr 19 '21 at 13:00
  • 4
    See the links. However, fixing your code is probably a better investment of your time. – Vladimir F Героям слава Apr 19 '21 at 13:02
  • Thank you for the help. I agree that changing the declarations from ```REAL :: x``` to ```REAL(rp) :: x``` as you suggest is a good idea. What would you do to change commands like ```CALL MPI_RECV(x, n, MPI_REAL, rankstart, tag, comm, stat, ierr)``` to allow easy switching from single to double precision? Would you do something like this: `IF (rp == 4) CALL MPI_RECV(x, n, MPI_REAL4, rankstart, tag, comm, stat, ierr)` ```IF (rp == 8) CALL MPI_RECV(x, n, MPI_REAL8, rankstart, tag, comm, stat, ierr)``` Is there a more elegant solution which would require fewer lines of code? – Peanutlex Apr 19 '21 at 13:07
  • 2
    Look into MPI_TYPE_CREATE_f90_REAL and similar, and elegant doesn't necessarily mean fewer lines. Note MPI_REAL4 and similar are not the best choices as they are not required to be supported by an MPI implementation. – Ian Bush Apr 19 '21 at 13:24
  • 1
    Let me also second Vladimir's comment "fixing your code is probably a better investment of your time". Personally I have a gut feeling that recompiling a library such as MPI with non-default datatype sizes will be a prime example of what I say whenever I see people suggesting -fdefault-real-8 and similar - which is don't do this, it will just lead to a life of pain. – Ian Bush Apr 19 '21 at 14:04
  • 2
    Whoops, wireless connection dropped. Arrgh, using -fdefault-real-8 to compile both the MPI library and OP's code is absolutely the wrong approach! The -fdefault-real-8 option breaks Fortran's storage association rules, and if quad precision is supported then double precision is promoted to quad (i.e., `REAL(8)` becomes `REAL(16)`). The purpose of the option is to aid porting code to a different precision not to replace that porting. – steve Apr 19 '21 at 16:55
  • @steve Which storage does it brake? The Fortran standard does not specify the default kind storage size nor the size of the double precision kind. I did note *"The library may request that the default integers and logicals are of the same storage size."*. I see no reason why the default kind could not be freely configarable in a Fortran compiler, unlike in C, as Fortran is not directly tied to the OS, And the Fortran standard does allow c_int /= default integer and c_float /= default real. – Vladimir F Героям слава Apr 19 '21 at 17:46
  • @VladimirF I'm sure you know this but it's not clear from the above - default real, default integer and default logical must all occupy one numeric storage unit. Thus use of a non-default kind real requires also using integers and logical of kind that occupy the same size. (and of course the concomitant promotion of double precision and complex). As long as all this is done what you say may be possible. I don't believe just -fdefault-real-8 does this. – Ian Bush Apr 19 '21 at 18:08
  • Default real kind is promoted to 2 numeric storage units (NSU) while default integer and logical still occupy 1 NSU. If `REAL(16)` exists, then `REAL(8)` is promoted to 4 NSU. It is an attempt to preserve storage association for real types, but I failed to consider integer and logical types. The implications are important for `COMMON`, `EQUIVALENCE`, `TRANSFER`, C-interop, etc. There is/was an issue with promoting literal-real-constants, which may have been fixed. The -freal-4-real-8 family of options promotes the kind type without mucking with NSU. – steve Apr 19 '21 at 18:28
  • @steve I repeat, I DID note: "The library may request that the default integers and logicals are of the same storage size.". It is the responsibility of the programmer to use these flags properly, but there is no reason why all default numeric types can't be 8 bytes and doubles 16 bytes. It is the `-freal-4-freal-8` that may causeinconsistence IMHO. – Vladimir F Героям слава Apr 19 '21 at 18:57
  • @VladimirF, You ask me "which storage does if brake [SIC]?". I told you. As the person who converted gfortran's original -r8 option to -fdefault-real-8 and made it work (for some definition of work), and reviewed and committed the -freal-4-real-8 family of options to gfortran, I'll simply state that these options should be avoided. – steve Apr 20 '21 at 01:41
  • 1
    @steve But it simply does not break this one when all numerical datatypes are enlarged. That is my point. It is the strength of Fortran that the default datatypes are not fixed, not a weakness. Who needs fixed-size types, there are other means to declare them instead using the defaults. – Vladimir F Героям слава Apr 20 '21 at 08:00