Clicky

Fortran Wiki
GFortran

GFortran, the GNU Fortran compiler, is part of the GNU Compiler Collection (GCC) since 2005 (it was forked from G95 in January 2003), which is licensed under GPLv3+ with GCC Runtime Library Exception. In 2023, GFortran nearly implements all of the Fortran 2008 standard and partially Fortran 2018.

  1. Installing GFortran
  2. Basic usage
  3. Options
  4. Parallel computing
  5. Contributing to GFortran
  6. Other useful links

Installing GFortran

Since 2015 and GCC 5.1, a major version is published every year: the first stable 2022 version was therefore GFortran 12.1. Four subsequent minor versions are then published during the four next years (for example 11.2, 10.3, 9.4 and 8.5). It can be interesting to install several versions, the latest for bleeding edge features and older ones for their robustness. For example, it is not rare to see up to 10% variations in the CPU speed of your program depending on the GCC version, and the latest version is not always the fastest.

You will find here the basic information needed to install GFortran on Linux, macOS, FreeBSD and Windows systems. More details can be found at fortran-lang.

Linux

Just install with your package manager the GFortran package, named gfortran in Debian-based distributions (Ubuntu, Mint…) or gcc-fortran in RPM-based distributions (Fedora, Red Hat, CentOS, openSUSE…) and Arch-based (Arch Linux, Manjaro, EndeavourOS…) distributions.

macOS

If you have installed Homebrew, install its GCC package:

% brew install gcc

If you have conda, a gfortran package is available for macOS and Linux:

% conda install -c conda-forge gfortran

FreeBSD

Just install the GCC package, for example for the latest GCC 12 release:

# pkg install gcc12

Windows

There are several ways to install GFortran on Windows. An easy way is to use the Quickstart Fortran application.

If you use MSYS2, GFortran packages are available for the latest release. For example, for the UCRT64 environment, type:

$ pacman -S mingw-w64-ucrt-x86_64-gcc-fortran

Other GFortran Windows binaries

Basic usage

The basic usage of GFortran is

gfortran [options] file...

For example, if your project has a module and the main program, just type:

$ gfortran my_module.f90 my_main.f90

The default executable is named a.out under Unix-like systems and a.exe under Windows systems.

Options

You can use both GCC options and the GFortran specific options. For example, the default name of the executable can be changed by adding the -o GCC option:

$ gfortran my_module.f90 my_main.f90 -o my_exec

In this section, we present only a selection of useful options, as there are hundreds of them!

Debugging

You can use the GCC debugging options:

  • -g produces debugging information in the operating system’s native format.
  • -p and -pg generate extra code to write profile information suitable for the analysis program prof (-p) or gprof (-pg).

You can use also the Fortran specific options:

  • -fcheck=all to enable all run-time test (array bounds, memory allocation, pointers…).

Diagnostic

  • -std specifies the standard to which the program is expected to conform, which may be one of f95, f2003, f2008, f2018, gnu (default), or legacy. For example: -std=f2008 for the Fortran 2008 standard.
  • -pedantic issues warnings for uses of extensions to the language.
  • -Wall enables commonly used warning options.
  • -Wextra enables some warning options for usages of language features which may be problematic.

GCC provides the link options -static-libgfortran and -static-libquadmath to force the use of the static versions.

Optimization

You can use the GCC optimization options:

  • -O0 (default) reduces compilation time and make debugging produce the expected results.
  • -O1 to reduce code size and execution time, without performing any optimizations that take a great deal of compilation time.
  • -O2 to optimize even more. GCC performs nearly all supported optimizations that do not involve a space-speed tradeoff.
  • -O3 to optimize yet more.
  • -Ofast enables all -O3 optimizations but also optimizations that are not valid for all standard-compliant programs.
  • -Og to optimize debugging experience. It should be the optimization level of choice for the standard edit-compile-debug cycle.
  • -Os to optimize for size. It enables all -O2 optimizations except those that often increase code size.
  • -Oz to optimize aggressively for size rather than speed.

GCC offers also machine-specific options starting with -m, especially:

  • -march=cpu-type generates instructions for the machine type cpu-type. -march=native enables all instruction subsets supported by the local machine. Further details in the GCC doc.
  • -mtune=native produces code optimized for the local machine.

Parallel computing

Parallel computation is achieved by exploiting different aspects of modern architectures: from vectorization instructions, multi-threading, message passing and offloading to GPU devices. The followings enable handling one or more of these aspects:

Vectorization

The first level of parallelism with vectorization can be achieved by the combination of -O3 and -march=native which enables the compiler to exploit the local machine vector instructions (SSE, AVX, AVX2, AVX512, etc):

$ gfortran -O3 -march=native

Programmer-instructed vectorization can be achieved with OpenSIMD (part of OpenMP), for details see this OpenMP API Specification page.

OpenMP

Use the option -fopenmp. You can specify the number of threads using the environment variable OMP_NUM_THREADS, for example in a UNIX-like system type that command before running the executable:

$ export OMP_NUM_THREADS=4

