I am trying to build a Fortran codebase on an IBM xl system with one source file giving compilation error as follows:
line 152.16: 1516-036 (S) Entity ctime has undefined type
After some Googling, I figure that ctime is a GNU Fortran function which is why the xl compilers are not liking it. Can someone suggest if there is any alternative function for ctime in IBM xl fortran compilers.
The ctime function converts a system time value to string. Ref section 9.74 pp. 124 of https://gcc.gnu.org/onlinedocs/gfortran.pdf
Fortran, since the 1990 standard if I remember correctly, defines a standard subroutine called date_and_time which will return the current date and time (if the computer it is running on is capable of telling a program that) in character and in numeric forms. Consult your favourite documentation set for details.
If your problem is to convert a date and time value stored in some numeric format to a string, that's what internal writes are for. If you don't know how to use internal writes to transform numbers into strings then (a) tut, and (b) ask for clarification.
If your entire codebase is infected with ctime you could write your own implementation and have the IBM compiler compile it for you.
The equivalent subroutine is ctime_, as mentioned in one of the answers, but note that the order of the arguments is different.
gfortran:
call ctime(time, result)
where time is an intent(in) integer argument
and result is an intent(out) character argument
XL Fortran:
call ctime_(str, time)
where str is the intent(out) character argument
and time is the intent(in) integer argument
You can find the full documentation of ctime_ in the XL Fortran language reference in the service and utility procedures chapter. Here is a link to the function in the XL Fortran 15.1 language reference:
Related
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'm trying to figure out how to use quadpack.
In a single folder, I located the contents of "qag.f plus dependencies" and the code blow as qag_test.f:
(maybe this code itself is not very important. This is in fact just a snippet from the quadpack document)
REAL A,ABSERR,B,EPSABS,EPSREL,F,RESULT,WORK
INTEGER IER,IWORK,KEY,LAST,LENW,LIMIT,NEVAL
DIMENSION IWORK(100),WORK(400)
EXTERNAL F
A = 0.0E0
B = 1.0E0
EPSABS = 0.0E0
EPSREL = 1.0E-3
KEY = 6
LIMIT = 100
LENW = LIMIT*4
CALL QAG(F,A,B,EPSABS,EPSREL,KEY,RESULT,ABSERR,NEVAL,
* IER,LIMIT,LENW,LAST,IWORK,WORK)
C INCLUDE WRITE STATEMENTS
STOP
END
C
REAL FUNCTION F(X)
REAL X
F = 2.0E0/(2.0E0+SIN(31.41592653589793E0*X))
RETURN
END
Using gfortran *.f (installed as MinGW 64bit), I got:
C:\Users\username\AppData\Local\Temp\ccIQwFEt.o:qag.f:(.text+0x1e0): undefined re
ference to `xerror_'
C:\Users\username\AppData\Local\Temp\cc6XR3D0.o:qage.f:(.text+0x83): undefined re
ference to `r1mach_'
(and a lot more of the same r1mach_ error)
It seems r1mach is a part of BLAS (and I don't know why it's not packaged in here but obtained as "auxiliary"), but what is xerror?
How do I properly compile this snippet in my environment, Win7 64bit (hopefully without Cygwin)?
Your help is very much appreciated.
xerror is an error reporting routine. Looking at the way it is called, it appears to use Hollerith constants (the ones where "foo" is written as 3hfoo).
if(ier.ne.0) call xerror(26habnormal return from qag ,
* 26,ier,lvl)
xerror in turn calls xerrwv, passing along the arguments (plus a few more).
This was definitely written before Fortran 77 became widespread.
Your best bet would be to use a compiler which still supports Hollerith constants, pull in all the dependencies (xeerwv has a few more, I don't know why you didn't get them from netlib) and run it through the compiler of your choice. Most compilers, including gfortran, support Hollerith; just ignore the warnings :-)
You will possibly need to modify one routine, that is xerprt. With gfortran, you could write this one as
subroutine xerprt(c,n)
character(len=1), dimension(n) :: c
write (*,'(500A)') c
end subroutine xerprt
and put this one into a separate file so that the compiler doesn't catch the rank violation (I know, I know...)
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.
I'm trying to integrate some C++ code into Fortran.
I have a doubt with equivalences between types,
is Fortran integer*1 equivalent to C++ bool?¿ if not, what is the correct C++ equivalent type?¿
Thank you so much in advance!
quoting from this link:
The INTEGER(1) type should be used for large arrays when memory is at
a premium for variables which will have only positive, negative, and
zero whole number values within the range of -129 to 127..
So, I'd say its C/C++ equivalent would be a signed char. The equivalent of bool is Fortran's logical type.
EDIT: M.S.B.'s answer is way better than mine; you're way better off doing what (s)he suggested.
The best thing to do is to use the Fortran ISO_C_Binding which provides types that match C types. That approach is compiler and platform independent. I'm less sure about C++ types but if you are sure of their C equivalent you should be good. The ISO_C_Binding provides the Fortran type C_BOOL to match the C type _Bool. The binding provides a long list of equivalent types. One place that the list appears is in the chapter "Intrinsic Modules" of the gfortran manual. Also see the "Mixed Language Programming" chapter. While I have cited the gfortran manual, as part of the Fortran 2003 language standard these features aren't particular to that compiler.
P.S. A comment suggests the use of int8_t. The matching type, on the Fortran side with the ISO C Binding, is C_INT8_T.
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.