Developer Reference for Intel® oneAPI Math Kernel Library for C

ID 766684
Date 11/07/2023
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

FFT Code Examples

This section presents examples of using the FFT interface functions described in "Fourier Transform Functions".

Here are the examples of two one-dimensional computations. These examples use the default settings for all of the configuration parameters, which are specified in "Configuration Settings".

One-dimensional In-place FFT

/* C example, float _Complex is defined in C9X */
#include "mkl_dfti.h"

float _Complex c2c_data[32];
float r2c_data[34];
DFTI_DESCRIPTOR_HANDLE my_desc1_handle = NULL;
DFTI_DESCRIPTOR_HANDLE my_desc2_handle = NULL;
MKL_LONG status;

/* ...put values into c2c_data[i] 0<=i<=31 */
/* ...put values into r2c_data[i] 0<=i<=31 */

status = DftiCreateDescriptor(&my_desc1_handle, DFTI_SINGLE,
                              DFTI_COMPLEX, 1, 32);
status = DftiCommitDescriptor(my_desc1_handle);
status = DftiComputeForward(my_desc1_handle, c2c_data);
status = DftiFreeDescriptor(&my_desc1_handle);
/* result is c2c_data[i] 0<=i<=31 */
status = DftiCreateDescriptor(&my_desc2_handle, DFTI_SINGLE,
                              DFTI_REAL, 1, 32);
status = DftiCommitDescriptor(my_desc2_handle);
status = DftiComputeForward(my_desc2_handle, r2c_data);
status = DftiFreeDescriptor(&my_desc2_handle);
/* result is the complex value r2c_data[i] 0<=i<=31 */
/* and is stored in CCS format*/
 

 

One-dimensional Out-of-place FFT

/* C example, float _Complex is defined in C9X */
#include "mkl_dfti.h"

float _Complex c2c_input[32];
float _Complex c2c_output[32];
float r2c_input[32];
float r2c_output[34];
DFTI_DESCRIPTOR_HANDLE my_desc1_handle = NULL;
DFTI_DESCRIPTOR_HANDLE my_desc2_handle = NULL;
MKL_LONG status;

/* ...put values into c2c_input[i] 0<=i<=31 */
/* ...put values into r2c_input[i] 0<=i<=31 */

status = DftiCreateDescriptor(&my_desc1_handle, DFTI_SINGLE,
                              DFTI_COMPLEX, 1, 32);
