> I'm having a tough time understanding the passing of array sections as
> subroutine arguments, particularly from the point of view of using f90 style
> syntax but avoiding copy-in/copy-out because of the associated cost.
>
> Let's say I have two modules, each with a subroutine:
>
> module A_mod
> contains
> subroutine a
> integer, parameter :: nface = 64, nlev = 32
> real :: aa(nface,nlev,5)
> i = 3
> call b( aa(1,1,i), nface, nlev )
> end subroutine
> end module
>
> module B_mod
> contains
> subroutine b( z, ni, nj )
> real, intent(inout) :: z(ni,nj)
> integer, intent(in) :: ni, nj
> z = 1.0
> end subroutine b
> end module
To get a valid program, let's change this to:
module B_mod
contains
subroutine b( z, ni, nj )
real, intent(inout) :: z(ni,nj)
integer, intent(in) :: ni, nj
z = 1.0
end subroutine b
end module
program main
use B_mod
integer, parameter :: nface = 64, nlev = 32
real :: aa(nface,nlev,5)
i = 3
call b( aa(1,1,i), nface, nlev )
write(*,*)aa(1,1,i)
end program main
> This is the usual style of passing arrays in f77 that I'm used to and works
> fine. By 'work' I mean the compiler generates no errors and the program runs
> satisfactorily.
>
> Now, if i change the call in subroutine a to :
> call b( aa(:,:,i), nface, nlev )
> there are no compilers errors but the program crashes after running for some
> time. As I understand it, this style of call must make the compile pass extra
> information about the bounds of array 'aa' to subroutine b. Presumably this
> leads to a gradual corruption of the stack??
If I do this to my little program, it works fine. In your big program,
it looks as if copying is taking place. There is no need for this since
aa(:,:,i) is contigous in the sense that its array elements in array-element
order are contiguous in the array-element order of aa. Beat up on your
vendor to add a run-time test that avoids this. I have been asking for
years and most vendors have now fixed things.
> In order to get the program working I assumed the difficulty was with the rank
> of the actual arguments, so I changed the declaration in subroutine b to:
> real, intent(inout) :: z(ni,nj,1)
>
> and the program works.
Of course, it does. The rank is not required to agree for an explicit-shape
array (though this is not a practice I recommend).
> I then tried declaring z(:,:,:) thinking this would also
> work but no, on running the program I get the runtime error message:
> COPY_IN: actual argument rank differs from dummy.
Of course, it does not. An assumed-shape array takes it shape from the
actual argument and the ranks are required to be the same.
I hope this helps,
John Reid.
|