160 likes | 345 Views
ICoCSIS. Fortran: Array Features. Session Five. Outline. Zero-sized Array Assumed-shaped Array Automatic Objects Allocation of Data Elemental Operations and Assignments Array-valued Functions The where Statement and Construct The forall Statement and Construct Pure Procedures
E N D
ICoCSIS Fortran: Array Features Session Five
Outline • Zero-sized Array • Assumed-shaped Array • Automatic Objects • Allocation of Data • Elemental Operations and Assignments • Array-valued Functions • The where Statement and Construct • The forall Statement and Construct • Pure Procedures • Elemental Procedures • Array of Pointers
Introduction Linguistic elements • Enhancing programming • Serves for optimization of performance • Libraries with intrinsic procedures • Integral part of programming environment Some definitions: • An array consists of a rectangular set of elements, all of the same type and type parameters. • The number of elements of an array is called its size real, dimension(-10:5) :: vector • An array may extend in more than one dimension, and Fortran allows up to seven dimensions real, dimension(5,4) :: b • The number of dimensions of an array is call rank • The sequence of extents is call shape.
Zero-sized arrays Fortran allows arrays to have zero size in all contexts. Two zero-sized arrays of the same rank may have different shapes. One might have shape (0,2) and the other (0,3) or (2,0). Such arrays of differing shape are not conformable and therefore may not be used together as the operands of a binary operation. An array is always conformable with a scalar so the statement zero-sized-array = scalar is valid and the scalar is ‘broadcast to all the array elements’, making this a ‘do nothing’ statement. A zero-sized array is regarded as being defined always, because it has no values that can be undefined.
Assumed-shape arrays • The shapes of actual and dummy arguments agree, but it is possible to require that the shape of the dummy array be taken automatically to be that of the corresponding actual array argument. • When the shape is declared by the dimension clause, each dimension has the form [lower-bound]: • If lower-bound is omitted, the default value is 1. Note that it is the shape that is passed, and not the upper and lower bounds. For example, if the actual array is a, declared as: real, dimension(0:10, 0:20) :: a and the dummy array is da, declared as: real, dimension(:, :) :: da then a(i,j) corresponds to da(i+1,j+1). • To get the natural correspondence, the lower bound must be declared: real, dimension(0:, 0:) :: da Note: A dummy array with the pointer attribute is not regarded as an assumed-shape array because its shape is not necessarily assumed.
Automatic objects A procedure with dummy arguments that are arrays whose size varies from call to call may also need local arrays whose size varies. A simple example is the array work in the subroutine to interchange two arrays. subroutine swap(a, b) real, dimension(:), intent(inout) :: a, b real, dimension(size(a)) :: work ! automatic array ! size provides the size of an array work = a; a = b; b = work end subroutine swap The other way that automatic objects arise is through varying character length. subroutine example(word1) character(len= *), intent(inout) :: word1 character(len= len(word1)) :: word2
Allocation of data (1) • The allocatableattribute – if an array is required to be of a size that is known only after some data have been read or some calculations performed: real, dimension(:, :), allocatable :: a deallocate (a) • The allocate statement – to give fresh storage for a pointer target directly. allocate ( allocation-list [, stat=stat ] ) where allocation-list is a list of allocations of the form allocate-object [ ( array-bounds-list ) ] each array-bound has the form [ lower-bound : ] upper-bound and statis a scalar integer variable that must not be part of an object being allocated. • The deallocatestatement deallocate ( allocate-object-list [,stat=stat] ) • Allocatable dummy arguments – a dummy arrray is permitted to have the allocatable attribute. In this case, the corresponding actual argument must be an allocatable array of the same type. • Allocatablefunctions – an array function result is permitted to have the allocatableattribute. • Allocatablecomponents – array components of derived type are permitted to have the allocatable attribute.
Allocation of data (2) • Allocatable arrays vs. pointers • Code for a pointer array is likely to be less efficient • If a defined operation involves a temporary variable of a derived type with a pointer component, the compiler will probably be unable to deallocate its target when storage for the variable is freed. • Intrinsic assignment is often unsuitable for a derived type with a pointer. • Similar considerations apply to a function invocation within an expression. • When a variable of derived type is deallocated, any ultimate allocatablecomponent that is currently allocated is also deallocated. To avoid memory leakage with pointer components, the programmer would need to deallocate each one explicitly and be careful to order the deallocations correctly.
Elemental operations and assignments An intrinsic operator can be applied to conformable operands, to produce an array result whose element values are the values of the operation applied to the corresponding elements of the operands. Such an operation is called elemental. For a function, the shape of the result is the shape of the array arguments. For example, we may find the square roots of all the elements of a real array thus: a = sqrt(a)
Array-valued functions Afunction may have an array-valued result. An array-valued function is not necessarily elemental.
The where statement and construct It is often desired to perform an array operation only for certain elements, say those whose values are positive. The where statement provides this facility. A simple example is where ( a > 1.0 ) a = 1.0/a ! a is a real array which reciprocates those elements of a that are greater than 1.0 and leaves the rest unaltered. The general form is where (logical-array-expr) array-variable = expr
The forall statement and construct When elements of an array are assigned values by a do construct such as do i = 1, n a(i, i) = 2.0 * x(i) ! a is rank-2 and x rank-1 end do the processor is required to perform each successive iteration in order and one after the other. This represents a potentially severe impediment to optimization on a parallel processor so, for this purpose, Fortran has the forall statement. The above loop can be written as forall(i= 1:n) a(i, i) = 2.0 * x(i)
Pure procedures To assert that a procedure has no side-effects – add the pure keyword to the subroutine or function statement. In practical terms, this is an assertion that the procedure • if a function, does not alter any dummy argument; • does not alter any part of a variable accessed by host or use association; • contains no local variable with the save attribute; • performs no operation on an external file; and • Contains no stop statement. pure function distance(p, q)
Elemental procedures Elemental intrinsic procedures are those with scalar dummy arguments that may be called with array actual arguments provided that the array arguments have the same shape (that is, provided all the arguments are conformable). For a function, the shape of the result is the shape of the array arguments. This feature exists too for non-intrinsic procedures. This requires the elemental prefix on the function or subroutine statement. This is an aid to optimization on parallel processors. elemental function add_intervals(a,b) type(interval) :: add_intervals type(interval), intent(in) :: a, b add_intervals%lower= a%lower + b%lower! Production code add_intervals%upper= a%upper + b%upper ! would allow for end function add_intervals ! roundoff. An elemental procedure must satisfy all the requirements of a pure procedure
Array elements An array element is a scalar of the form part-ref [%part-ref]... where part-ref is part-name[(subscript-list)] To illustrate this, take the type type triplet real :: u real, dimension(3) :: du real, dimension(3,3) :: d2u end type triplet An array may be declared of this type: type(triplet), dimension(10,20,30) :: tar and tar(n,2,n*n) ! n of type integer is an array element. It is a scalar of type triplet and tar(n, 2, n*n)%du is a real array with tar(n, 2, n*n)%du(2) as one of its elements
Arrays of pointers Although arrays of pointers as such are not allowed in Fortran, the equivalent effect can be achieved by creating a type containing a pointer component. type ptr type(entry), pointer :: point end type ptr type entry real :: value integer :: index type(ptr), pointer :: children(:) end type entry