Reputation: 10249
I'm trying to access some Fortran subroutines using F2PY
, but I've ran into the following problem during consecutive calls from IPython. Take this minimal Fortran code (hope that I didn't code anything stupid; my Fortran is a bit rusty..):
! test.f90
module mod
integer i
contains
subroutine foo
i = i+1
print*,i
end subroutine foo
end module mod
If I compile this using F2PY
(f2py3.5 -c -m test test.f90
), import it in Python and call it twice:
# run.py
import test
test.mod.foo()
test.mod.foo()
The resulting output is:
$ python run.py
1
2
So on every call of foo()
, i
is incremented, which is supposed to happen. But between different calls of run.py
(either from the command line or IPython interpreter), everything should be "reset", i.e. the printed counter should start from 1
for every call. This happens when calling run.py
from the command line, but if I call the script multiple times from IPython, i
keeps increasing:
In [1]: run run.py
1
2
In [2]: run run.py
3
4
I know that there are lots of posts showing how to reload imports (using autoreload
in IPython, importlib.reload()
, ...), but none of them seem to work for this example. Is there a way to force a clean reload/import?
Some side notes: (1) The Fortran code that I'm trying to access is quite large, old and messy, so I'd prefer not to change anything in there; (2) I could easily do test.mod.i = something
in between calls, but the real Fortran code is too complex for such solutions; (3) I'd really prefer a solution which I can put in the Python code over e.g. settings (autoreload
, ..) which I have to manually put in the IPython interpreter (forget it once and ...)
Upvotes: 1
Views: 1170
Reputation: 468
If you can slightly change your fortran code you may be able to reset without re-import (probably faster too).
The change is about introducing i
as a common and resetting it from outside. Your changed fortran code will look this
! test.f90
module mod
common /set1/ i
contains
subroutine foo
common /set1/ i
i = i+1
print*,i
end subroutine foo
end module mod
reset the variable i
from python as below:
import test
test.mod.foo()
test.mod.foo()
test.set1.i = 0 #reset here
test.mod.foo()
This should produce the result as follows:
python run.py
1
2
1
Upvotes: 1