Prev: How to control/prevent cast between from complex to realvariables
Next: Variable scope: how fortran deals with undeclared variables in subroutines?
From: Paul van Delst on 16 Feb 2010 16:48 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 16 Feb 2010 17:01 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 16 Feb 2010 17:14 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 16 Feb 2010 17:20 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 16 Feb 2010 17:37
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 |