2

I want to share data which is located in a Fortran 90 module between many self compiled F2PY extension modules. The documentation of F2PY says that this is not possible due to to how Python imports shared libraries in general.

F2PY generates wrappers to common blocks defined in a routine signature block. Common blocks are visible by all Fortran codes linked with the current extension module, but not to other extension modules (this restriction is due to how Python imports shared libraries).

[...]

The F2PY interface to Fortran 90 module data is similar to Fortran 77 common blocks.

Link to Documentation

Due to the fact, that I have to use about 100 nested Fortran 90 subroutines, I need to share data between them. Any suggestions how I can achieve that?

I thought about passing every variable as parameter to each subroutine and return the variables afterwards, but this sounds somehow wrong.

Community
  • 1
  • 1

1 Answers1

3

Though just a trial-and-error approach, how about putting the variable module and all the subroutines into a single file and compile it with f2py (*1)? For example...

mytest.f90:

include "vars.f90"
include "sub1.f90"
include "sub2.f90"

vars.f90:

module vars
    integer :: n = 100
end

sub1.f90:

subroutine sub1
    use vars, only: n
    implicit none
    print *, "sub1: n = ", n
end

sub2.f90:

subroutine sub2
    use vars, only: n
    implicit none
    print *, "sub2: n = ", n
    print *, "adding 1 to n"
    n = n + 1
    print *, "n = ", n
end

Compile:

f2py -c -m mytest mytest.f90

Test:

$ /usr/local/bin/python3
>>> import mytest
>>> mytest.vars.n
array(100, dtype=int32)
>>> mytest.sub1()
 sub1: n =          100
>>> mytest.sub2()
 sub2: n =          100
 adding 1 to n
 n =          101
>>> mytest.sub2()
 sub2: n =          101
 adding 1 to n
 n =          102
>>> mytest.vars.n = 777
>>> mytest.sub2()
 sub2: n =          777
 adding 1 to n
 n =          778

(*1) In the above case, simply giving all the file names to f2py seems sufficient, for example,

$ f2py -c -m mytest vars.f90 sub1.f90 sub2.f90
roygvib
  • 7,218
  • 2
  • 19
  • 36
  • It shouldn't be necessary to have them in one file. Compile them into one .so file should be fine. But the OP, for some strange reason, says it is not possible. – Vladimir F Героям слава Oct 23 '18 at 19:23
  • @VladimirF Thanks for the info, I've just tried it and it seems to work (for the test above). Then OP might try something like "f2py -c -m mytest vars.f90 sub1.f90 sub2.f90 ... sub100.f90" (or with wild card for sub*.f90) – roygvib Oct 23 '18 at 19:29
  • @roygvib : Thank you very much for the explanation and example! Now I got the clue/hint Vladimir F suggested. Vladimir F, thank you too for your help. I really appreciate it. I still have one question, is there a relevant difference between `$ f2py -c -m mytest vars.f90 sub1.f90 sub2.f90` and `f2py -c -m mytest mytest.f90` ? It looks like there is no difference because mytest.f90 contains vars.f90 + sub1.f90 + sub2.f90. – Napsterlicious Oct 24 '18 at 06:37
  • @Christopher49124 As far as I tested with the above example, there was no difference. But, I'm afraid that there may appear differences when some f2py-specific "directives" are used (for telling f2py about the argument intent etc). Overall, I guess it will be better to pass all the file names explicitly to the f2py command (like f2py -c -m mytest vars.f90 sub1.f90....). We may also be able to use bash etc to pass a lot of file names conveniently (rather than including them into a file). – roygvib Oct 24 '18 at 12:53