Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Bug in Fortran Visual Compiler

h_amini
Beginner
4,736 Views

Hi there

I think I found a bug in Visual Fortran Compiler 10.1.025. It is about a subroutine used to solve nonlinear equations with MFP approach (see below). The brief code is to apply equation Y = X^2 - 25 just for checking purpose.

The problem is that when I add two printing commands on lines 10 and 20, the code works perfectly, but when I omit them it does not! In fact, it can be checked by inputting 0.001, 100, 1 and 10 respectively to get X= 5.

Could someone let me know if it is a bug or I made a mistake? I compiled the subroutine with another compiler and it worked even after omitting the two printing commands.

Many thanks

Hamid

1 READ*, ERS, IMAX, EPSDPER, EPSDMAX

EPSL = EPSDPER; EPSU = EPSDMAX

CALL MFP(EPSL, EPSU, EPSD, ERS, ERA, ITER, IMAX)

GO TO 1

END

FUNCTION F(X)

F = X**2-25

RETURN

END

SUBROUTINE MFP(EPSL, EPSU, EPSD, ERS, ERA, ITER, IMAX)

ITER = 0

FL = F(EPSL)

FU = F(EPSU)

10 PRINT*, 'FL=', FL, 'FU=', FU

DO

EPSDOLD = EPSD

EPSD = EPSU - FU * (EPSL - EPSU) / (FL - FU)

20 PRINT*, 'EPSL=', EPSL, 'EPSU=', EPSU

FR = F(EPSD)

ITER = ITER + 1

C print*, 'iter=', iter

C100 PRINT*, 'EPSD=', EPSD

IF (EPSD.NE.0) ERA = ABS((EPSD - EPSDOLD) / EPSD) * 100

PRINT*, 'ERA=', ERA

TEST = FL * FR

IF (TEST.LT.0) THEN

EPSU = EPSD

FU = F(EPSU)

IU = 0

IL = IL + 1

IF (IL.GE.2) FL = FL / 2

ELSE IF (TEST.GT.0) THEN

EPSL = EPSD

FL = F(EPSL)

IL = 0

IU = IU + 1

IF (IU.GE.2) FU = FU / 2

ELSE

ERA = 0

END IF

print*, 'ERA=', ERA

IF (ERA.LT.ERS .OR. ITER.GT.IMAX) EXIT

END DO

AMFP1 = EPSD

PRINT*, 'X=', AMFP1

RETURN

END

0 Kudos
1 Solution
ender01
New Contributor I
4,717 Views
Quoting - h.amini

Hi Rich

Appreciated very much for your kind consideration of the problem.

The posted program gives the same wrong answer (X= 3.181818) after commenting the printing statements. However, as you annotated EPSDOLD is not initialized (Jim also mentioned the same about EPSD - thank you Jim). So, when I initialize EPSD or EPSDOLD to zero, the program works perfectly even if the floating point numbers are not double precision.

Interestingly, when I do not initialize them to zero and print them, they are zero! But sometimes the program does not work correctly depending on the printing statements. For example, in the following code, when lines 31, 32 and 33 are stated, the result is right:

.001

100

1

10

epsd 0.0000000E+00

epsd 0.0000000E+00

epsd 0.0000000E+00

epsd 3.181818

epsd 4.310345

epsd 5.142132

epsd 4.989630

epsd 4.999855

epsd 5.000141

X= 5.000000

but, when just one of the printing lines is commented, the result is wrong:

.001

100

1

10

epsd 0.0000000E+00

epsd 0.0000000E+00

X= 3.181818

If you could forward it to the developers, it may be interesting for them. The compiler I am using is: Intel Visual Fortran Compiler Professional for applications running on IA-32, Version 11.0 Build 20080930 Package ID: w_cprof_p_11.0.061.

FUNCTION F(X)

F = X**2-25

RETURN

END

SUBROUTINE MFP(EPSL, EPSU, EPSD, ERS, ERA, ITER, IMAX)

ITER = 0; IL = 0; IU = 0; !EPSD = 0

31 print*, 'epsd',epsd

FL = F(EPSL)

FU = F(EPSU)

32 print*, 'epsd',epsd

DO

33 print*, 'epsd',epsd

EPSDOLD = EPSD

EPSD = EPSU - FU * (EPSL - EPSU) / (FL - FU)

FR = F(EPSD)

ITER = ITER + 1

