Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Outdated DO loops in Fortran 2018+

I am working with a source code that might have been written before the most recent version of gfortran. I'm aware that the way DO, END DO, and CONTINUE has changed so that there can not be shared loop termination. There's a handy link here. The thing is, I don't know what the explanation really is telling me to do on that page. If I set up a really basic DO loop in a new script, it compiles with no error. I'm not sure how to reverse engineer this to find what the problem is.

Here is one part of the code that returns an error message.

              DO 20 II = I1, I2
              IW = ICN(II)
!             Has node iw been on stack already?
              IF (NUMB(IW)==0) GOTO 70
!             Update value of LOWL(IV) if necessary.
20          LOWL(IV) = MIN(LOWL(IV),LOWL(IW))

!           There are no more edges leaving node IV.
            ARP(IV) = -1
!           Is node IV the root of a block.
30          IF (LOWL(IV)<NUMB(IV)) GOTO 60

!           Order nodes in a block.
            NUM = NUM + 1
            IST1 = N + 1 - IST
            LCNT = ICNT + 1
!           Peel block off the top of the stack starting at the
!           top and working down to the root of the block.
            DO STP = IST1, N
              IW = IB(STP)
              LOWL(IW) = N + 1
              ICNT = ICNT + 1
              NUMB(IW) = ICNT
              IF (IW==IV) GOTO 50
            END DO

The error looks like this. Basically the same error repeats for any outdated DO loops that come up and is the only type of error that comes up when compiling.

dvode_f90_m.f90:15865:45:

15865 | 20          LOWL(IV) = MIN(LOWL(IV),LOWL(IW))
      |                                             1
Warning: Fortran 2018 deleted feature: DO termination statement which is not END DO or CONTINUE with label 20 at (1)

I would like to know how to rework the DO loops in this code chunk so that I can go through and update this source code. If it's relevant, I'm running GFortran9.3.0 on Cygwin.

like image 311
peasqueeze Avatar asked Sep 03 '20 19:09

peasqueeze


People also ask

What is the use of DO loop in Fortran?

Fortran - Do Loop Construct. The do loop construct enables a statement, or a series of statements, to be carried out iteratively, while a given condition is true.

Is the labelled form obsolete in Fortran 2018?

Indeed, the labelled form is obsolescent in Fortran 2018. For non-block DO constructs where the terminating action statement was also the target of a go to we rewrite such that the go to points to the (labelled) statement pulled in to the loop. We can also rewrite non-block DO constructs which share the terminating action statement.

What is the do construct in Fortran 2018?

The DO construct in Fortran 2018 (the block DO construct in previous language standards) requires the terminating statement to be either an end do statement or a (labelled) continue statement. (The end do statement must be labelled if the DO construct is a labelled DO construct such as do 1....)

How does Fortran calculate the result in stages?

where x and y are real and i is integer, FORTRAN computes the result in stages: First it calculates (2**i)/3 and evaluates it as an integer number, then multiplies the result by x and evaluates it as real.


Video Answer


2 Answers

As the warning message says, all DO loops should terminate with END DO or CONTINUE, for instance:

            DO 20 IV = 1, 100
            LOWL(IV) = MIN(LOWL(IV),LOWL(IW))
20          CONTINUE

Old versions of Fortran allowed the programmer to drop the terminating line, resulting in the shorter

            DO 20 IV = 1, 100
20          LOWL(IV) = MIN(LOWL(IV),LOWL(IW))

However, these two codes are functionally equivalent. You can test it on your own with some trivial loops.

like image 159
jacob Avatar answered Oct 20 '22 17:10

jacob


Before Fortran 2018 there were two forms of the DO construct: the block DO construct and the non-block DO construct. Fortran 2018 deleted the non-block DO construct and the warning from your compiler relates to using this deleted form. Shared termination is a slightly different issue.

The DO construct in Fortran 2018 (the block DO construct in previous language standards) requires the terminating statement to be either an end do statement or a (labelled) continue statement. (The end do statement must be labelled if the DO construct is a labelled DO construct such as do 1 ....)

A non-block DO construct was much less restrictive and allowed many other statements (action statements) to be the labelled end of a DO construct. However, the labelled termination statement was always within the scope of the DO construct (so would be executed in every iteration). An assignment statement (such as in the question) is an action statement.

This means that you can modernize the (Fortran 2008 non-block) DO construct of the question (removing comments and changing to free-form source for clarity)

DO 20 II = I1, I2
   IW = ICN(II)
   IF (NUMB(IW)==0) GOTO 70
20 LOWL(IV) = MIN(LOWL(IV),LOWL(IW))

with the unlabelled form

DO II = I1, I2
   IW = ICN(II)
   IF (NUMB(IW)==0) GOTO 70
   LOWL(IV) = MIN(LOWL(IV),LOWL(IW))
END DO

or the labelled form

DO 20 II = I1, I2
   IW = ICN(II)
   IF (NUMB(IW)==0) GOTO 70
   LOWL(IV) = MIN(LOWL(IV),LOWL(IW))
20 END DO ! OR CONTINUE

I'm sure many people would prefer the unlabelled form. Indeed, the labelled form is obsolescent in Fortran 2018.

For non-block DO constructs where the terminating action statement was also the target of a go to we rewrite such that the go to points to the (labelled) statement pulled in to the loop. We can also rewrite non-block DO constructs which share the terminating action statement.

like image 25
francescalus Avatar answered Oct 20 '22 15:10

francescalus