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

Fortran standard question: Aliasing involving dummy arguments

198 views
Skip to first unread message

Tobias Burnus

unread,
Jul 21, 2010, 2:42:28 PM7/21/10
to
Hi all,

I have an alias question regarding argument association.

I think the relevant part of the standard is "12.5.2.13 Restrictions on
entities associated with dummy arguments" (Fortran 2008, FDIS); in
Fortran 2003 it is 12.4.1.7 and in Fortran 95 it is 12.4.1.6. However,
there might be other relevant parts, which I have missed.


My question is whether the following program is valid. I think with
"target :: arr" (variant 1) it is, but the question is: Is it valid without?


If it is not valid, I assume that a conforming compiler could optimize
away the if-condition with the stop (variant 2). As I think it would
seriously hamper the optimization by the compiler, I hope that the
program is invalid. But currently, I do not see why. One possibility,
which I have not fully thought about is that it becomes invalid as for
"call bar(arr)" the actual argument is not a target, but I currently do
how this will propagate to foobar to make the program invalid.

If the program is valid, I expect the output "1 1 2" - and the same for
variant 1. For variant 2 I expect that the program's execution ends with
the STOP statement.


Quote from the standard (F2008, FDIS):
---------------------------
"While an entity is associated with a dummy argument, the following
restrictions hold. [...]

(3) Action that affects the value of the entity or any subobject of it
shall be taken only through the dummy argument unless [...]
(b) the dummy argument has the TARGET attribute, the dummy argument does
not have INTENT(IN), the dummy argument is a scalar object or an
assumed-shape array without the CONTIGUOUS attribute, and the actual
argument is a target other than an array section with a vector subscript.

(4) If the value of the entity or any subobject of it is affected
through the dummy argument, then at any time during the invocation and
execution of the procedure, either before or after the definition, it
may be referenced only through that dummy argument unless
[same subitems as for (3)]
---------------------------


The program:

MODULE m
IMPLICIT NONE
INTEGER :: arr(3) ! no target
! Variant 1:
! TARGET :: arr
CONTAINS
SUBROUTINE foobar (arg)
INTEGER, TARGET :: arg(:)
! Variant 2:
! arr(1) = 5
! arg(1) = 6
! if (arr(1) /= 5) stop 'to alias or not to alias'
! End Variant 2
arr(2:3) = arg(1:2)
END SUBROUTINE foobar
END MODULE m

PROGRAM main
USE m
IMPLICIT NONE
arr = (/ 1, 2, 3 /)
CALL bar(arr)
PRINT *, arr
contains
subroutine bar(x)
INTEGER, TARGET :: x(3) ! Target
CALL foobar (x)
PRINT *, x
end subroutine bar
END PROGRAM main


Tobias

glen herrmannsfeldt

unread,
Jul 21, 2010, 3:07:13 PM7/21/10
to
Tobias Burnus <bur...@net-b.de> wrote:

> I have an alias question regarding argument association.

> I think the relevant part of the standard is "12.5.2.13 Restrictions on
> entities associated with dummy arguments" (Fortran 2008, FDIS); in
> Fortran 2003 it is 12.4.1.7 and in Fortran 95 it is 12.4.1.6. However,
> there might be other relevant parts, which I have missed.

> My question is whether the following program is valid. I think with
> "target :: arr" (variant 1) it is, but the question is: Is it valid without?
(big snip, including program code)

One of the reason for the aliasing rules is that Fortran allows for
either call by reference or call by value result (also known as
copy-in/copy-out), and aliasing can fail for that reason.

I believe that your program, even with the TARGET attribute,
fails in the case of call by value result. I am not so sure
that I can connect that to the rules that you posted, though.

-- glen

Tobias Burnus

unread,
Jul 21, 2010, 3:37:54 PM7/21/10
to
glen herrmannsfeldt wrote:

> Tobias Burnus <bur...@net-b.de> wrote:
>> My question is whether the following program is valid. I think with
>> "target :: arr" (variant 1) it is, but the question is: Is it valid without?
> (big snip, including program code)
>
> One of the reason for the aliasing rules is that Fortran allows for
> either call by reference or call by value result (also known as
> copy-in/copy-out), and aliasing can fail for that reason.

There is no copy-in/copy-out in this case - or at least: The
implementation works such that a pointer associated in the procedure
remains associated after one returns in the caller. Cf. "12.5.2.4
Ordinary dummy variables" in Fortran 2008.

Actually, that's the reason that only assumed-shape arrays are allowed
and the contiguous attribute is disallowed in Section 12.5.2.13. The
above mentioned Section 12.5.2.4 states in Paragraph 9:

