Search code examples
pythonfortranwrapperfftwf2py

How to link with FFTW3 in f2py?


I'm trying to get some speedup for a Python implementation I wrote some time ago and decided to use f2py for that. I'm currently still testing some stuff and think that I need some help with getting FFTW3 to work. For a first test, I wrote the following subroutines:

subroutine initFFT(planF, a, res, n)
    implicit none
    include "fftw3.f"
    integer, INTENT(IN) :: n
    complex(KIND=8), dimension(n) :: a, res
    integer(KIND=8), intent(OUT) :: planF

    call dfftw_plan_dft(planF, 1, n, a, res, FFTW_FORWARD, FFTW_MEASURE)
end subroutine initFFT

subroutine operation(a, res, n, planF)
    implicit none
    INCLUDE 'fftw3.f'
    integer :: n
    integer(KIND=8) :: planF
    complex(KIND=8), dimension(n), intent(IN) :: a
    complex(KIND=8), dimension(n), intent(OUT) :: res

    call dfftw_execute_dft(planF, a, res)
end subroutine operation

I tested this with a simple main program

program test
    implicit none
    integer, parameter :: n = 3
    integer(KIND=8) :: planF
    complex(KIND=8), dimension(n) :: res, a

    call initFFT(planF, a, res, n)

    a = (/ 1., 1., 1./)
    call operation(a, res, n, planF)
end program test

and compiled with

gfortran -o ftest myFun.f90 -L/usr/lib -lfftw3 -I/usr/include

Everything worked and returned correct results. Now I tried to use this with f2py in the following way:

f2py -c myFun.f90 -m modf --f90flags="-L/usr/lib -lfftw3 -I/usr/include"

The problem is, that I get the following error-message, when I try to import the created module in Python (with import modf):

Import Error: modf.so undefined symbol: dfftw_execute_dft_

I spent quite some time with Google already but somehow I didn't find anything useful so far. Does anyone have an idea how to solve this?


Solution

  • Can you try by using directly the flags to f2py instead of via --f90flags?

    Currently, you tell the fortran compiler how to build the module but f2py then does not have any idea of the linking steps. What you need is that the final Python callable module is aware of the existence of fftw.

    f2py -c -L/usr/lib -lfftw3 -I/usr/include -m modf myFun.f90
    

    The options are given before the Fortran file name, as per https://docs.scipy.org/doc/numpy/f2py/usage.html