Intel® oneAPI Math Kernel Library Developer Reference - C
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”.
/* 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*/
/* 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*/
/* 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:
/* 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 */
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)); }
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.
/* 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. */