IF (EPSD.NE.0) ERA = ABS((EPSD - EPSDOLD) / EPSD) * 100

TEST = FL * FR

IF (TEST.LT.0) THEN

EPSU = EPSD

FU = F(EPSU)

IU = 0

IL = IL + 1

IF (IL.GE.2) FL = FL / 2

ELSE IF (TEST.GT.0) THEN

EPSL = EPSD

FL = F(EPSL)

IL = 0

IU = IU + 1

IF (IU.GE.2) FU = FU / 2

ELSE

ERA = 0

END IF

IF (ERA.LT.ERS .OR. ITER.GT.IMAX) EXIT

END DO

AMFP1 = EPSD

PRINT*, 'X=', AMFP1

RETURN

END

1 READ*, ERS, IMAX, EPSDPER, EPSDMAX

EPSL = EPSDPER; EPSU = EPSDMAX

CALL MFP(EPSL, EPSU, EPSD, ERS, ERA, ITER, IMAX)

GO TO 1

END

Many thanks

Hamid

Hi Hamid,

It looks like EPSD is not being updated as it's supposed to be (2 lines after the line numbered 33). If it's staying at zero (the default value) this means that your convergence condition is not going to be properly evaluated:

[cpp]IF(EPSD.NE.0) THEN

     ERA = ABS((EPSD - EPSDOLD) / EPSD) * 100

END IF
[/cpp]

ERA is not evaluated and so stays at its default (uninitialized value) of 0 (which is less than ERS). Which would kick you out after the first pass with the current value of EPSD. But we know that the first evaluation is 3.18181...

It looks like a compiler bug. Can you run the debugger and track EPSD? Does this happen when you run the debugger (different compiler options - less optimization)?

Rich

View solution in original post

0 Kudos
29 Replies
h_amini
Beginner
851 Views
Quoting - ender01

Hi Hamid,

It looks like EPSD is not being updated as it's supposed to be (2 lines after the line numbered 33). If it's staying at zero (the default value) this means that your convergence condition is not going to be properly evaluated:

IF(EPSD.NE.0) THEN ERA = ABS((EPSD - EPSDOLD) / EPSD) * 100 END IF


ERA is not evaluated and so stays at its default (uninitialized value) of 0 (which is less than ERS). Which would kick you out after the first pass with the current value of EPSD. But we know that the first evaluation is 3.18181...

It looks like a compiler bug. Can you run the debugger and track EPSD? Does this happen when you run the debugger (different compiler options - less optimization)?

Rich

Many thanks Rich

You are right. It seems there is a bug in the compiling optimization. In fact, when I disable optimizations with /debug:full the problem is solved. Also, when optimization level o1 is applied the program works perfectly. However, applying optimization level o2 or o3 causes the problem.

Hamid

0 Kudos
Jugoslav_Dujic
Valued Contributor II
851 Views

ERA is not evaluated and so stays at its default (uninitialized value) of 0 (which is less than ERS).

NO! NO! THOUSAND TIMES NO!

Please, get rid of the misconception that the "default, uninitialized value" is zero. It started this whole long thread and misunderstanding. It is NOT zero. It is a (semi-)RANDOM value. When it happens to be zero (or small enough), you get the "right" results, and otherwise you get the "wrong" results. But it's NOT, again, compiler's duty to make sure it is initialized to zero, unless you explicitly say so.

Sorry for yelling, but this is a very important concept to grasp, and you'll encounter many problems if you fail to adopt it.

0 Kudos
ender01
New Contributor I
851 Views
Quoting - Jugoslav Dujic

NO! NO! THOUSAND TIMES NO!

Please, get rid of the misconception that the "default, uninitialized value" is zero. It started this whole long thread and misunderstanding. It is NOT zero. It is a (semi-)RANDOM value. When it happens to be zero (or small enough), you get the "right" results, and otherwise you get the "wrong" results. But it's NOT, again, compiler's duty to make sure it is initialized to zero, unless you explicitly say so.

Sorry for yelling, but this is a very important concept to grasp, and you'll encounter many problems if you fail to adopt it.

While there is no Fortran standard for this, most compilers do handle this with a default (most even document it). Yell all you want, but what's important to realize is not that there is not a "default, uninitialized zero" but that compilers handle the condition differently and if you want any portability, you'd best not ignore it. If you'll read the posts above, you'll find that Hamid noted that his compiler was initializing the variable to zero. I can assure you that that was not an accident but was the result of an optimizing compiler setting a default value to an uninitialized variable.

