From: pizorn on
Does anybody know whether 'reshape' is always a copy function or is
this compiler-specific.
let's consider the following example:

program PROG
real, dimension(:,:,:,:),allocatable :: A
integer ::D
D=...
allocate( A(D,D,D,D))
A(:,:,:,:) = ...
call PROCA(reshape( A, (/D**2, D**2/)))
contains
subroutine PROCA(A)
real, dimension(:,:) :: A ! dimension(D**2, D**2)
! ...
end subroutine PROCA
end program

so the question is: will reshape allocate an array and copy the
contents of A(:,:,:,:) to Acopy(:,:) and then call PROCA or simply
call PROCA with the same A, just pretending it has a different shape?

I read that this is compiler specific (sometimes the compiler doesn't
really allocate a new array but indeed uses the old one). What is the
general rule?
From: Richard Maine on
pizorn <pizorn(a)gmail.com> wrote:

> Does anybody know whether 'reshape' is always a copy function or is
> this compiler-specific.
....
> I read that this is compiler specific (sometimes the compiler doesn't
> really allocate a new array but indeed uses the old one). What is the
> general rule?

The general rule is that the standard doesn't talk about such things as
whether a copy is made. That is considered an implementation strategy.
As long as the compiler makes things work as the standard specifies,
then it is free to copy or not. Thus yes, it is compiler specific.

That being said, the simplest implementation strategy is to make a copy.
That will always work. The standard's description is consistent with
such implementation. Note that RESHAPE is not special in this regard. It
is just a function; the standard doesn't have some special description
of it as being different from other functions. On the other hand,
because RESHAPE is an intrinsic function, the compiler can plausibly
know enough about it to optimize away the copy is some cases. It is an
optimization, though.

Also, note that there are cases just using the old array will give
incorrect results because of aliasing that results. An optimizer for
using the old array has to be smart enough to recognize those cases.

If you are concerned about performance, the safest thing to do is to
assume that a copy will be made. That might not be so in all situations
for all compilers, but it is "safe" in the sense of helping you avoid
potential performance hits.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: pizorn on
Thank you for your quick reply, this is exactly what I needed to know.

On May 19, 10:45 am, nos...(a)see.signature (Richard Maine) wrote:
> pizorn <piz...(a)gmail.com> wrote:
> > Does anybody know whether 'reshape' is always a copy function or is
> > this compiler-specific.
> ...
> > I read that this is compiler specific (sometimes the compiler doesn't
> > really allocate a new array but indeed uses the old one). What is the
> > general rule?
>
> The general rule is that the standard doesn't talk about such things as
> whether a copy is made. That is considered an implementation strategy.
> As long as the compiler makes things work as the standard specifies,
> then it is free to copy or not. Thus yes, it is compiler specific.
>
> That being said, the simplest implementation strategy is to make a copy.
> That will always work. The standard's description is consistent with
> such implementation. Note that RESHAPE is not special in this regard. It
> is just a function; the standard doesn't have some special description
> of it as being different from other functions. On the other hand,
> because RESHAPE is an intrinsic function, the compiler can plausibly
> know enough about it to optimize away the copy is some cases. It is an
> optimization, though.
>
> Also, note that there are cases just using the old array will give
> incorrect results because of aliasing that results. An optimizer for
> using the old array has to be smart enough to recognize those cases.
>
> If you are concerned about performance, the safest thing to do is to
> assume that a copy will be made. That might not be so in all situations
> for all compilers, but it is "safe" in the sense of helping you avoid
> potential performance hits.
>
> --
> Richard Maine                    | Good judgment comes from experience;
> email: last name at domain . net | experience comes from bad judgment.
> domain: summertriangle           |  -- Mark Twain

From: glen herrmannsfeldt on
pizorn <pizorn(a)gmail.com> wrote:
> Does anybody know whether 'reshape' is always a copy function or is
> this compiler-specific.
> let's consider the following example:

