"do i = 1, huge(i); end do" results in infinite loop

"do i = 1, huge(i); end do" results in infinite loop

Dear all,

The following program seems to goes into an infinite loop.
Is this an expected behavior?

program infinite_loop
  implicit none

  Integer:: i

  do i = 1, huge(i)
  end do

  stop
end program infinite_loop

$ ifort -v
ifort version 13.0.0
$ ifort infinite_loop.F90
$ ./a.out
#=> Get 100% use of CPU and never (at least 5 minutes...) finish.

Sincerely,
Amato

9 posts / novo 0
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.

You probably run into failure of something like IF(I>HUGE(I))EXIT or of the requirement that I is set to the next value upon exit.

Here is a simple explanation of why the test program causes the loop to execute "forever". The assembler output from the 12.1 compiler on Windows reads


.B1.3:

        push      1

        pop       eax
.B1.4:

        inc       eax

        jmp       .B1.4

One may surmise that, as TimP pointed out, the loop termination criterion cannot be met with 32-bit integers, so the compiler puts out a very simple and effective infinite loop!

What do you expect should happen? Does the Fortran standard require the loop to terminate?

Thank you for the replies.
I expected the program to successfully stop after huge(i) times iterations because:
1) according to ISO/IEC JTC1/SC22/WG5 N1601, "if(i > huge(i))" is not necessary to detect end of the loop.

(Ref: ftp://ftp.nag.co.uk/sc22wg5/N1601-N1650/N1601.txt)

      (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 0.
...
The execution cycle of a DO construct consists 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. If loop-control is [ , ] WHILE (scalar-logical-expr), the scalar-logical-expr
             is evaluated; if the value of this expression is false, the loop terminates and the DO construct
             becomes inactive. If, as a result, all of the DO constructs sharing the do-term-shared-stmt are inactive,
             the execution of all of these constructs is complete. However, if some of the DO constructs sharing the

             do-term-shared-stmt are active, execution continues with step (3) of the execution cycle of the active DO

             construct whose DO statement was most recently executed.

      (2)    If the iteration count is nonzero, the range of the loop is executed.

      (3)    The iteration count, if any, is decremented by one. The DO variable, if any, is incremented
             by the value of the incrementation parameter m3.

2) gfortran and g95 does not generate infinite loop.
3) The following program does not result in infinite loop.
program infinite_loop
  use, intrinsic:: iso_fortran_env, only: INT16
  implicit none

  Integer(INT16):: i

  do i = 1_INT16, huge(i)
  end do

  stop
end program infinite_loop

Are you using equivalent options when you compare ifort and gfortran, remembering that gfortran and g95 default to -O0?

What value does i take after the loop terminates (you skipped quotation of that part of the standard)?  Do any of the compilers optimize the loop away?

This falls under the area of compiler limits. We tend to convert counted loops into tested loops for performance reasons. Yes, this leaves things open to issues when the iteration count is HUGE(), but does anyone do this in a real program?

Steve

Thank you for the replies,

TimP:
> Are you using equivalent options when you compare ifort and gfortran, remembering that gfortran and g95 default to -O0?
I tried "ifort -O0" and also get infinite loop.
Both gfortran and g95 with -O2 or -O3 did not generate infinite loop.
> What value does i take after the loop terminates (you skipped quotation of that part of the standard)?
I did not skip it. Please see the second sentence of (3) in the quotation.
>> The DO variable, if any, is incremented by the value of the incrementation parameter m3.
Both gfortran and g95 return -2147483648, as expected.

Steve:
> Yes, this leaves things open to issues when the iteration count is HUGE(), but does anyone do this in a real program?
I used HUGE() loop in a small benchmark and encountered this limitation.
From next time, I'll use HUGE(i) - 1 loop if I want huge iteration.

Thanks a lot,
Amato

You'll also want to make sure that the work done in the loop is not optimized away - compilers can be very clever. A lot of "small benchmark" programs end up measuring something different than intended.

I would suggest instead picking a fixed large number that is sufficient for your measurement, rather than assuming what the value of HUGE is.

Steve

Steve, thank you for your suggestions. I will follow them.
Amato

Faça login para deixar um comentário.