0 Kudos
jugoslavdujic2
Beginner
851 Views
Quoting - ender01

I can assure you that that was not an accident but was the result of an optimizing compiler setting a default value to an uninitialized variable.

No. "Optimizing compiler" does not apply any defaults to uninitialized variables -- it is an accident. In my experience, the values are often reproducible (i.e. not entirely random -- that's why I referred to it as "semi-random" above), but generally different depending on optimization level and, worse still, depend whether it is run under debugger or not. You cannot -- and shouldn't -- make any assumption about those values.

The worst kind of bugs ("heisenbugs") appear only when run outside the debugger, or even only on customer's computer, and are commonly assigned to uninitialized variables.

0 Kudos
ender01
New Contributor I
851 Views
Quoting - jugoslavdujic2

No. "Optimizing compiler" does not apply any defaults to uninitialized variables -- it is an accident. In my experience, the values are often reproducible (i.e. not entirely random -- that's why I referred to it as "semi-random" above), but generally different depending on optimization level and, worse still, depend whether it is run under debugger or not. You cannot -- and shouldn't -- make any assumption about those values.

The worst kind of bugs ("heisenbugs") appear only when run outside the debugger, or even only on customer's computer, and are commonly assigned to uninitialized variables.

Again, different compilers do different things. Pounding your fist on the table saying it ain't so won't change that. I've worked with a lot of different Fortran compilers (of widely differing quality) on a lot of different systems (of widely differing quaiity) and I have seen compiler switch options that enable and disable the option to control a default assignment to an unitialized variable. It was even occasionally made explicit in the documentation that this was a non-standard Fortran setting. That being said, yes, some compilers don't provide any such reproducible default.

In any case, default or not, I would never suggest that it's acceptable practice to rely upon a default nor did I in any of my posts. In fact my advice was quite the opposite, start looking at the variables and how they're defined. I think that we're in violent agreement on that point. The fact that Hamid explicitly commented on the "repeatable" initialization of the variable to zero was the basis of my comment (and I'll bet it was right too).

In closing, don't come "yelling" like this about anything. Frankly, not knowing anything about you, I don't particularly have any reason to trust your "experience" and you sure haven't given me any.

0 Kudos
Jugoslav_Dujic
Valued Contributor II
851 Views
Quoting - ender01

Again, different compilers do different things. Pounding your fist on the table saying it ain't so won't change that. I've worked with a lot of different Fortran compilers (of widely differing quality) on a lot of different systems (of widely differing quaiity) and I have seen compiler switch options that enable and disable the option to control a default assignment to an unitialized variable. It was even occasionally made explicit in the documentation that this was a non-standard Fortran setting. That being said, yes, some compilers don't provide any such reproducible default.

In any case, default or not, I would never suggest that it's acceptable practice to rely upon a default nor did I in any of my posts. In fact my advice was quite the opposite, start looking at the variables and how they're defined. I think that we're in violent agreement on that point. The fact that Hamid explicitly commented on the "repeatable" initialization of the variable to zero was the basis of my comment (and I'll bet it was right too).

In closing, don't come "yelling" like this about anything. Frankly, not knowing anything about you, I don't particularly have any reason to trust your "experience" and you sure haven't given me any.

Well, we probably are in "violent agreement" as you said; let's bury the hachets.

I am aware I was harsh in my first post, but it was my knee-jerk reaction to sentence which read, quote again, "ERA is not evaluated and so stays at its default (uninitialized value) of 0". Maybe I'm guilty of jumping to conclusion of what you actually meant, but my reading was (and I think that you can see how it can easily be misread) that this means that ERA is automagically initialized to 0.

Yes, many compilers through the history did initialize to zero, and most still have an option to do so (/Qsave /Qzero for ifort). Many (l)users even relied on it. But it has never been part of the Standard, and there are certainly many bugs lurking around waiting to rear its ugly head in many "trusted" codes.

0 Kudos
ender01
New Contributor I
851 Views
Quoting - Jugoslav Dujic

Well, we probably are in "violent agreement" as you said; let's bury the hachets.

I am aware I was harsh in my first post, but it was my knee-jerk reaction to sentence which read, quote again, "ERA is not evaluated and so stays at its default (uninitialized value) of 0". Maybe I'm guilty of jumping to conclusion of what you actually meant, but my reading was (and I think that you can see how it can easily be misread) that this means that ERA is automagically initialized to 0.

