From: Paul van Delst on
Hello,

I have a module function like so

ELEMENTAL FUNCTION Cloud_Add( cld1, cld2 ) RESULT( cldsum )
TYPE(Cloud_type), INTENT(IN) :: cld1, cld2
TYPE(Cloud_type) :: cldsum
....
END FUNCTION Cloud_Add

that is overloaded with OPERATOR(+),

INTERFACE OPERATOR(+)
MODULE PROCEDURE Cloud_Add
END INTERFACE OPERATOR(+)

The "cloud" structure itself is part of the "atmosphere" structure,

TYPE :: Atmosphere_type
....
TYPE(Cloud_type), ALLOCATABLE :: Cloud(:)
....
END TYPE Atmosphere_type

for which I also have an "add" function, which includes a call to the Cloud_Add() function
via the + operator:

ELEMENTAL FUNCTION Atmosphere_Add( atm1, atm2 ) RESULT( atmsum )
TYPE(Atmosphere_type), INTENT(IN) :: atm1, atm2
TYPE(Atmosphere_type) :: atmsum
....
atmsum = atm1
....
IF ( atm1%n_Clouds > 0 ) THEN
nc = atm1%n_Clouds
atmsum%Cloud(1:nc) = atmsum%Cloud(1:nc) + atm2%Cloud(1:nc)
END IF
....
END FUNCTION Atmosphere_Add

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.

Any insights appreciated.

cheers,

paulv
From: glen herrmannsfeldt on
Paul van Delst <paul.vandelst(a)noaa.gov> wrote:
(snip)

> ELEMENTAL FUNCTION Cloud_Add( cld1, cld2 ) RESULT( cldsum )
(snip)
> that is overloaded with OPERATOR(+),
(snip)

> IF ( atm1%n_Clouds > 0 ) THEN
> nc = atm1%n_Clouds
> atmsum%Cloud(1:nc) = atmsum%Cloud(1:nc) + atm2%Cloud(1:nc)
> END IF
(snip)
> 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.

What is the value of nc at that point? If it is nowhere near
the value it should have, then segfault is likely. If it is,
then I would wonder about compiler bugs.

I notice that nc comes from atm1, but atm2 is used in the sum.
I would print nc as a debugging aid until the problem was fixed.

-- glen
From: Paul van Delst on
glen herrmannsfeldt wrote:
> Paul van Delst <paul.vandelst(a)noaa.gov> wrote:
> (snip)
>
>> ELEMENTAL FUNCTION Cloud_Add( cld1, cld2 ) RESULT( cldsum )
> (snip)
>> that is overloaded with OPERATOR(+),
> (snip)
>
>> IF ( atm1%n_Clouds > 0 ) THEN
>> nc = atm1%n_Clouds
>> atmsum%Cloud(1:nc) = atmsum%Cloud(1:nc) + atm2%Cloud(1:nc)
>> END IF
> (snip)
>> 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.
>
> What is the value of nc at that point? If it is nowhere near
> the value it should have, then segfault is likely. If it is,
> then I would wonder about compiler bugs.
>
> I notice that nc comes from atm1, but atm2 is used in the sum.
> I would print nc as a debugging aid until the problem was fixed.

Well, I can't print it out since the function is elemental, but your point is well taken -
the array slice may be a red herring.

I will check the values in a debugger.

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.

Thanks,

paulv
From: Harald Anlauf on
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.
From: glen herrmannsfeldt on
Paul van Delst <paul.vandelst(a)noaa.gov> wrote:
(snip)

>>> IF ( atm1%n_Clouds > 0 ) THEN
>>> nc = atm1%n_Clouds
>>> atmsum%Cloud(1:nc) = atmsum%Cloud(1:nc) + atm2%Cloud(1:nc)
>>> END IF
(snip)

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

>> What is the value of nc at that point? If it is nowhere near
>> the value it should have, then segfault is likely. If it is,
>> then I would wonder about compiler bugs.

>> I notice that nc comes from atm1, but atm2 is used in the sum.
>> I would print nc as a debugging aid until the problem was fixed.

> Well, I can't print it out since the function is elemental,
> but your point is well taken - the array slice may be a red herring.

I had noticed that Cloud_Add was elemental, but I didn't notice
the other one. I hope they remove this restriction. It does
make some sense, but it makes debugging hard sometimes.

> I will check the values in a debugger.

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

Well, if it was caused by an uninitialized value, it could be
very different on a different system.

It wouldn't seem a bad idea to check atm2%n_clouds also.

if(atm1%n_clouds.ne.atm2%n_clouds) STOP 123

It would have been nice to allow a variable on the STOP statement.

This is back to the question asked some weeks ago about how much
checking one should do on function arguments.

Also, note that the array add not using slice notation depends
on the two arrays having the same size.

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

-- glen