2

I wrapeed up a fortran code using f2py and called the module twice in a python code. But some variable values in the fortran code seems to be inheritated between these two calls.

I understand that the fortran variable declarations would only be executed once. But why would the variable values be saved between two calls of the module? Is there any way that I can reset the fortran module every time I call it in python?

Here is a test code, and the actual fortran code is much more complicated, so it may be impossible for me to simply clear some variables.

fortran code:

subroutine test
integer::aa=1
write(*,*) aa
aa=aa+1
end subroutine test

python code:

import test
test.test()
test.test()

the output will be :

1
2

the expected output should be :

1
1

Again that I cannot simply use the

integer::a
a=1

Because I have too many subroutines in my actual fortran code, so it is hard to check every variable declaration. So I wonder if there is any wiser way to crack this problem.


EDIT: summary of the comments till now:

  1. python import the fortran module as a library and it will remain in the memory between two calls. No useful "reload" methods reported yet.

  2. fortran has the implicit save problem as mentioned before. cs.rpi.edu/~szymansk/OOF90/bugs.html here is a useful link provided by @Oo.oO

And there is a new relevant question about the usage of the fortran module in parallel computation. As mentioned by @Pierre de Buyl, the module generated through f2py is not threadsafe. I am new to python and wonder if it is able to use the module in python's "multiprocessing". (If this question is considered to be irrelevant, I will remove it.)


EDIT2: Recently I tried the "data" command to assign values. And i find that it has the same implicit save problem as mentioned before.

integer::a
data a/1/
a=a+1
write(*,*) a

results:

2
3

Used to think the problem just occured in command like "integer::a=1".

Lamp
  • 21
  • 4
  • If you don't require the local variables to have the SAVE attribute, then it may be better to correct the Fortran code to remove the attribute, rather than work around that by "resetting" the module. – francescalus May 17 '19 at 06:01
  • @francescalus Thank you. But in my fortran code, the variables doesn't have the attribute SAVE. It seems that sometimes the variables are just saved by default (like the example I give). So the thing is, I have too many variables and subroutines, so it is hard to check all of them. – Lamp May 17 '19 at 06:23
  • 1
    Possible duplicate of https://stackoverflow.com/questions/3352741/fortran-assignment-on-declaration-and-save-attribute-gotcha – IanH May 17 '19 at 06:23
  • @IanH Thank you. I believe my question is partly similar to that one. But my point is I don't understand why the values are saved when i call the module twice in python. There are many complicated atmospheric or oceanic models written in fortran. So if I want to use them in python, does that mean I have no choice but to modify the whole model to be able to use them more than one time in my python code? – Lamp May 17 '19 at 06:38
  • The Fortran code is loaded as a "library" and remains in memory between the two calls. You will have to modify the Fortran code. By the way, this is what would happen as well if you were calling the code from a Fortran program. Despite the possibly confusing appearance, this is the way the routines were implemented. – Pierre de Buyl May 17 '19 at 07:23
  • @Pierre de Buyl Thank you. Because it works when i run the python code twice if it only calls fortran once, I just thought there maybe something i can do to the module, like reloading it or so. I am new to python and thank you again for your advice. – Lamp May 17 '19 at 08:22
  • I do not encourage the "reloading" of modules. It is often not possible and when it works, it depends a lot on the environment (what operating system, for instance). I you run a Python program that calls the routine, it loads the library once. If you re-execute the Python program, it reloads the library but you have lost all variables anyway. – Pierre de Buyl May 17 '19 at 11:27
  • @Lamp In Fortran, `integer :: aa=1` in a procedure, implicitly gives the variable the `save` attribute, meaning that its value will be initialized to `1` for the first call of the procedure, and thereafter, it will take its last modified value upon every new call. If you want `aa` to be reset to `1` on every call, then simply separate the value initialization from type-declaration, for example, write `integer :: aa; aa = 1`. – Scientist May 17 '19 at 19:42
  • @Pierre de Buyl Thank you. And it reminds me of a problem. Does that mean the fortran module generated through f2py cannot be used in parallel computation? – Lamp May 19 '19 at 07:43
  • As @King mentioned you are trapped with implicit "save". Take a look here for more gotchas: http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html – Oo.oO May 19 '19 at 19:07
  • @Lamp you could use it in MPI code as every process will load a copy of the library. You could not use it in multithreaded (e.g. OpenMP) code as it is not threadsafe. That does not solve the implicit save problem though. – Pierre de Buyl May 19 '19 at 19:25
  • 1
    I am now inclide to close the question as a duplicate of the link given by IanH. The reasons vere hopefully explained. Or do you still expect some kind of answer? To which question exactly that would be? If you want to ask how to relead a library, that woud be a topic for a different question. – Vladimir F Героям слава May 21 '19 at 07:12
  • @Vladimir F Thank you. Pierre de Buyl do answered my original quesstion. I actually expect answers to easier ways of using fortran code in python other than modifying the whole fortran code. I guess the question is too big now. I will ask another question about that. – Lamp May 21 '19 at 07:56
  • The data statement `data a/1/` and the explicit initialization `integer :: a=1` have the same effect of implying the SAVE attribute for `a`. – francescalus May 21 '19 at 09:51

0 Answers0