Fortran 90 and Beyond AE6382 Fortran 90+ OBJECTIVES Changes from Fortran 77 Essentials Program structure Data types and specification statements Essential program control Array changes AE6382 Fortran Changes Source code may now be in free-format New program structure New control statements added MODULE program unit added DO WHILE, CYCLE, EXIT New expression elements New type specification format New array operations Modules Scope Procedures – calling AE6382 Fortran Changes All Fortran 77 code should still work with a Fortran 95 compiler Except for ASSIGN statements, PAUSE, and the alternate RETURN Source code can be either classic format or new free format Free format – Spaces are significant in free format ! is now the comment character, ignore rest of line & is the continuation character C in column 1 means nothing ; separates multiple statements on a single line – no special spacing imposed, up to 132 characters – – – – Cannot be mixed in a single file AE6382 Fortran Source Format All Fortran 77 code should still work with a Fortran 95 compiler Except for ASSIGN statements, PAUSE, and the alternate RETURN Source code can be either classic format or new free format Free format – Spaces are significant in free format ! is now the comment character, ignore rest of line & is the continuation character C in column 1 means nothing ; separates multiple statements on a single line – no special spacing imposed, up to 132 characters – – – – Cannot be mixed in a single file AE6382 Statement Source Format Classic format PROGRAM MAIN C COMMENTS ARE ALLOWED IF A “C” IS PLACED IN COLUMN #1 DIMENSION X(10) READ(5,*) (X(I),I=1,10) WRITE(6,1000) X 1000 FORMAT(1X,’THIS IS A VERY LONG LINE OF TEXT TO SHOW HOW TO CONTINUE ’ * ‘THE STATEMENT TO A SECOND LINE’,/,10F12.4) Free format PROGRAM MAIN ! A COMMENT DIMENSION X(10) READ(5,*) (X(I),I=1,10) WRITE(6,1000) X ! Another comment 1000 FORMAT(1X,’THIS IS A VERY LONG LINE OF TEXT TO SHOW HOW TO CONTINUE ’& &‘THE STATEMENT TO A SECOND LINE’,/,10F12.4) AE6382 Fortran Program Units Fortran consists of PROGRAM unit, a main program – required SUBROUTINE unit FUNCTION unit MODULE unit These modules can contain internal sub-programs The BLOCK DATA unit is still valid for use with COMMON blocks – deprecated by MODULE Representing global data with a MODULE rather than a COMMON block is more maintainable AE6382 Program Layout of a main program Can contain an arbitrary number of internal sub-program units Variables in the main program are accessible in the subprograms, unless re-defined in the sub-program The sub-programs can themselves contain sub-programs PROGRAM main … CONTAINS SUBROUTINE sub … END SUBROUTINE sub FUNCTION func … END FUNCTION func END PROGRAM AE6382 Subroutine/Function Layout of a sub-program Can contain an arbitrary number of internal sub-program units Variables in the sub-program are accessible in the contained sub-programs, unless re-defined in the sub-program SUBROUTINE sub(formal arguments) <formal argument declarations> <local variable declarations> <executable statements> CONTAINS SUBROUTINE sub … END SUBROUTINE sub FUNCTION func … END FUNCTION func END SUBROUTINE sub AE6382 Module Layout of a module Contains type definitions and variable allocations Contains an arbitrary number of internal sub-program units MODULE mod <variable declarations> CONTAINS SUBROUTINE sub … END SUBROUTINE sub FUNCTION func … END FUNCTION func END MODULE mod AE6382 Module The MODULE is used to contain globally accessible variables and procedures Safer than a COMMON block Ensures type and argument safety for contained sub-programs The MODULE is accessed in a Fortran unit using the USE command The USE statements must come before any local declarations PROGRAM main USE module1 USE module2 <variable declarations> CONTAINS <internal procedures> END PROGRAM main AE6382 New Statements - Loops There are changes for loops in Fortran 90+ The DO WHILE statement The EXIT statement will terminate the loop The CYCLE statement will start next iteration of loop The EXIT and CYCLE statements also apply to normal DO loops DO WHILE (.TRUE.) … MAX = 100 DO WHILE (I < MAX) DO I=1,MAX,2 … IF (<…>) EXIT … IF (<…>) EXIT … IF (<…>) CYCLE … ENDDO … ENDDO I = I + 1 ENDDO AE6382 New Statements - Loops Loops can now be labeled (not the old Fortran statement label) These labels can be used as targets for EXIT and CYCLE This makes it possible to remove one of the few remaining uses of GOTO and statement labels MAX = 100 OUTER: DO I=1,IMAX INNER: DO J=1,JMAX … IF (<…>) EXIT INNER … IF (<…>) EXIT OUTER ENDDO ENDDO AE6382 New Expression Elements There are new relational operators defined .GT. > .GE. >= .LT. < .LE. <= .EQ. == .NE. /= AE6382 New Statements – Select Case There is a new SELECT CASE statement in Fortran 90+ Should be used to replace the various computed gotos found in Fortran 77 SELECT CASE (I) CASE(1,5,7) … CASE(8:10,21:31) … CASE(:-1) … CASE DEFAULT … END SELECT AE6382 Type Specification The type specifications for variables has been significantly expanded The type of the variable is specified Various properties of the variable can be specified The numerical accuracy can be controlled The Fortran 77 type is still valid Its use eliminates need for separate DIMENSION statements and the *number forms, INTEGER*4 INTEGER, DIMENSION(5) :: I, J REAL, PARAMETER :: PI = 3.14159 INTEGER, PARAMETER :: LONG = SELECTED_REAL_KIND(12,200) REAL(KIND=LONG) :: X AE6382 KIND Specification The KIND parameter is used to specify the precision/range of the variable There is a simple numeric value, implementation dependent – REAL(KIND=4) :: X – Frequently the number is the byte size There is a set of intrinsic functions that can be used, even at compile time, to select a value Precision identifiers can be user defined INTEGER, PARAMETER :: DP = SELECTED_REAL_KIND(15,307) This defines a kind named DP that is capable of 15 digits of precision with an exponent range of E-307 to E307 A defined kind can be used as INTEGER, PARAMETER :: DP = SELECTED_REAL_KIND(15,307) REAL(KIND=DP) :: X, Y X = 14.3E2_DP AE6382 KIND Specification There are several intrinsic functions that relate to KIND SELECTED_REAL_KIND(digits,range) SELECTED_INTEGER_KIND(digits) KIND(variable or constant) The available types depend on the compiler/architecture, the selected kind functions return the id of the available type that can accommodate the requested parameters A return of -1 as the kind value indicates that there is no support AE6382 KIND Specification There are several intrinsic functions that return information about types They return information about the kind of the supplied argument DIGITS(X) The number of significant digits EPSILON(X) The least positive number that added to 1 returns a number that is greater than 1 HUGE(X) The largest positive number MAXEXPONENT(X) The largest exponent MINEXPONENT(x) The smallest exponent PRECISION(X) The decimal precision RADIX(X) The base in the model RANGE(X) The decimal exponent TINY(X) The smallest positive number The type conversion intrinsics have been modified to use kind I = INT(X,KIND=kind) AE6382 Type Modifiers The PARAMETER modifier indicates that the variable is a constant INTEGER, PARAMETER :: PI = 3.14159 The DIMENSION modifier is used to dimension a variable REAL, DIMENSION(100,100):: A, B, C The POINTER modifier is used to declare a pointer The TARGET modifier is used to declare a variable that can be pointed to by a pointer variable REAL, POINTER :: X REAL, TARGET :: A X => A ! Setting the value of the pointer X = PI ! Setting the value of the object pointed to by the pointer NULLIFY(X) ! Break the pointer association AE6382 Type Modifiers - Formal Arguments The INTENT modifier is used on type specifications for formal argument lists SUBROUTINE SUB(A,B,C) INTEGER, INTENT(IN) :: A ! A is read-only in subroutine, may be constant in call INTEGER, INTENT(INOUT) :: B ! B can be updated, must be variable INTEGER, INTENT(OUT) :: C ! C can only be written to, must be variable The SAVE modifier is used to save a variable local to a procedure to retain its value for the next call SUBROUTINE SUB(A) INTEGER, INTENT(IN) :: A ! A is read-only in subroutine, may be constant in call INTEGER, DIMENSION(10) :: I ! will be reallocated on next entry INTEGER, SAVE :: TOTAL ! will have value saved for next entry AE6382 Data Initialization The new type specifiers allow the newly created variables to be initialized (replacement for DATA statements) REAL :: X = 70.42 INTEGER :: I = 1, J = 3 INTEGER, DIMENSION(5) :: K = (/ (2*I,I=1,5) /) REAL, DIMENSION (4) :: Y = (/ 1.0, 2.0, 3.0, 10.0 /) REAL, PARAMETER :: PI = 3.14159 The (/ … /) is the format for a vector constant With the PARAMETER modifier it is used to create constants AE6382 Derived Types Derived types correspond to a structure in C It is a composite type formed from other elements Use % to access components The component elements may also be derived types sphere%point%x TYPE point ! The definition of the new type REAL :: X, Y, Z END TYPE point TYPE(point) :: START, END ! Creating instances of the new type … START%X = 0.1 ; START%Y = 0.0 ; START%X = 100.0 END = point(10.0,10.0,10.0) ! Accessing components ! Using a constructor to set a value … END = START ! Assignment is automatically defined - + * / are NOT AE6382 Arrays Operations with arrays have been greatly expanded Whole array operations REAL, DIMENSION(10,10) :: A, B, C C = A + B C = A * B ! this is not a matrix multiply – c(i,j) = a(I,j) * b(i,j) C = 0.0 ! initialize entire array with 0.0 Terms associated with arrays rank number of dimensions bounds upper and lower limits of indices extent number of elements in dimension size total number of elements shape rank and extents conformable same shape AE6382 Array Terminology INTEGER, DIMENSION(15) :: A INTEGER, DIMENSION(5,0:5) :: B,C rank number of dimensions bounds upper and lower limits of indices extent number of elements in dimension size total number of elements shape rank and extents conformable same shape A: rank=1, bounds=1,15, extent=15, size=15, shape=(/ 15 /) B and c: rank=2, bounds=1,5 and 0,5, extent=5 and 6, size=30, shape=(/ 5,6 /) B and C are conformable AE6382 Array Declaration Defined shape arrays INTEGER, DIMENSION(15) :: A INTEGER, DIMENSION(5,0:5) :: B,C Allocatable arrays INTEGER, DIMENSION(:,:), ALLOCATABLE :: A ! creates a variable A that is a 2D matrix ! the variable A cannot be used until memory is allocated ALLOCATE(A(100,100),STAT=ERR) ! allocates memory for a 100x100 matrix that is assigned to A DEALLOCATE(A) ! releases the memory assigned to A Automatic arrays (cannot be SAVE’d in procedure) SUBROUTINE SUB(M,N) INTEGER :: M,N REAL, DIMENSION(M,N) :: A ! this array is allocated anew on every entry to SUB, its shape is based on ! the formal arguments M and N END SUBROUTINE SUB AE6382 Array Access Arrays can be accessed as whole array section or slice element Simple subscripts – returns a scalar REAL, DIMENSION(10,10) :: A A(I,J) Vector subscripts – returns an array REAL, DIMENSION(10,10) :: A A(/(1,2,5,10)/) AE6382 Array Access Whole array REAL, DIMENSION(10,10) :: A, B, C C = A + B C = A * B ! this is not a matrix multiply – c(i,j) = a(I,j) * b(i,j) C = 0.0 ! initialize entire array with 0.0 AE6382 Array Sections Array sections REAL, DIMENSION(10) :: A A(:) – whole array A(3:9) – an array consisting of elements 3-9 A(:5) - an array consisting of elements 1-5 A(1:9:2) – an array consisting of elements 1,3,5,7,9 REAL, DIMENSION(10,10) :: A A(:,:) – whole array A(:,1) – an array consisting of only the first column A(1,:) - an array consisting of only the first row A(1:2,3:5:2) – an array consisting of elements A(1,3),A(1,5),A(2,3),A(2,5) – 2D matrix AE6382 Arrays As Actual Arguments Arrays can be passed as arguments to procedures REAL, DIMENSION(10,10) :: A … CALL SUB(A) … CONTAINS SUBROUTINE SUB(X) REAL, INTENT(INOUT), DIMENSION(10,10) :: X ! explicit shape array ! actual array must have same shape … END SUBROUTINE SUB The actual array shape must match the formal array shape AE6382 Arrays As Actual Arguments Arrays can be passed as arguments to procedures REAL, DIMENSION(10,10) :: A … CALL SUB(A) … CONTAINS SUBROUTINE SUB(X) REAL, INTENT(INOUT), DIMENSION(:,:) :: X ! assumed shape argument ! takes the actual shape … END SUBROUTINE SUB The actual array shape is known requires internal procedure, module procedure, or an explicit INTERFACE specification AE6382 Arrays As Function Returns A function can return an array program test5 integer, dimension(3,3) :: a, b, c function mmult(x,y) integer, intent(in), dimension(:,:) :: x, y integer :: i integer, dimension(SIZE(x,1),SIZE(y,2)) :: mmult a = RESHAPE((/1,2,3,4,5,6,7,8,9/),(/3,3/)) integer :: i,j,k write(6,*)'a' do i=1,SIZE(x,1) do i=1,3 do j=1,SIZE(y,2) write(6,'(3i5)') (a(i,j),j=1,3) mmult(i,j) = 0.0 enddo do k=1,SIZE(x,2) b = TRANSPOSE(RESHAPE((/1,2,3,4,5,6,7,8,9/),(/3,3/))) mmult(i,j) = mmult(i,j) + x(i,k)*b(k,j) write(6,*)'b' enddo do i=1,3 write(6,'(3i5)') (b(i,j),j=1,3) enddo enddo enddo !do i=1,SIZE(mmult,1) ! write(6,'(3i5)') (mmult(i,j),j=1,SIZE(mmult,2)) c = mmult(a,b) !enddo write(6,*)'c' !write(6,'---') do i=1,3 write(6,'(3i5)') (c(i,j),j=1,3) end function mmult end program test5 enddo contains AE6382 Arrays and Where Statement The WHERE statement will change an array element based on its contents – check entire array Replaces an explicit do loop REAL, DIMENSION(10) :: A … WHERE(A < 0.0) A = 0.0 INTEGER, DIMENSION(10) :: A INTEGER, DIMENSION(10) :: A … INTEGER :: I WHERE(A < 0) … A = -1 ELSEWHERE A = 1 END WHERE <=> DO I=1,10 IF (A(I) < 0) THEN A(I) = -1 ELSEIF (A(I) > 0) THEN A(I) = 1 ENDIF ENDDO AE6382 Arrays Intrinsics There are many intrinsics that affect arrays DOT_PRODUCT(VEC1, VEC2) inner (dot) product of two rank 1 arrays MATMUL(MAT1, MAT2) `traditional' matrix-matrix multiplication MINLOC(SOURCE[,MASK]) Location of a minimum value in an array under an optional mask MAXLOC(SOURCE [,MASK]) Location of a maximum value in an array under an optional mask PRODUCT(SOURCE[,DIM][,MASK]) product of array elements (in an optionally specified dimension under an optional mask) SUM(SOURCE[,DIM][,MASK]) sum of array elements (in an optionally specified dimension under an optional mask) ALL(MASK[,DIM]) .TRUE. if all values are .TRUE., (in an optionally specified dimension) ANY(MASK[,DIM]) .TRUE. if any values are .TRUE., (in an optionally specified dimension) COUNT(MASK[,DIM]) number of .TRUE. elements in an array, (in an optionally specified dimension) MAXVAL(SOURCE[,DIM][,MASK]) maximum Value in an array (in an optionally specified dimension under an optional mask) MINVAL(SOURCE[,DIM][,MASK]) minimum value in an array (in an optionally specified dimension under an optional mask) AE6382 Arrays Intrinsics There are many intrinsics that affect arrays MERGE(TSOURCE,FSOURCE,MASK) merge two arrays under a mask, SPREAD(SOURCE,DIM,NCOPIES) replicates an array by adding NCOPIES of a dimension, PACK(SOURCE,MASK [,VECTOR ]) pack array into a one-dimensional array under a mask. UNPACK(VECTOR,MASK,FIELD) unpack a vector into an array under a mask. RESHAPE(SOURCE, SHAPE) is a general intrinsic function which delivers an array of a specific shape AE6382 Arrays and RESHAPE function The RESHAPE function takes an array and will output a new array of the specified shape INTEGER, DIMENSION(3,3) :: A … A = RESHAPE((/1,2,3,4,5,6,7,8,9/),(/3,3/)) AE6382 Using Modules The MODULE is the Fortran 90+ method of sharing data and procedures MODULE mod1 <declarations> CONTAINS SUBROUTINE sub … END SUBROUTINE sub FUNCTION func … END FUNCTION func END MODULE mod1 AE6382 Using Modules – Global Variables The declarations at the top of a module are global in scope – any program that USEs the module will have access to them This capability functionally replaces the COMMON block This is safer than the COMMON block complete type information of each declared variable is retained when the MODULE is compiled and is available to the user of the MODULE COMMON blocks suffer from inconsistent code fragments used in other units (typos, incomplete changes, …) AE6382 Using Modules – Global Variables The module allows Fortran to encapsulate data and procedures type specifications may have PUBLIC and PRIVATE modifiers to control visibility public is the default MODULE mod1 ! Global data INTEGER, PRIVATE :: TOTAL INTEGER, PUBLIC :: I,J,K CONTAINS SUBROUTINE sub … END SUBROUTINE sub FUNCTION func … END FUNCTION func END MODULE mod1 AE6382 Using Modules – Procedures FUNCTIONS and SUBROUTINES that are defined in the CONTAINS section of the MODULE are available to the program that uses the module This the preferred method of making external procedures available to a program the types and number of arguments are compiled into the module and are available to the caller this ensures safety in procedure invocations this also makes it possible to use the assumed-shape form of passing arrays AE6382 Using Modules Any Fortran program unit may access a module by placing the USE statement before any declarations PROGRAM main USE mod1 USE mod2 USE ONLY – restrict what is imported PROGRAM main USE mod1 ONLY I,J USE mod2 ONLY our_sub => sub1 The caller can rename, for local use, exported objects PROGRAM main USE mod1 USE mod2, our_sub => sub1 AE6382 Using Modules A module must be compiled before any program unit that uses it If a module is modified, all program units that use it must be re-compiled Everything in the module is included in the final executable file AE6382 Interfaces When a sub-program is located in a CONTAINS clause the compiler is able to check argument type and number The same is true when modules are used When external sub-programs are used (standing alone in their own file) this checking is not possible An INTERFACE block can be included in the calling program the code included is a definition block for the subroutine/function it is independent of the procedure source code – subject to inconsistency problems for a large number of library procedures (for example Fortran 77 code) an interface can be created and placed in a module AE6382 Interfaces MAIN.F95: PROGRAM main INTERFACE SUBROUTINE sub(a,b,c) REAL, INTENT(IN) :: a REAL, INTENT(IN), DIMENSION(:,:) :: a, c ! assumed shape arrays END SUBROUTINE sub END INTERFACE … CALL sub(…) … END PROGRAM main SUB.F95: SUBROUTINE sub(A,B,C) REAL, INTENT(IN) :: a REAL, INTENT(IN), DIMENSION(:,:) :: a, c ! assumed shape arrays … END SUBROUTINE sub AE6382 Scope When a sub-program is located in a CONTAINS clause or a USE’d module, variables declared at a higher level are available to lower levels, unless shadowed by a local declaration PROGRAM main INTEGER :: I, TOTAL … CONTAINS SUBROUTINE sub INTEGER :: I WRITE(6,*)’TOTAL=‘,TOTAL ! this is the TOTAL declared in the main program WRITE(6,*)’I=‘,I ! this is the local I END SUBROUTINE sub END PROGRAM main AE6382 More on Sub-Program Arguments Fortran 90+ allows a procedure to have optional arguments keyword specification of arguments PROGRAM main call sub(1.0,2.0) … call sub(CF=3.0,A=2.0,B=99.0) … CONTAINS SUBROUTINE sub(A,B,CF) REAL, INTENT(IN) :: A, B REAL, INTENT(IN), OPTIONAL :: CF REAL :: C C = 1.0 ! set a default value for C IF (PRESENT(CF)) C = CF … END SUBROUTINE sub END PROGRAM main AE6382 More on Sub-Program Arguments In a procedure call Once an optional argument has been omitted, all following arguments must be specified by keyword Once a keyword is used to specify an argument all following arguments must also be specified by keyword The PRESENT intrinsic function can test for the presence of an optional argument AE6382 Formatted IO Change One useful change in formatted I/O is the addition of the ES and EN format descriptors program test real :: x = 48975.38756 48975.38672 0.48975E+05 4.89754E+04 do i=1,2 write(6,'(3x,F15.5)') x 48.97539E+03 4.89754E+04 write(6,'(3x,E15.5)') x write(6,'(3x,1PE15.5)') x *************** write(6,'(3x,EN15.5)') x 0.48975E+15 write(6,'(3x,ES15.5)') x 4.89754E+14 write(6,*) ' ' 489.75388E+12 x = 1.0E10 * x 4.89754E+14 enddo end program test AE6382 AE6382 AE6382