Evolution of Fortran Standards Over the Few Decades
Total Page:16
File Type:pdf, Size:1020Kb
Evolution of Fortran standards over the few A brief overview of this course decades Advanced Fortran Programming concentrates on aspects The 1st version became a standard by John Backus related to the most recent versions of the Fortran (IBM/1957) standard (F2003/2008/2015) Mid-60’s the most significant version was labeled as an – some Fortran 95 less-known features are covered, too ANSI standard, called FORTRAN66 Our major F2003/F2008 subjects in this course are In 1978 the former “de-facto” FORTRAN77 standard was – Language interoperability approved and quickly became popular, contained e.g. – Object-oriented Fortran (OOF) – IMPLICIT statement – Parallel programming with Fortran coarrays – IF – THEN – ELSE IF – ELSE – ENDIF – CHARACTER data type – PARAMETER statement for specifying constants 1 2 Evolution of Fortran standards… Evolution of Fortran standards… An important extension to FORTRAN77 was release of A major step in keeping Fortran programming alive was “military standard” Fortran enhancements (also in 1978) introduction of the Fortran 90 standard in ’91 (ISO), ’92 by US DoD, and adopted by most FORTRAN77 compilers (ANSI) – IMPLICIT NONE – Free format source input (up to 132 characters per line) – DO – END DO – Dynamic memory handling – INCLUDE statement Marked a number of features obsolescent (but did not – Bit manipulation functions delete any features), e.g. All these were eventually incorporated to the next major – Arithmetic IF and computed GOTO statements official standard release – Fortran 90 – Alternate RETURN, and use of H in FORMAT statements 3 4 Evolution of Fortran standards… Evolution of Fortran standards… A minor revision in 1997 (ISO) some features were taken Fortran 2003 was a significant revision of the Fortran 95 from High Performance Fortran (HPF) specification, e.g. standard (introduced in 2004) – FORALL and nested WHERE clauses to improve vectorization – Object-oriented programming (OOP), e.g. – User-defined PURE and ELEMENTAL procedures . Type extension, (single) inheritance, polymorphism, … – Automatic DEALLOCATE when ALLOCATABLE out of scope – Parameterized derived types – Procedure POINTERs – POINTER and TYPE components default initializations – Interoperability with C (and other) languages Deleted some features previously marked as obsolescent – OS interfacing: command line arguments & env. variables – Use of non-INTEGERs as DO loop parameters – ALLOCATABLE improvements – H edit descriptor in FORMATs – POINTER improvements – ASSIGN and assigned GOTO – I0 edit descriptor for INTEGERs in FORMAT statements 5 6 Evolution of Fortran standards… Fortran 2008: A minor revision of Fortran 2003 (approved 2010) New features include – Coarrays – Submodules – CONTIGUOUS attribute – BLOCK construct – newunit= in OPEN statement – DO CONCURRENT construct – G0 edit descriptor for REALs in FORMAT statements 7 Outline Interaction with the operating system – Accessing command line arguments and environment variables – Running operating system commands from Fortran Less known features of allocatable variables contiguous attribute Useful features since Fortran 90 Further scope control mechanisms, associate and block constructs, submodules 8 9 Command line arguments Parameters to a program are very often given to programs as command line arguments – Input file(s), modify program behavior, etc. INTERACTION WITH THE OPERATING SYSTEM Besides command line arguments, environment variables are a common way to influence program behavior Fortran 2003 introduced a standardized method for – reading command line arguments – accessing values of environment variables 10 11 Command line arguments Command line arguments … Access separate command line arguments Access the whole command line get_command_argument(number[,value][,length][,stat call get_command(command[,length][,status]) us]) – command is of type character string and contains the value – number denotes which argument to get of the command line on return. – value is a character string that contains the value of the – length is of type integer and contains the length of the requested argument on return (optional) command line on return (optional) – length contains the length of the requested argument on return (optional) Get the number of command line arguments integer :: command_argument_count() 12 13 Command line input Environment variables Access a value of an environment variable Example: reading in subroutine read_command_line(height, width) integer, intent(out) :: height, width call get_environment_variable(name,value[,length] two integer values character(len=10) :: args(2) [,status][,trim_name]) from the command integer :: n_args, i n_args = command_argument_count() – name is a character string that contains the name of the line, e.g. if ( n_args /= 2 ) then write(*,*) ' Usage : ./exe height width' requested variable % ./a.out 100 100 stop end if – value is a character string that contains the value of the do i = 1, 2 requested variable call get_command_argument(i,args(i)) args(i) = trim(adjustl(args(i))) – length is the length of the requested variable on return end do (optional) read(args(1),*) height read(args(2),*) width – trim_name is of type logical and sets if trailing blanks are end subroutine read_command_line allowed in variable names or not (optional) 14 15 Environment variables: example Executing commands program environment Invoking external programs from within a program is implicit none character(len=256) :: enval sometimes useful integer:: len,stat – No source nor library API available for a useful program ! extract hostname – perl/python/etc parsing scripts call get_environment_variable('hostname',enval,len,stat) if (stat == 0) write (*,'(a,a)') 'host=', enval(1:len) Fortran 2008 has a standardized method for invoking an external command ! extract user call get_environment_variable('user',enval,len,stat) if (stat == 0) write (*,'(a,a)') 'user=', enval(1:len) end program environment 16 17 Executing commands Executing commands: example Execute a command line program execcommand call execute_command_line(command[,wait] implicit none [,exitstat][,cmdstat][,cmdmsg]) integer :: estat, cstat call execute_command_line('ls -al', .true., estat, cstat) – command is a character string containing the command if (estat==0) write (*,'(a)') 'command completed successfully’ – wait is logical value indicating if command termination is to be end program execcommand waited (optional) – exitstat is an integer value containing the return value of the command if wait=.true. (optional) – cmdstat is zero if command executed successfully (optional) – cmdmsg is a character string containing explanatory message for positive values of cmdstat (optional) 18 19 Automatic deallocate subroutine sub1 An allocatable variable, integer, allocatable :: a(:) allocate(a(1000)) which is declared as a local call use_array( a ) variable in procedure and LESS KNOWN FEATURES OF ALLOCATE ! deallocate(a) ! not needed gets allocated, will be end subroutine sub1 automatically deallocated subroutine sub2 upon returning back from integer, allocatable, save :: a(:) routine allocate(a(1000)) call use_array( a ) This is “out of scope” rule deallocate(a) ! is needed holds as long as variables do end subroutine sub2 not have save attribute as well 20 21 Allocatable derived data type component Allocatable as a dummy argument program test module my_mod An allocatable variable can The Fortran 90 standard integer :: n type my_type introduced user-defined real, allocatable :: a(:) appear in the procedure real, allocatable :: array(:) call read_input(a, n) argument list end type my_type datatypes, but dynamic call use_array (a, n) end module my_mod allocation was restricted to deallocate(a) Enables dynamic memory end program test allocation in the called subroutine sub(n) pointers only routine based on sizing use my_mod The restriction was removed subroutine read_input(a, n) implicit none real, allocatable, intent(out) :: a(:) information integer, intent(in) :: n in Fortran 2003 integer, intent(out) :: n – Allocated (and perhaps type(my_type) :: t Allocation remains intact read *, n initialized) data is returned : even after going out of allocate(a(n)) allocate(t % array (n) ) read *, a to the caller : scope, if the type was ! no automatic deallocate here The caller must remember end subroutine sub defined in a module end subroutine sub to deallocate 22 23 Function return value as allocatable Assignment to an allocatable variable program pack A function return value can Assigning values to an real :: unpacked(1000) program test real, allocatable :: a(:) have the allocatable real, allocatable :: a(:), b(:) allocatable array via data or a = pack_data(unpacked) attribute real :: input(3) from another array triggers call use_packed_data(a) read *,input ! read 3 values from stdin deallocate(a) Works similarly as when a = input ! automatic allocate automatic allocation contains allocatable is a dummy ! a(:) = input(:) would be illegal ! – If array was already allocated, function pack_data(x) result (pk) print *,size(a) ! gives 3 but its size was not sufficient, real, allocatable :: pk(:) argument b = (/ 1,2,4,8,16 /) ! automatic alloc. real, intent(in) :: x(:) a = [ a, b ] ! automatic extent ok the extent size will be allocated integer :: npk print *,size(a) ! size now = 8 automatically npk = num_distinct_values(x) ! deallocate legal, but not necessary allocate(pk(npk)) May require additional deallocate(a, b) call get_distinct_values(x,...,pk,npk) end program test compiler flags, like –assume end function