|
 |
How can I use CDABS, DCMPLX, DCONJG, DIMAG and DREAL? |
 |
These are not standard Fortran intrinsic functions, though they are a common extension. We recommend that they be converted to standard Fortran using the following table.
| Specific |
Equivalent Modern Fortran Generic Intrinsic Function |
| CDABS(A) |
Abs(a) |
| DCMPLX(X,Y) |
Cmplx(x,y,Kind=Kind(0d0)) |
| DCONJG(Z) |
Conjg(z) |
| DIMAG(Z) |
Aimag(z) |
| DREAL(Z) |
Real(z) |
Alternatively, the ‘-dcfuns’ option can be used to make the compiler recognise these functions.
|
|
 |
Are non-standard specific intrinsic functions such as CDEXP available? |
 |
No. These functions have never been part of any Fortran standard, and there is not universal agreement on their spelling.
However, they are never needed: just use the standard generic intrinsic functions: ABS, ACOS, ASIN, ATAN, ATAN2, CONJG, COS, COSH, DIM, EXP, LOG, LOG10, MAX, MIN, SIGN, SIN, SINH, SQRT, TAN and TANH can all be applied to any precision Real (and where appropriate, Complex) data.
If you have a program that uses a specific intrinsic (non-standard or standard) that consists of a prefix in front of one of the functions listed above, removing the prefix (usually C, CD, CQ, D, Q or Z) is nearly always the right thing to do; for example, references to an intrinsic CEXP, DEXP, CDEXP, CQEXP, DCEXP, QEXP, ZEXP can all safely be replaced by EXP.
For a few functions, the rule is slightly different: xINT and xNINT, where x is one of the prefixes listed above, should be changed to AINT or ANINT respectively.
|
|
 |
Is there a DTIME or ETIME function? |
 |
No.
These functions are not standard Fortran; their functionality is provided by the standard Fortran intrinsic subroutines CPU_TIME and SYSTEM_CLOCK. If you have a package that wants to use the DTIME and/or ETIME procedures, you can add one or two of the following examples to your code. The first example provides DTIME and ETIME> written entirely in standard Fortran 95 (and thus will work on any Fortran 95 compiler); the second provides DTIME and ETIME using the NAG Fortran Compiler interface to Posix.
NOTE: By design, the DTIME and ETIME functions are not and cannot be thread-safe. If your code might be executed in a multi-threaded environment, you should use SYSTEM_CLOCK to measure elapsed time.
! DTIME in standard Fortran.
Real Function dtime(time)
Real time(2)
Double Precision,Save :: last_time = 0
Double Precision this_time
Intrinsic Cpu_Time
Call Cpu_Time(this_time)
time(1) = this_time - last_time
time(2) = 0
dtime = time(1)
last_time = this_time
End Function
! DTIME via NAG Fortran Compiler Posix module.
Real Function dtime(time)
Use F90_Unix_Env,Only:tms,times
Real time(2)
Type(tms),Save :: lastbuf
Logical :: start = .True.
Type(tms) buffer
Integer junk
junk = times(buffer)
If (start) Then
lastbuf%utime = 0
lastbuf%stime = 0
start = .false.
End If
time(1) = buffer%utime - lastbuf%utime
time(2) = buffer%stime - lastbuf%stime
dtime = time(1) + time(2)
lastbuf = buffer
End Function
! ETIME in standard Fortran.
Real Function etime(time)
Real time(2)
Call Cpu_Time(etime)
time(1) = etime
time(2) = 0
End Function
! ETIME via NAG Fortran Compiler Posix module.
Real Function etime(time)
Use F90_Unix_Env,Only:tms,times
Real time(2)
Type(tms) buffer
Integer junk
junk = times(buffer)
time(1) = buffer%utime
time(2) = buffer%stime
etime = buffer%utime + buffer%stime
End Function
|
|
 |
Is there a FLUSH procedure? |
 |
Yes.
The NAG Fortran Compiler has a number of built-in modules to provide access to a large number of Posix-related system calls. In order to access these, the appropriate module must be accessed with a USE statement. The FLUSH routine is in the F90_UNIX_IO module.
However, from Fortran 2003 this functionality is available through the FLUSH statement; we recommend that this be used in new programs. Here is a simple example showing how to use it.
Program slow_dots
!
! This program prints 10 dots, one per second, then finishes.
!
Use Iso_Fortran_Env,Only:output_unit
Implicit None
Integer i
Do i = 1,10
Write(*,'(a)',Advance='No') '.'
Call delay
Flush(output_unit)
End Do
Print *,'Done.'
Contains
Subroutine delay
Integer per_second,start,now
Intrinsic System_Clock
Call System_Clock(Count=start,Count_Rate=per_second)
If (start==-huge(start)) Stop 'No clock.'
Do
Call System_Clock(Count=now)
If (now<start .Or. now>=start+per_second) Exit
End Do
End Subroutine
End Program
|
|
 |
Is there a GETENV procedure? |
 |
