Академический Документы
Профессиональный Документы
Культура Документы
M. D. Jones, Ph.D.
Center for Computational Research University at Buffalo State University of New York
1 / 140
2 / 140
Introduction
History
History of FORTRAN
One of the earliest of the high-level programming languages, FORTRAN (short for Formula Translation) was developed by John Backus at IBM in the 1950s (circa 1953 for the 704, rst released in 1957): FORTRAN 66, ANSI standard (X3.9-1966) based on FORTRAN IV FORTRAN 77, X3.9-1978, improved I/O Fortran 90, ISO/IEC 1539:1991(E), FORTRAN becomes Fortran Fortran 95, ISO/IEC 1539-1:1997, minor revisions Fortran 2003, ISO/IEC 1539:2004, command line arguments, more intrinsics, IEEE exception handling, C interoperability Fortran 2008, revision to Fortran 2003, to include BIT type and Co-array parallel processing (not yet widely supported)
4 / 140
Introduction
So What?
So why is Fortran still in use? Efciency has always been a priority, in the sense that compilers should produce efcient code. Fortran data are generally not allowed to be aliased (e.g. pointers) making life easier on the compiler Designed from the outset as the tool for numerically intensive programming in science and engineering Backward compatibility - most modern compilers can still compile old (as in decades!) code
5 / 140
Introduction
So What?
Indeed, Fortran celebrated its 50th birthday in 2007. How many other high-level languages can you say that about? Think of it this way - it is arguably the most efcient, compact, portable high-level language available. And you will likely still be able to use programs written today until you retire (unmodied, at that) ...
6 / 140
Introduction
So What?
Introduction
So What?
In this presentation I will focus almost entirely on Fortran 90/95 features, with some side notes on FORTRAN 77 (mostly for contrast). This talk is not intended to be exhaustive in its coverage of Fortran syntax, but should be enough to yield a rough and ready knowledge for HPC.
8 / 140
Introduction
Source Format
While FORTRAN 77 used by default a xed format for its source code, the default with Fortran 95 is now a free format, in which lines can be up to 132 columns long, with a maximum of 39 continuation lines, indicated by the & character.
9 / 140
Introduction
Source Format
132 ! & ;
1 2 3
p r i n t , You need two c o n t i n u a t i o n & &c h a r a c t e r s when s p l i t t i n g a token & & o r s t r i n g across l i n e s
10 / 140
Introduction
Source Format
Statement Labels
Statement labels are still in fashion, and consist of 1-5 digits (leading zeros are neglected), e.g.
1 2 3 101 2 WRITE( 6 , ) E n t e r r u n i d :( <=9 chars ) READ( , 2 ) r u n i d format ( a9 )
11 / 140
Introduction
Source Format
Names
In Fortran, names must: Start with a letter (a-z) Contain only letters, digits, and underscore Must not be longer than 31 characters
12 / 140
Introduction
Source Format
More Resources
Good reference material on all things Fortran: M. Metcalf and J. Reid, Fortran 90/95 Explained, 2nd Ed., (Oxford, Great Britain, 2000) Fortran 95/2003 Explained, 3rd Ed., (Oxford, Great Britain, 2004), with M. Cohen Modern Fortran Explained, (Oxford, Great Britain, 2011), with M. Cohen Metcalfs online tutorial:
http://wwwasdoc.web.cern.ch/wwwasdoc/WWW/f90/f90.html
13 / 140
Language Elements
Implicit Types
Implicit Types
Unfortunately FORTRAN historically allowed implicit types, which by default were: FORTRAN 77 implicit real (a-h,o-z) implicit integer (i-n) Thanks to backward compatibility, this feature is still present: Fortran implicit type (letter-list) [,type (letter-list) ...]
15 / 140
Language Elements
Implicit Types
Implicit None
I would recommend starting every declaration block with the following: Fortran implicit none which will turn all implicit typing off, and save a lot of potential errors (misspelled variable names just being one of them). Use implicit types at your own risk!
16 / 140
Language Elements
Intrinsic Types
Basic Declarations
Declarative Syntax <type> [,<attribute-list>] :: <variable-list> & [ =<value> ] The attribute is usually one of PARAMETER, DIMENSION, or POINTER.
17 / 140
Language Elements
Intrinsic Types
We have ve different intrinsic types, integer, real, logical, complex, and character. The syntax looks like:
integer : : i real : : x complex : : z l o g i c a l : : beauty character : : c
These are all of default kind ... (Note that integers can also be represented in binary (base 2), octal (base 8), and hex (base 16))
18 / 140
Language Elements
Intrinsic Types
Kind
There is an intrinsic function KIND that returns an integer and can be used to query (or set) the kind type of a variable Fortran KIND(x) returns default integer whose value is the kind type parameter value of x
19 / 140
Language Elements
Intrinsic Types
Language Elements
Intrinsic Types
Best illustrated by example - this is a chunk of code that use in all of my Fortran codes:
integer , parameter : : s i =KIND ( 1 ) , sp=KIND ( 1 . 0 ) , sc=KIND ( ( 1 . 0 , 1 . 0 ) ) , d i =SELECTED_INT_KIND(2RANGE( 1 _ s i ) ) , & dp=SELECTED_REAL_KIND(2PRECISION ( 1 . 0 _sp ) ) , & dc=SELECTED_REAL_KIND(2PRECISION ( 1 . 0 _sc ) ) &
Note the use of underscores in literal constants to indicate kind type, which is quite generally applicable:
1 2 r e a l ( kind=dp ) : : a , b , c complex ( kind=dc ) : : z i = ( 0 . 0 _dp , 1 . 0 _dp )
21 / 140
Language Elements
Intrinsic Types
PARAMETER Attribute
Instead of the old FORTRAN 77 PARAMETER statement, one can use the parameter attribute:
REAL, PARAMETER : : E = 2.71828 , PI = 3.141592
22 / 140
Language Elements
Intrinsic Types
Arrays can be indicated by the old-type DIMENSION attribute, or simply in the declaration itself:
1 2 3 r e a l , dimension ( 3 ) : : a real : : b (3) r e a l : : c ( 1:1)
23 / 140
Language Elements
Intrinsic Types
24 / 140
Language Elements
Intrinsic Types
Initializing Arrays
Note that the RESHAPE function can also be used to initialize an array of rank greater than 1.
25 / 140
Language Elements
Intrinsic Types
Character Arrays
Better known as strings, Fortran is not the best for string handling (it is intended for number crunching, after all), but modern Fortran is considerably improved in this regard:
1 2 3 character , dimension ( 1 2 0 ) : : l i n e 1 character ( len =120) : : l i n e 2 character ( len =120) , dimension ( 8 0 ) : : page
and we will come back later to some of the intrinsic string handling functions and subroutines.
26 / 140
Language Elements
Derived Types
Derived Types
It is often advantageous to dene your own data types:
1 2 3 4 5 TYPE Coords_3D real : : r , theta , phi END TYPE Coords_3D ! spherical coordinates
TYPE( Coords_3D ) : : p o i n t 1 , p o i n t 2
N.B. Derived type components can not be ALLOCATABLE (but they can be POINTERS).
27 / 140
Language Elements
Derived Types
Note that two variables of the same type can be handled very simply. Derived types should always be placed in a MODULE.
28 / 140
Language Elements
Pointers
Pointers
Fortran nally has the capability (often best left unused) of using pointers. Along with ALLOCATABLE and automatic arrays, pointers make up the 3 types of dynamic data in Fortran 90/95. Pointers can be members of derived types, most useful for implementation of linked lists:
1 2 3 4 5 6 7 r e a l , pointer , dimension ( : , : ) : : a real , pointer : : x , y ! ! NULLIFY ( x , y , a ) ! Point to nothing x => n u l l ( ) ! F o r t r a n 95 o n l y ALLOCATE( x , y , a ( 1 0 0 : 1 0 0 ) ) ! Fresh s t o r a g e a l l o c a t i o n
We will talk a bit more about pointers later when dealing with other aspects of dynamic memory.
29 / 140
Language Elements
Pointers
DATA Statement
30 / 140
Scalar Expressions
Scalar Expressions
Scalar expressions use operators , , /, +, . The following table summarizes the result KIND for all but exponentiation ()
a I I I R R R C C C b I R C I R C I R C used(a) a real(a,kind(b)) cmplx(a,0,kind(b)) a a cmplx(a,0,kind(b)) a a a used(b) b b b real(b,kind(a)) b b cmplx(b,0,kind(a)) cmplx(b,0,kind(a)) b result I R C R R C C C C
32 / 140
Scalar Expressions
33 / 140
Scalar Expressions
Relational Operators
Fortran supports the old-style FORTRAN 77 relational operators as well as more modern syntax (which most compilers were supporting by extension anyway): 77 .lt. .le. .eq. .ne. .gt. .ge. Modern < <= == /= > >=
34 / 140
Scalar Expressions
Logical Operators
The logical operators are simply: .not. .and. .or. .eqv. .neqv. logical negation logical intersection logical union logical equivalence logical non-equivalence
35 / 140
Scalar Expressions
Character Operations
36 / 140
Scalar Expressions
Array Assignment
Arrays can be assigned using expressions that involve arrays of the same shape, or by scalar (in which case the scalar is applied to all elements of the array), e.g.
1 2 3 4 real : : a(20 ,20) ,b(10) a(1 ,11:20) = b a = a + 1.0
37 / 140
Control Constructs
IF Conditional
IF Construct
1 2 3 4 5 6 7
[ name : ]
i f ( expr ) then block [ else i f ( expr ) then [ name ] block ] . . . [ else [ name ] block ] end i f [ name ]
Note that the optional name is only for program clarity (especially for nested loops), and needs to be unique. Also note the single statement variation:
i f ( expr ) s i n g l es t a t em e n t
39 / 140
Control Constructs
DO Loops
DO Loops
where the loop is executed MAX(0,(expr2-expr1+expr3)/expr3) times, and var is a named scalar integer variable, and expr1, expr2, and expr3 are scalar integer expressions (expr3 must be nonzero if used).
40 / 140
Control Constructs
DO Loops
Innite DO Loop
One important variation on the DO construct is the endless do loop, which has a simple means to exit:
1 2 3 4 do i = i +1 i f ( i >= enough ) e x i t end do
Note that the exit statment is also handy for early termination in bounded loops. The cycle statement is similar, but just drops execution to the next iteration.
41 / 140
Control Constructs
DO Loops
DO-WHILE Loop?
There is a DO-WHILE construct, but with the exit option for early loop termination, it is not really worth talking about ...
1 2 3 DO WHILE ( a / = b ) ... END DO
42 / 140
Control Constructs
DO Loops
Ah, the bane of FORTRAN 77 programmers everywhere - the infamous GOTO statement. Still supported in Fortran 90/95, be wary of using the GOTO. If you have to use it, make it as clear as you possibly can.
1 2 3 4 5 6 7 101 WRITE( 6 , ) E n t e r r u n i d :( <=9 chars ) READ( , ( a9 ) ) r u n i d i =INDEX ( r u n i d , )1 INQUIRE ( f i l e = r u n i d ( 1 : i ) / / " . i n " , e x i s t = i f e x ) i f ( . n o t . i f e x ) goto 101 OPEN( u n i t = i u n i t , f i l e = r u n i d ( 1 : i ) / / . i n , status = o l d , & & form= f o r m a t t e d )
43 / 140
Control Constructs
DO Loops
! ! ! !
to to to to
10 1 9 2
44 / 140
Control Constructs
CASE Construct
The CASE construct can be used as an efcient substitute for a more elaborate IF ... THEN ... ELSEIF ... ELSE ... END IF construct.
45 / 140
Control Constructs
CASE Construct
46 / 140
47 / 140
Modules
Modules
Modules provide a way to package together commonly used code (similar to the old common blocks in FORTRAN 77) and have distinct advantages: Can be used to hide internal data and routines through PRIVATE and PUBLIC declarations Can contain common subroutines and functions with explicit interfaces which can be changed without affecting calling code Modules can (and often should) be compiled separately, before the program units that use them
49 / 140
Modules
Module Syntax
50 / 140
Modules
51 / 140
Modules
Using Modules
Modules encapsulate code that can be made accessible to other program units through the USE statement:
1 2 3 MODULE TBatoms USE TBconst ...
52 / 140
Modules
You can allow or prevent access to the internal workings of a module using the PRIVATE and PUBLIC attributes:
1 2 PRIVATE : : pos , s t o r e , s t a c k _ s i z e PUBLIC : : pop , push ! hidden ! n o t hidden
or
1 2 3 PUBLIC ! set default v i s i b i l i t y INTEGER , PRIVATE , SAVE : : s t o r e ( s t a c k _ s i z e ) , pos INTEGER , PRIVATE , PARAMETER : : s t a c k _ s i z e = 100
53 / 140
Modules
Renaming/USE ONLY
54 / 140
Modules
Module Summary
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
MODULE modname . . . type d e f s . . . G l o b a l data ... CONTAINS SUBROUTINE sub_1 ... CONTAINS SUBROUTINE i n t e r n a l _ 1 ... END SUBROUTINE i n t e r n a l _ 1 SUBROUTINE i n t e r n a l _ 2 ... END SUBROUTINE i n t e r n a l _ 2 END SUBROUTINE sub_1 ... FUNCTION fun_1 ... CONTAINS ... END FUNCTION fun_1 END MODULE modname
55 / 140
Subroutines
Subroutine Syntax
The syntax for a subroutine call is given by SUBROUTINE [recursive] subroutine subroutine-name[([dummy arguments])]
56 / 140
Subroutines
Argument Intent
You can provide information to the compiler (always a good idea!) about the dummy arguments to a routine by:
1 2 3 REAL, INTENT ( IN ) : : arg1 REAL, INTENT (OUT) : : arg2 REAL, INTENT ( INOUT ) : : arg3 ! passing i n v a l u e ! r e t u r n i n g value only ! both a p p l y
You should always make use of the INTENT attribute - it allows the compiler to do extensive error checking and optimization (remember, the more that your compilers knows about your code, the better it will be able to perform).
57 / 140
Subroutines
SAVE Attribute
The SAVE attribute can be applied to a specied entity, or all of the local entities in a procedure:
1 2 3 4 SUBROUTINE sub_1 ( arg1 , arg2 ) integer , save : : number_calls = 0 ... number_calls = number_calls +1
1 2 3 4
58 / 140
Functions
The syntax for a function call is given by FUNCTION type [recursive] function function-name[([dummy arguments])] & [result(result-name)]
59 / 140
Explicit Interfaces
Explicit Interfaces
External subprograms have an implicit interface by default (even if one uses the external statement to indicate that a subunit is outside the current code, the arguments and their types remain unspecied), and an INTERFACE block is necessary to specify an explicit interface of an external subprogram; as mentioned above, this allows type-checking of actual and formal arguments in a reference to a subprogram
60 / 140
Explicit Interfaces
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
INTERFACE SUBROUTINE r e s i d (m, n , x , fvec , i f l a g ) USE TBatoms USE TBconst USE T B f i t d a t a USE T B f l a g s USE TBmat USE TBopt USE TBparams i m p l i c i t none integer , i n t e n t ( i n ) : : m, n integer , i n t e n t ( i n out ) : : i f l a g r e a l ( kind=dp ) , i n t e n t ( i n ) : : x ( n ) r e a l ( kind=dp ) , i n t e n t ( i n out ) : : f v e c (m) END SUBROUTINE r e s i d END INTERFACE
Note that the syntax of the interface-body is just an exact copy of the subprograms header, argument specications, function result, and END statement.
61 / 140
Explicit Interfaces
INTERFACE Properties
Can not use both EXTERNAL and INTERFACE Explicit interfaces required for POINTER or TARGET dummy arguments in a procedure, or pointer-valued function result Explicit interfaces also required for OPTIONAL, KEYWORD, and procedural arguments Even when not required, explicit interfaces are a good idea (usually placed inside a MODULE)
62 / 140
Explicit Interfaces
1 2 3 4
f o r long l i s t s
Note that optional and keyword arguments need explicit interfaces, and should come after positional arguments.
63 / 140
Procedures as Arguments
Procedures as Arguments
When using a procedure as an argument, an explicit interface is required (as it is for POINTER, optional, and keyword arguments):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 REAL FUNCTION minimum ( a , b , f u n c ) ! r e t u r n s t h e minimum v a l u e o f t h e f u n c t i o n f u n c ( x ) ! i n the i n t e r v a l ( a , b ) REAL, INTENT ( i n ) : : a , b INTERFACE REAL FUNCTION f u n c ( x ) REAL, INTENT ( IN ) : : x END FUNCTION f u n c END INTERFACE REAL f , x : f = func ( x ) ! i n v o c a t i o n o f t h e user f u n c t i o n . : END FUNCTION minimum
64 / 140
Recursion
Recursion
65 / 140
Recursion
Generally indirect recursion is of the form A calls B calls A ... - in this case integrate calls func which calls integrate ...
66 / 140
Input/Output
Fortran I/O
Too large a topic to cover in its entirety here - we will focus on the basics required to familiarize you with basic Fortran I/O functionality.
68 / 140
Input/Output
File Handling
OPEN
OPEN ( [ UNIT= integer , ] FILE= f i l e n a m e , [ERR= l a b e l , ] & [ STATUS=status , ] [ACCESS=method , ] [ ACTION=mode , ] & [RECL= i n t expr )
filename is a string status is OLD, NEW, REPLACE, SCRATCH or UNKNOWN method is DIRECT or SEQUENTIAL mode is READ, WRITE or READWRITE RECL (record length) needs to be specied for DIRECT access les
69 / 140
Input/Output
File Handling
OPEN Examples
Note that UNIT 1-7 are typically reserved (6, or , is almost always the standard output, for example), and each le stream needs a unique number.
1 2 3 4 5 6 7 8 OPEN( 1 7 , FILE= o u t p u t . d a t ,ERR=10 , STATUS= REPLACE , & ACCESS= SEQUENTIAL ,ACTION= WRITE ) : OPEN( 1 4 , FILE= i n p u t . d a t ,ERR=10 , STATUS= OLD , RECL= iexp , & ACCESS= DIRECT ,ACTION= READ ) : w r i t e ( u n i t = i o u n i t , fmt= " ( a ) " , i o s t a t = b a d u n i t ) t i t l e i f ( b a d u n i t > 0 ) c a l l e r r o r _ h a n d l e r ( ERR_IO )
70 / 140
Input/Output
File Handling
INQUIRE
A very handy statement for querying the status of a le by unit number or lename:
INQUIRE ( [ UNIT = ] u n i t | FILE= f i l e n a m e , ilist )
and there are many possible entries in ilist, of which the most handy are: IOSTAT=ios as in the OPEN syntax EXIST=log_exist returns a logical on the existence of the le OPENED=log_opened returns a logical on whether the le is open
71 / 140
Input/Output
File Handling
INQUIRE Example
1 2 3 4 5 6 7 8 9 10
! ! Open i n p u t f i l e f a i l g r a c e f u l l y i f n o t found . ! INQUIRE ( f i l e = r u n i d ( 1 : l e n _ r u n i d ) / / . i n , e x i s t = e x i s t _ i n ) i f ( . n o t . e x i s t _ i n ) then w r i t e ( , ) < r e a d i n > Unable t o open i n p u t f i l e : , & runid (1: len_runid ) / / . in stop endif OPEN( f i l e = r u n i d ( 1 : l e n _ r u n i d ) / / . i n , status = o l d , u n i t = i n u n i t )
72 / 140
Input/Output
File Handling
CLOSE unattach specied unit number REWIND place le pointer back to start of le BACKSPACE place le pointer back one record ENDFILE force writing end-of-le
1 2 3 4 REWIND( 1 1 ) BACKSPACE( UNIT=27) ENDFILE ( 1 9 ) CLOSE( 1 3 , IOSTAT= i o _ v a l u e )
73 / 140
Input/Output
READ
READ ( [ UNIT= unit , ] [FMT=format , ] [ IOSTAT= i n t v a r i a b l e , ] & [ERR= l a b e l , ] [END= l a b e l , ] [EOR= l a b e l , ] & [ADVANCE=advmode , ] [REC= i n t expr , ] & [ SIZE=num chars ] ) < o u t p u tl i s t >
where the non-obvious entries are: unit is an integer (some lower values are reserved) or for standard input format is a string of FORMAT statement label number label is a statement label adv-mode is YES or NO IOSTAT returns zero for no error
74 / 140
Input/Output
READ Example
1 2 3
READ( 1 4 ,FMT= ( 3 ( F10 . 7 , 1 x ) ) ,REC= i e x p ) a , b , c READ( 1 4 , ( 3 ( F10 . 7 , 1 x ) ) ,REC= i e x p ) a,b,c ! same as above READ( , ( A ) ,ADVANCE= NO ,EOR=12 , SIZE=nch ) s t r
75 / 140
Input/Output
WRITE
WRITE ( [ UNIT= unit , ] [FMT=format , ] [ IOSTAT= i n t v a r i a b l e , ] & [ERR= l a b e l , ] [ADVANCE=advmode , ] & [REC= i n t expr ) < o u t p u tl i s t >
76 / 140
Input/Output
FORMAT
Fortran does have quite an elaborate formatting system. Here are the highlights. Iw Fw.d Ew.d Lw Aw nX Note that: The E descriptor is just the F with scientic notation w chars of integer data w chars of real data, d decimal places w chars of real data, d decimal places w chars of logical data w chars of CHARACTER data skip n spaces
77 / 140
Input/Output
FORMAT Example
1 2
3 name abcd
14.45000
0.14567E+02
Note that are quite a few other format descriptors, much less commonly used.
78 / 140
Input/Output
Unformatted I/O
Unformatted I/O is simpler (no FORMAT statements) and involves less overhead, less chance of roundoff error), but is inherently non-portable, since it relies on the detailed numerical representation. A le must be either entirely formatted or unformatted, not a mix of the two.
READ( 1 4 ) A WRITE( 1 5 , IOSTAT= i o s ,ERR=2001) B
Note that unformatted i/o is generally quite a lot faster than formatted so unless you are concerned with moving your les from one platform to another, you will be much better off using unformatted i/o.
79 / 140
Assumed-shape Arrays
Arrays passed as dummy arguments should generally be what are called assumed-shape arrays, meaning that the dimensions are left to the actual (calling arguments):
1 2 3 4 SUBROUTINE stubby ( a , b ) i m p l i c i t none real , intent ( in ) : : a ( : ) , b ( : , : ) :
Note that the default bounds (1) apply Actual arguments can not be vector subscripted or themselves assumed-shape
81 / 140
Automatic Arrays
Local arrays whose extent is determined by dummy arguments are called automatic objects. Example:
1 2 3 4 5 SUBROUTINE stubby1 ( b ,m, n ) integer , i n t e n t ( i n ) : : m, n r e a l , i n t e n t ( inout ) : : b ( : , : ) ! assumed REAL : : b1 (m, n ) ! automatic REAL : : b2 ( SIZE ( b , 1 ) , SIZE ( b , 2 ) ) ! a u t o m a t i c
Note that both assumed-shape arrays and automatic objects are likely to be placed on the stack in terms of memory storage.
82 / 140
Dynamic(Allocatable) Arrays
Allocatable Arrays
Finally, dynamic data storage elements for Fortran! An array that is not a dummy argument or function can be given the ALLOCATABLE attribute:
real , allocatable : : a ( : , : ) : : ALLOCATE( a ( ntypes , 0 : ntypes + 2 ) ) ! ntypes i s an i n t e g e r : ! l o t s o f work : DEALLOCATE( a )
Note that ALLOCATABLE arrays can not be part of a derived type (have to use a POINTER to get the same functionality) - that oversight should be xed in Fortran 2003.
83 / 140
Dynamic(Allocatable) Arrays
The optional stat= specier can be used to test the success of the (de)allocation through the scalar integer istat. As usual, zero for success. Leaving out stat= should result in a termination if the (de)allocation was unsuccessful.
84 / 140
More Pointers
Pointer Flexibility
Note that you can not associate pointers with just any variable (as in C), instead the variables must be declared using the target attribute:
real , target : : x , y (100) , z ( 4 , 4 ) integer , t a r g e t : : m, n ( 1 0 ) , k ( 1 0 , 1 0 ) real , pointer : : ptr1 , ptr2 , ptr_y ( : ) , ptr_z1 ( : ) , ptr_z2 ( : , : ) p t r 1 => x alpha = exp ( p t r 1 ) nullify ( ptr1 ) ! ! ! ! s i m p l e p o i n t e r assignment p o i n t e r shares memory l o c a t i o n w i t h x , b u t used l i k e any v a l u e f r e e s up p o i n t e r
i f ( a s s o c i a t e d ( p t r 1 ) ) then print , ptr1 i s associated i f ( a s s o c i a t e d ( p t r 1 , t a r g e t =x ) ) then print , ptr1 i s associated with " x " endif endif
85 / 140
More Pointers
Note that pointers can also be used as components of derived types, making for very exible data structures.
86 / 140
More Pointers
Pointer Considerations
Some things to think about when using pointers in Fortran: Can create complex (and difcult to maintain) code Easy to create bugs that only arise at run-time Inhibit compiler optimization (difcult to predict data patters and disjoint memory structures)
87 / 140
Elemental Operations
Elemental Operations
We have already seen elemental operations in which conformable operands can be used with intrinsic operators, e.g.
real : : a(100 ,100) ... a = SQRT( a )
will apply the square root operator individually to all of the elements of a. Not only intrinsics can be elemental, and you can also use the elemental declaration in user-dened functions (Requires Fortran 95) as well.
88 / 140
Array-valued Functions
Array-valued Functions
Functions can return arrays - just be careful that you ensure that the interface is an explicit one. An example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 PROGRAM a r r f u n c i m p l i c i t none integer , parameter : : ndim=36 integer , dimension ( ndim , ndim ) : : m1, m2 : m2 = f u n k y (m1, 4 ) : CONTAINS FUNCTION f u n k y (m, s c a l ) integer , i n t e n t ( i n ) : : ima ( : , : ) integer , i n t e n t ( i n ) : : s c a l i n t e g e r : : f u n k y ( SIZE (m, 1 ) , SIZE (m, 2 ) ) f u n k y ( : , : ) = m( : , : ) s c a l END FUNCTION f u n k y END PROGRAM a r r f u n c
89 / 140
Array-valued Functions
WHERE Statement
Useful for performing array operations only on certain elements of an array, but preserving the compact syntax:
WHERE ( l o g i c a la r r a yexpr ) a r r a yassignments END WHERE
1 2 3 4 5
in the example all arrays are of the same shape, and the assignment is said to be masked using the comparison (which is done element by element). Fortran 95 also provides for masks in additional ELSEWHERE statements.
90 / 140
Array-valued Functions
Implied is that the assignment is trivially data-parallel, i.e. it can be carried out in any order, and therefore can be more efcient than a more traditional loop. Construct form:
FORALL( i = 2 :N1, j = 2 :N1) U( i , j ) = U( i , j 1) + U( i , j +1) + U( i 1, j ) + U( i +1 , j ) V ( i , j ) = U( i , j ) END FORALL
where the results are executed in any order, held in temporary storage (to avoid indeterminate results), and then updated in arbitrary order.
91 / 140
Array-valued Functions
The body of a FORALL construct can be quite general (containing statements, additional FORALL or WHERE statements/constructs, etc.), but must not branch (e.g. goto) out of the construct. Any included subprograms must be pure, in the sense of inducing no undesired side-effects in the sense of inducing an order dependence that would impede parallel processing.
92 / 140
Array-valued Functions
93 / 140
Array Intrinsics
Fortran is designed around the notion of data manipulation, so it is not a great surprise that it has a number of built-in functions for array manipulation, some of which we have already seen (elemental operations, masking).
94 / 140
Array Functions
95 / 140
i n t e g e r : : i , j , max_element ( 2 ) , max_element_2 ( 2 ) r e a l : : Amax , Amax_2 , Amat ( 1 0 0 , 1 0 0 ) Amat = RESHAPE( ( / ( ( 1 0 0 ( i 1)+ j , j =1 ,100 ) , i =1 ,100) / ) , ( / 100 , 100 / ) , ORDER= ( / 2 , 1 / ) ) max_element = MAXLOC( Amat ) Amax = MAXVAL( Amat ) ! f i n d s t h e element o f Amax w i t h ! max v a l u e [ A( 1 0 0 , 1 0 0 ) = ! 10000 ]
96 / 140
97 / 140
Array Reshaping
RESHAPE is a general intrinsic function which delivers an array of a specic shape:
RESHAPE( source , shape [ , pad ] [ , o r d e r ] )
returns an array whose shape is given by the constant rank-1 integer array (nonnegative elements) shape derived from the array source. If order is absent, elements of pad are used to ll out remaining elements in the result (whose size may then exceed that of source. order can be used to pad the result in non-element order.
1 2 3 4 r e a l : : A2 ( 2 , 2 ) A2 = RESHAPE( ( / 1 , 2 , 3 , 4 / ) , ( / 2 , 2 / ) ) p r i n t , A2 : 1 ,1 1 ,2 = ,A2 ( 1 , 1 ) , A2 ( 1 , 2 ) p r i n t , A2 : 2 ,1 2 ,2 = ,A2 ( 2 , 1 ) , A2 ( 2 , 2 ) ! c r e a t e a 2x2 m a t r i x from 1x4 v e c t o r
98 / 140
Vector/Matrix Intrinsics
Fortran 90 has several intrinsics for vector dot products matrix multiplication and transposition:
DOT_PRODUCT(vector_1,vector_2) MATMUL(matrix_1,matrix_2) TRANSPOSE(matrix) dot product of two rank-1 equal length vectors matrix multiplication transposition of any rank-2 array
99 / 140
Fortran Intrinsics
Intrinsics Categories
There are roughly 75 new intrinsic routines (versus FORTRAN 77), but they roughly fall into 4 categories:
1 2 3 4
I am going to group them a bit differently, and only cover the more common ones. Consult a good reference1 for a thorough list.
1 Metcalf,
101 / 140
Fortran Intrinsics
Mathematical Intrinsics
Mathematical Intrinsics
Far too many to enumerate here - you can nd a handy reference for the full set in other references. Note that almost all support a generic interface supporting available KIND types, and that most are elemental.
SQRT, EXP, LOG, LOG10, SIN, COS, TAN, ASIN, ACOS, ATAN, SINH, COSH, TANH
102 / 140
Fortran Intrinsics
Numerical Intrinsics
Numerical Intrinsics
103 / 140
Fortran Intrinsics
String Functions
String Functions
Yes, Fortran does have string handling capability! And in fact, it is much improved. The following table gives a brief synopsis:
ACHAR(I) ADJUSTL(STRING) ADJUSTR(STRING) CHAR(I, kind) IACHAR(C) ICHAR(C) INDEX(STRING, SUBSTRING, back) LEN(STRING) LEN_TRIM(STRING) REPEAT(STRING, NCOPIES) SCAN(STRING, SET, back) TRIM(STRING) VERIFY(STRING, SET, back) ASCII character of number I Adjusts to the left Adjusts to the right Returns character of number I ASCII number of char C Number of char C Starting pos of substring in string Length of STRING Length of string without trailing blanks String concatnation Position of 1st occurrence of any char in SET in STRING Returns string without trailing blanks Position of 1st char in STRING not in SET
104 / 140
Fortran Intrinsics
String Functions
The following functions can be used for ASCII lexical string comparisons:
LGE( STRING_A , LGT( STRING_A , LLE ( STRING_A , LLT ( STRING_A , STRING_B ) STRING_B ) STRING_B ) STRING_B )
Note that if the strings are of differing length, the shorter will be padded with blanks for comparative purposes. All return default logical results.
105 / 140
Fortran Intrinsics
Bitwise Intrinsics
Bitwise Intrinsics
NOT(I)
106 / 140
Fortran Intrinsics
Random Numbers
harvest can be an array, and the range of the random numbers are the interval [0, 1). size is intent OUT and returns the size of the integer seed array, which can be input (put) or returned (get).
107 / 140
Fortran Intrinsics
Real-time Clock
Modern Fortran provides a pair of routines to access the real-time clock: DATE_AND_TIME DATE_AND_TIME([date] [,time] [,zone] [,values]) date character string in form ccyymmdd time character string in form hhmmss.sss zone character string in form Shhmm, difference between local and UTC values integer vector of size at least 8 with year, month, day, difference from UTC in minutes, hour, minutes, seconds, milliseconds
108 / 140
Fortran Intrinsics
SYSTEM_CLOCK SYSTEM_CLOCK([count][,count_rate][,count_max]) count processor-dependent value of processor clock (-huge(0) if no clock) count_rate clock counts per second (0 if no clock) count_max maximum for count (0 if no clock)
109 / 140
Fortran Intrinsics
CPU Time
Fortran 95 only: CPU_TIME CPU_TIME(time) time real assigned to processor-dependent time in seconds (negative value if no clock)
r e a l : : t1 , t 2 : CALL CPU_TIME ( t 1 ) ! F o r t r a n 9 5 o n l y : : CALL CPU_TIME ( t 2 ) p r i n t , Time spent i n code : , t2t1 , seconds
In my experience the CPU_TIME intrinsic is not very precise, however, and depends rather strongly on the compiler ...
110 / 140
Fortran Intrinsics
STOPWATCH
STOPWATCH is not part of standard Fortran, but is a nice little package written by William Mitchell at NIST: http://math.nist.gov/StopWatch which supports a more full featured set of timing routines (including wall time, cpu time, and system time).
111 / 140
Fortran Intrinsics
Array Functions
Array Functions
The array intrinsic functions will be discussed in a special section devoted to arrays ...
112 / 140
113 / 140
Inquiry Functions
i =s
k =0
dk r k ,
where i s r q dk integer value sign (+,) radix (r > 1) number of digits (q > 1) k -th digit, (0 dk < r )
115 / 140
Inquiry Functions
x = sbe
k =1
fk bk ,
where x s b e p fk real value sign (+,) base (b > 1) exponent (q > 1) number mantissa digits (p > 1) k -th digit, (0 fk < b)
116 / 140
Inquiry Functions
Inquiry Functions
The inquiry functions are given in the following table: digits(x) epsilon(x) huge(x) minexponent(x) maxexponent(x) precision(x) radix(x) range(x) tiny(x) value of (q, p) for (integer,real) b1p largest value in model minimum e maximum e decimal precision base b of integers decimal exponent range smallest positive value (real)
Note that all of these functions are generic, and can be used with any supported KIND.
117 / 140
Inquiry Functions
Using the same representational model as the inquiry functions. Designed to return values related to components of real type. exponent(x) fraction(x) nearest(x,s) rrspacing(x) scale(x,i) set_exponent(x,i) spacing(x) value of e in real model fractional part in real model value nearest x in direction of sign of s reciprocal of relative spacing, |xbe |bp xbi xbie bep if x/ = 0 and in range, else TINY
118 / 140
IEEE Arithmetic
The Fortran 2003 (and later) standard contains facilities for IEEE exception handling. The IEEE1 / ISO2 standard for oating-point arithmetic greatly helped in developing portable numeric code. The goal is to allow for a portable way to test and set the ve oating-point exception ags in the IEEE standard.
1 2
IEEE 754-1985, Standard for oating-point arithmetic IEC 559:1989, Binary oating-point arithmetic for microprocessor systems
Scientic Programming With Modern Fortran HPC-I Fall 2012 120 / 140
IEEE Arithmetic
IEEE Exceptions
IEEE Exceptions
IEEE exceptions: Overow the result of an operation exceeds the data format Division by Zero nite numerator, zero denominator (result is ) Invalid operation invalid (e.g. 0) - result is NaN Underow result of operation too small for data representation Inexact result of operation can not be represented without rounding
121 / 140
IEEE Arithmetic
IEEE Intrinsics
IEEE Intrinsics
Three intrinsic modules are provided: IEEE_EXCEPTIONS IEEE_ARITHMETIC, itself loads IEEE_EXCEPTIONS IEEE_FEATURES Inability to load one of these modules will indicate a non-compliant compiler. For detailed usage, see, for example, Metcalf & Reid. At this point there are relatively few compilers that have explicit support for these modules.
122 / 140
Object-Oriented Fortran?
Modules
Note that Fortran modules can be used as objected oriented programming (OOP) constructs: Creation of derived types that behave just like intrinsic types Intrinic types and operators can be overloaded Data can be hidden (encapsulated) In such a way one can create semantic extensions
124 / 140
Object-Oriented Fortran?
Generic Interfaces
Generic Interfaces
User-supplied functions, like most of the intrinsics, can have generic interfaces. For example, consider the intrinsic ABS(x) - behind the scenes, the function actually called depends on the KIND of the argument: CABS for x complex ABS for x real IABS for x integer
125 / 140
Object-Oriented Fortran?
Generic Interfaces
126 / 140
Object-Oriented Fortran?
Generic Interfaces
1 2 3 4 5 6 7 8 9 10 11
PROGRAM Main IMPLICIT NONE USE u s e f u l _ 1 real : : rx (1000) integer : : i x (1000) : CALL e x e m p l i f y ( r x ) ! g e n e r i c c a l l CALL e x e m p l i f y ( i x ) ! g e n e r i c c a l l : END PROGRAM Main
The rule being that the argument list makes the actual choice of routine unambiguous.
127 / 140
Object-Oriented Fortran?
Operator Overloading
Operator Overloading
Operators can be overloaded using the INTERFACE OPERATOR statement: Specify the MODULE PROCEDURE/ to deal with the implementation Useful (if not required) for derived types Operator name/symbox can be any of the intrinsics or any sequence of 31 characters or less in length enclosed in periods (other than .true. and .false) Be wary when overloading intrinsic operators - binary operators can not be made unary, etc. Can not redene intrinsically dened operations (must remain unambiguous)
128 / 140
Object-Oriented Fortran?
Operator Overloading
Object-Oriented Fortran?
130 / 140
Object-Oriented Fortran?
The assignment operator (=) is a little special - overloading it requires an INTERFACE ASSIGNMENT with a SUBROUTINE: The rst argument has INTENT(OUT) and represents the left-hand side of the assignment The second argument has INTENT(IN) and represents the right-hand side The subroutine must be pure, i.e. not alter global data, or produce any output
131 / 140
Object-Oriented Fortran?
1 2 3 4 5 6 7 8 9 10 11 12 13 14
MODULE u s e f u l _ 3 IMPLICIT NONE INTERFACE ASSIGNMENT ( = ) MODULE PROCEDURE f r a c _ e q END INTERFACE PRIVATE f r a c _ e q CONTAINS SUBROUTINE f r a c _ e q ( l h s , r h s ) type ( f r a c ) , i n t e n t ( out ) : : l h s type ( f r a c ) , i n t e n t ( i n ) : : r h s : ! body has t o have an assignment t o l h s END SUBROUTINE f r a c _ e q : END MODULE u s e f u l _ 3
132 / 140
Simple
It is fairly common to want to convert to a string, in C/C++ you can cast or use sprintf, and in Fortran you can use an internal le to write to a string. In the following example we use an internal le (basically a string) to convert an integer to a string, and then build a le name incorporating that string (suppose, for example, that you wanted to write out a separate le for each rank in an MPI application).
134 / 140
Simple
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
program t e s t c h a r i m p l i c i t none ! c o n v e r t i n t e g e r t o s t r i n g f o r use i n f i l e name character ( len =) , parameter : : a l p ha b e t 1 = a b c d e f g h i j k l m , & al p h a be t 2 = nopqrstuvwxyz character ( len =) , parameter : : numerals= 0123456789 character ( len =12) : : c s t r i n g integer : : t e s t i n t p r i n t , F i r s t f o u r l e t t e r s : , al p h a b et 1 ( 1 : 4 ) p r i n t , alphanumeric : , al p h a b et 1 / / a lp h a b et 2 / / numerals ! t e s t convert i n t to s t r i n g t e s t i n t =123 write ( cstring , ( i12 ) ) t e s t i n t p r i n t , " t e s t s t r i n g = " ,TRIM ( ADJUSTL ( c s t r i n g ) ) , " . " p r i n t , " f i l e n a m e t e s t = " , " o u t f i l e _ " / / TRIM ( ADJUSTL ( c s t r i n g ) ) / / " . d a t " end program t e s t c h a r
135 / 140
Simple
1 2 3 4 5 6
136 / 140
Simple
New to Fortran 2003, command line arguments are now supported. The following example illustrates the use of get_command, command_argument_count, and get_command_argument to process command line arguments to a Fortran program.
137 / 140
Simple
! cmdline . f 9 0 - s i m p l e command i n e argument p a r s i n g example l ! t e s t f o r t r a n 2 0 0 3 s u p p o r t f o r get_command_argument , get_command , ! and command_argument_count program cmdline i m p l i c i t none character ( len =255) : : cmd character ( len =) , parameter : : v e r s i o n = 1 . 0 character ( len =32) : : arg , date 8 , t i m e 10 , zone5 l o g i c a l : : do_time = . f a l s e . integer : : i c a l l get_command ( cmd ) w r i t e ( , ) E n t i r e command l i n e : w r i t e ( , ) t r i m ( cmd ) do i = 1 , command_argument_count ( ) c a l l get_command_argument ( i , arg ) s e l e c t case ( arg ) case ( v , - v e r s i o n ) p r i n t ( 2 a ) , cmdline v e r s i o n , v e r s i o n stop case ( h , - h e l p ) call print_help () stop case ( t , - t i m e ) do_time = . t r u e . case d e f a u l t p r i n t ( a , a , / ) , Unrecognized command i n e o p t i o n : l call print_help () stop end s e l e c t end do
, arg
138 / 140
Simple
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
! P r i n t t h e date and , o p t i o n a l l y , t h e t i m e c a l l date_and_time (DATE=date , TIME=time , ZONE=zone ) w r i t e ( , ( a ," " , a ," " , a ) , advance= no ) date ( 1 : 4 ) , date ( 5 : 6 ) , date ( 7 : 8 ) i f ( do_time ) then w r i t e ( , ( x , a , " : " , a , x , a ) ) t i m e ( 1 : 2 ) , t i m e ( 3 : 4 ) , zone else write ( , ( a ) ) end i f contains subroutine p r i n t _ h e l p ( ) p r i n t ( a ) , usage : cmdline [ OPTIONS ] print (a) , p r i n t ( a ) , W i t h o u t f u r t h e r o p t i o n s , cmdline p r i n t s t h e date and e x i t s . print (a) , p r i n t ( a ) , cmdline o p t i o n s : print (a) , p r i n t ( a ) , v , - v e r s i o n p r i n t v e r s i o n i n f o r m a t i o n and e x i t p r i n t ( a ) , h , - h e l p p r i n t usage i n f o r m a t i o n and e x i t p r i n t ( a ) , t , - t i m e p r i n t time end subroutine p r i n t _ h e l p end program cmdline
139 / 140
Simple
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
[ u2 : ~ / d _ f o r t r a n ] $ i f o r t o cmdline cmdline . f 9 0 [ u2 : ~ / d _ f o r t r a n ] $ . / cmdline E n t i r e command l i n e : . / cmdline 20120926 [ u2 : ~ / d _ f o r t r a n ] $ . / cmdline v E n t i r e command l i n e : . / cmdline v cmdline v e r s i o n 1 . 0 [ u2 : ~ / d _ f o r t r a n ] $ . / cmdline - h e l p E n t i r e command l i n e : . / cmdline - h e l p usage : cmdline [ OPTIONS ] W i t h o u t f u r t h e r o p t i o n s , cmdline p r i n t s t h e date and e x i t s . cmdline o p t i o n s : v , - v e r s i o n p r i n t v e r s i o n i n f o r m a t i o n and e x i t h , - h e l p p r i n t usage i n f o r m a t i o n and e x i t t , - t i m e p r i n t time [ u2 : ~ / d _ f o r t r a n ] $ . / cmdline - t i m e E n t i r e command l i n e : . / cmdline - t i m e 20120926 16:18 0400
140 / 140