Baffled by the impossible

37 views
Skip to first unread message

Ken

unread,
May 1, 2012, 2:00:06 AM5/1/12
to gg95
I have an F77 program that produces different numerical results
depending on the presence / absence of a single write statement that
prints a blank line. I've tried re-booting my computer (thinking that
something got corrupted) but that doesn't change anything. How could
this possibly be?

Sukhbinder Singh

unread,
May 1, 2012, 2:38:35 AM5/1/12
to gg...@googlegroups.com
I have faced similar problem. This isn't an issue with corruption of
memory.

When I investigated the issue, I found that the problem with array
size or the arguments passed to the subroutines.

Double check the arguments. And check if arrays are declared with
right dimension. This will solve your problem.


Why inserting a write statement or inserting a comment resolves this
prob, I am yet to find a definite answer.


Good luck.

Sent from my iPhone
> --
> You received this message because you are subscribed to the Google
> Groups "gg95" group.
> To post to this group, send email to gg...@googlegroups.com.
> To unsubscribe from this group, send email to gg95+uns...@googlegroups.com
> .
> For more options, visit this group at http://groups.google.com/group/gg95?hl=en
> .
>

Larry Baker

unread,
May 1, 2012, 1:49:26 PM5/1/12
to Ken, gg...@googlegroups.com
Ken,

This is usually a sign that you are accessing memory incorrectly or
that you are using an uninitialized variable. Try enabling run-time
array bounds checking. Also, check for uninitialized variables. I
think g95 only does this at compile time, though, and does not have a
run-time equivalent. Another common mistake is to rely on a value of
a variable across multiple calls to a procedure without declaring it
in a SAVE statement. Finally, check your argument lists to be sure
the actual arguments match the dummy arguments in number and type.

Larry Baker
US Geological Survey
650-329-5608
ba...@usgs.gov

Ken

unread,
May 2, 2012, 3:26:23 PM5/2/12
to gg95
Thanks for the pointers. I thought this would be easy considering I
have only 2 arrays, no subroutines, and about 50 lines of total code.
Wrong. I spent 2 hours last night and could find absolutely nothing
wrong. I use IMPLICIT NONE to ensure that all variables are
declared. I tried writing out the result of every calculation in the
program thinking I might spot something goofy, but no luck. Since the
write statements are present, the result is as expected. Would
converting the code to F90 accomplish anything? This is puzzling to
put it mildly.

Larry Baker

unread,
May 2, 2012, 3:54:42 PM5/2/12
to Ken, gg...@googlegroups.com
Ken,

I suggest you post your code.  50 lines is not very much.

Larry Baker
US Geological Survey
650-329-5608
ba...@usgs.gov


Ken

unread,
May 2, 2012, 6:19:12 PM5/2/12
to gg95
Thanks. Here it is. I'll likely be embarrased as to how easy the
problem is.


IMPLICIT NONE
INTEGER M, N, I, J, K
DOUBLE PRECISION ALPHA, BETA, TEMP, T, XNORM
DOUBLE PRECISION SM, Y, DA, ONE, ZERO
PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )
PARAMETER ( M=5, N=5 )
DOUBLE PRECISION A(M,N), TAU(N)
INTRINSIC SQRT

TAU = ZERO

A(1,1) = 0.0D0
A(2,1) = 408.0D0
A(3,1) = -25.0D0
A(4,1) = 703.0D0
A(5,1) = 237.0D0

A(1,2) = 9.0D0
A(2,2) = 320.0D0
A(3,2) = 556.0D0
A(4,2) = -155.0D0
A(5,2) = -74.0D0

A(1,3) = 296.0D0
A(2,3) = 480.0D0
A(3,3) = 106.0D0
A(4,3) = -431.0D0
A(5,3) = 0.0D0

A(1,4) = A(1,2)
A(2,4) = A(2,2)
A(3,4) = A(3,2)
A(4,4) = A(4,2)
A(5,4) = A(5,2)

A(1,5) = 190.0D0
A(2,5) = -194.0D0
A(3,5) = 229.0D0
A(4,5) = -389.0D0
A(5,5) = 357.0D0

WRITE (*, '(5F18.10)') ((A(I,J),J=1,N),I=1,M)
WRITE (*, *)