> program PROG
> real, dimension(:,:,:,:),allocatable :: A
> integer ::D
> D=...
> allocate( A(D,D,D,D))
> A(:,:,:,:) = ...
> call PROCA(reshape( A, (/D**2, D**2/)))
> contains
> subroutine PROCA(A)
> real, dimension(:,:) :: A ! dimension(D**2, D**2)
> ! ...
> end subroutine PROCA
> end program

> so the question is: will reshape allocate an array and copy the
> contents of A(:,:,:,:) to Acopy(:,:) and then call PROCA or simply
> call PROCA with the same A, just pretending it has a different shape?

Unless the compiler can determine that PROCA doesn't change the
array, I would think it would have to make a copy. As an internal
subroutine, it might be able to determine that, or if the argument
was INTENT(IN).

> I read that this is compiler specific (sometimes the compiler doesn't
> really allocate a new array but indeed uses the old one). What is the
> general rule?

If used as an argument to an intrinsic function that is known not
to modify its arguments, users are going to expect the performance
of no copy. As an argument to SUM, for example.

-- glen
From: Ron Shepard on
In article
<6a998024-d8a2-4c08-9487-370d81bc3f09(a)q33g2000vbt.googlegroups.com>,
pizorn <pizorn(a)gmail.com> wrote:

> Does anybody know whether 'reshape' is always a copy function or is
> this compiler-specific.
> let's consider the following example:
>
> program PROG
> real, dimension(:,:,:,:),allocatable :: A
> integer ::D
> D=...
> allocate( A(D,D,D,D))
> A(:,:,:,:) = ...
> call PROCA(reshape( A, (/D**2, D**2/)))
> contains
> subroutine PROCA(A)
> real, dimension(:,:) :: A ! dimension(D**2, D**2)
> ! ...
> end subroutine PROCA
> end program
>
> so the question is: will reshape allocate an array and copy the
> contents of A(:,:,:,:) to Acopy(:,:) and then call PROCA or simply
> call PROCA with the same A, just pretending it has a different shape?

The RESHAPE() and the TRANSPOSE() intrinsics are similar in this
respect. In some cases, such as the above, the compiler might
determine that the storage sequence of the individual elements for
the two declarations are the same and avoid the copy operations
(going in and/or returning from the subprogram). However, this
depends on such things as optimization level, so you cannot depend
on the behavior. As others have pointed out, the behavior might
also depend on the INTENT of the dummy argument.

For example, if A(:,:,:,:) were a dummy argument rather than a local
array, then the compiler could not know that the first D**2 elements
all have the same spacing, so a copy would almost certainly have to
be made by the reshape. For programmers who were adept as using
storage sequence association in their f77 codes, this was (and is)
an important restriction in using array syntax and deferred shape
declarations in the newer versions of the language.

> I read that this is compiler specific (sometimes the compiler doesn't
> really allocate a new array but indeed uses the old one). What is the
> general rule?

You can tell what is happening in any specific case by using the
nonstandard, but common, LOC() function. Or c_loc() with compilers
that support the c interop stuff in f2003. Check the address of one
of the array elements of the actual and the dummy arguments that are
associated through the call. If they are the same, then your
compiler managed to avoid a copy (that time). If the addresses are
different, then a copy was made.

One of the new features of f2008 (which I don't use yet, so I may
get some details wrong) is that you can assign pointers of higher
rank to 1-D arrays. The 1-D array will always have a fixed spacing
between the elements, allowing storage association magic to work
again. This would allow you, for example, to allocate the array as
A(D**4), and assign A2(:,:) or A4(:,:,:,:) pointers to that array.
Those pointers could then be used in the PROCA() call in the usual
way, avoiding the array copies in many cases. The downside, of
course, is that using the pointer arrays and the target attributes
suppresses many of the optimizations that are allowed otherwise, so
the programmer must be aware of the tradeoffs if efficiency is
important. In the worst case, your fortran program could end up
being as slow as a C program, and we wouldn't want that, right? :-)

$.02 -Ron Shepard