The XL Fortran Compiler offers full support for the Fortran 77, 90 and 95 language standards.
The IBM xlf Fortran compiler is used in a similar manner to most UNIX compilers. The most basic compile is of the form
% xlf source.f
This will produce an executable named a.out. However, this usage assumes Fortran 77 syntax and does not produce optimized code. Basic ways to use XLF to produce optimized parallel programs are introduced in this document.
XL Fortran is usually invoked by making an appropriate choice from a set of many commands. Each command is really an alias for xlf packaged with a set of commonly used options.
Some examples of compiler commands with their default behavior are :
| Command | Description |
|---|---|
| xlf | Fortran 77 compliant; f77 fixed-form source code |
| mpxlf | Parallel environment, Fortran 77 behavior |
| xlf_r | xlf with links to thread-safe components |
| mpxlf_r | Parallel environment xlf with thread-safe components |
| xlf90 | Fortran 90 compliant; f90 free-form source code |
| mpxlf90 | Parallel environment, Fortran 90 behavior |
| xlf90_r | xlf90 with links to thread-safe components |
| mpxlf90_r | Parallel environment xlf90 with thread-safe components |
NERSC recommends the following as a standard compile line for modern Fortran production parallel codes:
% mpxlf90_r -O3 -qstrict -qarch=auto -qtune=auto filename.f
Please note: The flag "-qextchk" does not work with MPI codes.
The following table lists some functionality of the various compiler
names. Note that DM means Distributed Memory (spread across nodes)
and SM means Shared Memory (within a node), using a thread-safe
model.
Fortran defaults indicates the
the basic behavior of the compiler, e.g. f90 implies the compiler accepts the
Fortran 90 source form. See below for more details. However, all compiler
commands accept Fortran 77/90/95 language elements, provided the source form is
appropriate.
The recommended compiler names are in bold.
| Compiler Name | Functionality | ||
|---|---|---|---|
| DM Parallel | SM Parallel | Fortran defaults | |
| xlf | No | No | 77 |
| xlf_r | No | Yes | 77 |
| mpxlf | Yes | No | 77 |
| mpxlf_r | Yes | Yes | 77 |
| xlf90 | No | No | 90 |
| xlf90_r | No | Yes | 90 |
| mpxlf90 | Yes | No | 90 |
| mpxlf90_r | Yes | Yes | 90 |
| xlf95 | No | No | 95 |
| xlf95_r | No | Yes | 95 |
| mpxlf95 | Yes | No | 95 |
| mpxlf95_r | Yes | Yes | 95 |
Distributed-memory parallelism is typically directly through the MPI library or through a library like PESSL or ScaLAPACK built on MPI. Shared-memory parallelism is available through SMP libraries like ESSL-SMP or NAG-SMP, explicitly through OpenMP, IBM tasking directives, automatic parallelization by the compiler, or the pthreads API.
Similar to most Unix compilers, the compilation process can stopped before linking by using "-c", and specifying ".o" files on the command line will cause them to be linked:
% xlf90_r -c filename.f % xlf90_r -o executable_name filename.o
IBM's version of UNIX is known as AIX. The compiler commands listed above are in your AIX search path when you log in.
NERSC has installed the modules package for installation and maintenance of all third-party software. Compiling and linking with programming libraries is greatly simplified by using modules. Type module avail for a list of available modules and module help modulename for help using a specific module.
A number of popular utilities are available in the GNU module.
By default, the compilers expect all Fortran source files to have the extension ".f", and all Fortran source files that require preprocessing to have the extension ".F". To change this behavior, you can use the "-qsuffix" option:
% xlf90_r -qsuffix=f=f90:cpp=F90 file1.f90 file2.F90
This command will compile files ending in ".f90", and preprocess and compile files ending in ".F90".
By default, the compilers with Fortran 77 defaults require fixed form Fortran source. Compilers with Fortran 90 defaults require free form Fortran source. To change this behavior, use either the -qfree=f90, or -qfixed=72 option:
% xlf90_r -qfixed=72 filename.f % xlf_r -qfree=f90 filanem2.f
The file filename.f is compiled under the assumption that it is written in 72 column (using a number other than 72 is allowed) Fortran 77 source form, and the file filename2.f is compiled assuming it is written using the Fortran 90 free form.
To provide data to the preprocessor, such as defining a macros etc., use the following syntax:
% xlf_r -WF,-DSINGLE a.F
This command will preprocess the files a.F, passing the option "-DSINGLE" to the cpp command.
The main difference in the behavior of Fortran 77 and Fortran 90/95 compilers is in the default treatment of data. Using one of the Fortran 77 compilers, all data is treated as if it had appeared in a Fortran "save" statement - it is statically allocated. Data which is statically allocated is preserved across subroutine calls. Using one of the Fortran 90 or 95 compilers results in all data (not included in a save statement) being allocated on the stack. Data which is allocated on the stack is not reserved across subroutine calls.
Fortran 90/95 has a defined standard for NAMELIST data files. This differs from format used by IBM prior to the standard. To use the old NAMELIST style, set the environment variable XLFRTEOPTS to namelist=old and recompile your program.
The default datatype sizes in XL Fortran are shown below:
| Type | Length (bytes) |
|---|---|
| byte1 | 1 |
| character | 1 |
| complex | 2 × 4 |
| double complex1 | 2 × 8 |
| double precision | 8 |
| integer/logical | 4 |
| pointer | 4 |
| real | 4 |
The default sizes of some of the datatypes can be changed with the "-qrealsize" and "-qintsize" options:
% xlf90_r -qrealsize=8 -qintsize=8 a.f
specifies that all reals will be promoted to 8 bytes (also promotes complex to 2 × 8 bytes, double precision to 16 bytes, and double complex to 2 × 16 bytes) and all integers (also promotes logicals) will be promoted to 8 bytes. Promotion only affects constants, variables, and functions for which no specific length or kind is declared.
The compiler also accepts KIND specifiers, or the "*" notation, for the following datatypes:
| Type | KIND | * | Length (bytes) |
|---|---|---|---|
| complex | 4 | 8 | 2 × 4 |
| 8 | 16 | 2 × 8 | |
| 16 | 32 | 2 × 16 | |
| integer/logical | 1 | 1 | 1 |
| 2 | 2 | 2 | |
| 4 | 4 | 4 | |
| 8 | 8 | 8 | |
| real | 4 | 4 | 4 |
| 8 | 8 | 8 | |
| 16 | 16 | 16 |
Invoking any of the compilers starting with "mp" enables the program for running across several nodes of the SP. Of course, you are responsible for using a library such as MPI to arrange communication and coordination in such a program. Any of the mp compilers sets the include path and library paths to pick up the MPI library.
% mpxlf90_r a.f
The shared-memory support implied by the _r suffix is required in order to use the MPI I/O subroutines.
XL Fortran supports a variety of shared-memory parallelism constructs.
OpenMP supports multi-platform shared-memory parallel programming in C/C++ and Fortran on many architectures. XL Fortran supports all OpenMP directives.
See Using OpenMP with xlf on the NERSC SP.
The compiler will attempt to automatically parallelize simple loop constructs if you use the option -qsmp:
% xlf90_r -qsmp a.f
You can use the "-qreport=smplist" to generate a listing describing which loops were successfully parallelized.
By default xlf does not trap floating point exceptions. For example, dividing by zero or taking the square root of a negative number will not cause a running program to crash. The result will be marked as a NaN or INF and may taint other variables that perform operations using that result, but the program will not halt. However, a 1/INF will become a floating point zero, which may not be what is intended.
You can enable trapping these floating point exceptions with the compiler option -qflttrp. The program will then crash and write a core file when one of the exceptions is encountered. Enabling these traps may affect performance.
You can enable trapping for one or all of the following exception conditions:
The xlf compiler syntax is
% xlf_r -qflttrap=exception:enable source.f
For example, this line will compile source.f to enable trapping divide by zeros and invalid results:
% xlf_r -qflttrap=zerodivide:invalid:enable source.f
The generic POWER processor will not trap square roots of a negative number, but the POWER3 on the NERSC SP will. However, you must explicitly compile for the POWER3, e.g.
% xlf_r -qarch=pwr3 -qflttrap=zerodivide:invalid:enable source.f
Using the optimization flags when compiling with XL Fortran can substantially increase the performance of your programs. See IBM Compiler Optimization Flags for a detailed description of the most useful compiler options.
The xlf run-time libraries maintain I/O buffers for improved performance. If you have applications in which Fortran routines work with routines in other languages or in which a Fortran process works with other processes on the same data file, the data written by Fortran routines may not be seen immediately by other parties (and vice versa), because of the buffering.
You can control buffering at run-time by setting an environment variable, XLFRTEOPTS, or by using the SETRTEOPTS Fortran procedure. For example,
% setenv XLFRTEOPTS buffering={enable | disable_preconn | disable_all}
Note: I/O buffering is always enabled for files on sequential access devices (such as pipes, terminals, sockets, and tape drives). The setting of the buffering option has no effect on these types of files.
You call also call the XLF service routine flush_ in your code:
CALL flush_(logical_unit_number)
If you disable I/O buffering for a logical unit, you do not need to call the Fortran service routine flush_ to flush the contents of the I/O buffer for that logical unit.