[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::fortran

Title:Digital Fortran
Notice:Read notes 1.* for important information
Moderator:QUARK::LIONEL
Created:Thu Jun 01 1995
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:1333
Total number of notes:6734

1197.0. "atan2 and optimization" by RHETT::HALETKY () Tue Feb 25 1997 15:16

    
    Hello,
    
    We have a cusotmer who claims that atan2 in fortran is not working as
    the F77 standard dictates. He claims it should return 0 if the args
    passed are 0,0.
    
    atan2 in the C library reports that it would cause a FPE and the return
    value is not gauranteed.
    
    We also notice that the FPE does not show up is the optimization level
    is changed from 1 to 4 or 5.
    
    Any information would be appreciated.
    
    Best regards,
    Ed Haletky
    Digital CSC
T.RTitleUserPersonal
Name
DateLines
1197.1The standard passesTLE::EKLUNDAlways smiling on the inside!Tue Feb 25 1997 15:3126
    	You would do well when customers make such statements
    to ask for the page in the standard where this is stated...
    The f77 standard (page 15-29) states: "The arguments must
    not both have the value zero."  f90 makes a similar
    statement in section 13.13.15: "If Y has the value zero, X
    must not have the value zero."
    
    	I would take these statements to mean:
    
    	1. The user is cautioned to NOT allow the arguments to
    both be zero.
    
    	2. Neither standard prescribes a behavior when both
    are zero.
    
    	3. The implementor may do whatever they wish when
    this happens.
    
    	4. This behavior may vary with compiler switches and/or
    optimization levels and/or different releases of the compiler.
    
    	It's not good to depend upon undefined behavior!
    	
    Cheers!
    Dave Eklund
    
1197.2libm ATAN2(0.,0.) returns NaNTLE::WHITLOCKStan WhitlockWed Feb 26 1997 15:2516
ATAN2 (0.,0.) returns a NaN, regardless of whether its args are known at
compile-time or run-time and at all optimization levels.  So

	READ (5,*) X,Y
	WRITE (6,*) X,Y,ATAN2 (X,Y)

when X and Y are read in as 0 returns a NaN, as does

	WRITE (6,*) ATAN2 (0.0,0.0)

This is true at all -O levels.  The NaN causes program termination at -fpe0 and
is printed at -fpe1 and higher.

So what does the customer expect?  And why?

/Stan
1197.3atan2 and zero returnRHETT::HALETKYThu Feb 27 1997 15:4113
    The cusotmer expects it to return 0.
    
    However I would expect the output and errors to be the same
    irregardless of optimization level. One (-01) gives a FPE. -O5 does not
    give this error.
    
    
    WHat can we do to help the cusotmer instead of quoting standards? I'm
    sure they'll find it interesting and then promptly ignore it as it
    doesn't match their perceived notions.
    
    -ed haletky
    Digital CSC
1197.4I'm not riding on their airplanes...TLE::EKLUNDAlways smiling on the inside!Thu Feb 27 1997 17:2761
    	How about if we consider a similar situation where a
    customer wanted SQRT(X) te be treated like SQRT(ABS(X)).
    The customer argues that the error message is not
    "constructive", and we should just take the absolute
    value before doing the SQRT.  Well, this is an interesting
    notion, but it will never happen in the "real" SQRT function
    (unless the Fortran Standard committee decides this is a
    good thing...).
    
    	The best suggestion is to tell the customer to write
    their own function, something like:
    
    	FUNCTION SQRT_PRIVATE (X)
    	 SQRT_PRIVATE = SQRT(ABS(X))
    	END
    
    Customers are always free to write their own versions
    of mathematical routines.  In general, we are NOT going
    to change ours without VERY good reason.
    
    	Incidently, you might also suggest that there is a good
    reason why atan2(0.,0.) was left undefined.  The committee could
    not reach consensus any other way.
    
    	Furthermore, I would suggest that if the customer's
    program ends up trying to evaluate atan2(0.,0.), there is
    an astonishingly good chance that one (or both) of the
    zero values resulted from an underflow condition.  This
    really means that the algorithm may be seriously flawed
    (not conditioned properly).  In fact I would bet that
    a serious look at WHY the program ends up with this
    situation will reveal a fundamental error in the
    algorithm being used.  The kindest result may be an
    error message.  At worst, the user needs to add code
    to prevent the attempt to evaluate atan2(0.,0.), and
    do whatever needs to be done to "recover" cleanly.
    
    	Even better is to do the analysis to figure out
    how the algorithm can be made more robust much earlier.
    I can assure you that most programs getting to this point
    are already in trouble, and while zero or NaN (or pi/2) may
    be good values in SOME cases, they will cause more
    serious problems in later stages of the computation.
    For example, you may see a subsequent divide by the
    zero (or NaN), and begin to propagate exceptional
    values throughout the application.
    
    	The bottom line is that the user has not thought
    through the consequences of us making such a change.
    While one application MAY benefit, others may suffer
    (a lot).  I'd suggest a review of just how the customer
    found themselves in this particular trouble, before
    being able to offer constructive suggestions.  Trying
    to blunder forwards after assigning some interesting
    value to atan2(0.,0.) is just going to lead to more
    problems (IMHO).
    
    Cheers!
    Dave Eklund
    
    
1197.5timescales...GIDDAY::GILLINGSa crucible of informative mistakesThu Feb 27 1997 18:2319
    
    Just to add to Dave's response. Please point out to the customer
    that even if Fortran Engineering decided to implement the requested
    change and did so tomorrow, the customer would not see the change
    until the next version of their operating system (since it's an RTL
    change). Certainly it may be released as a patch, but patching is not
    necessarily a good path to take, especially if there are customers
    further down the food chain. Even if they want to go for a patch, the
    time scale is likely to me order months before an *official* patch
    containing the fix becomes available.
    
    Therefore, if the customer wants an immediate fix, they will have to
    implement some kind of workaround themselves. In your customer's
    case it's quite trivial to write a jacket for the routine which does
    precisely what they want, regardless of what Fortran decides to do.
    
    (I've just explained this to my customer who has a "real" problem with
    the INQUIRE statement).
    						John Gillings, Sydney CSC
1197.6'they do' compilers _&_ RTLsCOMEUP::SIMMONDSSee The Amazing Shrinking DIGITAThu Feb 27 1997 19:078
.2>    change and did so tomorrow, the customer would not see the change
.2>    until the next version of their operating system (since it's an RTL
    
    Yeah-but.. the current (Alpha) Fortran products depend on new RTL kits,
    so a change _could_ conceivably become visible sooner than 'the next OS
    version'..
    
    John.
1197.7QUARK::LIONELFree advice is worth every centThu Feb 27 1997 21:236
    No - we are not making this change.  We have influence over the Fortran
    RTLs, but to change the long-established behavior of a math RTL routine
    would require more justification than "a customer would prefer it this
    way".
    
    				Steve
1197.8a failing example would helpTLE::WHITLOCKStan WhitlockFri Feb 28 1997 08:3228
I have a very expensive looking laminated card on my wall with the Digital
burgundy logo that says our mission is to "deliver... solutions... on high-
performance platforms...".

So if the user wants ATAN2 (0.,0.) to be 0., he can either use

	if (X .eq. 0.) .and. (y .eq. 0.) then
	    Z = 0.
	else
	    Z = atan2 (x, y)
	endif

or he can use

	Z = atan2 (X, Y)
	if isnan (Z) Z = 0

That gets him the answer he wants.  Now you also said

>>    However I would expect the output and errors to be the same
>>    irregardless of optimization level. One (-01) gives a FPE. -O5 does not
>>    give this error.
    
This is not the behavior I saw with the little examples I quoted in .2 so I'd
like to see the examples of when the result of ATAN2 is different at different
-O levels.

/Stan
1197.9Atan2 not the questionRHETT::HALETKYMon Mar 03 1997 14:5233
    
    
    My concern is not that atan2 is incorrect. My concern is that different
    levels of Optimization report different floating point problems with
    the same code. I'll explain to the customer what the standard says but
    with level O4 and O5 compilation no FPE occurs. This is quite odd:
    
    sh -x o
    + f77 t.f -O1 -o t 
    + ./t 
    forrtl: error (65): floating invalid
    o: 669 Abort - core dumped
    + f77 t.f -O2 -o t 
    + ./t 
    forrtl: error (65): floating invalid
    o: 674 Abort - core dumped
    + f77 t.f -O3 -o t 
    + ./t 
    forrtl: error (65): floating invalid
    o: 679 Abort - core dumped
    + f77 t.f -O4 -o t 
    + ./t 
    + f77 t.f -O5 -o t 
    + ./t 
    
    
    The above is the compilation I ran with DFA410 and OSF v4.0b. Note the
    same results do NOT occur. This is my concern. Whether or not an
    undefined function like atan2 returns 0 or not according to the
    standard is not an issue.
    
    Edward L. Haletky
    Digital CSC
1197.10show us the source pleaseTLE::WHITLOCKStan WhitlockMon Mar 03 1997 15:186
RE: .9

Could you please show us what t.f is?  It is possible that at -O4, the optimizer
discarded the ATAN2 call so you don't see the fpe.

/Stan
1197.11Source codeRHETT::HALETKYTue Mar 04 1997 09:2832
    
    Here is t.f:
    
    c
    c     compile with
    c       f77 -o bug bug.f -O2
    c
    c     program coredumps with -O2 or -O3 optimizations, but NOT with
    other
    c     optimizations (even though they may perform -O3 ?!?!)
    c
          program BUG
          implicit none
    
          double precision x,y,phi
    
          x=0.d0
          y=0.d0
          call atn(x,y,phi)
          stop
          end
    
          subroutine atn(x,y,phi)
          implicit none
          double precision x,y,phi
    
          phi=atan2(y,x)
    
    
          return
          end
    
1197.12QUARK::LIONELFree advice is worth every centTue Mar 04 1997 09:565
-O4 and above do inline expansion of subroutines, allowing the compiler to
determine that the value of the atan2 call is never used.  Try adding
a WRITE of phi after the call to atn.

					Steve