Yes, many compilers through the history did initialize to zero, and most still have an option to do so (/Qsave /Qzero for ifort). Many (l)users even relied on it. But it has never been part of the Standard, and there are certainly many bugs lurking around waiting to rear its ugly head in many "trusted" codes.

Great, thank you. No harm, no foul. I can see your point, but I think the context here is important. I was trying to be more pendagogical and lead Hamid to paying more attention to how variable are defined and used, and, ultimately to understanding what the ramifications are. It is a lot less important to know what value was assigned than to understand what can happen if you don't define variables properly. The specific mechanism through which a value is assigned is beside the point. Perhaps I should have been more precise but I felt it would be more productive to illustrate the the fact that you can't rely on a consistent automatic assignment (you'll note that I pointed out that my program did not initialize thet variable to zero) than to discuss the details of compiler design. I'll also note that I know of no commercial Fortran compiler (I'm not claiming an exhaustive study here) that does not specifically address undefined variables as part of its design. Though it may not be discussed in the documentation provided (and may explicitly warn against using an uninitialized variable in a computatoin), I've never seen an uninitialized variable merely given the contents of the address referenced by the variable (and if you've ever had an array subscript go out of bounds, you know what those numbers can look like). And you're absolutely right about the "trusted code" though I'd add that that set of code includes operating systems, IDEs, and even compilers.

0 Kudos
ender01
New Contributor I
851 Views
Quoting - Jugoslav Dujic

Well, we probably are in "violent agreement" as you said; let's bury the hachets.

I am aware I was harsh in my first post, but it was my knee-jerk reaction to sentence which read, quote again, "ERA is not evaluated and so stays at its default (uninitialized value) of 0". Maybe I'm guilty of jumping to conclusion of what you actually meant, but my reading was (and I think that you can see how it can easily be misread) that this means that ERA is automagically initialized to 0.

Yes, many compilers through the history did initialize to zero, and most still have an option to do so (/Qsave /Qzero for ifort). Many (l)users even relied on it. But it has never been part of the Standard, and there are certainly many bugs lurking around waiting to rear its ugly head in many "trusted" codes.

Great, thank you. No harm, no foul. I can see your point, but I think the context here is important. I was trying to be more pendagogical and lead Hamid to paying more attention to how variable are defined and used, and, ultimately to understanding what the ramifications are. It is a lot less important to know what value was assigned than to understand what can happen if you don't define variables properly. The specific mechanism through which a value is assigned is beside the point. Perhaps I should have been more precise but I felt it would be more productive to illustrate the the fact that you can't rely on a consistent automatic assignment (you'll note that I pointed out that my program did not initialize thet variable to zero) than to discuss the details of compiler design. I'll also note that I know of no commercial Fortran compiler (I'm not claiming an exhaustive study here) that does not specifically address undefined variables as part of its design. Though it may not be discussed in the documentation provided (and may explicitly warn against using an uninitialized variable in a computatoin), I've never seen an uninitialized variable merely given the contents of the address referenced by the variable (and if you've ever had an array subscript go out of bounds, you know what those numbers can look like). And you're absolutely right about the "trusted code" though I'd add that that set of code includes operating systems, IDEs, and even compilers.

0 Kudos
anthonyrichards
New Contributor III
851 Views
Quoting - ender01

Great, thank you. No harm, no foul. I can see your point, but I think the context here is important. I was trying to be more pendagogical and lead Hamid to paying more attention to how variable are defined and used, and, ultimately to understanding what the ramifications are. It is a lot less important to know what value was assigned than to understand what can happen if you don't define variables properly. The specific mechanism through which a value is assigned is beside the point. Perhaps I should have been more precise but I felt it would be more productive to illustrate the the fact that you can't rely on a consistent automatic assignment (you'll note that I pointed out that my program did not initialize thet variable to zero) than to discuss the details of compiler design. I'll also note that I know of no commercial Fortran compiler (I'm not claiming an exhaustive study here) that does not specifically address undefined variables as part of its design. Though it may not be discussed in the documentation provided (and may explicitly warn against using an uninitialized variable in a computatoin), I've never seen an uninitialized variable merely given the contents of the address referenced by the variable (and if you've ever had an array subscript go out of bounds, you know what those numbers can look like). And you're absolutely right about the "trusted code" though I'd add that that set of code includes operating systems, IDEs, and even compilers.

0 Kudos
Reply