Developer Reference

  • 2020.2
  • 07/15/2020
  • Public Content
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” .
In the Fortran examples, the
use mkl_dfti
statement assumes that:
  • The
    mkl_dfti.f90
    module definition file is already compiled.
  • The
    mkl_dfti.mod
    module file is available.
One-dimensional In-place FFT
! Fortran example. ! 1D complex to complex, and real to conjugate-even Use MKL_DFTI Complex :: X(32) Real :: Y(34) type(DFTI_DESCRIPTOR), POINTER :: My_Desc1_Handle, My_Desc2_Handle Integer :: Status !...put input data into X(1),...,X(32); Y(1),...,Y(32)   ! Perform a complex to complex transform Status = DftiCreateDescriptor( My_Desc1_Handle, DFTI_SINGLE,& DFTI_COMPLEX, 1, 32 ) Status = DftiCommitDescriptor( My_Desc1_Handle ) Status = DftiComputeForward( My_Desc1_Handle, X ) Status = DftiFreeDescriptor(My_Desc1_Handle) ! result is given by {X(1),X(2),...,X(32)}   ! Perform a real to complex conjugate-even transform Status = DftiCreateDescriptor(My_Desc2_Handle, DFTI_SINGLE,& DFTI_REAL, 1, 32) Status = DftiCommitDescriptor(My_Desc2_Handle) Status = DftiComputeForward(My_Desc2_Handle, Y) Status = DftiFreeDescriptor(My_Desc2_Handle) ! result is given in CCS format.  
 
One-dimensional Out-of-place FFT
! Fortran example. ! 1D complex to complex, and real to conjugate-even Use MKL_DFTI Complex :: X_in(32) Complex :: X_out(32) Real :: Y_in(32) Real :: Y_out(34) type(DFTI_DESCRIPTOR), POINTER :: My_Desc1_Handle, My_Desc2_Handle Integer :: Status ...put input data into X_in(1),...,X_in(32); Y_in(1),...,Y_in(32) ! Perform a complex to complex transform 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, X_in, X_out ) Status = DftiFreeDescriptor(My_Desc1_Handle) ! result is given by {X_out(1),X_out(2),...,X_out(32)} ! Perform a real to complex conjugate-even transform Status = DftiCreateDescriptor(My_Desc2_Handle, DFTI_SINGLE, DFTI_REAL, 1, 32) Status = DftiSetValue( My_Desc2_Handle, DFTI_PLACEMENT, DFTI_NOT_INPLACE) Status = DftiCommitDescriptor(My_Desc2_Handle) Status = DftiComputeForward(My_Desc2_Handle, Y_in, Y_out) Status = DftiFreeDescriptor(My_Desc2_Handle) ! result is given by Y_out in CCS format.  
 
Two-dimensional FFT
The following is an example of two simple two-dimensional transforms. Notice that the data and result parameters in computation functions are all declared as assumed-size rank-1 array
DIMENSION(0:*)
. Therefore two-dimensional array must be transformed to one-dimensional array by
EQUIVALENCE
statement or other facilities of Fortran.
! Fortran example. ! 2D complex to complex, and real to conjugate-even Use MKL_DFTI Complex :: X_2D(32,100) Real :: Y_2D(34, 102) Complex :: X(3200) Real :: Y(3468) Equivalence (X_2D, X) Equivalence (Y_2D, Y) type(DFTI_DESCRIPTOR), POINTER :: My_Desc1_Handle, My_Desc2_Handle Integer :: Status, L(2) !...put input data into X_2D(j,k), Y_2D(j,k), 1<=j=32,1<=k<=100 !...set L(1) = 32, L(2) = 100 !...the transform is a 32-by-100   ! Perform a complex to complex transform Status = DftiCreateDescriptor( My_Desc1_Handle, DFTI_SINGLE,& DFTI_COMPLEX, 2, L) Status = DftiCommitDescriptor( My_Desc1_Handle) Status = DftiComputeForward( My_Desc1_Handle, X) Status = DftiFreeDescriptor(My_Desc1_Handle) ! result is given by X_2D(j,k), 1<=j<=32, 1<=k<=100   ! Perform a real to complex conjugate-even transform Status = DftiCreateDescriptor( My_Desc2_Handle, DFTI_SINGLE,& DFTI_REAL, 2, L) Status = DftiCommitDescriptor( My_Desc2_Handle) Status = DftiComputeForward( My_Desc2_Handle, Y) Status = DftiFreeDescriptor(My_Desc2_Handle) ! result is given by the complex value z(j,k) 1<=j<=32; 1<=k<=100 ! 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
! Fortran example ! 1D complex to complex, not in place Use MKL_DFTI Complex :: X_in(32), X_out(32) type(DFTI_DESCRIPTOR), POINTER :: My_Desc_Handle Integer :: Status !...put input data into X_in(j), 1<=j<=32 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 X_out(1),X_out(2),...,X_out(32)
 
