fftw3: Plan execution in Fortran
7.4 Plan execution in Fortran
=============================
In C, in order to use a plan, one normally calls 'fftw_execute', which
executes the plan to perform the transform on the input/output arrays
passed when the plan was created (
Using Plans). The
corresponding subroutine call in modern Fortran is:
call fftw_execute(plan)
However, we have had reports that this causes problems with some
recent optimizing Fortran compilers. The problem is, because the
input/output arrays are not passed as explicit arguments to
'fftw_execute', the semantics of Fortran (unlike C) allow the compiler
to assume that the input/output arrays are not changed by
'fftw_execute'. As a consequence, certain compilers end up
repositioning the call to 'fftw_execute', assuming incorrectly that it
does nothing to the arrays.
There are various workarounds to this, but the safest and simplest
thing is to not use 'fftw_execute' in Fortran. Instead, use the
functions described in
New-array Execute Functions, which take
the input/output arrays as explicit arguments. For example, if the plan
is for a complex-data DFT and was created for the arrays 'in' and 'out',
you would do:
call fftw_execute_dft(plan, in, out)
There are a few things to be careful of, however:
* You must use the correct type of execute function, matching the way
the plan was created. Complex DFT plans should use
'fftw_execute_dft', Real-input (r2c) DFT plans should use use
'fftw_execute_dft_r2c', and real-output (c2r) DFT plans should use
'fftw_execute_dft_c2r'. The various r2r plans should use
'fftw_execute_r2r'. Fortunately, if you use the wrong one you will
get a compile-time type-mismatch error (unlike legacy Fortran).
* You should normally pass the same input/output arrays that were
used when creating the plan. This is always safe.
* _If_ you pass _different_ input/output arrays compared to those
used when creating the plan, you must abide by all the restrictions
of the new-array execute functions (
New-array Execute
Functions). The most tricky of these is the requirement that the
new arrays have the same alignment as the original arrays; the best
(and possibly only) way to guarantee this is to use the
'fftw_alloc' functions to allocate your arrays (
Allocating
aligned memory in Fortran). Alternatively, you can use the
'FFTW_UNALIGNED' flag when creating the plan, in which case the
plan does not depend on the alignment, but this may sacrifice
substantial performance on architectures (like x86) with SIMD
instructions (
SIMD alignment and fftw_malloc).