"If the dummy argument has the TARGET attribute, does not have the VALUE
attribute, and either the effective argument is simply contiguous or the
dummy argument is a scalar or an assumed-shape array that does not have
the CONTIGUOUS attribute, and the effective argument has the TARGET
attribute but is not a coindexed object or an array section with a
vector subscript then
* any pointers associated with the effective argument become associated
with the corresponding dummy argument on invocation of the procedure, and
* when execution of the procedure completes, any pointers that do not
become undefined (16.5.2.5) and are associated with the dummy argument
remain associated with the effective argument."


> I believe that your program, even with the TARGET attribute,
> fails in the case of call by value result.

I disagree.

Tobias

Dick Hendrickson

unread,
Jul 21, 2010, 5:27:18 PM7/21/10
to
I don't remember any of the details, but in the (early?) 90s there was a
difficult interpretation (took several years to resolve) about targets
and arguments. The net result was that copy-in/copy-out was effectively
forbidden for at least some arguments with pointer and target
attributes. If you have access to the early interps, you might be able
to search for "copy" and see what you come up with. It might give you a
leg up on understanding some of the words about arguments. Sorry I
don't remember anything else!

Dick Hendrickson

Dick Hendrickson

unread,
Jul 21, 2010, 5:43:59 PM7/21/10
to
On 7/21/10 4:27 PM, Dick Hendrickson wrote:
[snip]

>>
>> Tobias
> I don't remember any of the details, but in the (early?) 90s there was a
> difficult interpretation (took several years to resolve) about targets
> and arguments. The net result was that copy-in/copy-out was effectively
> forbidden for at least some arguments with pointer and target
> attributes. If you have access to the early interps, you might be able
> to search for "copy" and see what you come up with. It might give you a
> leg up on understanding some of the words about arguments. Sorry I don't
> remember anything else!
>
> Dick Hendrickson
Found it, good old 125! I don't know if this is what you need, but I
think it's where the words you quoted come from.

Dick Hendrickson

NUMBER: 000125
TITLE: Copy in/copy out of target dummy arguments KEYWORDS: argument -
dummy, target, interface - explicit,
argument association
DEFECT TYPE: Erratum
STATUS: X3J3 approved; ready for WG5

QUESTION:Previous Fortran standards have permitted copy in/copy out as a
valid implementation for argument passing to procedures, as does Fortran 90.
Fortran 90 introduces POINTER and TARGET attributes. Sections 12.4.1.1 and
C.12.8 indicate that it was intended that copy in/copy out also be a valid
implementation for passing an actual argument that has the TARGET attribute
to a dummy argument that has the TARGET attribute. The following example
demonstrates a case where a copy in/copy out implementation may get
different
results from an implementation which does not use a copy in/copy out method
for such a combination of arguments.

POINTER IPTR
TARGET I
IPTR => I
CALL SUB (I, IPTR)
...
CONTAINS
SUBROUTINE SUB (J, JPTR)
POINTER JPTR
TARGET J
PRINT *, ASSOCIATED (JPTR, J)
END SUBROUTINE
END

Is this a flaw in the standard?

ANSWER:Yes, there is a flaw in the standard. The edits supplied disallow
copy
in/copy out as a valid implementation for passing an actual argument
that has
the TARGET attribute to a corresponding argument that has the TARGET
attribute, and is either scalar or is an assumed-shape array.

Discussion: The changes apply only to target dummy arguments. Without the
changes the behaviour of the example in the question would surprise many
programmers. Other examples not involving the ASSOCIATED function are also
affected by these changes in such a way that they too will have a more
expected
behaviour. One such example is included in the edit to section C.12.8.

An earlier answer to this defect included different wording for the
start of the
second paragraph of edit 3:

"If the dummy argument has the TARGET attribute and the corresponding
actual argument has the TARGET attribute but is not an array section with a
vector subscript:"

and did not include the paragraph:

"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.

(2) When execution of the procedure completes, the pointer
association status of any pointer that is pointer associated with the dummy
argument is processor dependent."

An earlier answer to this defect included different wording for the
first paragraph
of edit 4.

"When execution of a procedure completes, any pointer that remains
defined and that is associated with a dummy argument that has the TARGET
attribute, remains associated with the corresponding actual argument if the
actual argument has the TARGET attribute and is not an array section with a
vector subscript."

The earlier versions of edits 3 and 4, along with edits 1 and 2 were
included in
corrigendum 2.

EDITS:

1. Section 12.4.1.1, add at the end of the fourth paragraph [173:6],

"If the dummy argument has the TARGET attribute and the actual
argument has the TARGET attribute but is not an array section with a vector
subscript, the dummy and actual arguments must have the same shape."

