Copy-in/Copy-out

From: Larry Young (cartrip_at_swbell.net)
Date: 02/24/04


Date: Tue, 24 Feb 2004 14:46:45 GMT

I'm trying to understand Fortran's Copy-in/Copy-out of arrays, so I
wrote the small program below. I don't have a current copy of the
standard or Adams, et. al, but I do have Metcalf and Reid. I've read
5.7.3 many times. As I understand it, the calls to SubTarget without
the vector index are the only ones guaranteed not to create a copy.
This seems like a huge black hole. What is particularly disconcerting
are all the calls to SubNormal that generate a copy even when the
array is stored in contiguous memory, e.g. pointer or assumed shape
actual argument. Most programmers would think that if an argument is
declared as a target or pointer, it should be safe to assign a pointer
to it. Of course, there's a big problem when the copy goes away. Also,
this means that if I run a million node simulation that requires 100
million words of allocated pointers, I'll need twice that amount of
memory.

These results are with Lahey Fortran using the nonstandard pointer
intrinsic function.
Larry Young

! --------------------------------------------------------------------
PROGRAM Code13
   ! Interfaces -------------------------------------
   Interface
   Subroutine SubNormal(str,p,A,n) ! same w/ or /wo interface
      include 'defines.fi'
      Character, Intent(in) :: str*(*)
      integer, Intent(in) :: p,n
      Real, Intent(in) :: A(n) ! same with target
      End Subroutine SubNormal
   End Interface
   Interface
      Subroutine SubTarget(str,p,A) ! assumed shape, target
         include 'defines.fi'
         Character, Intent(in) :: str*(*)
         integer, Intent(in) :: p
         Real, Intent(in), Target :: A(:) ! same without target
      End Subroutine SubTarget
   End Interface
   Interface
      Subroutine SubPointer(str,p,A) ! assumed shape, pointer
         include 'defines.fi'
         Character, Intent(in) :: str*(*)
         integer, Intent(in) :: p
         Real, Pointer :: A(:)
      End Subroutine SubPointer
   End Interface
   ! ------------------------------------------------
   integer, parameter :: n=4
   integer :: i,index(n),pa,pb,pc,pd,pe
   Real :: A(n),C(2*n)
   Real, Target :: B(n),D(2*n)
   Real, Pointer :: Bp(:)=>Null(),Dp(:)= >Null()
   Real, Pointer :: Ep(:)=>Null()
   !Real, Allocatable :: Ep(:)
   index = (/3,1,4,2/)
   A = (/(2*i,i=1,n)/)
   B = (/(2*i-1,i=1,n)/)
   C = (/(-2*i,i=1,2*n)/)
   D = C + 1.0
   Bp => B
   Dp => D
   Allocate(Ep(n))
   Ep = (/(-2*i+1,i=1,n)/)
   pa = pointer(A)
   pb = pointer(B)
   pc = pointer(C)
   pd = pointer(D)
   pe = pointer(Ep)
   Print *," A:",pointer(A),A
   Print *," B:",pointer(B),B
   Print *,"Bp:",pointer(Bp),Bp
   Print *," C:",pointer(C),C(1:n)
   Print *," D:",pointer(D),D(1:n)
   Print *,"Dp:",pointer(Dp),Dp(1:n)
   Print *,"Ep:",pointer(Ep),Ep(1:n)
   ! Calls to SubNormal --------------------------
   print *,'SubNormal:'
   Call SubNormal("A(neither): ",pa,A,n) ! not copied
   Call SubNormal("B(target): ",pb,B,n) ! not copied
   Call SubNormal("Bp(pointer):",pb,Bp,n) ! copied
   Call SubNormal("Ep(pointer):",pe,Ep,n) ! copied
   Call SubNormal("A(index): ",pa,A(index),n) ! copied
   Call SubNormal("C(1:n): ",pc,C(1:n),n) ! not copied
   Call SubNormal("C(1:2*n:2): ",pc,C(1:2*n:2),n) ! copied
   Call SubNormal("D(1:2*n:2): ",pd,D(1:2*n:2),n) ! copied
   Call SubNormal("Dp(1:2*n:2):",pd,Dp(1:2*n:2),n) ! copied
   ! Calls to SubTarget --------------------------
   print *,'SubTarget:'
   Call SubTarget("A(neither): ",pa,A) ! not copied
   Call SubTarget("B(target): ",pb,B) ! not copied
   Call SubTarget("Bp(pointer):",pb,Bp) ! not copied
   Call SubTarget("Ep(pointer):",pe,Ep) ! not copied
   Call SubTarget("A(index): ",pa,A(index)) ! copied
   Call SubTarget("C(1:n): ",pc,C(1:n)) ! not copied
   Call SubTarget("C(1:2*n:2): ",pc,C(1:2*n:2)) ! not copied
   Call SubTarget("D(1:2*n:2): ",pd,D(1:2*n:2)) ! not copied
   Call SubTarget("Dp(1:2*n:2):",pd,Dp(1:2*n:2)) ! not copied
   ! Calls to SubPointer -------------------------
   print *,'SubPointer:'
   !Call SubPointer("A(neither): ",pa,A) ! not valid
   !Call SubPointer("B(target): ",pb,B) ! not valid
   Call SubPointer("Bp(pointer):",pb,Bp) ! not copied
   Call SubPointer("Ep(pointer):",pe,Ep) ! not copied
   !Call SubPointer("A(index): ",pa,A(index)) ! not valid
   !Call SubPointer("C(1:n): ",pc,C(1:n)) ! not valid
   !Call SubPointer("C(1:2*n:2): ",pc,C(1:2*n:2)) ! not valid
   !Call SubPointer("D(1:2*n:2): ",pd,D(1:2*n:2)) ! not valid
   !Call SubPointer("Dp(1:2*n:2):",pd,Dp(1:2*n:2)) ! not valid
   Deallocate(Ep)
