My apologies if this is a very stupid question; my Fortran isn't great. I'm porting some old Fortran code and have come across this subroutine definition:
SUBROUTINE SET_HYDROMODULE(HYDROMODULE)
IMPLICIT NONE
INTEGER*4 HYDROMODULE [VALUE]
...
END
Intel Fortran passes this through without blinking an eye, though with warnings for non-standard language features enabled it gives this warning:
warning #7009: Attribute syntax is not standard F95
gfortran assumes that it's an attempt at a coarray specification, though it's not a valid one.
Can someone tell me what the meaning of the [VALUE] clause is?
Edit Is it a non-standard way of specifying pass-by-value? Is it equivalent to this:
INTEGER*4, VALUE :: HYDROMODULE
I seem to see it a lot in c-interoperability code, which would suggest this.
The VALUE attribute was added in Fortran 2003, so it is not surprising that it doesn't work with Fortran 95. The Fortran Standard (2008) specifies in section 5.3.18 "VALUE attribute". From what I read there, it needs to be specified as
INTEGER*4, VALUE :: HYDROMODULE
Section 5.4.16 in the Standard defines a second form, the VALUE statement:
INTEGER*4 :: HYDROMODULE
VALUE :: HYDROMODULE
The other form you gave seems to be an Intel extension. gfortran supports the VALUE attribute (at least in version 4.9).
A quick search revealed that apart from ensuring inter-operability the VALUE attribute can indeed by used to enforce some kind of call by value, from here:
When this attribute is specified, the effect is as if the actual
argument is assigned to a temporary, and the temporary is the argument
associated with the dummy argument. The actual mechanism by which this
happens is determined by the processor.
Related
I uploaded a 2F1 hypergeometric function but it turns out that it does not compile on my computer. It is from this article. I use
GNU Fortran (Built by Jeroen for the R-project) 8.3.0
shiped with RTools 4.0. Can you figure out why it does not compile and how this could be solved? In the code below, I just kept the one line that generates the error. The error is given next.
MODULE HYP_2F1_MODULE
!--------------------------------------------------------------------
IMPLICIT NONE
INTEGER, PARAMETER :: PR=KIND(1.0D0)
REAL(PR) :: ONE=1.0D0
CONTAINS
!
END MODULE HYP_2F1_MODULE
!
!----------------------------------------------------------------------
RECURSIVE FUNCTION LOG_GAMMA(Z) RESULT(RES)
USE HYP_2F1_MODULE
IMPLICIT NONE
COMPLEX(PR),INTENT(IN) :: Z
COMPLEX(PR) :: RES
!
RES = LOG_GAMMA( ONE -z);
!
END FUNCTION LOG_GAMMA
Here is the error message
testZ.f90:18:22:
RES = LOG_GAMMA( ONE - Z);
1
Error: 'x' argument of 'log_gamma' intrinsic at (1) must be REAL
There is a Fortran 2008+ intrinsic of the same name
16.9.119 LOG_GAMMA (X)
1 Description. Logarithm of the absolute value of the gamma function.
2 Class. Elemental function.
3 Argument. X
shall be of type real. Its value shall not be a negative integer or
zero.
There is some sort of clash I do not completely understand here. The obvious workaround is to rename your function. What I can say is that without the result clause (which you need because of the recursive attribute) the intrinsic would be shadowed. It might be a compiler bug.
Also consider, whether the intrinsic of the same name couldn't also do what you need from your function.
In addition to #VladimirF's suggestions, you can add the compiler flag -std=f95 to enforce compliance with the Fortran 95 standard. Provided you haven't added -fall-intrinsics this will disable all intrinsics from standards after Fortran 95, and should make the legacy code work.
I was given some legacy code to compile. Unfortunately I only have access to a f95 compiler and have 0 knowledge of Fortran. Some modules compiled but others I was getting this error:
Error: Old-style type declaration REAL*16 not supported at (1)
My plan is to at least try to fix this error and see what else happens. So here are my 2 questions.
How likely will it be that my code written for Fortran 75 is compatible in the Fortran 95 compiler? (In /usr/bin my compiler is f95 - so I assume it is Fortran 95)
How do I fix this error that I am getting? I tried googling it but cannot see to find a clear crisp answer.
The error you are seeing is due to an old declaration style that was frequent before Fortran 90, but never became standard. Thus, the compiler does not accept the (formally incorrect) code.
In the olden days before Fortran 90, you had only two types of real numbers: REAL and DOUBLE PRECISION. These types were platform dependent, but most compilers nowadays map them to the IEEE754 formats binary32 and binary64.
However, some machines offered different formats, often with extra precision. In order to make them accessible to Fortran code, the type REAL*n was invented, with n an integer literal from a set of compiler-dependent values. This syntax was never standard, so you cannot be sure of what it will mean to a given compiler without reading its documentation.
In the real world, most compilers that have not been asked to be strictly standards-compliant (with some option like -std=f95) will recognize at least REAL*4 and REAL*8, mapping them to the binary32/64 formats mentioned before, but everything else is completely platform dependent. Your compiler may have a REAL*10 type for the 80-bit arithmetic used by the x86 387 FPU, or a REAL*16 type for some 128-bit floating point math. However, it is important to stress that since the syntax is not standard, the meaning of that type could change from compiler to compiler.
Finally, in Fortran 90 a way to refer to different kinds of real and integer types was made standard. The new syntax is REAL(n) or REAL(kind=n) and is supported by all standard-compliant compilers. However, The values of n are still compiler-dependent, but the standard provides three ways to obtain specific, repeatable results:
The SELECTED_REAL_KIND function, which allows you to query the system for the value of n to specify if you want a real type with certain precision and range requirements. Usually, what you do is ask for it once and store the result in an INTEGER, PARAMETER variable that you use when declaring the real variables in question. For example, you would declare a type with at least 15 digits of precision (decimal) and exponent range of at least 100 like this:
INTEGER, PARAMETER :: rk = SELECTED_REAL_KIND(15, 100)
REAL(rk) :: v
In Fortran 2003 and onwards, the ISO_C_BINDING module contains a series of constants that are meant to give you types guaranteed to be equivalent to the C types of the same compiler family (e.g. gcc for gfortran, icc for ifort, etc.). They are called C_FLOAT, C_DOUBLE and C_LONG_DOUBLE. Thus, you could declare a variable equivalent to a C double as REAL(C_DOUBLE) :: d.
In Fortran 2008 and onwards, the ISO_FORTRAN_ENV module contains a different series of constants REAL32, REAL64 and REAL128 that will give you a floating point type of the appropriate width - if some platform does not support one of those types, the constant will be a negative number. Thus, you can declare a 128-bit float as REAL(real128) :: q.
Javier has given an excellent answer to your immediate problem. However I'd just briefly like to address "How likely will it be that my code written for Fortran 77 is compatible in the Fortran 95 compiler?", with the obvious typo corrected.
Fortran, if the programmer adheres to the standard, is amazingly backward compatible. With very, very few exceptions standard conforming Fortran 77 is Fortran 2008 conforming. The problem is that it appears in your case the original programmer has not adhered to the international standard: real*8 and similar is not, and has never been part of any such standard and the problems you are seeing are precisely why such forms should never be, and should never have been used. That said if the original programmer only made this one mistake it may well be that the rest of the code will be OK, however without the detail it is impossible to tell
TL;DR: International standards are important, stick to them!
When we are at guessing instead of requesting proper code and full details I will venture to say that the other two answers are not correct.
The error message
Error: Old-style type declaration REAL*16 not supported at (1)
DOES NOT mean that the REAL*n syntax is not supported.
The error message is misleading. It actually means that the 16-byte reals are no supported. Had the OP requested the same real by the kind notation (in any of the many ways which return the gfortran's kind 16) the error message would be:
Error: Kind 16 not supported for type REAL at (1)
That can happen in some gfortran versions. Especially in MS Windows.
This explanation can be found with just a very quick google search for the error message: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56850#c1
It does not not complain that the old syntax is the problem, it just mentions it, because mentioning kinds might be confusing even more (especially for COMPLEX*32 which is kind 16).
The main message is: We really should be closing these kinds of questions and wait for proper details instead of guessing and upvoting the question where the OP can't even copy the full message the compiler has spit.
If you are using GNU gfortran, try "real(kind=10)", which will give you 10 bytes (80-bits) extended precision. I'm converting some older F77 code to run floating point math tests - it has a quad-precision ( the real*16 you mention) defined, but not used, as the other answers provided correctly point out (extended precision formats tend to be machine/compiler specific). The gfortran 5.2 I am using does not support real(kind=16), surprisingly. But gfortran (available for 64-bit MacOS and 64-bit Linux machines), does have the "real(kind=10)" which will give you precision beyond the typical real*8 or "double precision" as it was called in some Fortran compilers.
Be careful if your old Fortran code is calling C programs and/or maybe making assumptions about how precision is handled and floating point numbers are represented. You may have to get deep into exactly what is happening, and check the code carefully, to ensure things are working as expected, especially if fortran and C routines are calling each other. Here is url for the GNU gfortran info on quad-precision: https://people.sc.fsu.edu/~jburkardt/f77_src/gfortran_quadmath/gfortran_quadmath.html
Hope this helps.
I just encountered the following in ifort (IFORT) 15.0.0 2014072
program integerkinds
use iso_fortran_env
implicit none
integer(kind=selected_int_kind(15)):: j15
print *,'Selected Integer Kind 15:'
print *, huge(j15)
print *, int(huge(j15))
print *, int(huge(j15),kind=selected_int_kind(15))
end program integerkinds
for which the output is
Selected Integer Kind 15:
9223372036854775807
-1
9223372036854775807
shouldn't the compiler automatically choose the correct return type based on int()'s argument? This unexpected behavior has just cost me about 2500 hours of computing time on our cluster :(
The documentation states (http://nf.nci.org.au/facilities/software/intel_fortran_reference.pdf at page 9-80):
Argument Type Result Type
INTEGER(1), INTEGER(2), INTEGER(4) INTEGER(4)
INTEGER(1), INTEGER(2), INTEGER(4), INTEGER(8) INTEGER(8)
According to this table Integer(8) as argument should give Integer(8) as result type, but the output gives -1. Looks like a bug to me, but I wanted to get a second pair of eyes on this before I go and bug the intel developers. Is there something in the standard that I am overlooking that mandates a -1 as return value here?
No. That table is wrong or misleading (the multiple rows, which otherwise make no sense, may possibly reflect variation in behaviour given some compatibility option, but if so I'm not aware of what option it is). In standard Fortran, the kind of the result of the INT generic intrinsic only depends on the presence and value of the KIND argument. If the KIND argument is not present then the result has default integer kind, otherwise the KIND argument specifies the KIND of the result.
The value of the argument to the second invocation of INT in your example program cannot be represented in a default integer for that compiler, in the absence of compile options that change the default integer kind. Your code is non-conforming.
While the text has not changed materially (apart from perhaps becoming more confusing) I note that the documentation that you link to is ancient.
I've been using using an underscore to define an integer as a specific kind in fortran.
Here is a snippet of code to demonstrate what 1_8 means, for example:
program main
implicit none
integer(2) :: tiny
integer(4) :: short
integer(8) :: long
tiny = 1
short = 1
long = 1
print*, huge(tiny)
print*, huge(1_2)
print*, huge(short)
print*, huge(1_4)
print*, huge(long)
print*, huge(1_8)
end program main
Which returns (with PGI or gfortran):
32767
32767
2147483647
2147483647
9223372036854775807
9223372036854775807
I'm using the huge intrinsic function to return largest number of the given kind. So 1_8 is clearly the same kind as integer(8). This works for real numbers also, although I haven't shown it here.
However, I've been unable to find any documentation of this functionality and I don't remember where I learned it. My question is:
Is using _KIND standard fortran? Does anybody have a source for this?
Edit: It's been pointed out that the kind values I've used (2,4,8) are not portable - different compilers/machines may give different values for huge(1_4), for example.
It is standard Fortran, as of Fortran 90, though the set of valid kind values for each type and the meaning of a kind value is processor dependent.
The Fortran standard is the definitive source for what is "standard" Fortran. ISO/IEC 1539-1:2010 is the current edition, which you can buy, or pre-publication drafts of that document are available from various places. https://gcc.gnu.org/wiki/GFortranStandards has a collection of useful links.
I would expect that many compiler manuals (e.g - see section 2.2 of the current PGI Fortran reference manual) and all reasonable textbooks on modern Fortran would also describe this feature.
As already answered, this notation is standard fortran, but using these specific numeric values for kinds is not portable. Previous answers have described compilers that use other schemes. There are several other approaches that are portable.
First, use the kind scheme to define symbols, then use those symbols for numeric constants:
integer, parameter :: RegInt_K = selected_int_kind (8)
write (*, *) huge (1_RegInt_K)
Or use the kind definitions that are provided in the ISO_FORTRAN_ENV module, e.g.,
write (*, *) huge (1_int32)
The kinds of this module are specified in the number of bits used for storage. Some of the kinds are only available with Fortran 2008. If those are missing in your compiler, you can use the kind definitions provided with the ISO_C_BINDING, which is older.
To add to IanH's answer the specification for an integer literal constant in Fortran 2008 is given in 4.4.2.2. Something like 1_8 fits in with R407 and R408 (for the obvious digit-string):
int-literal-constant is digit-string [_kind-param]
kind-param is digit-string or scalar-int-constant-name
You can find similar for other data types (although note that for characters the kind parameter is at the front of the literal constant).
I am newbie to FORTRAN. I have some FORTRAN programs written in Intel FORTRAN and now I am compiling them using gfortran.
One of the subroutines uses the JFIX() function. When I complie the following error is thrown.
undefined reference to 'jfix_'
The subroutine has reference to this intrinsic function on the top like External::JFIX
Can anyone help me resolve this?
JFIX is an Intel extension to FORTRAN. It converts its argument to INTEGER(4).
There may be a GNU FORTRAN equivalent, or you may have to provide it yourself.
The Intel FORTRAN Language Reference is available from various places on the web. Here's one.
JFIX may be the one you need, but you should be careful as JFIX not only converts real to integers (as INT does), but also all other kinds of stuff to integer(4).
From the Intel Fortran Language Reference found here, it converts
INTEGER(1), INTEGER(2), INTEGER(4), INTEGER(8),
REAL(4), REAL(8), REAL(16), COMPLEX(4),
COMPLEX(8), COMPLEX(16)
to
INTEGER(4)
That was just to say to you and future readers: while it's the equivalent of INT in your case here, it is not the case everywhere.
As you're new to Fortran let me just give one more precision: the number between parenthesis is the precision kind of the variable. For instance, REAL(4) is simple precision on a "conventional" architecture, REAL(8) double precision.