jacobwilliams/odepack

Wrong Intent(out) specified for argument 'flag' of Subroutine MDI

Opened this issue · 4 comments

I built each of the nine examples using the NAG compiler with the -dusty option, and obtained normal output. Next, I added the -O2 option to see if the results remained the same. In many of the examples, that was the case. However, for the `lsodes' example, the run stopped with errors. I got the absurd output:

Run with mf = 11. Input work lengths lrw, liw = 1000 90

DLSODES- RWORK length insufficient (for Subroutine ODRV).
Length needed is .ge. LENRW (=I1), exceeds LRW (=I2)
In above message, I1 = 245 I2 = 1000

It took some effort to track the cause of this mishap to the declaration in `mdi.inc':


subroutine mdi(N,Ia,Ja,Max,V,L,Head,Last,Next,Mark,Tag,Flag)

...

integer,intent(out)   :: Flag

A peculiar property of Intent(Out) is that such a variable becomes undefined at subprogram entry, and the user must define the argument before returning from the subprogram. In this case, the variable flag is assigned a value only when a condition is satisfied. Otherwise, it becomes undefined. Normally, compilers do not emit code to make this undefinition happen, so we do not notice the error. In the present example and with one compiler, the consequences were catastrophic.

This problem did not occur in Fortran 77 since there was no Intent attribute to worry about. When a code polishing tool outputs Intent(out), it is usually advisable to remove the Intent attribute unless one can establish that redefinition will definitely occur before subroutine exit.

Once I removed Intent(out) for the 'flag' argument, the program ran normally.

There are several other instances of Intent(out) in the *.inc files. They may bite us one day.

I like the intent for documentation purposes but what it actually does and/or how well the compiler can trap if out-only values are set or not makes it risky. Want to go through these, not just remove them all right now; but this one was definitely incorrect. I also want to go through the history and see if I added that or if the spag(1) program did; and let them know if it was spag(1) which I unfortunately no longer have access to.add

I would like to add the fpm command for NAG to the README file as well. What command would you recommend?

I am not an FPM user, so I can only tell you the flags that I used with the NAG compiler, starting in the src directory:

nagfor -dusty -C -C=undefined -c M_odepack.f90
cd ..\example
nagfor -dusty -C -C=undefined -I..\src lsodis.f90 ..\src\M_odepack.o

Regarding INTENT(out), at least remove that attribute for the dummy 2-D array arguments of the various Jacobian evaluation routines. Many of these calculate only the non-zero terms of the Jacobian, and having INTENT(OUT) may cause the other terms to become undefined.

In the DDOT BLAS function, set the function return variable DDOT to zero before executing the short return when n < 1.

Useful for fpm(1) as well, but I do not have nagfor to test with; but I did want the Makefile work for nagfor;
without fpm(1) the idea is that for several common compilers you just do 'cd src;make COMPILER'
I added a preliminary nagfor option so "make nagfor" will hopefully work. It should work for ifort, gfortran, nvfortran, and nagfor.

Once the bugs have been removed, the NAG compiler can be used with no option flags needed other than -dusty. Furthermore, if the user is not hunting for bugs, the user may just as well use Gfortran instead.