I have a scientific simulation in Fortran. In it, I need to calculate a large array (say 10^5 elements, a size known / that can be preset when writing the code) "once" around the beginning, and then this array will need to be shared / accessed / read into a lot of times (basically at each step, so possibly millions of times).
What is the recommended way of sharing such an array with other subroutines ? Given that I want the code creating the large array to be its own entity.
Say there is case 1, where :
There is case 2, where :
Finally there is case 3, which is exactly as case 2, except the array could be physically preset / written in code as a data statement.
What would be the best practice in each case, and to optimize speed / minimize possible runtime penalties ?
Edit : this is the solution I have in place for now. Have a module of the form
module big_array
parameter (nbigarray=10**5)
real my_by_array(nbigarray)
contains
subroutine init_big_array(arglist)
*[here some code populating / creating *my_big_array*]*
return
end
end module
run init_big_array
once at the start of the program and use the module wherever my_big_array
is needed.
Here is an intro to dynamic memory management that allows one to expose array
to subprograms.
module foo
implicit none ! Always include this statement
!
! Make everything private and only expose those entities
! that are needed.
!
private
public array, init_array, destroy_array
integer, allocatable :: array(:)
contains
!
! Destroy array
!
subroutine destroy_array
if (allocated(array)) then
deallocate(array)
end if
end subroutine
subroutine init_array(n)
integer, intent(in) :: n
if (n < 0) then
!
! Could implement a fallback. Perhaps,
! allocate a zero-sized array.
!
write(*,'(A)') 'init_array: memory allocation issue'
stop
end if
!
! Check if array is allocated and the requested size
! differs from the current allocated size.
!
if (allocated(array)) then
if (size(array) /= n) then
call destroy_array
allocate(array(n))
end if
else
allocate(array(n))
end if
end subroutine
end module foo
program main
use foo, only : array, init_array
implicit none
integer m
!
! Perhaps, "read(*,*) m" to allow user to size
! memory appropriately.
!
m = 100
call init_array(m)
call bar
end program
subroutine bar
use foo, only : array
implicit none
if (allocated(array) then
print *, size(array)
else
write(*,'(A)') 'whoops'
end if
end subroutine bar