480 likes | 697 Views
Introduction to Fortran 90 Part - II. Consulting Services Group Sidd Ghosh (presenter) Feb 15, 2011 NCAR/CISL/HSS/CSG Consulting Services Group. Contents. Working with F90 array sections Functions and subroutines Fortran 90 pointers Passing array section across subroutines Modules
E N D
Introduction to Fortran 90 Part - II Consulting Services Group SiddGhosh (presenter) Feb 15, 2011 NCAR/CISL/HSS/CSG Consulting Services Group
Contents • Working with F90 array sections • Functions and subroutines • Fortran 90 pointers • Passing array section across subroutines • Modules • Operators for user-defined data types • Intrinsic functions • Overloading functions and operators • Input/Output • Highlights of 2008 standard
Examples, exercises etc. ssh –X <user-name>@miragex.ucar.edu replace x with one of 0, 1, 2, 3, 4 randomly The option –X for forwarding X display, you need only if you use x-based editor like nedit cp -r /glade/home/sghosh/f90-2 .
Fortran90 array syntax similar to array syntax of Matlab, NCL or IDL Each rank may have the structure beg-ind : end-ind: stride Each index can be any integer, +ive, -iveor 0 (zero stride is illegal and does not make sense anyway!) Note: The syntax is similar to NCL but contrast this with Matlab: beg-ind : stride : end-ind
Syntax of Array Section real :: a(10), b(10,10), c(4,4), d(4,4) a = 1 ! Store 1 in all elements of a a(1:10:3) = 2 ! Store 2 in 1st, 4th, 7th and 10th elements of a c = b(1:10:3,1:10:3) ! Needs to be conformable d = sqrt( b(1:10:3,1:10:3) ) ! Element wise operations Note: Array sections are rectangular
Syntax of Array Section a = 1 ! Store 1 in all elements of a a(1:10:3) = 2 ! Store 2 in 1st, 4th, 7th and 10th elements of a • May appear in both left and right hand side of an assignment • But needs to be conformable
Syntax of Array Section a(1:7:3) = a(2:8:3) Before assignment After assignment
Ref: array/ex1.f90, array/ex2.f90 • Notes: • The syntax: • a = (/1,2,3,4,5,6,7,8,9,10/) • Means assign 1 through 10 into consecutive 10 locations of array a • The I/O notation: • print '(“a(:) “,10(i3))', a • Means print the character string “a(:) “ and then keep room for 10 integer locations each with 3 character wide.
Multi-dimensional array Column major storage order in 2D
Output from array/ex3.f90 Complete array a a( 1,:) 1. 11. 21. 31. 41. 51. 61. 71. 81. 91. a( 2,:) 2. 12. 22. 32. 42. 52. 62. 72. 82. 92. a( 3,:) 3. 13. 23. 33. 43. 53. 63. 73. 83. 93. a( 4,:) 4. 14. 24. 34. 44. 54. 64. 74. 84. 94. a( 5,:) 5. 15. 25. 35. 45. 55. 65. 75. 85. 95. a( 6,:) 6. 16. 26. 36. 46. 56. 66. 76. 86. 96. a( 7,:) 7. 17. 27. 37. 47. 57. 67. 77. 87. 97. a( 8,:) 8. 18. 28. 38. 48. 58. 68. 78. 88. 98. a( 9,:) 9. 19. 29. 39. 49. 59. 69. 79. 89. 99. a(10,:) 10. 20. 30. 40. 50. 60. 70. 80. 90. 100. Array section a(1:m,1:m) b( 1,:) 1. 11. 21. 31. b( 2,:) 2. 12. 22. 32. b( 3,:) 3. 13. 23. 33. b( 4,:) 4. 14. 24. 34. Array section a(m:2*m-1,m:2*m-1) b( 1,:) 34. 44. 54. 64. b( 2,:) 35. 45. 55. 65. b( 3,:) 36. 46. 56. 66. b( 4,:) 37. 47. 57. 67.
Output from array/ex4.f90 Complete array a a( 1,:) 1. 11. 21. 31. 41. 51. 61. 71. 81. 91. a( 2,:) 2. 12. 22. 32. 42. 52. 62. 72. 82. 92. a( 3,:) 3. 13. 23. 33. 43. 53. 63. 73. 83. 93. a( 4,:) 4. 14. 24. 34. 44. 54. 64. 74. 84. 94. a( 5,:) 5. 15. 25. 35. 45. 55. 65. 75. 85. 95. a( 6,:) 6. 16. 26. 36. 46. 56. 66. 76. 86. 96. a( 7,:) 7. 17. 27. 37. 47. 57. 67. 77. 87. 97. a( 8,:) 8. 18. 28. 38. 48. 58. 68. 78. 88. 98. a( 9,:) 9. 19. 29. 39. 49. 59. 69. 79. 89. 99. a(10,:) 10. 20. 30. 40. 50. 60. 70. 80. 90. 100. Array section a(1:n:3,1:n:3) b( 1,:) 1. 31. 61. 91. b( 2,:) 4. 34. 64. 94. b( 3,:) 7. 37. 67. 97. b( 4,:) 10. 40. 70. 100.
Vector array index Array index may also be explicitly enumerated in a vector real :: a(10), b(3) b = a( (/1, 7, 2/) ) ! 1st, 7th and 2nd element ! of a goes to 3 ! consecutive elements of b Ref: array/ex5.f90
Output from array/ex5.f90 a( 1,:) 1. 11. 21. 31. 41. 51. 61. 71. 81. 91. a( 2,:) 2. 12. 22. 32. 42. 52. 62. 72. 82. 92. a( 3,:) 3. 13. 23. 33. 43. 53. 63. 73. 83. 93. a( 4,:) 4. 14. 24. 34. 44. 54. 64. 74. 84. 94. a( 5,:) 5. 15. 25. 35. 45. 55. 65. 75. 85. 95. a( 6,:) 6. 16. 26. 36. 46. 56. 66. 76. 86. 96. a( 7,:) 7. 17. 27. 37. 47. 57. 67. 77. 87. 97. a( 8,:) 8. 18. 28. 38. 48. 58. 68. 78. 88. 98. a( 9,:) 9. 19. 29. 39. 49. 59. 69. 79. 89. 99. a(10,:) 10. 20. 30. 40. 50. 60. 70. 80. 90. 100. a( (/1,4,9/), (/5,7,3/) ) 41. 61. 21. 44. 64. 24. 49. 69. 29. l=( 10 5 2 ), m=( 3 8 ), a(l,m) 30. 80. 25. 75. 22. 72. Note: Order of indices may be non-monotonic too
Forall construct forall ( indx-triplets, .. , condition ) <body> end forall • condition may involve more than one index (possible to manage non-rectangular blocks) • logically all the operations on body are simultaneous • compilers may choose to parallelize the body • Ref: • array/ex6.f90 Note: Contrast this with identical body of operations under do-loops
where construct where ( mask-array/logical-array-condition ) <body> end where • Elemental operation, condition applies to one element • mask array and the target array could be the same • logically simultaneous, hence may be parallelizable • Refs: • array/ex7.f90
Functions and Subroutines • To modularize the operations for easier • code management and • code organization • like most high Level language Fortran also has sub program functionality with well defined interfaces and scoping. function structure function <name> ( arguments,.. ) <declarations..> <body> end function call syntax x = myfunction( y, z )
Subroutine structure subroutine <subroutine-name>( arguments,.. ) <declarations> <body of subroutine> end subroutine <subroutine-name> Subroutine call syntax call mysubroutine( x, y, .. ) • Note: • Default interface is arguments, • Functions return a value while subroutine does not (only difference) • Unless a single return value is needed fortran programmers prefer subroutine, we will follow this convention • Refs: subp/ex[1-3].f90
closer look at Subprogram structure • Subprogram name needs to be unique within the scoping unit (whole program before we introduce module!) • Arguments and return values are dummy variables i.e. passed by references (or actual memory locations are defined by the caller
Jacobi Iteration (i+1,j) (i,j) (i,j-1) (i,j+1) (i-1,j)
closer look at Subprogram structure • subprogram unit are local (or type automatic, has meaningful existence within a single call and not between calls by default) • Multi-dimensional array definition needs to be either assumed shape or explicit • Ref: • subp/ex4.f90 subp/ex5.f90
Internal Subprogram • Internal subprograms (as the name suggests) are subprogram blocks inside a subprogram • are visible only from the container subprogram • Inherits all the variables and states from caller • May define local variables • If there is a name collision with parent the local name becomes a distinct variable (careful!)
Internal Subprogram syntax subroutine xyz(a, b,.. ) <body> contains subroutine pqr(..) <body> end subroutine end subroutine Ref: subp/ex6.f90
Fortran90 Pointers • points to an object, typically array locations • F90 pointer has an associated type, rank and strides etc. • often called a descriptor in contrast with Cray or C pointers • May point to NULL, or even to an illegal memory location (beware!) • Standard 2003 allows pointers to a function too • Every locations allocated in F90 will have an associated type, rank and stride (contrast with C and Cray pointers in Fortran)
Fortran90 Pointers syntax real, pointer :: a, b(:,:), c(:,:) allocate(b(10,10)) ! 10 x 10 real memory ! associated c => b ! c points to the same ! locations as b c => b(1:n:2,1:n:2) ! c points to an array ! section of b Ref: pointers/ex1.f90
Notes on F90 pointers • As we have seen memory can be allocated against pointers or • Pointers may point to an already allocated locations • Pointers once legally defined is valid reference just like any other normal variables or references in Fortran • Pointers may point to array sections defined using triplets but • Vector indices are not allowed (why?) • It is not legal to pass NULL pointer across sub programs
Differences with Allocatable attribute • Memory may be allocated both against variables with allocatable attributes and pointers but • Allocatable attributes have more stringent runtime check of garbage collections • Pointers may point to a previously allocated location • F95 specification requires deallocation of automatic variables
Passing Array-sections across subroutines • It is important to realize while passing array-sections or pointers defined using array sections with explicit interface i.e. following F77 style the compiler will have to create temporary copy to allow conformance. • It is recommended to use assumed shape arrays to avoid overhead due to copy and copy-back and also the potential problems with asynchronous programming e.g. asynchronous MPI communications. • Ref: • pointers/internal/ex[1-3].f90
Modules • Container of data and subprogram units • Allows access to its contents in different subprogram units through use statements • Allows fine grain access through private/public clause • Equivalent functions of common blocks in F77 but with many more features
Modules syntax module <name> <declarations> contains function xyz(a, b,..) <..> end function subroutine pqr(p,..) end subroutine end module
Modules as a simple container of data • Data defined under a module are real locations (as against dummy locations) • By use statement program units refer to these locations. • Similar to common blocks in F77 but needs to be make accessible to subprograms by use statement as against defined as it was done with common blocks, so less error prone Ref: modules/ex1.f90
Modules, data hiding • Not all the data is needed by all the subprograms • So why not subprograms take only that is needed ? • Rationale: • Less possibility of erroneous reference or avoid namespace collisions • Syntax: • use mymodule : only x, y, z Ref: modules/ex2.f90
Modules, data hiding, from module side • Module itself dictates what to expose • Rationale: • Single point of control • Even less errorprone • Syntax: • private <data>, procedure • public data, procedure Ref: modules/ex3.f90
Modules procedures • Modules may contain procedures • These procedures may be the only interfaces to act on data it contains • Rationale: • Forcing user to act on data in a standard form • Starting point of Object Oriented Methodologies Ref: modules/ex4.f90
Notes on Module data and procedures • Modules may use other modules in a chain of dependencies but cyclic use is illegal • Module variables and function/subprograms may be renamed while using to avoid name collision • The only clause may allow few selective variables to be used • Module data is of type automatic by default, so it is important to add save attribute (but it is always implemented as static)
Notes on Module data and procedures • Module procedure arguments are always checked for type and rank between caller and callee during compilation • Module procedures inherit all the module variables and has access to all other procedures within the scope of the parent module, it may explicitly include (use) others as well. Ref: modules/ex[5-6].f90
Operators between user defined data types • Recall that the only defined operator for user defined data type is “=“ • One or more operators may be created to operate between two or more objects of user defined type • The allowed syntax for user defined operator is • .xyz. • where xyz is any convenient alphabetic (not numeric) string.
Syntax for defining operator interface operator (.xyz.) function .. subroutine .. module procedure .. end interface Ref: operator/ex1.f90
Intrinsic functions • These are elementary mathematical and other utility functions to operate on basic data types or query on program environment • All the F77 intrinsic functions are supported and few newer intrinsic functions are added • The list is long, some of the common ones are sqrt, sin, cos, tan, asin, acos, atan, atan2, exp, sinh, max, min etc.
Intrinsic functions • Example of newly added intrinsic functions are date_and_time, random_number, maxloc, minloc etc. • Complex data type is intrinsically supported in Fortran, so corresponding complex version of these functions (if applicable) are also supported. • Fortran Language reference manual which comes with the compiler is the best place for exhaustive list and almost always google works most efficiently after a little experience
Intrinsic Functions and Overloading Many of the intrinsic functions operate on variables with different precisions, rank etc. Example: xsqrt = sqrt( x ) The returned value that is stored in xsqrtwill be of same type and rank as x. Compiler recognizes the data types and redirects the call to appropriate functions for correct return values Ref: overload/ex1.f90
Generic interface and overload • Procedures may be overloaded through a generic interface blocks • Presence of argument(s), type and rank associates appropriate call at compile time Basic syntax: interface <name> module procedure <xyz> module procedure <abc> end interface Note: If interface location does not have access to full arguments then those need to be described using dummy arguments. Ref: overload/ex2.f90
Overloading operators Combination of operations of defining operator and procedure overload In example overload/ex3.f90 the intrinsic operator * is overloaded for product between 2 matrices and A matrix and a vector
Sequential Unformatted I/O • Unformatted I/O preserves the image of variables as existing in memory • Typically needed to write restart files Syntax to open files open(11,file=‘data.dat’,form=‘unformatted’) To write write(11)x, y, z ! Each of these may be ! array of basic or user ! defined types To read read(11)x,y,z
Sequential Unformatted I/O Note: Often these data files are called binary files and machine readable only Ref: io/ex2.f90 (to write) io/ex3.f90 (to read)
Integer / string conversion • Write integer to a character string • Typically used to manipulate file names • Ref: • io/ex4.f90 • Read integer off a character string • Typically used to manipulate arguments to program • Ref: • io/ex5.f90
Fortran 2008 standard • Big thing is Co-array fortran (CAF) • sub modules, breaking module into several subs (one module does not get too big, big relief for WRF devs!) • concurrent do loops (equiv. omp parallel do) • Polymorphic allocate (almost equiv C cast) • Max rank to 15 • newunit finds an I/O unit dynamically • Few more intrinsics Bessel etc.