Yes.
The NAG Fortran Compiler has a number of built-in modules to provide access to a large number of Posix-related system calls. In order to access these, the appropriate module must be accessed with a USE statement. The GETENV routine is in the F90_UNIX_ENV module.
However, from Fortran 2003 this functionality is available through the standard intrinsic procedure GET_ENVIRONMENT_VARIABLE; we recommend that this be used in new programs. Here is a simple example showing how to use it.
Program environment_example
!
! This program displays the values of the environment variables FRED and
USERNAME
! (if they exist).
!
Implicit None
Call show('FRED')
Call show('USERNAME')
Contains
Subroutine show(name)
Character(*),Intent(In) :: name
Character(:),Allocatable :: value
Integer len,status
Intrinsic Get_Environment_Variable
Call Get_Environment_Variable(name,Status=status,Length=len)
If (status==1) Then
Print *,'Environment variable "',name,'" does not exist.'
Else If (status/=0) Then
Print *,'Unexpected error',status,'for environment variable "',name,'"'
Else
Allocate(Character(len) :: value)
Call Get_Environment_Variable(name,Value=value)
Print *,'The value of environment variable "',name,'" is "',value,'".'
End If
End Subroutine
End Program
|
|
 |
Is there a “SYSTEM” procedure? |
 |
Yes. The NAG Fortran Compiler has a number of built-in modules to provide access to a large number of Posix system calls. In order to access these, the appropriate module must be accessed with a USE statement. The SYSTEM routine is in the F90_UNIX_PROC module. The following is a very simple example of how to use SYSTEM.
Program system_example
Use f90_unix_proc
Call system('dir')
End Program
|
|
 |
Can I use ‘$’ in a format to suppress newline? |
 |
No, the NAG Fortran Compiler does not accept this extension.
This extension is completely obsolete with the introduction, by Fortran 90, of non-advancing input/output. Here is an example of how to produce a prompt with standard Fortran.
Program prompting
Character(80) name
Write (*,90000,Advance='No')
90000 Format('What is your name? ')
Read *, name
Print *, 'Hello ', Trim(name)
End Program
|
|
 |
How can I compile a very old (Fortran 66/77) program without getting errors? |
 |
The NAG Fortran Compiler carries out a strict check for conformance to the Fortran standard and also carries out a large number of checks for obviously incorrect code. While this is the correct behaviour for a compiler when new code is being developed, it is sometimes necessary to reduce the stringency of error checking to allow older code written to lower standards to compile. There are a number of compiler options to compile such legacy code.
- -dusty
- Downgrades a number of common errors found in legacy code to warnings. Hence compilation can continue; these warnings can be suppressed by the ‘-w’ option. This option implies the ‘-mismatch_all’ option.
- -mismatch
- Downgrades errors resulting from mismatch in argument lists to warnings. Calls to routines in the same file must still be correct.
- -mismatch_all
- As ‘-mismatch’, but even incorrect calls to routines in the same file are accepted.
|
|
 |
What does the warning “TAB format input” mean? |
 |
TAB format is an extension to Fortran 77, and operates when TAB characters are found in fixed form source files. Because it is an extension, a warning message is produced. This format is a bit complicated, and not recommended for new programs (use free form source instead). |
|
 |
Why does the message “Byte count on numeric data type” appear? |
 |
This is an extension to Fortran 77 that was made obsolete by Fortran 90. Instead of specifying the number of bytes, Fortran 90 has kinds of each datatype, and intrinsic functions for choosing a kind based on the desired properties (SELECTED_INT_KIND and SELECTED_REAL_KIND). The NAG Fortran Compiler also provides a module, F90_KIND, which has named constants for convenient kind selection (the names for Integer and Real/Complex are also available from the standard intrinsic module ISO_FORTRAN_ENV). The equivalence between byte sizes and kinds using these names is as follows.
| Type * Byte Size |
Type(Kind Name) |
| INTEGER*1 |
Integer(int8) |
| INTEGER*2 |
Integer(int16) |
| INTEGER*4 |
Integer(int32) |
| INTEGER*8 |
Integer(int64) |
| REAL*4 |
Real(real32) |
| REAL*8 |
Real(real64) |
| REAL*16 |
Real(real128) |
| COMPLEX*8 |
Complex(real32) |
| COMPLEX*16 |
Complex(real64) |
| COMPLEX*32 |
Complex(real128) |
The kind of an integer or real constant is specified by appending an underscore and the kind value (or name); e.g. 120_int8 is an 8-bit integer constant, and 3.14159265358979323846264338327950288_real128 is a 128-bit real value.
|
|
 |
Why do I get the message “KIND value does not specify a valid representation method” with the NAG compiler? |
 |
The interpretation of kind values depends on the compiler. There are at least two obvious methods: sequential (1 to N, where N is the number of kinds) and byte (use the number of bytes for Integer and Real type). The NAG Fortran Compiler (and some other compilers) by default uses sequential kind numbering, so single and double precision real are REAL(1) and REAL(2), not REAL(4) and REAL(8). The disadvantage of the so-called “byte” scheme is that for the Complex type, the setting is the number of bytes for each part, i.e. half the total, which can be confusing.
The compiler option ‘-kind=sequential’ (the default) or ‘-kind=byte’ selects the method.
|
|
 |
What does “Buffer overflow on output” mean? |
 |