Using Status Checking Functions
This example illustrates the use of status checking functions described in
“Fourier Transform Functions”
.
! Fortran type(DFTI_DESCRIPTOR), POINTER :: desc integer status ! ...descriptor creation and other code status = DftiCommitDescriptor(desc) if (status .ne. 0) then if (.not. DftiErrorClass(status,DFTI_NO_ERROR) then print *, 'Error: ‘, DftiErrorMessage(status) endif endif    
 
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.
Notice that the data and result parameters in computation functions are all declared as assumed-size rank-1 array
DIMENSION(0:*)
. Therefore two-dimensional array must be transformed to one-dimensional array by
EQUIVALENCE
statement or other facilities of Fortran.
! Fortran use mkl_dfti Complex :: X_2D(20,40) Complex :: X(800) Equivalence (X_2D, X) INTEGER :: STRIDE(2) type(DFTI_DESCRIPTOR), POINTER :: Desc_Handle_Dim1 type(DFTI_DESCRIPTOR), POINTER :: Desc_Handle_Dim2 ! ... 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 Status = DftiSetValue( Desc_Handle_Dim1, DFTI_NUMBER_OF_TRANSFORMS, 40 ) Status = DftiSetValue( Desc_Handle_Dim1, DFTI_INPUT_DISTANCE, 20 ) Status = DftiSetValue( Desc_Handle_Dim1, DFTI_OUTPUT_DISTANCE, 20 ) Status = DftiCommitDescriptor( Desc_Handle_Dim1 ) Status = DftiComputeForward( Desc_Handle_Dim1, X ) ! perform 20 one-dimensional transforms along 2nd dimension Stride(1) = 0; Stride(2) = 20 Status = DftiSetValue( Desc_Handle_Dim2, DFTI_NUMBER_OF_TRANSFORMS, 20 ) Status = DftiSetValue( Desc_Handle_Dim2, DFTI_INPUT_DISTANCE, 1 ) Status = DftiSetValue( Desc_Handle_Dim2, DFTI_OUTPUT_DISTANCE, 1 ) Status = DftiSetValue( Desc_Handle_Dim2, DFTI_INPUT_STRIDES, Stride ) Status = DftiSetValue( Desc_Handle_Dim2, DFTI_OUTPUT_STRIDES, Stride ) Status = DftiCommitDescriptor( Desc_Handle_Dim2 ) Status = DftiComputeForward( Desc_Handle_Dim2, X ) 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
“Two-Dimensional REAL In-place FFT (Fortran Interface)”
is two-dimensional in-place transform and Example
“Two-Dimensional REAL Out-of-place FFT (Fortran Interface)”
is two-dimensional out-of-place transform in Fortran interface.
Note that the data and result parameters in computation functions are all declared as assumed-size rank-1 array
DIMENSION(0:*)
. Therefore two-dimensional array must be transformed to one-dimensional array by
EQUIVALENCE
statement or other facilities of Fortran.
Two-Dimensional REAL In-place FFT
! Fortran example. ! 2D and real to conjugate-even Use MKL_DFTI Real :: X_2D(34,100) ! 34 = (32/2 + 1)*2 Real :: X(3400) Equivalence (X_2D, X) type(DFTI_DESCRIPTOR), POINTER :: My_Desc_Handle Integer :: Status, L(2) Integer :: strides_in(3) Integer :: strides_out(3) ! ...put input data into X_2D(j,k), 1<=j=32,1<=k<=100 ! ...set L(1) = 32, L(2) = 100 ! ...set strides_in(1) = 0, strides_in(2) = 1, strides_in(3) = 34 ! ...set strides_out(1) = 0, strides_out(2) = 1, strides_out(3) = 17 ! ...the transform is a 32-by-100 ! Perform a real to complex conjugate-even transform Status = DftiCreateDescriptor( My_Desc_Handle, DFTI_SINGLE,& DFTI_REAL, 2, L ) Status = DftiSetValue(My_Desc_Handle, DFTI_CONJUGATE_EVEN_STORAGE,& DFTI_COMPLEX_COMPLEX) Status = DftiSetValue(My_Desc_Handle, DFTI_INPUT_STRIDES, strides_in) Status = DftiSetValue(My_Desc_Handle, DFTI_OUTPUT_STRIDES, strides_out) Status = DftiCommitDescriptor( My_Desc_Handle) Status = DftiComputeForward( My_Desc_Handle, X ) Status = DftiFreeDescriptor(My_Desc_Handle) ! result is given by the complex value z(j,k) 1<=j<=17; 1<=k<=100 and ! is stored in real matrix X_2D in CCE format.
Two-Dimensional REAL Out-of-place FFT
! Fortran example. ! 2D and real to conjugate-even Use MKL_DFTI Real :: X_2D(32,100) Complex :: Y_2D(17, 100) ! 17 = 32/2 + 1 Real :: X(3200) Complex :: Y(1700) Equivalence (X_2D, X) Equivalence (Y_2D, Y) type(DFTI_DESCRIPTOR), POINTER :: My_Desc_Handle Integer :: Status, L(2) Integer :: strides_out(3)