Whole document tree
Calling FFTW from FortranThe standard FFTW libraries include special wrapper functions that allow Fortran programs to call FFTW subroutines. This chapter describes how those functions may be employed to use FFTW from Fortran. We assume here that the reader is already familiar with the usage of FFTW in C, as described elsewhere in this manual.
In general, it is not possible to call C functions directly from
Fortran, due to Fortran's inability to pass arguments by value and also
because Fortran compilers typically expect identifiers to be mangled
somehow for linking. However, if C functions are written in a special
way, they are callable from Fortran, and we have employed this
technique to create Fortran-callable "wrapper" functions around the
main FFTW routines. These wrapper functions are included in the FFTW
libraries by default, unless a Fortran compiler isn't found on your
system or
As a result, calling FFTW from Fortran requires little more than
appending ` Wrapper Routines
All of the uniprocessor and multi-threaded transform routines have
Fortran-callable wrappers, except for the wisdom import/export functions
(since it is not possible to exchange string and file arguments portably
with Fortran) and the specific planner routines (see Section Discussion on Specific Plans). The name of the wrapper routine is the same as that
of the corresponding C routine, but with
In general, you should take care to use Fortran data types that
correspond to (i.e. are the same size as) the C types used by FFTW. If
your C and Fortran compilers are made by the same vendor, the
correspondence is usually straightforward (i.e. FFTW Constants in Fortran
When creating plans in FFTW, a number of constants are used to specify
options, such as
Instead, we have placed Fortran equivalents of the FFTW constant
definitions in the file integer FFTW_FORWARD,FFTW_BACKWARD parameter (FFTW_FORWARD=-1,FFTW_BACKWARD=1) integer FFTW_REAL_TO_COMPLEX,FFTW_COMPLEX_TO_REAL parameter (FFTW_REAL_TO_COMPLEX=-1,FFTW_COMPLEX_TO_REAL=1) integer FFTW_ESTIMATE,FFTW_MEASURE parameter (FFTW_ESTIMATE=0,FFTW_MEASURE=1) integer FFTW_OUT_OF_PLACE,FFTW_IN_PLACE,FFTW_USE_WISDOM parameter (FFTW_OUT_OF_PLACE=0) parameter (FFTW_IN_PLACE=8,FFTW_USE_WISDOM=16) integer FFTW_THREADSAFE parameter (FFTW_THREADSAFE=128)
In C, you combine different flags (like Fortran ExamplesIn C you might have something like the following to transform a one-dimensional complex array: fftw_complex in[N], *out[N]; fftw_plan plan; plan = fftw_create_plan(N,FFTW_FORWARD,FFTW_ESTIMATE); fftw_one(plan,in,out); fftw_destroy_plan(plan); In Fortran, you use the following to accomplish the same thing: double complex in, out dimension in(N), out(N) integer plan call fftw_f77_create_plan(plan,N,FFTW_FORWARD,FFTW_ESTIMATE) call fftw_f77_one(plan,in,out) call fftw_f77_destroy_plan(plan)
Notice how all routines are called as Fortran subroutines, and the plan
is returned via the first argument to call fftw_f77_threads_one(8,plan,in,out) To transform a three-dimensional array in-place with C, you might do: fftw_complex arr[L][M][N]; fftwnd_plan plan; int n[3] = {L,M,N}; plan = fftwnd_create_plan(3,n,FFTW_FORWARD, FFTW_ESTIMATE | FFTW_IN_PLACE); fftwnd_one(plan, arr, 0); fftwnd_destroy_plan(plan); In Fortran, you would use this instead: double complex arr dimension arr(L,M,N) integer n dimension n(3) integer plan n(1) = L n(2) = M n(3) = N call fftwnd_f77_create_plan(plan,3,n,FFTW_FORWARD, + FFTW_ESTIMATE + FFTW_IN_PLACE) call fftwnd_f77_one(plan, arr, 0) call fftwnd_f77_destroy_plan(plan)
Instead of calling
Note that we pass the array dimensions in the "natural" order; also
note that the last argument to To transform a one-dimensional real array in Fortran, you might do: double precision in, out dimension in(N), out(N) integer plan call rfftw_f77_create_plan(plan,N,FFTW_REAL_TO_COMPLEX, + FFTW_ESTIMATE) call rfftw_f77_one(plan,in,out) call rfftw_f77_destroy_plan(plan) To transform a two-dimensional real array, out of place, you might use the following: double precision in double complex out dimension in(M,N), out(M/2 + 1, N) integer plan call rfftw2d_f77_create_plan(plan,M,N,FFTW_REAL_TO_COMPLEX, + FFTW_ESTIMATE) call rfftwnd_f77_one_real_to_complex(plan, in, out) call rfftwnd_f77_destroy_plan(plan) Important: Notice that it is the first dimension of the complex output array that is cut in half in Fortran, rather than the last dimension as in C. This is a consequence of the wrapper routines reversing the order of the array dimensions passed to FFTW so that the Fortran program can use its ordinary column-major order. Go to the first, previous, next, last section, table of contents. |