5

Using F2PY as a wrapper, is it possible to use subroutines with subroutine calls? And if so, how?

In case I am unclear, I mean like this:

    SUBROUTINE average(a, b, out)

    real a, b, out
cf2py intent(in) a, b
cf2py intent(out) out

    call add(a, b, out)

    out=out/2

    END

The add subroutine is as follows:

  subroutine add(a, b, out)

  real a, b, out

  out = a + b

  return
  end

Trying f2py -c -m average average.f and importing to python I get:

ImportError: ./average.so: undefined symbol: add_

Also, adding intents to the second subroutine does not fix the issue.

2 Answers2

6

You need to include the file containing add in your compile command, e.g.

f2py -c -m average average.f add.f

The shared library you import needs to have its references resolved at import time, which means they need to be either contained in the library or linked to it. You can accomplish keeping your functions in separate libraries like this:

gfortran -shared -fPIC -o add.so add.f
f2py -c -m average average.f add.so

which will produce a python module that does not itself contain add but will have a runtime link dependency on add.so for the function.

casey
  • 6,855
  • 1
  • 24
  • 37
  • Thanks for the answer! Following your instructions and then importing average into python I get: ImportError: add.so: cannot open shared object file: No such file or directory. So somehow it still isn't finding the shared library.. – Ryan Garland Aug 12 '15 at 14:13
  • @RyanGarland if you go that method you need to make sure `add.so` is accessible in the `LD_LIBRARY_PATH` so the dynamic linker can find it. If you are not familiar withe the caveats of dynamic linking I recommend just compiling `add.f` into your python library with the first command. – casey Aug 12 '15 at 14:15
  • Ah, no problem. The first method works so I will stick with that for the time being. Many thanks! – Ryan Garland Aug 12 '15 at 15:31
0

You guys already figured, but just to build on to casey's response: If you run into a situation where you want to avoid having to compile add.f over again each time you modify average.f, you can use the static library, this way you don't have to make a link to LD_LIBRARY_PATH:

$ gfortran -c add.f
$ f2py -c -m average average.f add.o

The first command above will generate the static object (library) file. Second one used that object file to compile your final subroutine for python.

SMISA16
  • 11
  • 3