The Fortran standard has no directives and no preprocessor, so everything on this page is an extension. They are written so that a compiler that does not know them sees only a comment: a directive is a comment with a sentinel at its start. The viewer shows a sentinel comment as a directive (a separate colour from comments), and the lines of a preprocessor as directives too.
Sentinel comments
| Sentinel | Used for |
|---|---|
!$omp | OpenMP directives. Also !$ompx for implementation extensions |
!$acc | OpenACC directives |
!$cuf | CUDA Fortran directives of NVIDIA: !$cuf kernel do |
!$ followed by a blank | conditional compilation: the rest of the line is code when OpenMP is on and a comment when it is off |
!dir$, !DIR$ | Intel and Cray compiler directives (ivdep, vector, unroll, loop count, attributes, freeform, fixedformlinesize, simd …) |
!dec$, !idec$ | DEC and Intel: attributes dllexport, attributes alias, freeform and nofreeform, and the preprocessor-like if defined(…), define, endif, message |
!gcc$ | GNU Fortran: attributes, unroll n, builtin (name) attributes simd (notinbranch), ivdep, vector, novector |
!pgi$, !$pragma | Portland Group (now NVIDIA) and Sun/Oracle compiler directives |
!ibm*, @process in column 1 | IBM XL Fortran directives (!IBM* UNROLL(4)) and option lines (@PROCESS NOOPT) |
!ocl | Fujitsu compiler directives |
!cdir, !nec$ | NEC SX vectorising compiler |
!hpf$ | High Performance Fortran (a data-parallel dialect of the 1990s) |
!mic$, !vd$, !$par, !$doacross, !$sgi, !$mp | Cray, Convex, SGI and other vendors’ parallelisation directives, mostly historical |
In free form the sentinel is the first thing on the line (after blanks) and is written without a space inside it: !$omp, not ! $omp, which is an ordinary comment (the viewer follows this). A trailing
! after the directive text is an ordinary comment.
Sentinels in fixed form
In fixed form the sentinel begins in column 1 and takes the place of the comment mark: C$OMP, c$omp, *$OMP and !$OMP (and likewise C$ACC, CDIR$, CDEC$, CMIC$, CIBM*).
Columns 6 and beyond carry the text, and a non-blank, non-zero character in column 6 continues the directive on the next line:
C$OMP PARALLEL DO PRIVATE(I)
C$OMP+REDUCTION(+:S)
DO 10 I = 1, N
S = S + A(I)
10 CONTINUE
C$OMP END PARALLEL DO
CDIR$ IVDEP
C$ NT = OMP_GET_MAX_THREADS()
+ in column 6 continues the directive, and C$ followed by blanks is conditional compilation.OpenMP
OpenMP is a specification of directives for shared-memory parallelism, in Fortran, C and C++. The Fortran forms are !$omp directive [clauses], in the code and, for many, closed by !$omp end directive.
In free form a directive may be continued with a trailing & and a !$omp& (or !$omp) at the start of the next line. The preprocessor macro _OPENMP is defined to the year and month of the version
(201511 for 4.5, 202011 for 5.1, 202111 for 5.2).
Directives (OpenMP 5.2): parallel, do, sections, section, single, workshare, masked (and the older master), critical, barrier, atomic, flush, ordered, task, taskwait, taskgroup, taskloop, taskyield,
simd, declare simd, loop, scan, scope, teams, distribute, target, target data, target enter data, target exit data, target update, declare target, declare reduction, declare mapper, declare variant, threadprivate, allocate, allocators, requires,
depobj, cancel, cancellation point, metadirective, dispatch, interop, assume, nothing, error, tile, unroll, and the combined forms such as parallel do, parallel sections, parallel workshare, target teams distribute parallel do simd.
Clauses: private, firstprivate, lastprivate, shared, default, reduction, in_reduction, task_reduction, copyin, copyprivate, schedule, collapse, ordered, nowait, if, num_threads, proc_bind, safelen, simdlen, aligned, linear, depend,
priority, final, untied, mergeable, grainsize, num_tasks, map, to, from, device, num_teams, thread_limit, dist_schedule, defaultmap, is_device_ptr, use_device_ptr, allocate, order, bind, filter, atomic_default_mem_order and others.
The lists are written from knowledge of the OpenMP 5.2 specification, whose PDF could not be text-extracted for this page (see “Not described” on the overview); the specification at openmp.org is the reference for the exact set. The viewer does not look inside a directive: the whole line, from the sentinel to a trailing comment, is one directive colour, so every directive and clause is covered the same.
OpenACC
!$acc directives, for accelerators such as GPUs: parallel, kernels, serial, loop, parallel loop, kernels loop, serial loop, data, enter data, exit data, host_data, update, wait, atomic, declare, routine, init, shutdown, set, cache, each closed by !$acc end … where it opens a region.
Clauses include copy, copyin, copyout, create, delete, present, deviceptr, attach, detach, no_create, async, wait, num_gangs, num_workers, vector_length, gang, worker, vector, seq, independent, auto, collapse, tile,
reduction, private, firstprivate, default, if, self, device_type, bind, nohost and finalize. The macro _OPENACC is defined as the year and month of the version. See openacc.org.
Conditional compilation lines
A comment of the form !$ (free form, !$ then a blank) or C$ , *$ , !$ (fixed form) holds code that is compiled only when OpenMP is enabled, so one source builds with and without it:
!$ use omp_lib
integer :: nt
nt = 1
!$ nt = omp_get_max_threads()
print *, 'threads:', nt
The viewer colours the !$ as a directive and the rest of the line as code.
The C preprocessor
Fortran files are often run through cpp (in its traditional mode so that Fortran text is not mangled) or fpp. GNU Fortran does so for the extensions .F, .FOR, .FTN, .fpp, .FPP, .F90, .F95, .F03 and .F08, and for any file under -cpp.
#define N 100
#ifdef USE_MPI
use mpi
#else
integer :: rank = 0
#endif
#if defined(__GFORTRAN__) && __GNUC__ >= 12
! newer compiler
#elif defined(__INTEL_COMPILER)
! Intel
#endif
#include "config.h"
#pragma once
# 1 "file.F90"
- the lines are
#define,#undef,#if,#ifdef,#ifndef,#elif,#else,#endif,#include,#line,#error,#warning,#pragmaand the line markers# 12 "file"thatcppwrites. A line may be continued with a trailing backslash, and the viewer takes the continued lines as one directive - predefined macros differ by compiler:
__GFORTRAN__,__GNUC__,__INTEL_COMPILER,__NVCOMPILER,__FLANG,_OPENMP,_OPENACC - the viewer does not expand macros or hide the branch of a conditional that is switched off: both branches are coloured as Fortran
- pitfalls: a Fortran
//may look like a C++ comment to a non-traditionalcpp; an apostrophe in a comment may upset one; a macro that expands to a long line can pass the 132-column limit (use-ffree-line-length-none)
Coco and other tools
- Coco (ISO/IEC 1539-3, “Conditional compilation”) uses lines that start with
??:?? if (debug) then,?? else,?? end if,?? integer, parameter :: n = 10. A few projects used it; it was never widely supported, and the viewer colours its lines as directives - fypp, a Python-based preprocessor for Fortran, uses
#:lines and${…}$or$:and@:forms. Its files are normally named.fyppor.F90; the#lines are coloured as directives - pFUnit test files (
.pf) use@test,@assertEqualand similar lines; these are not coloured specially - the Microsoft and DEC metacommands (
$DEFINE,$IF,$ENDIF,$INCLUDE:'file') start with$in column 1 of fixed form and are coloured as directives
INCLUDE
include 'file' is the language’s own include line (a statement that the compiler replaces by the file’s text), not a directive. Its search path is set by -I. The viewer colours the word as a keyword and the file name as a string.