status = DftiSetValue(my_desc1_handle, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
status = DftiCommitDescriptor(my_desc1_handle);
status = DftiComputeForward(my_desc1_handle, c2c_input, c2c_output);
status = DftiFreeDescriptor(&my_desc1_handle);
/* result is c2c_output[i] 0<=i<=31 */
status = DftiCreateDescriptor(&my_desc2_handle, DFTI_SINGLE,
                              DFTI_REAL, 1, 32);
Status = DftiSetValue(my_desc1_handle, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
status = DftiCommitDescriptor(my_desc2_handle);
status = DftiComputeForward(my_desc2_handle, r2c_input, r2c_output);
status = DftiFreeDescriptor(&my_desc2_handle);
/* result is the complex r2c_data[i] 0<=i<=31   and is stored in CCS format*/
 

 

Two-dimensional FFT

/* C99 example */
#include "mkl_dfti.h"

/* complex data in, complex data out */
float _Complex c2c_data[32][100];
/* real data in, complex data out */
float r2c_data[34][102];
DFTI_DESCRIPTOR_HANDLE my_desc1_handle = NULL;
DFTI_DESCRIPTOR_HANDLE my_desc2_handle = NULL;
MKL_LONG status;MKL_LONG dim_sizes[2] = {32, 100};

/* ...put values into c2c_data[i][j] 0<=i<=31, 0<=j<=99 */
/* ...put values into r2c_data[i][j] 0<=i<=31, 0<=j<=99 */

status = DftiCreateDescriptor(&my_desc1_handle, DFTI_SINGLE,
                              DFTI_COMPLEX, 2, dim_sizes);
status = DftiCommitDescriptor(my_desc1_handle);
status = DftiComputeForward(my_desc1_handle, c2c_data);
status = DftiFreeDescriptor(&my_desc1_handle);
/* result is the complex value c2c_data[i][j], 0<=i<=31, 0<=j<=99 */
status = DftiCreateDescriptor(&my_desc2_handle, DFTI_SINGLE,
                              DFTI_REAL, 2, dim_sizes);
status = DftiCommitDescriptor(my_desc2_handle);
status = DftiComputeForward(my_desc2_handle, r2c_data);
status = DftiFreeDescriptor(&my_desc2_handle);
/* result is the complex r2c_data[i][j] 0<=i<=31, 0<=j<=99
   and is stored in CCS format*/
 

 

The following example demonstrates how you can change the default configuration settings by using the DftiSetValue function.

For instance, to preserve the input data after the FFT computation, the configuration of DFTI_PLACEMENT should be changed to "not in place" from the default choice of "in place."

The code below illustrates how this can be done:

Changing Default Settings

/* C99 example */
#include "mkl_dfti.h"

float  _Complex x_in[32], x_out[32];
DFTI_DESCRIPTOR_HANDLE my_desc_handle = NULL;
MKL_LONG status;

/* ...put values into x_in[i] 0<=i<=31 */

status = DftiCreateDescriptor(&my_desc_handle, DFTI_SINGLE,
                              DFTI_COMPLEX, 1, 32);
status = DftiSetValue(my_desc_handle, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
status = DftiCommitDescriptor(my_desc_handle);
status = DftiComputeForward(my_desc_handle, x_in, x_out);
status = DftiFreeDescriptor(&my_desc_handle);
/* result is the complex value x_out[i], 0<=i<=31 */
 

 

Using Status Checking Functions

This example illustrates the use of status checking functions described in "Fourier Transform Functions".

/* C99 example */
#include "mkl_dfti.h"

DFTI_DESCRIPTOR_HANDLE desc = NULL;
MKL_LONG status;

/* ...descriptor creation and other code */

status = DftiCommitDescriptor(desc);
if (status && !DftiErrorClass(status, DFTI_NO_ERROR))
{
   printf('Error: %s\n', DftiErrorMessage(status));
}

 

Computing 2D FFT by One-Dimensional Transforms

Below is an example where a 20-by-40 two-dimensional FFT is computed explicitly using one-dimensional transforms.

/* C */
#include "mkl_dfti.h"

float _Complex data[20][40];
MKL_LONG status;
DFTI_DESCRIPTOR_HANDLE desc_handle_dim1 = NULL;
DFTI_DESCRIPTOR_HANDLE desc_handle_dim2 = NULL;

/* ...put values into data[i][j] 0<=i<=19, 0<=j<=39 */

status = DftiCreateDescriptor(&desc_handle_dim1, DFTI_SINGLE,
                              DFTI_COMPLEX, 1, 20);
status = DftiCreateDescriptor(&desc_handle_dim2, DFTI_SINGLE,
                              DFTI_COMPLEX, 1, 40);

/* perform 40 one-dimensional transforms along 1st dimension */
/* note that the 1st dimension data are not unit-stride */
MKL_LONG stride[2] = {0, 40};

status = DftiSetValue(desc_handle_dim1, DFTI_NUMBER_OF_TRANSFORMS, 40);
status = DftiSetValue(desc_handle_dim1, DFTI_INPUT_DISTANCE, 1);
status = DftiSetValue(desc_handle_dim1, DFTI_OUTPUT_DISTANCE, 1);
status = DftiSetValue(desc_handle_dim1, DFTI_INPUT_STRIDES, stride);
status = DftiSetValue(desc_handle_dim1, DFTI_OUTPUT_STRIDES, stride);
status = DftiCommitDescriptor(desc_handle_dim1);
status = DftiComputeForward(desc_handle_dim1, data);
/* perform 20 one-dimensional transforms along 2nd dimension */
/* note that the 2nd dimension is unit stride */
status = DftiSetValue(desc_handle_dim2, DFTI_NUMBER_OF_TRANSFORMS, 20);
status = DftiSetValue(desc_handle_dim2, DFTI_INPUT_DISTANCE, 40);
status = DftiSetValue(desc_handle_dim2, DFTI_OUTPUT_DISTANCE, 40);
status = DftiCommitDescriptor(desc_handle_dim2);
status = DftiComputeForward(desc_handle_dim2, data);
status = DftiFreeDescriptor(&desc_handle_dim1);
status = DftiFreeDescriptor(&desc_handle_dim2); 
 
 

 

The following code illustrates real multi-dimensional transforms with CCE format storage of conjugate-even complex matrix. Example "Three-Dimensional REAL FFT (C Interface)" is three-dimensional out-of-place transform in C interface.

Three-Dimensional REAL FFT

 
/* C99 example */
#include "mkl_dfti.h"

float input[32][100][19];
float _Complex output[32][100][10];  /* 10 = 19/2 + 1 */
DFTI_DESCRIPTOR_HANDLE my_desc_handle = NULL;
MKL_LONG status;
MKL_LONG dim_sizes[3] = {32, 100, 19};
MKL_LONG strides_out[4] = {0, 100*10*1, 10*1, 1};

//...put values into input[i][j][k] 0<=i<=31; 0<=j<=99, 0<=k<=9

status = DftiCreateDescriptor(&my_desc_handle,
                              DFTI_SINGLE, DFTI_REAL, 3, dim_sizes);
status = DftiSetValue(my_desc_handle,
                      DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX);
status = DftiSetValue(my_desc_handle, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
status = DftiSetValue(my_desc_handle, DFTI_OUTPUT_STRIDES, strides_out);

status = DftiCommitDescriptor(my_desc_handle);
status = DftiComputeForward(my_desc_handle, input, output);
status = DftiFreeDescriptor(&my_desc_handle);
/* result is the complex output[i][j][k] 0<=i<=31; 0<=j<=99, 0<=k<=9
   and is stored in CCE format. */