user2452600
user2452600

Reputation: 43

FORTRAN IV/66 program stalls in DO loops

I copied a FORTRAN IV program from a thesis, so it presumably worked at the time it was written. I compiled it with gfortran. When running, it stalls in an integration subroutine. I have tried easing off the residuals but to no avail. I am asking for help because (presuming no mistakes in code) gfortran might not like the archaic 66/IV code, and updating it is outside my abilities.

The program gets stuck by line 9, so I wonder if the DO loops are responsible. Note, lines 1 and 6 are unusual to me because ',1' has been added to the ends: e.g. =1,N,1.

I don't think it's necessary to show the FUNC subroutine called on line 5 but am happy to provide it if necessary.

If you need more detailed information I am happy to provide it.

00000001 13  DO 22 TDP=QDP,7,1
00000002     TD=TDP-1
00000003     X=X0+H0
00000004     IF(TD.EQ.QD) GOTO 15
00000005     CALL FUNC(N,DY,X,Y,J)   
00000006 15  DO 21 RD=1,N,1
00000007     GOTO (120,121,122,123,124,125,126),TDP
00000008 120     RK(5*N*RD)=Y(RD)
00000009     GOTO 21
00000010 121     RK(RD)=HD*DY(RD)
00000011     H0=0.5*HD
00000012     F0=0.5*RK(RD)
00000013     GOTO 20
00000014 122     RK(N+RD)=HD*DY(RD)
00000015     F0=0.25*(RK(RD)+RK(N+RD))
00000016     GOTO 20
00000017 123     RK(2*N+RD)=HD*DY(RD)
00000018     H0=HD
00000019     F0=-RK(N+RD)+2.*RK(2*N+RD)
00000020     GOTO 20
00000021 124     RK(3*N+RD)=HD*DY(RD)
00000022     H0=0.66666666667*HD
00000023     F0=(7.*RK(RD)+10.*RK(N+RD)+RK(3*N+RD))/27.
00000024     GOTO 20
00000025 125     RK(4*N+RD)=HD*DY(RD)
00000026     H0=0.2*HD
00000027     F0=(28.*RK(RD)-125.*RK(N+RD)+546.*RK(2*N+RD)+54.*RK(3*N+RD)-
00000028    1378.*RK(4*N+RD))/625.
00000029     GOTO 20
00000030 126     RK(6*N+RD)=HD*DY(RD)
00000031     F0=0.1666666667*(RK(RD)+4.*RK(2*N+RD)+RK(3*N+RD))
00000032     X=X0+HD
00000033     ER=(-42.*RK(RD)-224.*RK(2*N+RD)-21.*RK(3*N+RD)+162.*RK(4*N+RD)
00000034    1+125.*RK(6*N+RD))/67.2
00000035     YN=RK(5*N+RD)+F0
00000036     IF(ABS(YN).LT.1E-8) YN=1
00000037     ER=ABS(ER/YN)
00000038     IF(ER.GT.G0) GOTO 115
00000039     IF(ED.GT.ER) GOTO 20
00000040     QD=-1
00000041 20  Y(RD)=RK(5*N+RD)+F0
00000042 21  CONTINUE
00000043 22  CONTINUE

Upvotes: 4

Views: 903

Answers (3)

tim18
tim18

Reputation: 620

Not all f66 compilers adhered to the convention of executing a loop at least once, but it was a common (non-portable) assumption. Similarly, the assumption of all static variables was not a portable one, but can be implemented by adding a SAVE statement, beginning with f77. A further assumption that SAVE variables will be zero-initialized is even more non-portable, but most compilers have an option to implement that.

If an attempt is being made to resurrect old code, it is probably worth while to get it working before modernizing it incrementally so as to make it more self-documenting. The computed goto looks like a relatively sane one which could be replaced by select case, at a possible expense of optimization. Here the recent uses of the term "modernization" become contradictory.

Upvotes: 1

High Performance Mark
High Performance Mark

Reputation: 78364

It's difficult to be certain (not entirely sure your snippet exactly matches your source file) but your problem might arise from an old FORTRAN gotcha -- a 0 in column 6 is (or rather was) treated as a blank. Any other (non-blank) character in column 6 is/was treated as a continuation indicator, but not the 0.

Upvotes: 3

cup
cup

Reputation: 8299

The ,1 bits are to get the compiler to spot the errors. It is quite common to do the following

DO 10 I = 1.7

That is perfectly legal since spaces are allowed in variable names. If you wish to avoid that, then put in the extra number. The following will generate errors

DO 10 I = 1.7,1
DO 10 I = 1,7.1
DO 10 I = 1.7.1

Re the program getting struck, try puting a continuation line between labels 21 and 22. The if-goto is the same as if-not-then in the later versions of Fortran and the computed goto is the same as a select statement. You don't need to recode it: there is nothing wrong with it other than youngsters getting confused whenever they see goto. All you need to do is indent it and it becomes obvious. So what you will have is

    DO 22 TDP = QDP, 7, 1
       ...
       DO 23 RD = 1, N, 1
          GOTO (...) TDP
             ...
             GOTO 21
             ...
             GOTO 20
             ...
             GOTO 20
             ...
20        CONTINUE
          Y(RD) = ...
21        CONTINUE
23      CONTINUE
22   CONTINUE

You will probably end up with far more code if you try recoding it. It will look exactly the same except that gotos have been replaced by other words. It is possible that the compiler is generating the wrong code so just help it by putting a few dummy (CONTINUE) statements.

Upvotes: 0

Related Questions