.. default-domain:: chpl

.. module:: FFTW
   :synopsis: Single-threaded FFT computations via key routines from FFTW (version 3)

FFTW
====

Single-threaded FFT computations via key routines from FFTW (version 3)

This module defines Chapel wrappers for key single-threaded 64-bit
routines from FFTW (http://www.fftw.org), version 3.  For
multi-threaded routines, refer to the :mod:`FFTW_MT` module.  Over
time, the intention is to expand these modules to support additional
routines, prioritizing based on requests and feedback from users.


To use this module:

1. Ensure that FFTW (version 3) is installed on your system and that
   the header and library files (e.g., fftw3.h, libfftw3.*) are
   either installed in a standard system location or that your C
   compiler's environment variables are set up to find them
   (alternatively, the Chapel compiler's ``-I`` and ``-L`` flags can
   be used to specify these locations).

2. Add ``use FFTW;`` to your Chapel code.

3. Compile and run your Chapel program as usual.


As in standard FFTW usage, the flow is to:

1. Create plan(s) using the :proc:`plan_dft* <plan_dft>` routines.

2. Execute the plan(s) one or more times using :proc:`execute`.

3. Destroy the plan(s) using :proc:`destroy_plan`.

4. Call :proc:`cleanup`.


Note that each of the Chapel :proc:`plan_dft* <plan_dft>` routines
support both `in-place` and `out-of-place` versions of the
transforms, where the former versions use a single array for both
input and output, and the latter use two distinct arrays.

In future versions of this module, we anticipate improving the
plan_dft*() interfaces to make better use of Chapel features and
move further away from C-isms (like the overloaded role of `flags`
and the use of C-based types).  Such features are expected to take
advantage of Chapel's support for default argument values and
keyword-based argument passing.  We are also thinking about changing
the interface for the in-place routines to use array slicing rather
than separate arguments for the array and domain.

.. data:: config param noFFTWsizeChecks = false

   
   Controls execution-time array size checks in the FFTW
   :proc:`plan_dft` routines (set to `true` to disable checks).
   

.. type:: type fftw_plan

   
   An opaque type used to store and reuse FFTW plans across multiple
   routines.
   

.. function:: proc plan_dft(input: [?Din] complex(128), output: [?Dout] complex(128), sign: c_int, flags: c_uint): fftw_plan

   
   Creates a plan for an out-of-place complex-to-complex DFT.
   
   :arg input: The input array, which can be of any rank
   :type input: [] `complex(128)`
   
   :arg output: The output array, whose size and shape must match the input array's
   :type output: [] `complex(128)`
   
   :arg sign: :const:`FFTW_FORWARD` or :const:`FFTW_BACKWARD`
   :type sign: `c_int`
   
   :arg flags: the bitwise-or of any planning-rigor or algorithm-restriction flags that should be used in creating the plan (e.g., :const:`FFTW_MEASURE` ``|`` :const:`FFTW_PRESERVE_INPUT`)
   :type flags: `c_int`
   
   :returns: The :type:`fftw_plan` representing the resulting plan
   

.. function:: proc plan_dft(arr: [] complex(128), sign: c_int, flags: c_uint): fftw_plan

   
   Creates a plan for an in-place complex-to-complex DFT.
   
   :arg arr: The array to use as the in-place input/output array.
   :type arr: [] `complex(128)`
   
   :arg sign: :const:`FFTW_FORWARD` or :const:`FFTW_BACKWARD`
   :type sign: `c_int`
   
   :arg flags: the bitwise-or of any planning-rigor or algorithm-restriction flags that should be used in creating the plan (e.g., :const:`FFTW_MEASURE` ``|`` :const:`FFTW_PRESERVE_INPUT`)
   :type flags: `c_int`
   
   :returns: The :type:`fftw_plan` representing the resulting plan
   

.. function:: proc plan_dft_r2c(input: [?Din] real(64), output: [?Dout] complex(128), flags: c_uint): fftw_plan

   
   Create a plan for a real-to-complex, out-of-place DFT.
   
   :arg input: The input array, which can be of any rank
   :type input: [] `real(64)`
   
   :arg output: The output array, whose size and shape must match the input array's, except for the leading dimension which should be n/2 + 1, where n is the size of the input array's leading dimension.  See the `FFTW documentation <http://www.fftw.org/fftw3_doc/Multi_002dDimensional-DFTs-of-Real-Data.html#Multi_002dDimensional-DFTs-of-Real-Data>`_ for more information.
   :type output: [] `complex(128)`
   
   :arg flags: the bitwise-or of any planning-rigor or algorithm-restriction flags that should be used in creating the plan (e.g., :const:`FFTW_MEASURE` ``|`` :const:`FFTW_PRESERVE_INPUT`)
   :type flags: `c_int`
   
   :returns: The :type:`fftw_plan` representing the resulting plan
   

.. function:: proc plan_dft_r2c(realDom: domain, arr: [?D] ?t, flags: c_uint): fftw_plan

   
   Create a plan for a real-to-complex, in-place DFT.
   
   :arg realDom: Describes the indices of the 'real' view of the array
   :type realDom: `domain`
   
   :arg arr: The array to be used as the in-place input/output array.  If passing in an array of `real` elements, the leading dimension of the array must be padded to store 2(n/2 + 1) elements, where `n` is the size of the corresponding dimension of `realDom`.  If passing in an array of `complex` elements, the leading dimension should be (n/2 + 1).  See the `FFTW documentation <http://www.fftw.org/fftw3_doc/Multi_002dDimensional-DFTs-of-Real-Data.html#Multi_002dDimensional-DFTs-of-Real-Data>`_ for more information.
   :type arr: [] `T` where `T` is of type `real(64)` or `complex(128)`
   
   :arg flags: the bitwise-or of any planning-rigor or algorithm-restriction flags that should be used in creating the plan (e.g., :const:`FFTW_MEASURE` ``|`` :const:`FFTW_PRESERVE_INPUT`)
   :type flags: `c_int`
   
   :returns: The :type:`fftw_plan` representing the resulting plan
   

.. function:: proc plan_dft_c2r(input: [?Din] complex(128), output: [?Dout] real(64), flags: c_uint): fftw_plan

   
   Create a plan for a complex-to-real, out-of-place DFT.
   
   :arg input: The input array, whose size and shape must match the output array's, except for the leading dimension which should be n/2 + 1, where n is the size of the output array's leading dimension.  See the `FFTW documentation <http://www.fftw.org/fftw3_doc/Multi_002dDimensional-DFTs-of-Real-Data.html#Multi_002dDimensional-DFTs-of-Real-Data>`_ for more information.
   :type input: [] `complex(128)`
   
   :arg output: The output array
   :type output: [] `real(64)`
   
   :arg flags: the bitwise-or of any planning-rigor or algorithm-restriction flags that should be used in creating the plan (e.g., :const:`FFTW_MEASURE` ``|`` :const:`FFTW_PRESERVE_INPUT`)
   :type flags: `c_int`
   
   :returns: The :type:`fftw_plan` representing the resulting plan
   

.. function:: proc plan_dft_c2r(realDom: domain, arr: [?D] ?t, flags: c_uint): fftw_plan

   
   Create a plan for a complex-to-real, in-place DFT.
   
   :arg realDom: Describes the indices of the 'real' view of the array
   :type realDom: `domain`
   
   :arg arr: The array to be used as the in-place input/output array.  If passing in an array of `real` elements, the leading dimension of the array must be padded to store 2(n/2 + 1) elements, where `n` is the size of the corresponding dimension of `realDom`.  If passing in an array of `complex` elements, the leading dimension should be (n/2 + 1).  See the `FFTW documentation <http://www.fftw.org/fftw3_doc/Multi_002dDimensional-DFTs-of-Real-Data.html#Multi_002dDimensional-DFTs-of-Real-Data>`_ for more information.
   :type arr: [] `T` where `T` is of type `real(64)` or `complex(128)`
   
   :arg flags: the bitwise-or of any planning-rigor or algorithm-restriction flags that should be used in creating the plan (e.g., :const:`FFTW_MEASURE` ``|`` :const:`FFTW_PRESERVE_INPUT`)
   :type flags: `c_int`
   
   :returns: The :type:`fftw_plan` representing the resulting plan
   

.. function:: proc execute(const plan: fftw_plan)

   
   Execute an FFTW plan.
   
   :arg plan: The plan to execute, as computed by a `plan_dft*()` routine.
   :type plan: `fftw_plan`
   

.. function:: proc destroy_plan(plan: fftw_plan)

   
   Destroy an FFTW plan.
   
   :arg plan: The plan to destroy
   :type plan: `fftw_plan`
   

.. function:: proc cleanup()

   
   Clean up FFTW overall.
   

.. data:: const FFTW_FORWARD: c_int

   Request a forward transform (i.e., use a negative exponent in the tranform). 

.. data:: const FFTW_BACKWARD: c_int

   Request a backward transform (i.e., use a positive exponent in the transform). 

.. data:: const FFTW_ESTIMATE: c_uint

   Specify that a simple heuristic should be used to pick a plan
   quickly.  This will prevent the input/output arrays from being
   overwritten during planning. 

.. data:: const FFTW_MEASURE: c_uint

   Specify that FFTW should try and find an optimized plan by
   computing several FFTs and measuring their execution time.
   This can consume some time.
   

.. data:: const FFTW_PATIENT: c_uint

   Specify that FFTW should expend a greater effort finding an
   optimized plan. 

.. data:: const FFTW_EXHAUSTIVE: c_uint

   Specify that FFTW should expend an even greater effort finding an
   optimized plan. 

.. data:: const FFTW_WISDOM_ONLY: c_uint

   This is a special planning mode that is useful for querying
   whether wisdom is available.  When using it, the plan is only
   created when wisdom is available for the given problem; otherwise
   a `null plan` is returned.  This can be combined with other flags
   to create a plan if the wisdom available was created in that mode
   (e.g., :const:`FFTW_WISDOM_ONLY` ``|`` :const:`FFTW_PATIENT`).  For more details on
   this flag and the previous four, refer to `Section 4.3.2
   <http://www.fftw.org/doc/Planner-Flags.html>`_ of the FFTW manual
   

.. data:: const FFTW_DESTROY_INPUT: c_uint

   Specify that an out-of-place transform is permitted to overwrite
   its input array with arbitrary data.  This permits more efficient
   algorithms to be used in some cases. 

.. data:: const FFTW_PRESERVE_INPUT: c_uint

   Specify that an out-of-place transform cannot change its input
   array. 

.. data:: const FFTW_UNALIGNED: c_uint

   Specify that the algorithm may not impose any unusual alignment
   requirements on the input/output arrays.  This flag should not be
   necessary for current Chapel use since the planner will
   automatically detect such cases.  For more details on this flag
   and the previous two, refer to `Section 4.3.2
   <http://www.fftw.org/doc/Planner-Flags.html>`_ of the FFTW manual.
   

