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

Possible Bug with Intel Fortran

prop_design
New Contributor I
758 Views

Hi,

 

I noticed something odd with Intel Fortran. If you have a loop like

 

DO 10 B = 1, 9

 

10 CONTINUE

 

and you write B after the loop ends, you get a number that is 1 higher than what it should be. So in this case, if you do something like

 

WRITE (*,*) B

 

Instead of 9 you get 10 written to screen. This seems like a bug to me.

 

Thanks,

 

Anthony

0 Kudos
1 Solution
Barbara_P_Intel
Moderator
730 Views

Not a bug. I found the answer in Modern Fortran Explained.  I also asked one of the developers on the Intel Fortran team who understands the Fortran specification for details. Ready for his reply?

 

11.1.7.4 Execution of a DO construct

11.1.7.4.1 Loop Initiation

. . . the following steps are performed in sequence . . .

                (2) The DO variable becomes defined with the initial parameter m1

                (3) The iteration count is established and is the value of the expression (m2-m1+m3)/m3, unless that value is negative,

                       In which case the iteration count is zero.

So, for the example in the post, B gets the value 1.  The iteration count is established to be (9-1+1)/1 = 9.

 

11.1.7.4.3 The execution cycle

The execution cycle of a DO construct that is not a DO CONCURRENT construct consist of the following steps performed

In sequence repeatedly until termination.

  1. The iteration count, if any, is tested.  If it is zero, the loop terminates and the DO construct becomes inactive. . . .
  2. The block of the loop is executed.
  3. The iteration count, if any is decremented by one.  The DO variable, if any, is incremented by the incrementation parameter m3.

 

11.1.7.4.5 Loop termination

For a DO construct that is not a DO CONCURRENT construct, the loop terminates, and the DO construct becomes inactive,

when any of the following occurs.

  • The iteration count is determined to be zero or the scalar-logical-expr is false, when tested during step (1)

of the above execution cycle.

  • . . .

So, let’s apply these rules.  We have established the trip count is 9, and the value of B is 1 by the rules of loop initiation. The following shows the value of B and the value of the trip count as each iteration of the execution cycle applies

                B             Trip count

                1                   9

                2                   8

                3                   7

                4                   6

                5                   5

                6                   4

                7                   3

                8                   2

                9                   1

                10                0

 

So, when the value of the iteration count is zero and the loop terminates, the value of the DO variable B is 10, not 9. 

View solution in original post

9 Replies
Barbara_P_Intel
Moderator
731 Views

Not a bug. I found the answer in Modern Fortran Explained.  I also asked one of the developers on the Intel Fortran team who understands the Fortran specification for details. Ready for his reply?

 

11.1.7.4 Execution of a DO construct

11.1.7.4.1 Loop Initiation

. . . the following steps are performed in sequence . . .

                (2) The DO variable becomes defined with the initial parameter m1

                (3) The iteration count is established and is the value of the expression (m2-m1+m3)/m3, unless that value is negative,

                       In which case the iteration count is zero.

So, for the example in the post, B gets the value 1.  The iteration count is established to be (9-1+1)/1 = 9.

 

11.1.7.4.3 The execution cycle

The execution cycle of a DO construct that is not a DO CONCURRENT construct consist of the following steps performed

In sequence repeatedly until termination.

  1. The iteration count, if any, is tested.  If it is zero, the loop terminates and the DO construct becomes inactive. . . .
  2. The block of the loop is executed.
  3. The iteration count, if any is decremented by one.  The DO variable, if any, is incremented by the incrementation parameter m3.

 

11.1.7.4.5 Loop termination

For a DO construct that is not a DO CONCURRENT construct, the loop terminates, and the DO construct becomes inactive,

when any of the following occurs.

  • The iteration count is determined to be zero or the scalar-logical-expr is false, when tested during step (1)

of the above execution cycle.

  • . . .

So, let’s apply these rules.  We have established the trip count is 9, and the value of B is 1 by the rules of loop initiation. The following shows the value of B and the value of the trip count as each iteration of the execution cycle applies

                B             Trip count

                1                   9

                2                   8

                3                   7

                4                   6

                5                   5

                6                   4

                7                   3

                8                   2

                9                   1

                10                0

 

So, when the value of the iteration count is zero and the loop terminates, the value of the DO variable B is 10, not 9. 

prop_design
New Contributor I
722 Views

hi barbara,

 

thanks for looking into this and the detailed explanation.

 

anthony

0 Kudos
jimdempseyatthecove
Honored Contributor III
660 Views

Barbara,

You might suggest your documentation team be more explicit in the DO documentation

RE: After termination, the DO variable retains its last value (the one it had when the iteration count was tested and found to be zero).

 

That statement can be ambiguous as to what the "last value" means. IOW

a) is it the last value used in the loop?

b) is it the last value set (inc/dec by step) prior to testing the decremented count?

 

While the shown examples illustrates: control variable is incremented, loop count decremented, loop count tested for 0 and exit loop when 0. Note, someone may stop reading the Description upon seeing "last value".

 

Jim Dempsey

0 Kudos
prop_design
New Contributor I
654 Views

hi jim,

 

i didn't see the documentation for this. so it wouldn't have helped me, regardless of what it might say. i was just assuming that if you specify a range it would keep that range and not go past it. i learned Fortran 77 so long ago that I don't really remember what the specification is. from what Barbara says, this behavior is how the specification is defined. that's unfortunate. luckily, this didn't cause me any problems though.

0 Kudos
Steve_Lionel
Honored Contributor III
711 Views

There are, in fact, some codes that rely on this behavior.

0 Kudos
prop_design
New Contributor I
708 Views

hi steve,

 

i just happened to notice this by accident. fortunately, i never use the loop index for anything. i needed to print out the index for debugging and was surprised to see it go past what i specified. to me it seems like a bug. however, based on the responses, i see that it is following the standard and others use it this way. interestingly, if you only write the index within the loop, it reports as expected (1 to 9). it is only when you write it after the loop that it goes one past what it should (in my opinion at least).

0 Kudos
Steve_Lionel
Honored Contributor III
653 Views

Could be worse - in some languages, the loop variable is undefined on exit from the loop. What's important to note is that Fortran effectively does the loop test at the beginning of the loop, not the end. Even though Jim is correct that the standard defines things in terms of iteration counts, the behavior is as if the increment is done before the test.

0 Kudos
prop_design
New Contributor I
650 Views

hi steve,

 

yeah, that is kind of what i was thinking about it. it seems like there is more calculations than need to be. even though, these days, computing power would mask it. but seems odd to count past something for no apparent reason. if you always go to some number, why count one past it. seems like wasted compute power. but ultimately, a trivial amount of waste i guess. if you write the loop index inside the loop, it reports as expected (start to last). it's only when you write outside the loop that it's one higher. i can't really understand why they would have specified it like this. but Fortran has never been easy for me to understand to begin with, lol.

0 Kudos
jimdempseyatthecove
Honored Contributor III
637 Views

>> if you always go to some number, why count one past it.

Apparently you are confusing how C treats loops where it (may) use the loop control variable for testing the upper limit.

Fortran, on the other hand, computes an iteration count, then (provided it is .GT. 0), processes the loop body, decrement the count, and if new count .GT. 0, continues the loop. This permits the binary code to contain one branch statement as opposed to two.

 

To do it (without counting past) would require two branches (either at the bottom of the loop or one extra at top and one at the bottom).

IOW Fortran chose to perform faster code.

 

Jim Dempsey

0 Kudos
Reply