From: Richard Maine on
Paul van Delst <paul.vandelst(a)noaa.gov> wrote:
[code elided]

> When invoked, the line
>
> atmsum%Cloud(1:nc) = atmsum%Cloud(1:nc) + atm2%Cloud(1:nc)
>
> causes a segfault. When I change it to the more usual
>
> atmsum%Cloud = atmsum%Cloud + atm2%Cloud
>
> everything is fine. No segfault and results are correct.
>
> Obviously my use of array slices when the function result is also one of
> the arguments is causing a problem. Regular clf readers will know that
> treating an array slice like an array will one day BYITA - today appears
> to be my turn.
>
> First off, is the array-slice version legal? If it is, can anyone put
> forward a possible explanation as to what the mechanism of that error
> might be. E.g. something is being copied and the order one of the
> operations is important and/or...? I just want to provide some sort of
> cogent explanation of the problem to others so they don't do what I did.

I don't see anything obviously wrong with either version. Being a style
that I don't normally personally use doesn't count as wrong. The nature
of the problem is not obvious to me.

But I do want to correct one things that is an error - not in the code,
but in your description of it. The function result is *NOT* one of the
arguments to the function - not even close. You are making what is a
very common mistake. Let me simplify to a trivial function invocation,
without any array issues or operator overloads. Consider

y = f(x)

The y here is *NOT* the function result. That's not the way assignment
works. Conceptually, the y=f(x) is done in two steps. (One can break it
down further, but these two are the relevant ones here).

1. Evaluate f(x). In doing that, you don't look at any other context. It
isn't relevant that it is in an assignment statement at all, much less
what is on the left-hand side of the assignment. Just evaluate f(x) as
it stands. Store the result in some unnamed temporary place if needed.

2. Then do the assignment. Take the value computed in step 1 and assign
it to y.

Compilers are quite likely to optimize away the temporary in some cases,
combining the two steps into one. But you still need to start with this
2-step model as the basic concept and consider anything else to be just
an optimization.

When you are making extensive use of things like defined operations, it
is particularly important to keep the two-step model in mind. The
assignment part might well not be trivial. In particular, it could be a
defined assignment in some cases. If you have a defined assignment, the
compiler is less likely to be able to optimize things to get rid of it
as a separate step.

You could possibly be running into bugs in the compiler's attempt to
optimize things here. The fact that the variable on the left-hand side
of the assignment is also used on the right-hand side might preclude
such optimization unless the compiler is particularly smart about how to
manage such things. That probably means you have a temporary variable
with an allocatable component that needs to get appropriately allocated
and deallocated behind your back. That's all supposed to work, but it is
at least fertile ground for comipler bugs. (Of course, it is also
fertile ground for user errors to interact badly with non-obvious but
correct compiler behavior).

No, I don't know why it would be different when you use array slices.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: Richard Maine on
glen herrmannsfeldt <gah(a)ugcs.caltech.edu> wrote:

> (I presume STOP is allowed in elemental functions, but maybe not.)

Not.

F2003:

C1276 A pure subprogram shall not contain a stop-stmt.

--
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
Richard Maine <nospam(a)see.signature> wrote:
> glen herrmannsfeldt <gah(a)ugcs.caltech.edu> wrote:

>> (I presume STOP is allowed in elemental functions, but maybe not.)

> Not.

> F2003:

> C1276 A pure subprogram shall not contain a stop-stmt.

What are you supposed to use STOP for? In subroutines and functions
it is usually a last resort when everything is wrong and you just
want to get out of there. (I believe some systems have kernel panic
when there is nothing else to do.)

It seems to me that whoever wrote the specs for ELEMENTAL never
worked on real code.

Oh well.

-- glen
From: Paul van Delst on


Harald Anlauf wrote:
> On Feb 16, 11:14 pm, Paul van Delst <paul.vande...(a)noaa.gov> wrote:
>
>> BTW, the problem only appears to occur on an IBM system using xlf95. On a linux system
>> (RHE 5.0, gfortran 4.4) everything looks to be o.k.
>
> Which xlf version? Some older versions had problems with allocatable
> derived type components, but recent versions of xlf2003 (e.g. v12.1)
> have improved a lot.

$ xlf2003 -qversion
IBM XL Fortran for AIX, V12.1
Version: 12.01.0000.0001

:o(

I redid all the tests using the xlf2003 invocation rather than xlf95 (grasping at straws
here), but got the same problem.

cheers,

paulv

From: Paul van Delst on
Richard Maine wrote:
> Paul van Delst <paul.vandelst(a)noaa.gov> wrote:
> [code elided]
>
>> When invoked, the line
>>
>> atmsum%Cloud(1:nc) = atmsum%Cloud(1:nc) + atm2%Cloud(1:nc)
>>
>> causes a segfault. When I change it to the more usual
>>
>> atmsum%Cloud = atmsum%Cloud + atm2%Cloud
>>
>> everything is fine. No segfault and results are correct.
>>
>> Obviously my use of array slices when the function result is also one of
>> the arguments is causing a problem. Regular clf readers will know that
>> treating an array slice like an array will one day BYITA - today appears
>> to be my turn.
>>
>> First off, is the array-slice version legal? If it is, can anyone put
>> forward a possible explanation as to what the mechanism of that error
>> might be. E.g. something is being copied and the order one of the
>> operations is important and/or...? I just want to provide some sort of
>> cogent explanation of the problem to others so they don't do what I did.
>
> I don't see anything obviously wrong with either version. Being a style
> that I don't normally personally use doesn't count as wrong. The nature
> of the problem is not obvious to me.
>
> But I do want to correct one things that is an error - not in the code,
> but in your description of it. The function result is *NOT* one of the
> arguments to the function - not even close. You are making what is a
> very common mistake. Let me simplify to a trivial function invocation,
> without any array issues or operator overloads. Consider

Thanks, Richard. You're right - my thinking about it was wrong. It's one of those
incorrect beliefs one acquires early on and, well, just seems to stick. :o(

> When you are making extensive use of things like defined operations, it
> is particularly important to keep the two-step model in mind. The
> assignment part might well not be trivial. In particular, it could be a
> defined assignment in some cases. If you have a defined assignment, the
> compiler is less likely to be able to optimize things to get rid of it
> as a separate step.

No, I've moved away from defined assignments every since I discovered (I believe through
one of your replies to a post of mine on that particular subject) that the "intrinsic"
assignment handles all the allocations.

> You could possibly be running into bugs in the compiler's attempt to
> optimize things here. The fact that the variable on the left-hand side
> of the assignment is also used on the right-hand side might preclude
> such optimization unless the compiler is particularly smart about how to
> manage such things. That probably means you have a temporary variable
> with an allocatable component that needs to get appropriately allocated
> and deallocated behind your back. That's all supposed to work, but it is
> at least fertile ground for comipler bugs. (Of course, it is also
> fertile ground for user errors to interact badly with non-obvious but
> correct compiler behavior).

Even though I'm a firm believer in the 99/100 rule-of-thumb[*] regarding compiler errors
(mostly through personal experience), I think this might be one. I just cannot get the
code to break on my linux system. Bummer, :o(

Thanks & cheers,

paulv

[*] Whenever a programmer "discovers" a compiler bug, 99 times out of 100 it's their own
code that's buggy.