4.3 Dynamic Arrays

next up previous
Next: 4.4 Array-valued Functions Up: 4 Data Parallelism Previous: 4.2 Array Sections

4.3 Dynamic Arrays


Fortran 90 has three varieties of dynamic arrays. All three allow array creation at run time with sizes determined by computed (or input) values. These three varieties of dynamic arrays are:

Automatic Arrays
Automatic arrays are local arrays whose sizes depend upon values associated with dummy arguments. Automatic arrays are automatically created (allocated) upon entry to the procedure and automatically deallocated upon exit from the procedure. The size of an automatic array typically is different in different activations of the procedure. Examples of automatic arrays are:
function F18(A,N)
 integer  N                    ! A scalar
 real A(:,:)                   ! An assumed shape array
 real F18(size(A,1)  )         ! The function result itself is
                               !  an automatic array.

 complex  Local_1(N,2*N+3)     ! Local_1 is an automatic array
                               !  whose size is based on N.

 real Local_2(size(A,1),size(A,2))     ! Local_2 is an automatic array
                               !  exactly the same size as A.

 real Local_3(4*size(A,2))     ! Local_3 is a one-dimensional 
                               !  array 4 times the size of 
                               ! the second dimension of A.
 ...                           !  
end function F18
Note the importance of the intrinsic inquiry functions, such as SIZE (which returns the argument array size in a specified dimension) in declaring automatic arrays. Fortran 90 provides a number of inquiry functions that are allowed to appear in declarations. Array bounds and sizes, character lengths, and type kinds may all be specified with expressions involving these inquiry functions. Roughly, a specification expression, as such expressions are called, is a scalar integer expression that has operands whose values are determinable upon entry to the procedure. Such operands include constants, references to intrinsic procedures, and variables accessible through dummy arguments, modules, common, and (in the case of module and internal procedures) the host procedure.

Allocatable Arrays
Allocatable arrays are those explicitly declared ALLOCATABLE. An allocatable array may be local to a procedure or may be placed in a module and effectively be global to all procedures of the application. An allocatable array is explicitly allocated with the ALLOCATE statement, and deallocated either explicitly with the DEALLOCATE statement or, if it is a local array for which SAVE has not been specified, automatically upon exit from the procedure. (If SAVE has been specified, local allocatable arrays can persist from one execution of the procedure to the next - they must be explicitly deallocated with a DEALLOCATE statement.) A global allocatable array persists until it is explicitly deallocated, which may occur in a procedure different from the one in which it was allocated. Use an allocatable (or pointer) array if its size depends on a computed value other than a dummy argument or variable in a module, common, or the host. The allocation status (allocated or not allocated) of an allocatable array may be tested with the ALLOCATED intrinsic function. Examples of allocatable arrays are:
subroutine Peach
 use Recipe                    ! Accesses global allocatable array, Jam.

 real, allocable :: Pie(:,:)   ! Pie is a 2-dimensional allocatable array.
 allocate ( Pie(N,2*N )   )    ! Allocate a local allocatable array.

 if (.not.allocated(Jam)) allocate ( Jam(4*M) )
                               ! Allocate a global allocable array if
                               ! it is not already allocated.
 ... deallocate ( Pie )
end subroutine Peach

module Recipe                  ! Jam is a global allocatable array, and
 real, allocable :: Jam(:)     ! can be allocated and deallocated in
 ...                           ! any procedure(s) using this module.
end module Recipe
Note that the declared bounds for allocatable arrays are simply colons, indicating that these will be provided later, at the time of allocation. This makes allocatable array declaration appear similar to assumed-shape dummy argument declaration, appropriate because the ``deferred" nature of the sizes of the dimensions is conceptually similar.

Pointer Arrays
Pointer arrays are similar to allocatable arrays in that they are explicitly allocated with the ALLOCATE statement to have arbitrary computed sizes and are explicitly deallocated with the DEALLOCATE statement. Examples of pointer arrays are given in section 1, in the subsection entitled Pointers. These examples also illustrate target arrays and the use of pointer assignment, the latter of which cannot be used with allocatable arrays. Additional, very simple, examples of pointer arrays result by replacing ``allocatable" with ``pointer" in the preceding examples of allocatable arrays.

In addition, pointer arrays can be used as aliases for (``point to") other arrays and array sections; the pointer assignment statement is used to establish such aliases. The target for pointer associations (as such aliasing is called) may be other explicitly allocated arrays, or static or automatic arrays that have been explicitly identified as allowable targets for pointers. The association status of a pointer array may be tested with the ASSOCIATED intrinsic function. Finally, pointer arrays may be dummy arguments and structure components, neither of which are allowed for allocatable arrays. Given this apparent similarity between allocatable arrays and pointer arrays, what is the fundamental distinction between these two forms of dynamic arrays, and when should allocatable arrays be used rather than pointer arrays? Pointer arrays subsume all of the functionality of allocatable arrays, and in this sense allocatable arrays are never needed-pointer arrays could always suffice. The problem with pointer arrays is efficiency. Though pointer arrays must always point to explicit targets, which makes optimization practical that would otherwise be infeasible, pointer assignment makes optimization of pointer arrays much more difficult than for allocatable arrays. Because of their more limited nature and functionality, allocatable arrays are just ``simpler" and can be expected to be more efficient than pointer arrays.

Therefore, when all that is needed is simple dynamic allocation and deallocation of arrays, and automatic arrays are not sufficient, use allocatable arrays. A common example of this is if a ``work array" is needed of a size dependent upon the results of a local computation. If, on the other hand, the algorithm calls for a dynamic alias, of for example a ``moving" section of a host array, then a pointer array is probably indicated.

next up previous
Next: 4.4 Array-valued Functions Up: 4 Data Parallelism Previous: 4.2 Array Sections