Intel® IPP provides several functions to compute the forward and reverse fast Fourier transform algorithm for real or complex data. While there are 1D and 2D versions in the library, this article will focus on 1D.
There are two sets of functions: DFT and FFT. For a general single interface, use DFT. The DFT functions implement the FFT algorithm for arbitrary array sizes, including powers of 2. The Intel® IPP FFT functions are limited to powers of 2. Internally, the DFT functions check for a power of 2 input size and call the FFT functions for that special case. If you only use power of 2 sizes you can skip these checks and call the FFT functions directly.
In previous versions of Intel® IPP buffers for internal state, twiddle factors, etc. were allocated internally. As a general Intel® IPP strategy, allowing your application to handle these buffers directly gives you more options and control. Internal allocations are now deprecated.
Note, starting from IPP version 9.0, the DFTInitAlloc_* or FFTAllocInit_* are removed, please replace the *InitAlloc* APIs by the *GetSize_*, and *Init_* APIs, as showed in the bellow examples.
Here is a basic description of the external buffer initialization sequence for Intel® IPP FFT. This pattern is a familiar one, used for many Intel® IPP functions.
1) Query the implementation to get the sizes of required buffers and allocate them. For FFT this is
- A "spec" to hold configuration details, coefficients/twiddle factors, etc.
- A working buffer for initialization (used in init only -- can be freed immediately after)
- A working buffer for the FFT operation
2) Do the init step. This is separate from the main function so that anything that can be precalculated for a specific signal size, normalization, and accuracy hint can be done outside of a loop. This precalculated information is referenced later through the spec structure.
3) do the FFT. The necessary inputs are
- Input and output buffer. In most cases these can be the same. That is, the destination buffer can be the source buffer for in-place operation.
- The spec (holds anything where there is a speed advantage to precalculate).
- The working buffer (holds any temporary values).
Example code implementing all of these steps with external allocation is below. There are many similarities between FFT and DFT, with just a few differences to note. One is that DFT uses a signed integer length while FFT uses a power of 2 order. The other is that ippsFFTInit returns an aligned pointer to the spec. When buffers are allocated with Intel® IPP malloc, they are already aligned so this will be the same address as the original spec buffer.
DFT: (Use this for a general implementation, power of 2 and any other size.)
FFT: (Special power of 2 only case, skips a few checks so may be minimally faster than calling DFT.)
Error/status checks are omitted above for shorter presentation. However, especially for larger signal sizes, checking the status of the GetSize and Init steps can be important. There is no simple formula to determine the largest supported size.
The goal of this article is to provide a starting point for developing applications using IPP's 1D Fourier transform functions. For more please see the IPP reference manual.
"