This means that your program attempted a sequential write, in a single record, with more bytes than will fit into the file buffer for that unit. The default buffer size for formatted input/output is 1024 bytes; for unformatted input/output, the default is unlimited.
To change the buffer size you can use the RECL= specifier in the OPEN statement for the file you wish to write. For example:
Open(13,File="myfile",Form="Formatted",Recl=2048)
will establish a buffer size of 2048 bytes on unit 13.
Note that Fortran provides the IOLENGTH= specifier in the INQUIRE statement to discover the needed value for RECL= for an unformatted file. For example:
Inquire(Iolength=n) big_array
Open(13,File="dump",Form="Unformatted",Recl=N)
will establish a sufficiently large buffer for unit 13 to allow the entirety of big_array to be read or written in one input/output statement.
An unlimited buffer size can be established for formatted input/output by using the Fortran 2003 feature “stream access”; however, this will disable the BACKSPACE statement on that unit. For example,
Open(13,File="list",Form="Formatted",Access="Stream")
will open unit 13 for stream access, enabling formatting input/output of records of unlimited length, but disabling the ability to backspace the unit.
|
|
 |
Why do I get the message “Variable X size of N bytes is too big”? |
 |
This means that your variable is larger than the maximum object size supported by the NAG Fortran Compiler's current mode. The maximum object size supported by the compiler is as follows
| Application Bitness |
Variable Size Limit |
| 32-bit |
2GB |
| 64-bit |
1TB |
These limits also apply to the total amount of memory used by variables at runtime.
|
|
 |
How can I control the maximum size of a named constant (PARAMETER)? |
 |
The maximum size of a named constant is controlled with the −max_parameter_size= option. This takes a limit in megabytes (MB); the default is −max_parameter_size=50.
|
|
 |
When doing mixed-language programming, what are the functions f90_init and f90_io_finish? |
 |
These functions are needed when the main program is in C instead of Fortran. The f90_init function initialises the Fortran environment, including the floating-point status, command-line arguments, and input/output subsystem. The f90_io_finish function writes the contents of all the Fortran output buffers to their files, and closes all the Fortran files. The following example shows how to use these functions.
int main(int argc,char *argv[])
{
f90_init(argc,argv);
/* At this point Fortran routines can be safely called. */
f90_io_finish();
return 0;
}
|
|
 |
On program termination, the warning “Floating underflow occurred”; how can I find out where this is happening? |
 |
Floating underflow is quite common in programs, and is rarely a problem. If it is a problem, you can set the IEEE halting mode for underflow to cause the program to stop when it happens; note that you should also set the “Traceback for runtime errors (−gline)” option so that the location will be reported.
The following program shows how to use IEEE halting mode to cause termination on underflow.
Program underflow_halt
Use Ieee_Exceptions
Implicit None
Call Ieee_Set_Halting_Mode(Ieee_Underflow, .True.)
Call make_underflow(0.5)
Contains
Subroutine make_underflow(x)
Real, Intent(In) :: x
Real :: y
Integer :: n
y = x
n = 1
Do
y = y**2
If (y==0) Exit
n = n + 1
Print *, 'Step', n, 'value', y
End Do
Print *, 'Zero reached at step', n
End Subroutine
End Program
|
|
 |
On program termination, the warning “Floating underflow occurred”; how can I stop this warning from appearing? |
 |
The Floating underflow warning can be suppressed in two ways:
- the underflow flag can be set to false before program termination;
- the link-time option −no_underflow_warning can be used.
The following program shows how to use IEEE halting mode to turn the underflow flag off prior to program termination.
Program turn_underflow_flag_off
Use Ieee_Exceptions
Implicit None
Call make_underflow(0.5)
Call Ieee_Set_Flag(Ieee_Underflow, .False.)
Contains
Subroutine make_underflow(x)
Real, Intent(In) :: x
Real :: y
Integer :: n
y = x
n = 1
Do
y = y**2
If (y==0) Exit
n = n + 1
Print *, 'Step', n, 'value', y
End Do
Print *, 'Zero reached at step', n
End Subroutine
End Program
|
|
 |
How can I read unformatted files written on a system with a different file format (e.g. endianness)?
How can I write unformatted files so they can be read on a system with a different file format (e.g. endianness)? |
 |
Unformatted file conversion is provided by three mechanisms:
- the −convert= option;
- the CONVERT= specifier on the OPEN statement;
- the FORT_CONVERTn environment variable.
Unformatted file conversion affects both reading and writing, so the same mechanism provides the answer for both questions.
The most common conversion requirement is for big-endian files with all floating-point data in IEEE format; this is provided by the “−convert=big_ieee” option which is on the Detail (1) tab of the Fortran Compiler pane of Project Settings.
For full details of the conversion mechanisms please refer to the NAG Fortran Compiler Release 5.3 Manual; compiler options are explained in section 2.4, and the specifier and environment variable are explained in section 5.1.5.
|
|
 |
Is it possible to redistribute applications built with the NAG Fortran Compiler? |
 |
Yes, it is possible. The easiest way to do this is to link the NAG Fortran Compiler run time library statically using the −unsharedrts option.
|