2. Section 12.4.1.1, fifth paragraph, last sentence [173:10-13]
delete, "with a dummy argument of the procedure that has the TARGET
attribute or"

3. Section 12.4.1.1, delete the sixth paragraph [173:14-17] and
replace with,

"If the dummy argument does not have the TARGET or POINTER
attribute, any pointers associated with the actual argument do not become


associated with the corresponding dummy argument on invocation of the

procedure.

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

(1) Any pointers associated with the actual argument


become associated with the corresponding dummy argument on invocation of

the procedure.

(2) When execution of the procedure completes, any
pointers associated with the dummy argument remain associated with the
actual
argument.

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.

(2) When execution of the procedure completes, the pointer
association status of any pointer that is pointer associated with the dummy
argument is processor dependent.

If the dummy argument has the TARGET attribute and the corresponding actual
argument does not have the TARGET attribute or is an array section with a
vector subscript, any pointers associated with the dummy argument become
undefined when execution of the procedure completes."

4. Section C.12.8, delete the second paragraph through the end of
the section [292:5-37] and replace with

"When execution of a procedure completes, any pointer that remains
defined and that is associated with a dummy argument that has the TARGET
attribute and is either scalar or is an assumed-shape array, remains
associated
with the corresponding actual argument if the actual argument has the TARGET
attribute and is not an array section with a vector subscript.

REAL, POINTER :: PBEST
REAL, TARGET :: B (10000)
CALL BEST (PBEST, B) ! Upon return PBEST is associated
... ! with the "best" element of B
CONTAINS
SUBROUTINE BEST (P, A)
REAL, POINTER :: P
REAL, TARGET :: A (:)
... ! Find the "best" element A(I)
P => A (I)
RETURN
END SUBROUTINE
END

When the procedure BEST completes, the pointer PBEST is associated with an
element of B.

An actual argument without the TARGET attribute can become associated with a
dummy argument with the TARGET attribute. This permits pointers to become
associated with the dummy argument during execution of the procedure that
contains the dummy argument. For example:

INTEGER LARGE(100,100)
CALL SUB(LARGE)
...
CALL SUB()
CONTAINS
SUBROUTINE SUB(ARG)
INTEGER, TARGET, OPTIONAL :: ARG(100,100) INTEGER, POINTER,
DIMENSION(:,:) :: PARG IF (PRESENT(ARG)) THEN
PARG => ARG
ELSE
ALLOCATE (PARG(100,100))
PARG = 0
ENDIF
... ! Code with lots of references to PARG IF (.NOT. PRESENT(ARG))
DEALLOCATE(PARG) END SUBROUTINE SUB
END

Within subroutine SUB the pointer PARG is either associated with the dummy
argument ARG or it is associated with an allocated target. The bulk of
the code
can reference PARG without further calls to the PRESENT intrinsic."

Tobias Burnus

unread,
Jul 21, 2010, 6:02:35 PM7/21/10
to
Dick Hendrickson wrote:
> On 7/21/10 4:27 PM, Dick Hendrickson wrote:
>> I don't remember any of the details, but in the (early?) 90s there was a
>> difficult interpretation (took several years to resolve) about targets
>> and arguments. The net result was that copy-in/copy-out was effectively
>> forbidden for at least some arguments with pointer and target
>> attributes. [...]

> Found it, good old 125! I don't know if this is what you need, but I
> think it's where the words you quoted come from.

I also found it at
ftp://ftp.ncsa.uiuc.edu/sc22wg5/ftp.nag.co.uk/N1101-N1150/N1141.ps.gz
(on page 11). Thanks for digging.

However, I think it does not apply here. My issue is not whether copy
in/copy out happens; I think the standard is pretty clear that it does not.

My problem is whether a compiler can do optimizations such as turning

non_target_var = 5
target_dummy = 42
if (non_target_var == 5) then
call do_this
else
call do_that
end if

into

non_target_var = 5
target_dummy = 42
call do_this

So far I had the impression that such an optimization is allowed for
nontarget/nonpointer variables.

However, for the example I have created, it seems that the arguments are
allowed to alias, which makes this optimization very difficult. At the
moment I do not see any way out except of assuming that all variables
alias which servilely hampers optimizations. (The issue is that "actual
argument has target" is not enough if the effective argument is also
accessible by different means and without target attribute.)

Therefore, I hope that the example is invalid.

Tobias

glen herrmannsfeldt

unread,
Jul 21, 2010, 6:32:22 PM7/21/10
to
Tobias Burnus <bur...@net-b.de> wrote:

> I have an alias question regarding argument association.