END PROGRAM Code13
Subroutine SubNormal(str,p,A,n)
   Character, Intent(in) :: str*(*)
   integer, Intent(in) :: p,n
   Real, Intent(in) :: A(n,1)
   print *,"SubNormal:",str,p == pointer(A),pointer(A),A
End Subroutine SubNormal
Subroutine SubTarget(str,p,A)
   Character, Intent(in) :: str*(*)
   integer, Intent(in) :: p
   integer :: n
   Real, Intent(in), Target :: A(:)
   n = Size(A)
   print *,"SubTarget:",str,p == pointer(A),pointer(A),A
   Call SubNormal(str,pointer(A),A,n) ! copies always
End Subroutine SubTarget
Subroutine SubPointer(str,p,A)
   Character, Intent(in) :: str*(*)
   integer, Intent(in) :: p
   integer :: n
   Real, Pointer :: A(:)
   n = Size(A)
   print *,"SubPointer:",str,p == pointer(A),pointer(A),A
End Subroutine SubPointer



Relevant Pages

  • Re: Copy-in/Copy-out
    ... -|declared as a target or pointer, it should be safe to assign a pointer ... -| Character, Intent:: str* ... -| End Interface ... -| Subroutine SubTarget! ...
    (comp.lang.fortran)
  • Re: Copy-in/Copy-out
    ... Compiling program unit SubNormal at line 90: ... procedure definition and A in interface body shall be the same. ... -|> declared as a target or pointer, it should be safe to assign a pointer ... -| Subroutine SubTarget! ...
    (comp.lang.fortran)
  • Re: Kind of new to cray pointers
    ... a generic interface block (it can't be the name of a generic ... I can change what the generic name does by pointing the pointer at ... recursive subroutine qsort ... typetemp ...
    (comp.lang.fortran)
  • Re: Copy-in/Copy-out
    ... "Larry Young" wrote in message ... > declared as a target or pointer, it should be safe to assign a pointer ... End Interface ... End Subroutine SubNormal ...
    (comp.lang.fortran)
  • Re: Assumed shape array help
    ... Modules also essentially force the compiler to do compile time checks for argument agreement. ... The subprogram interface has always been Fortran's weak spot for hard to find user errors. ... When this option is selected, the compiler creates a module file containing the interface for each subroutine and function, and then it looks for the generated module when it sees a call to a subroutine or function. ... arrays, ...
    (comp.lang.fortran)