Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

efficiency of explicit vs. assumed shape arrays

638 views
Skip to first unread message

Lonnie Hamm

unread,
Jul 12, 2000, 3:00:00 AM7/12/00
to
When passing an array to a subroutine, are there any standard assumptions
that can be made about how the array is passed. Is the address of the first
element in the array passed or is the array copied in and out, maybe using
temporary arrays. I suppose this may vary depending upon compiler and
whether the array is assumed or explicit shaped.

Tim Prince

unread,
Jul 12, 2000, 3:00:00 AM7/12/00
to
You are correct, many, perhaps the majority, of f77 compilers, passed
the address of the first element of an array, the scheme used by f2c,
g77, et al. Copy in /copy out always has been a possibility used by
some compilers, and explicit interfaces permit additional possibilities.
Certain combinations of f90 syntax without explicit interfaces (not
recommended) may force a copy in/copy out.

--
Tim Prince
"Lonnie Hamm" <ha...@okstate.edu> wrote in message
news:8kit44$84...@news.cis.okstate.edu...

Richard Maine

unread,
Jul 13, 2000, 3:00:00 AM7/13/00
to
"Lonnie Hamm" <ha...@okstate.edu> writes:

> When passing an array to a subroutine, are there any standard assumptions
> that can be made about how the array is passed. Is the address of the first
> element in the array passed or is the array copied in and out, maybe using
> temporary arrays. I suppose this may vary depending upon compiler and
> whether the array is assumed or explicit shaped.

Tim Prince gave what I think to be a pretty good answer here.
Basically, yes, it may vary depending on several things. There are
some things that are common to most compilers, but these kinds of
things are not specified by the standard and do vary. It is not
safe to count on them.

One thing I'll add that Tim didn't say. Any program that can tell the
difference is not standard-conforming.....well, unless the program can
tell the difference by noticing the performance or something of that
sort. Performance can be majorly affected, and for this reason, you may
want to be aware of what to expect in certain situations. You code might
not care in terms of getting correct answers, but it might care a lot
in terms of getting decent performance.

The situation where you are most likely to encounter copy-in/copy-out
is when a non-contiguous actual argument (i.e. an array slice) is
passed to a dummy argument that is not assumed shape. For assumed shape
dummies, an explicit interface is needed, and this typically includes
(behind your back) the stride information necessary to properly access
the elements of the slice. If the dummy is not assumed shape, then
the subroutine might not, in general, be able to deal with non-contiguous
arrays (indeed, it might have been compiled with an f77 compiler - some
of the funny criteria in this area are to make sure that it is possible
to call f77-compiled subroutines with an f90-compiled main). In this case,
the calling routine is likely to make a contiguous copy.

You also occasionally run into this even when the actual argument is
contiguous, if that contiguity was not trivially obvious at compile
time. For example, if you are passing a pointer, which *could*
point to an array slice, even though it never actually does. There is
an obvious run-time optimization to make here. Many compilers do the
optimization, but some don't.

These are just some fairly common cases. There are some others, and they
do vary from one compiler to another.

--
Richard Maine
ma...@altair.dfrc.nasa.gov

Richard Maine

unread,
Jul 13, 2000, 3:00:00 AM7/13/00
to

James Van Buskirk

unread,
Jul 13, 2000, 3:00:00 AM7/13/00
to

Richard Maine wrote in message ...

>One thing I'll add that Tim didn't say. Any program that can tell the
>difference is not standard-conforming.....well, unless the program can
>tell the difference by noticing the performance or something of that
>sort.

I'm not so sure about that. Consider:

! CopyTest3.f90 -- attempts to check for copy-in/copy-out
module test3
implicit none
contains
subroutine test1(x, y)
integer, target :: x(:)
integer, target :: y(size(x))
integer, pointer :: a, b

a => x(size(x))
b => y(1)
if(associated(a, b)) then
write(*,'(a)') 'No copies through test 1.'
else
write(*,'(a)') 'Copies made by test 1.'
end if
call test2(x, y, size(x))
end subroutine test1

subroutine test2(x, y, n)
integer, intent(in) :: n
integer, target :: x(n)
integer, target :: y(n)
integer, pointer :: a, b

a => x(n)
b => y(1)
if(associated(a, b)) then
write(*,'(a)') 'No copies through test 2.'
else
write(*,'(a)') 'Copies made by test 2.'
end if
end subroutine test2
end module test3

program copytest3
use test3
implicit none
integer, target :: test(19)

call test1(test(1:10), test(10:19))
end program copytest3

Output with CVF 6.1A:

No copies through test 1.
Copies made by test 2.

Seems to be a detectable difference. Where did this code fail
to conform?

Richard Maine

unread,
Jul 14, 2000, 3:00:00 AM7/14/00
to
"James Van Buskirk" <tor...@ix.netcom.com> writes:

> Richard Maine wrote in message ...
>
> >One thing I'll add that Tim didn't say. Any program that can tell the
> >difference is not standard-conforming.....well, unless the program can
> >tell the difference by noticing the performance or something of that
> >sort.
>
> I'm not so sure about that. Consider:

...[elided]


> Seems to be a detectable difference. Where did this code fail
> to conform?

1. Association is a concept defined by the language. Copy-in/copy-out is
an implementation mechanism for certain features. The two are *NOT*
necessarily tied quite as tightly as you seem to assume. It is possible,
for example, for a processor to do a copy-in, but keep track of the fact
that the copy is associated with the original. (Seems like a complicated
thing to do, but its possible). Your test would fail to notice that
distinction.

So by testing association, you are not strictly testing whether or
not a copy occured. Perhaps a bit pedantic here, as in practice I
don't think any compilers are quite as strange as the standard allows
here. But some for distributed environments just might be. I'm not
really an expert in those kinds of environments, but in principle you
can get cases where multiple data copies on different processors
are associated in some sense.

2. You are depending on a feature specified by the standard to be
processor-dependent. Section 12.4.1.1 of f95

"If the dummy argument has the TARGET attribute and is an explicit-shape
array or is an assumed-size array, and the corresponding actual argument
has the TARGET attribute but is not an array section with a vector
subscript

(1) On invocation of the procedure, whether any pointers associated
with the actual argument become associated with the corresponding
dummy argument is processor-dependent ..."

If one studies this enough (and if it doesn't damage your brain first),
you can conclude that its in essense saying that it is processor
dependent whether or not copy-in/copy-out occurs in this case, but
it says it just in terms of association just in case association
does something "strange" (see point 1 for picky distinctions).

3. I abhor that particular part of the standard (the infamous interp 125).
Its all but impossible to remember all the complicated conditions.
I'd have preferred a far simpler set of rules that one could actually
remember. This would have made the rules more conservative, in that
they would disallow some particular cases that ought to be workable.
But I lost out to the crowd that wanted to precisely specify the
exact cases that turn out to be naturally implementable with maximum
performance; this makes the specification pretty messy. My personal
rule is much simpler - don't do anything particularly close to that
and you won't have to worry about all the quirks.

I assure you that *I* didn't remember all the conditions mentioned in
the above quote (much less all the other combinations of conditions
mentioned in the surrounding text). In fact, my first reaction was
that it was likely a compiler bug and that the TARGET attribute
should have essentially forced the compiler to not do the copy
(it just wouldn't surprise me to find compilers that didn't get all
these complicated conditions right). But on about my 3rd careful
reading, I concluded that this case falls into the above particular
conditions where its stated to be processor-dependent.

--
Richard Maine
ma...@altair.dfrc.nasa.gov

0 new messages