Introduction to Modern Fortran

Key Points

Connecting to ARCHER2 and transferring data
  • We should all understand and follow the ARCHER2 Code of Conduct to ensure this course is conducted in the best teaching environment.

  • ARCHER2’s login address is login.archer2.ac.uk.

  • You have to change the default text password the first time you log in

  • MFA is mandatory in ARCHER2

Hello World
  • A Fortran program begins with a program statement and ends with an end program statement.

  • A print statement is a simple way to write output to the terminal.

  • A write statement provides more control including ways to write to file.

  • Modules can be loaded with the use statement.

  • The iso_fortran_env module provides symbols which can be used to help read from and write to the terminal.

Variables
  • Fortran provides the intrinsic numeric types of integer, real and complex.

  • Without a kind, these types are implementation-defined. Use kind to specify the representation of variables.

  • The iso_fortran_env intrinsic module provides standard kinds such as real32 and real64.

  • Always use implicit none to prevent the accidental implicit declaration of new variables.

  • Use the parameter attribute to make the value associated with the name constant.

Logical and conditionals, character variables
  • Fortran provides two non-numeric intrinsic data types: logical and character.

  • A program’s flow can be directed using the results of logical operations used in conjunction with if and case constructs.

Loops and loop control
  • Iteration in Fortran is based around the do construct (somewhat analogous to C for construct). There is no equivalent of the C++ iterator class.

  • Without any control, a do loop will execute forever.

  • A loop iteration can be skipped with a cycle statement.

  • A loop can be ended if an exit statement is encountered.

  • It is very common to control the execution of a loop with an integer variable.

Array declarations
  • Unlike C, which often uses pointers to handle array data, Fortran has arrays which are an intrinsic feature of the language.

  • The number of dimensions in an array is its rank.

  • The number of elements in one of an array’s dimensions is its extent.

  • The ordered sequence of extents in an array is its shape.

  • The total number of elements in an array, equal to the product of its shape, is its size.

  • In Fortran array indices begin at 1 by default, but this can be changed if required.

  • New arrays can be created by using the intrinsic reshape() function with an existing one.

  • An array with an unknown size can be allocated at runtime.

  • Compilers are typically able to help you debug issues with arrays if you ask them to.

Array expressions and assignments
  • Fortran allows flexible operations on arrays or subsets of array elements and provides numerous intrinsic functions for such operations.

  • Some of these, such as all() and any() can be useful in directing the logical flow of a program.

Mini exercise: a choice of two
  • With a fairly small amount of the Fortran language, you can already solve some real problems.

Modules and compilation of modules
  • Modules in Fortran provide the way to structure collections of related definitions and operations, and make them available elsewhere.

Functions and subroutines
  • Functions and subroutines are referred to collectively as _procedures_.

  • Using intent for dummy variables allows control over whether updates to their values are permitted.

  • Procedures can be modified with prefixes such as pure and recursive which ensure respectively that the procedure has no side-effects and that it is able to directly or indirectly call itself.

  • Procedures may be defined as module sub-programs for which the compiler will automatically generate the contract block as part of the module file.

More on array dummy arguments
  • There are some additional considerations to think about when dummy arguments are arrays.

  • You may wish to pass the shape of the array explicitly, at the cost of providing more dummy arguments.

  • Arrays may have an assumed shape, but remember that they only receive the shape and not the original bounds of its dimensions.

  • Allocatable arrays can also be used as dummy arguments.

  • Dummy arguments can have the optional attribute. The corresponding actual arguments can be positional or provided as a keyword argument.

More on characters and strings
  • String-handling can be problematic if there is no mechanism to keep track of the length of the string.

  • Remember that Fortran provides intrinsic functions such as trim() and operators such as concatenation // which can help with string manipulation.

  • Pay attention when using strings as dummy arguments or procedure results.

Formats and edit descriptors
  • Control over the appearance of output is via the format specifier, which is a string.

  • This similar in spirit to the format string provided to printf() in C.

  • The use of a format allows predictable tabulation of output for human readers.

Operations on external files
  • Writing data to, or reading data from, an external file is an essential part of a useful application.

  • Unit numbers are integers which are used as handles to open files.

  • Errors from I/O can be handled with labels and by examining the returned message.

Using namelists
  • Namelists are declared using the namelist /namelist-group-name/ variable-name-list construct.

  • Read and write namelists by passing them directly to the read and write statements.

  • Remember that namelists cannot be read out of order from a file without first moving backwards through the file.

Exercises
  • Gain more experience putting your new knowledge to use.

Structures: derived types
  • The ability to aggregate related data in a structure is important.

  • Fortran offers the _derived type_ in addition to intrinsic types.

  • In its simplest form, one may think of this as the analogue to a C struct.

  • Derived types also form the basis of aggregation of data and related operations or procedures (viz. object-oriented programming); however, this introductory course will only touch on this feature.

Pointers and targets
  • Pointers are extremely useful for certain types of operations: they provide a way to refer indirectly to other variables or names (they act as an _alias_), or can be used for establishing dynamic data structures.

  • Remember to always initialise a pointer, to null() if necessary.

  • If a pointer is allocated, memory for its type is allocated and the pointer becomes associated.

  • The move_alloc() intrinsic function moves a memory allocation from one allocatable variable to another.

Procedures again: interfaces
  • An interface provides important information about a procedure to the compiler. Without this information, the compiler may not be able to use it.

  • When using modules, interfaces are generated automatically and provided to the compiler.

  • If not in a module, a function can be made visible to the compiler by declaring it with the external attribute, but the compiler can go further by checking the argument types if you write a full, explicit interface block.

  • Interfaces can also be used to implement limited polymorphism and operator overloading for derived types.

  • An elemental function is one which can be applied to a scalar actual argument or element-by-element to an array actual argument.

Miscellaneous
  • Fortran provides other utility procedures that can help with your program’s functionality.

  • These allow you to retrieve information from the calling command line and environment.

  • You can pass commands back to the operating system, but you should be very careful that your code remains portable.

  • Timing your code with cpu_time() can help you profile your code.

Other things you may see
Exercises: conjugate gradient and matrices
  • Fortran performance and array handling make it ideal for the solution of intense problems.

Exercises