Search code examples
memory-managementfortranallocation

Creating a subroutine to deallocate arrays in the main program


I have a Fortran main program, with many allocated arrays in it. I created a subroutine that allocates these arrays that the main program calls. I'd like to do a similar thing for the deallocates, but I'm receiving a compiler error, saying they are not defined as allocatable. I originally wrote the code like this:

SUBROUTINE deallocate_jacobian(int3, int4, int5, Diag, Off_Diag_LR, Off_Diag_RL)
use Globals_module,   only : alloc_stat
!--------------------------------------------end of use--------------------------------------------!
integer(i4), intent(in) :: int3, int4, int5
real(dp), intent(inout) ::  Diag(int3, int3, int4),  off_diag_lr(int3, int3, int5), off_diag_rl(int3, int3, int5)
!------------------------------------------end of intents------------------------------------------!
deallocate(Diag,        STAT = alloc_stat)
deallocate(Off_Diag_LR, STAT = alloc_stat)
deallocate(Off_Diag_RL, STAT = alloc_stat)
END SUBROUTINE deallocate_jacobian

I then rewrote it like so:

SUBROUTINE deallocate_jacobian(int3, int4, int5, Diag, Off_Diag_LR, Off_Diag_RL)
use Globals_module,   only : alloc_stat
!--------------------------------------------end of use--------------------------------------------!
integer(i4), intent(in) :: int3, int4, int5
real(dp), allocatable, intent(out) :: Diag(:,:,:),  off_diag_lr(:,:,:), off_diag_rl(:,:,:)
!------------------------------------------end of intents------------------------------------------!
deallocate(Diag,        STAT = alloc_stat)
deallocate(Off_Diag_LR, STAT = alloc_stat)
deallocate(Off_Diag_RL, STAT = alloc_stat)
END SUBROUTINE deallocate_jacobian

The compiler errors disappeared, but I'm wondering if I'm not missing a bigger issue with the allocatable intent, inout stuff.


Solution

  • The first thing to say is to remind the reader that there is a distinction between a dummy argument of a procedure and the actual argument in the reference to the procedure. In particular, the dummy argument doesn't, in general, "know" things about the actual argument other than what it knows about itself.

    That, then, is why Diag isn't allocatable in the first attempt but is in the second.

    Now, the question ask about wider aspects of allocatable dummy arguments. There are lots of questions in which involve parts of this question, so I'll just summarize those of common relevance and leave the interested parties to research further.

    1. To consider the allocation status of the dummy argument it must be allocatable.
    2. To be associated with an allocatable dummy argument the actual argument must be allocatable.
    3. The ranks of the actual and dummy arguments when both are allocatable must match.
    4. Type parameters of the actual and dummy arguments when both are allocatable must match in which are deferred.
    5. If an allocatable dummy argument has intent(out) then the actual argument is deallocated on invocation of the procedure and the dummy argument starts life in the procedure as not allocated.
    6. If an allocatable dummy argument has intent(in) it cannot have its allocation status changed in the procedure.
    7. If an allocatable dummy argument hasn't intent(out) then it has the same bounds/extents as the actual argument (instead of the usual 1-indexed default lower bounds).