You can also spawn threads dynamically at run time in two different ways:

  1. within the directives

    use omp_lib
    !$omp paralel do num_threads(num_threads)
    ... parallel code
    !$omp end parallel do
  2. As a routine call

    use omp_lib
    call omp_set_num_threads(num_threads)
    !$omp parallel do
    ... parallel code
    !$omp end parallel do

Accelerator devices: OpenACC

OpenACC support was introduced in GCC 5. Depending on the target GPU architecture (Intel, Nvidia, AMD) different offloading backends are available, read here. For Nvidia PTX offloading, you need to install the following backend:

$ sudo apt install gcc-offload-nvptx

Now, you can compile your code with the flag -fopenacc and test

!$acc parallel loop
do i = 1,n
... parallel code offloaded to GPU
end do

OpenCoarrays

GFortran does not natively support coarrays (Fortran 2008) and the parallel programming features introduced by the 2018 standard. You need to install the OpenCoarrays software.

For example, in an Ubuntu Linux distribution type:

$ sudo apt install libcoarrays-dev libcoarrays-mpich-dev
$ git clone https://github.com/sourceryinstitute/OpenCoarrays.git
$ cd OpenCoarrays
$ ./install.sh

and accept the installation of the MPICH library (although OpenCoarrays can also work with Open MPI).

You need to define the environment variables in your terminal (you can add it in your ~/.bash_profile):

$ source /home/my_login/OpenCoarrays/prerequisites/installations/opencoarrays/2.9.2/setup.sh

here for the 2.9.2 version.

Use the command caf instead of gfortran to compile your program, and cafrun -n to run it with the number of images you want:

$ caf main.f90
$ cafrun -n 4 ./a.out 

OpenMPI

If you want to build OpenMPI locally follow these instructions.

You can also install a pre-built package (linux or WSL):

$ sudo apt-get update
$ sudo apt-get install openmpi-bin

Then include the header file in your Fortran program/modules:

include 'mpif.h' ! To be included in files calling MPI functions
call MPI_INIT(err) ! should be invoked just once at the beginning of your main program
... code ! N instances of your program with specific communication steps
call MPI_FINALIZE(err) ! should be invoked just once at the end of your main program

Compile and run the code:

$ mpif90 main.f90 -o main.exe
$ mpirun -np 4 main.exe

This is a useful link with a concise Hello world for starters.

Contributing to GFortran

GFortran is free software developed by volunteer users and any help is welcome.

Bug reporting

You can report bugs in the GCC Bugzilla system: first, update your major GFortran version to its latest release, then search if the bug was already reported, then file the bug. You can also use the GFortran mailing list fortran@gcc.gnu.org if you are uncertain on how to handle Bugzilla.

Development

Anyone interested in joining the GFortran developers team should send an email to gfortran@gcc.gnu.org or jvdelisle@gcc.gnu.org to receive an invitation to join the GFortran Mattermost workspace (now hosted by the Oregon State University Open Source Lab), which was created in December 2022 to facilitate chat, patch discussions, mentoring new folks, etc. See also that January 2023 message by Paul Richard Thomas to comp.lang.fortran. And that 2008 message by Tobias Burnus to comp.lang.fortran contains advice that are still pertinent.

See the Quickstart Guide to Hacking Gfortran. The GNU Fortran Compiler Internals documents the internals of GFortran.

You can also contribute to GFortran at the Google Summer of Code: https://gcc.gnu.org/wiki/SummerOfCode.

Downloading the sources

You can read the GCC sources by cloning that read-only git repository:

$ git clone git://gcc.gnu.org/git/gcc.git

or if you have firewall problems:

$ git clone https://gcc.gnu.org/git/gcc.git

Concerning Fortran, the sub-directories are gcc/fortran, libgfortran, gcc/testsuite/gfortran.dg and gcc/testsuite/gfortran.fortran-torture.

To build GCC, you also need to install the libraries GMP, MPFR and MPC.

Testing the latest nightly build

Unofficial GFortran 32-bit and 64-bit binary packages based on the current development source code can be found on http://gcc.gnu.org/wiki/GFortranBinaries. For example, to install the latest 64-bit nightly binary in a Linux system, download and install the latest GCC trunk build:

$ cd /tmp
$ wget https://gfortran.meteodat.ch/download/x86_64/nightlies/gcc-trunk.tar.xz
$ cd /opt
$ sudo tar -xJf /tmp/gcc-trunk.tar.xz
$ /opt/gcc-trunk/bin/gfortran --version
GNU Fortran (GCC) 13.0.1 20230227 (experimental) [master r13-6353-g529e03b988]

Then set LD_LIBRARY_PATH and PATH: see that GFortran wiki page for details on bash and csh/tcsh. For zsh, this will work for both the x86_64 and i386 versions:

# Determine platform
ARCH=`uname -m`

# GFortran
export PATH=/opt/gcc-trunk/bin:${PATH}

if [[ ${ARCH} == "x86_64" ]]; then
    LIB64="64"
fi

if [ -z "$LD_LIBRARY_PATH" ]; then
  LD_LIBRARY_PATH="/opt/gcc-trunk/lib${LIB64}"
else
  LD_LIBRARY_PATH="/opt/gcc-trunk/lib${LIB64}:$LD_LIBRARY_PATH"
fi
export LD_LIBRARY_PATH

Standards Compliance