I am trying to understand a part of code written in fortran. The code contains the following part:
REAL(KIND=8), DIMENSION(x,y), INTENT(INOUT) :: AR
_REAL_, DIMENSION(x,y), INTENT(INOUT) :: BR
From this page , i came to know that _REAL_ is a preprocessor for precision control.
- What does
_REAL_actually do in this code? - Can
ARvalues be assigned toBR? Is there type incompatibility problem between them? - I was trying to assign the values of
ARtoBRusing a C functionextern "C" void assign_(double *AR, double *BR , int *x, int*y)But I am having a problem, and it seems like the problem is due to the incompatibility issue betweenARandBRbecause if I change the above code to:
REAL(KIND=8), DIMENSION(x,y), INTENT(INOUT) :: AR REAL(KIND=8), DIMENSION(x,y), INTENT(INOUT) :: BR, the problem is solved. Is there any problem if I changed the code this way?
The page that you referenced seems to be a bug report on building the Molecular Dynamics software package, Amber. I infer this from the link (.../gcc-bugs/...), from the second line of the page which states:
and finally from the description which explains how to change the precision of the Amber build (installing a single or double precision version the software).
If the written code you are looking at is a part of Amber, then the page you have referenced does explain what
_REAL_does in the code. Namely, it's a general type definition that based on the working precision either is replaced at compile time withreal(kind=4)orreal(kind=8). According to the description for Amber, the default build is double precision, which implies that when compiled,_REAL_would be replaced withreal(kind=8). This should answer question 1.Note that in fortran values of
ARcan always be assigned toBR, but they will require casting to the appropriate type. I.e. ifBRis an integer array, the values ofARwill be need to be casted into integers. Assuming that the written code you are looking at is for Amber again, and that the default double precision is not overriden, thenBRis a double precision array just asARis, so values can be freely assigned between them.As for question 3., you maybe need to define a macro so that
_REAL_actually does mean double precision. While not often discussed, many fortran compilers will happily apply a preprocessor. For automatic preprocessing (allowing the compiler to determine the flags), one just needs to ensure that the fortran source file has the correct extension, such as.F90,.F,.fpp, or.FPPas outlined in the first paragraph on this documentation page for gfortran (quick note that these are understood by the intel compilers as well). As I usually code in Fortran 90 or later, the extension.F90works wonders for me. Then, probably in the header of your source file, just add the following line:note that I add more than one space between the last underscore and real as to emphasize that there must be a space there. Doing this will allow the Fortran compiler to replace all occurrences of
_REAL_withreal(kind=8)and give you a way to globally modify real precision by modifying one line without invoking a compiler flag.I think that doing this might get your external C reference to work.