> I think the relevant part of the standard is "12.5.2.13 Restrictions on
> entities associated with dummy arguments" (Fortran 2008, FDIS); in
> Fortran 2003 it is 12.4.1.7 and in Fortran 95 it is 12.4.1.6. However,
> there might be other relevant parts, which I have missed.
(snip)
(with arr and arg alias associated)

> arr(2:3) = arg(1:2)

In addition to the previous comments, note that Fortran requires
array assignment to behave as if the entire right side is evaluated
before the left side is changed. If the compiler can't be sure that
there is no aliasing, a temporary array will be required in this case.

Maybe that is part of the question you are asking, but I thought
it worth mentioning.

As far as I know, in the majority of array assignment cases the
compiler can determine that there is no aliasing and does the
assignment element by element. In many cases, pointers are an
indication to the compiler that legal aliasing might occur, and
the compiler should take that into account.

-- glen

Tobias Burnus

unread,
Jul 21, 2010, 6:56:06 PM7/21/10
to
glen herrmannsfeldt wrote:
> Tobias Burnus <bur...@net-b.de> wrote:
>> I have an alias question regarding argument association.
>
>> arr(2:3) = arg(1:2)
>
> In addition to the previous comments, note that Fortran requires
> array assignment to behave as if the entire right side is evaluated
> before the left side is changed. If the compiler can't be sure that
> there is no aliasing, a temporary array will be required in this case.

Exactly that's my problem: I think I have found a loop hole in the
standard, which makes it impossible to assume that a variable does not
alias - at least if in the procedure a dummy with the TARGET or POINTER
attribute exists (or is available via host association). [If one takes
the type into account, this reduces a bit, but still a huge number of
optimizations are no longer possible.]

At least I have still the feeling that the original program is valid and
none of the 7 compilers I have tried manages to give the correct result.
One does so, if one compiles everything in one file, but it also fails
(except with -O0) if one places the code in two files.

Tobias

glen herrmannsfeldt

unread,
Jul 21, 2010, 7:44:17 PM7/21/10
to
Tobias Burnus <bur...@net-b.de> wrote:
> glen herrmannsfeldt wrote:
>> Tobias Burnus <bur...@net-b.de> wrote:
>>> I have an alias question regarding argument association.

>>> arr(2:3) = arg(1:2)

>> In addition to the previous comments, note that Fortran requires
>> array assignment to behave as if the entire right side is evaluated
>> before the left side is changed. If the compiler can't be sure that
>> there is no aliasing, a temporary array will be required in this case.

> Exactly that's my problem: I think I have found a loop hole in the
> standard, which makes it impossible to assume that a variable does not
> alias - at least if in the procedure a dummy with the TARGET or POINTER
> attribute exists (or is available via host association). [If one takes
> the type into account, this reduces a bit, but still a huge number of
> optimizations are no longer possible.]

With pointers, there are likely many cases where the compiler
can't assume no aliasing. This is the complaint (mostly by
Fortran programmers) of C and C pointers.

The TARGET attribute is an indication to the compiler that there
might be pointers to that variable, and not to do some optimizations
that would otherwise be possible. I would say that it was a loophole
only if the compiler could, according to the standard, wrongly
assume no aliasing when, in fact, aliasing was allowed.

If you followed all the rules, (and I haven't verified that
you did), and the compiler gets it wrong, then it is a
compiler bug.

> At least I have still the feeling that the original program is valid and
> none of the 7 compilers I have tried manages to give the correct result.
> One does so, if one compiles everything in one file, but it also fails
> (except with -O0) if one places the code in two files.

-- glen

robert....@oracle.com

unread,
Jul 22, 2010, 1:03:01 AM7/22/10
to
On Jul 21, 12:07 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu>
wrote:

You are correct. None of the variants of the program presented are
standard conforming.

Bob Corbett

robert....@oracle.com

unread,
Jul 22, 2010, 1:25:38 AM7/22/10
to

None of the variants of the program presented are standard
conforming. The assignment at the end of the module
subroutine foobar violates the restriction described in
item (3). The restriction is violated during the
execution of the subroutine bar. The call of the
subroutine foobar results in an "action that affects
the value of the entity" associated with the dummy
argument x that is not "taken only through the dummy
argument." The dummy argument x is not a scalar and
is not an assumed-shape array.

Consider what happens if the call of bar in the main
program is replaced with

call bar(arr(3:1:-1)

and the call of foobar in bar is replaced with

call foobar(arr(3:1:-1))

Bob Corbett

robert....@oracle.com

unread,
Jul 22, 2010, 1:37:08 AM7/22/10
to

Oops. I should have written

call foobar(x(3:1:-1)

for the call of foobar.

Bob Corbett

0 new messages