Search code examples
pythonfortranf2py

Using internal allocatable arrays with f2py


I am using f2py to wrap some Fortran subroutines. When calling from Python, I always use explicit arrays for the input/output, but have a few working arrays that need to be allocatable. These arrays have no interface with Python. A small test subroutine that replicates the problem is shown below:

subroutine test(n, x, y)

    !f2py intent(in) n, x
    !f2py intent(out) y
    !f2py depend(n) x

    integer, intent(in) :: n, x(n)
    integer, intent(out) :: y

    integer, allocatable :: z(:)

    allocate(z(n))

    z(:) = 10

    y = z(2) + x(1)

end subroutine test

Whenever I use internal allocatable arrays I get the following output when doing "python setup.py develop" with NumPy's distutils package:

test.o : error LNK2019: unresolved external symbol _gfortran_runtime_error referenced in function test_
test.o : error LNK2019: unresolved external symbol _gfortran_runtime_error_at referenced in function test_
test.o : error LNK2019: unresolved external symbol _gfortran_os_error referenced in function test_
ASAP\lib\asap_lib.pyd : fatal error LNK1120: 3 unresolved externals

I am using NumPy's Configuration class from numpy.distutils.misc_utl and gfortran 5.2.0, mingw64, Windows 10.

The program will compile just fine if I use gfortran directly, but when it gets hooked up with f2py (or somewhere in that process) things fail. I can comment out the allocate line and it will compile, but obviously not work at runtime. There are always 3 unresolved externals no matter how many allocatable arrays I have.

While I'm here, I get similar link errors if the Fortran subroutine has a write or print statement in it. I don't need them, would just be useful for debugging if anyone has an idea.

Thanks for the help.

UPDATE 1:

Using the Configuration class from numpy.distutils.misc_util I added an extra link option

config.add_extension('test_lib', sources, extra_link_args=['/FORCE']

after looking at the info here at Microsoft Linker Options. The '/FORCE' is the key option. The print or write command still throw back exit code 255 in Python, but at least the allocatable arrays seem to be working, which is all I cared about.

Seems like a hack, but if anybody knows what is causing the original problem I probably still have a deeper rooted issue that I need to address.


Solution

  • I had a link problem and specifying compiler=mingw32 in the f2py options fixed all the problems.