Developer Reference for Intel® oneAPI Math Kernel Library for C
DFTI_FWD_STRIDES, DFTI_BWD_STRIDES
The FFT interface provides configuration parameters that define the layout of multidimensional data in the computer memory. For \(d\)-dimensional data set \(X\) defined by dimensions \(N_1 \times N_2 \times \dots \times N_d\), the layout describes where a particular element \(X(k_1, k_2, \dots, k_d)\) of the data set is located. The memory address of the element \(X(k_1, k_2, \dots, k_d)\) is
\[\text{address of } X(k_1, k_2, \dots, k_d) = \text{ptr} + (s_0 + k_1 \times s_1 + k_2 \times s_2 + \dots + k_d \times s_d) \times u\]
where
ptr is the address stored in the pointer supplied to the compute function
\(u\) is the number of bytes per element of the desired precision for the assumed data type in the corresponding domain (see the table Assumed Element Types in the Forward and Backward Domains)
\(s_0\) is the displacement
\(s_1, \dots, s_d\) are generalized strides.
The configuration parameters DFTI_FWD_STRIDES and DFTI_BWD_STRIDES enable you to get and set these values. The configuration value is an array of values \((s_0, s_1, \dots, s_d)\) of MKL_LONG data type.
The DFTI_FORWARD_DOMAIN, DFTI_COMPLEX_STORAGE, and DFTI_CONJUGATE_EVEN_STORAGE configuration parameters define the type of the elements as shown in the table Assumed Element Types in the Forward and Backward Domains :
Assumed Element Types in the Forward and Backward Domains
Descriptor Configuration |
Element Type in the Forward Domain |
Element Type in the Backward Domain |
|---|---|---|
DFTI_FORWARD_DOMAIN=DFTI_COMPLEXDFTI_COMPLEX_STORAGE=DFTI_COMPLEX_COMPLEX |
Complex |
Complex |
DFTI_FORWARD_DOMAIN=DFTI_COMPLEXDFTI_COMPLEX_STORAGE=DFTI_REAL_REAL |
Real |
Real |
DFTI_FORWARD_DOMAIN=DFTI_REALDFTI_CONJUGATE_EVEN_STORAGE=DFTI_COMPLEX_REAL |
Real |
Real |
DFTI_FORWARD_DOMAIN=DFTI_REALDFTI_CONJUGATE_EVEN_STORAGE=DFTI_COMPLEX_COMPLEX |
Real |
Complex |
The DFTI_FWD_STRIDES configuration parameter defines the layout of data in the forward domain, and DFTI_BWD_STRIDES defines the layout of data in the backward domain. For DftiComputeForward, the forward-domain layout describes the input and the backward-domain layout describes the output. For DftiComputeBackward, the backward-domain layout describes the input and the forward-domain layout describes the output. Therefore, the same committed descriptor can be used for both computation directions without interchanging stride settings.
For in-place transforms ( DFTI_PLACEMENT=DFTI_INPLACE ) that use the same physical layout in both domains, the forward-domain and backward-domain layouts must be equivalent. When the domains use different physical layouts, set both layouts explicitly. Ensure a consistent configuration for in-place transforms, that is, the memory address of the leading entries along the last dimension as laid out by DFTI_FWD_STRIDES and DFTI_BWD_STRIDES must be identical in forward and backward domains.
The FFT interface supports both positive and negative stride values. If you use negative strides, set the displacement of the data as follows:
\[s_0 = \sum_{i=1}^d (N_i - 1) \times \max(-s_i, 0)\]
By default, the library selects a tightly packed layout for each domain. The order of the strides depends on the programming language. For example:
MKL_LONG dims[] = { n_d, ..., n_2, n_1 };
DftiCreateDescriptor(&hand, precision, domain, d, dims);
// The above call assumes data declaration: type X[n_d] ...[n_2][n_1]
// Default strides are { 0, n_{d-1}*...*n_2*n_1, ..., n_2*n_1*1, n_1*1, 1 }
Note that in case of a real FFT (DFTI_FORWARD_DOMAIN=DFTI_REAL), where different data layouts in the backward domain are available (see DFTI_PACKED_FORMAT), the default value of the strides is not intuitive for the recommended CCE format (configuration setting DFTI_CONJUGATE_EVEN_STORAGE=DFTI_COMPLEX_COMPLEX). In case of an in-place real transform with the CCE format, set the strides explicitly, as follows:
MKL_LONG dims[] = { n_{d}, ..., n_{2}, n_{1} };
MKL_LONG rstrides[] = { 0, 2*n_{d-1}*...*n_{2}*(n_{1}/2+1), ..., 2*n_{2}*(n_{1}/2+1), 2*(n_{1}/2+1), 1 };
MKL_LONG cstrides[] = { 0, n_{d-1}*...*n_{2}*(n_{1}/2+1), ..., n_{2}*(n_{1}/2+1), (n_{1}/2+1), 1 };
DftiCreateDescriptor(&hand, precision, DFTI_REAL, d, dims);
DftiSetValue(hand, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX);
DftiSetValue(hand, DFTI_FWD_STRIDES, rstrides);
DftiSetValue(hand, DFTI_BWD_STRIDES, cstrides);
Limitation Note
Real, in-place transforms with the number of points \(N\) of a non-unit stride dimension exceeding \(2^{27-p} -1\) for \(N\) a power-of-two, or \(2^{23-p} -1\) for \(N\) not a power-of-two, are currently not supported, where \(p=0\) for single precision and \(p=1\) for double precision. If a descriptor is created (for example, using DftiCreateDescriptor) and set (for example, using DftiSetValue) to do such a transform, a DFTI_1D_MEMORY_EXCEEDS_INT32 error is returned at commit time (for example, by DftiCommitDescriptor).To better understand configuration of strides, you can also refer to these examples in your Intel® oneAPI Math Kernel Library (oneMKL) directory:
./examples/dftc/source/basic_sp_complex_dft_2d.c
./examples/dftc/source/basic_sp_complex_dft_3d.c
./examples/dftc/source/basic_dp_complex_dft_2d.c
./examples/dftc/source/basic_dp_complex_dft_3d.c
./examples/dftc/source/basic_sp_real_dft_2d.c
./examples/dftc/source/basic_sp_real_dft_3d.c
./examples/dftc/source/basic_dp_real_dft_2d.c
./examples/dftc/source/basic_dp_real_dft_3d.c