Numerics
Assumed-Shape Array
One Procedure, Any Size
An assumed-shape dummy argument arr(:) accepts an array of any size, and size(arr) queries its length at runtime.
Program
Play the program to compute the integer mean of two different arrays with one subroutine.
assumed_shape.f90
Replay: real traced execution (multi-file project)
program assumed_shape_demo
implicit none
integer :: a(3) = [1, 2, 3]
integer :: b(5) = [10, 20, 30, 40, 50]
integer :: result_
call mean_int(a, result_)
print '(I0)', result_
call mean_int(b, result_)
print '(I0)', result_
contains
subroutine mean_int(arr, m)
integer, intent(in) :: arr(:)
integer, intent(out) :: m
m = sum(arr) / size(arr)
end subroutine mean_int
end program assumed_shape_demo
a ← [1, 2, 3]
2implicit none3integer :: a(3) = [1, 2, 3]4integer :: b(5) = [10, 20, 30, 40, 50]values this step[1, 2, 3]ab ← [10, 20, 30, 40, 50]
3integer :: a(3) = [1, 2, 3]4integer :: b(5) = [10, 20, 30, 40, 50]5integer :: result_values this step[10, 20, 30, 40, 50]bcall ← mean_int(a, result_)
5integer :: result_6call mean_int(a, result_)7print '(I0)', result_values this stepmean_int(a, result_)call[1, 2, 3]am ← 2
13 integer, intent(out) :: m14 m = sum(arr) / size(arr)15end subroutine mean_intvalues this step2m[1, 2, 3]arr3size(arr)print '(I0)', result_
6call mean_int(a, result_)7print '(I0)', result_8call mean_int(b, result_)output2values this step2result_call ← mean_int(b, result_)
7print '(I0)', result_8call mean_int(b, result_)9print '(I0)', result_values this stepmean_int(b, result_)call[10, 20, 30, 40, 50]bm ← 30
13 integer, intent(out) :: m14 m = sum(arr) / size(arr)15end subroutine mean_intvalues this step30m[10, 20, 30, 40, 50]arr5size(arr)print '(I0)', result_
8 call mean_int(b, result_)9 print '(I0)', result_10containsoutput30values this step30result_
Follow the Two Calls
astarts as[1, 2, 3].mean_int(a, result_)seessize(arr) = 3and stores2.- The first print writes
2. bstarts as[10, 20, 30, 40, 50].mean_int(b, result_)seessize(arr) = 5and stores30, then prints30. | call | array | size | result | | --- | --- | --- | --- | |mean_int(a, result_)|[1, 2, 3]| 3 | 2 | |mean_int(b, result_)|[10, 20, 30, 40, 50]| 5 | 30 |
assumed-shape
`arr(:)` declares a dummy argument that takes its shape from the caller.
size
`size(arr)` returns the runtime length.
reuse
The same procedure works for arrays of any length.
Exercise: assumed_shape.f90
Reproduce the outputs 2 and 30, then trace how the same arr(:) procedure uses size 3 for a and size 5 for b.