DO 70 J = 1, N-1
ALPHA = A(J,J)

SM = ZERO
DO 20 I = J+1, M
SM = SM + A(I,J)**2
20 CONTINUE

XNORM = SQRT(SM)

IF (XNORM.EQ.ZERO) THEN
TAU(J) = ZERO
ELSE
BETA = SQRT( ALPHA**2 + XNORM**2 )
IF (ALPHA.GE.ZERO) THEN
BETA = -BETA
END IF

TAU(J) = (BETA - ALPHA) / BETA
T = -TAU(J)
DA = ONE / (ALPHA - BETA)

DO 30 I = J+1, M
A(I,J) = A(I,J) * DA
30 CONTINUE

A(J,J) = ONE

DO 60 K = J+1, N
Y = ZERO
DO 40 I = J, M
Y = Y + A(I,J) * A(I,K)
40 CONTINUE

IF (Y.NE.ZERO) THEN
TEMP = T * Y

*---different result if write statement commented out ---
WRITE(*,*)
*--------------------------------------------------------

DO 50 I = J, M
A(I,K) = A(I,K) + A(I,J) * TEMP
50 CONTINUE
END IF
60 CONTINUE
A(J,J) = BETA
END IF
70 CONTINUE

WRITE (*, *)
WRITE (*, '(5F18.8)') ((A(I,J),J=1,N),I=1,M)
WRITE (*, *)
WRITE (*, '(5F18.8)') (TAU(J),J=1,N)

END

Larry Baker

unread,
May 2, 2012, 9:27:13 PM5/2/12
to Ken, gg...@googlegroups.com
Ken,

I don't have access to my system with g95 at the moment.  But, I ran your code through gfortran and ifort, both with and without the write.  I got the identical results every time.  I told both compilers to disable optimization (-O0) and I asked for run-time checking.  You might try different levels of optimization and see if that matters.  You could be seeing a bug in g95.  That is just speculation -- I have no way of confirming that until I can get to my system with g95.

Larry Baker
US Geological Survey
650-329-5608
ba...@usgs.gov


Arjan van Dijk

unread,
May 3, 2012, 4:30:15 AM5/3/12
to gg...@googlegroups.com
Hi!

Please don't use .EQ. for the comparison of real-valued parameters, let alone double precision! Instead, set a small tolarance value (one that makes sense!) and check the absolute value to be smaller than that:


REAL(Float), PARAMETER :: Epsilon = 1.E-10_Float

...

IF (ABS(Y).LT.Epsilon) THEN
...
ELSE
...
ENDIF


I guess that this makes the difference. I have had many situations where my code behaved like yours. Switching off the optimizer, re-compilation with a different compiler, preferably with lots of check-switches, generally pointed out coding errors or sloppiness at totally different parts in the code, leading to a solution of the unwanted behaviour. This is why I try to install as many Fortran-compilers as I can. Try to code defensively (with a sufficient set of checks in your code for all hypothetical situations that you THINK will not occur): when you re-use a piece of code that ran okay for 1000 times, it will fall into its own pit on the 1001-th occasion!

Happy coding!

Arjan

Ken

unread,
May 11, 2012, 3:42:18 PM5/11/12
to gg95
OK, turning off optimization seems to solve the problem, but I'm not
sure what that tells me. Re comparing floats to zero, I was thinking
the same thing, but I'm using LAPACK as a model and float compares to
zero appear are common in the routines I've seen.

Robert Funnell

unread,
May 11, 2012, 4:00:45 PM5/11/12
to gg95
On Fri, 11 May 2012, Ken wrote:

> OK, turning off optimization seems to solve the problem, but I'm not
> sure what that tells me. ...

Turning off optimization just shifts things around in memory and in
this case happens to hide the problem.

> ... Re comparing floats to zero, I was thinking
> the same thing, but I'm using LAPACK as a model and float compares to
> zero appear are common in the routines I've seen.

Comparing a float to zero may be useful for avoiding divide-by-zero
errors. Maybe there are other times it's OK, but in most cases it's
not a good idea. I don't know what cases it's being used for in
LAPACK.

Reply all
Reply to author
Forward
0 new messages