I a little curious about the famous odepack Fortran code which contain several robust ODE solvers, which I believe is still heavily used today (it must be wrapped by other Python, Julia packages in some way. ) Code can be downloaded below,
So I tried to compile it and run it. I use Intel OneAPI + VS2017 in windows 10.
In release mode, it compile and run no problem. But in debug mode, I see error
'The type of the actual argument differs from the type of the dummy argument.
This is a very common issue in some F77 code, which use assumed-size arrays.
So in this case, the program did
CALL DPREPI (NEQ, Y, S, RWORK(LYH), ...)
Now in the subroutine DPREPI, the argument in RWORK(LYH) position is called YH which is actually an assume-size array,
SUBROUTINE DPREPI (NEQ, Y, S, YH ...) ... INTEGER NEQ DOUBLE PRECISION Y, S, YH, ... DIMENSION NEQ(*), Y(*), S(*), YH(*) ...
So I am just confused, in the release mode, did the Fortran code actually load the elements from LYH in RWORK array, i.e., RWORK(LYH:) as YH in subroutine DPREPI?
Or does Fortran just load the single element RWORK(LYH) as the YH in subroutine DPREPI?
I am also confused that, NEQ is an integer when CALL DPREPI, but again in subroutine DPREPI, NEQ is an array actually. Does Fortran automatically understand that when input an interger neq, NEQ(*) will just become an integer? What is the logic?
Overall, my question is,
How to properly solve this kind of error?
It seems not correct to change the definition of NEQ,…, YH in subroutine DPREPI. Do I define some interface of subroutine DPREPI so that it can handle both NEQ, …,YH as number and as array?
Thank you very much in advance!
I do see that in @jacobwilliams odepack github page, it says it seems allow those strange ‘treating number as array’ behavior.
ODEPACK contains a few instances where ANSI Fortran 77 is violated: (a) In various places in the LSODES and LSODIS solvers, a call to a subroutine has a subscripted real array as an argument where the subroutine called expects an integer array. Calls of this form occur in Subroutine DLSODES (to DSTODE), in DIPREP (to DPREP), in Subroutine DLSODIS (to DSTODI), and in DIPREPI (to DPREPI). Another such call occurs in the DLSODES demonstration program, from the main program to Subroutine SSOUT. This is done in order to use work space in an efficient manner, as the same space is sometimes used for real work space and sometimes for integer work space. If your compiler does not accept this feature, one possible way to get the desired result is to compile the called routines and calling routines in separate jobs, and then combine the binary modules in an appropriate manner. If this procedure is still not acceptable under your system, it will be necessary to radically alter the structure of the array RWORK within the LSODES or LSODIS solver package. (See also Note 5 below.) (b) Each ODEPACK solver treats the arguments NEQ, Y, RTOL, and ATOL as arrays, even though the length may be only 1. Moreover, except for Y, the usage instructions say that these arguments may be either arrays or scalars. If your system does not allow such a mismatch, then the documentation of these arguments should be changed accordingly.
But I am just curious, how to set the compiler flag, and how does compiler treat such cases? Like argument is defined as an array, but the actual input is a number.