Intel® oneAPI Math Kernel Library
Ask questions and share information with other developers who use Intel® Math Kernel Library.
6977 Discussions

Mult-transform FFT only computes half the points

sudoLife
New Contributor I
553 Views

Hi,

 

As described by me and another person in a similar thread , there's something going on with multi-dimensional transforms.

 

Here's my full example:

test_intel.cpp:

 

#include <mkl.h>
#include <fstream>
#include <iostream>
#include <vector>
#include <complex>

int main(void)
{
    int rangePoints = 1024;
    int rxNum = 8;

    std::vector<double> inputData(rxNum * rangePoints, 0.0);

    // Using MKL_Complex16 yields the same result
    std::vector<std::complex<double>> spectrum(rangePoints * rxNum);

    std::ifstream file("input.txt", std::ifstream::binary);

    file.read(reinterpret_cast<char *>(inputData.data()), sizeof(double) * rxNum * rangePoints);
    // At this point, input data contains 8 arrays in one, row-major.

    DFTI_DESCRIPTOR_HANDLE rangeHandle;

    auto status = DftiCreateDescriptor(&rangeHandle, DFTI_DOUBLE, DFTI_REAL, 1, rangePoints);
    status = DftiSetValue(rangeHandle, DFTI_NUMBER_OF_TRANSFORMS, rxNum);
    status = DftiSetValue(rangeHandle, DFTI_INPUT_DISTANCE, rangePoints);
    status = DftiSetValue(rangeHandle, DFTI_OUTPUT_DISTANCE, rangePoints);
    status = DftiSetValue(rangeHandle, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
    status = DftiCommitDescriptor(rangeHandle);


    DftiComputeForward(rangeHandle, inputData.data(), spectrum.data());

    // Print a few entries to illustrate the point
    // As you will see from the output, half of the data is missing
    for (int i = 0; i < rxNum; i++)
    {
        std::cout << "RX: " << i + 1 << ", Points: ";
        for (int j = 0; j < 10; j++)
        {
            std::cout << spectrum[rangePoints * i + j] << " ";
        }
        std::cout << "\n";
    }

    DftiFreeDescriptor(&rangeHandle);
    return 0;
}

 

CMakeLists.txt:

 

cmake_minimum_required(VERSION 3.15)

project(test_intel LANGUAGES CXX)

add_executable(test_intel test_intel.cpp)
find_package(MKL CONFIG REQUIRED)
target_link_libraries(test_intel PRIVATE MKL::MKL)

 

I'm attaching the input file mentioned in the code as well.

 

The problem is that I only get meaningful data for half of the arrays, the rest of data is zero.

0 Kudos
1 Solution
sudoLife
New Contributor I
507 Views

I found the solution.

 

First, a bit of background: in real-to-complex FFTs, only half of the points are computed. The rest can be reconstructed from the first half due to conjugate-even symmetry.

 

The problem in my example is the DFTI_CONJUGATE_EVEN_STORAGE setting, which by default is set to the deprecated DFTI_COMPLEX_REAL. And my output array elements are std::complex<double>, so I ended up with garbage.

 

Solution: set DFTI_CONJUGATE_EVEN_STORAGE to DFTI_COMPLEX_COMPLEX. Check this link  for more information.

Remember, you still need to reconstruct the second halves of the output arrays if you need them.

 

The rest of the code doesn't need to be changed. So, that's all there is to the story.  Intel, you really need to stop setting deprecated parameter values as defaults.

View solution in original post

0 Kudos
2 Replies
sudoLife
New Contributor I
508 Views

I found the solution.

 

First, a bit of background: in real-to-complex FFTs, only half of the points are computed. The rest can be reconstructed from the first half due to conjugate-even symmetry.

 

The problem in my example is the DFTI_CONJUGATE_EVEN_STORAGE setting, which by default is set to the deprecated DFTI_COMPLEX_REAL. And my output array elements are std::complex<double>, so I ended up with garbage.

 

Solution: set DFTI_CONJUGATE_EVEN_STORAGE to DFTI_COMPLEX_COMPLEX. Check this link  for more information.

Remember, you still need to reconstruct the second halves of the output arrays if you need them.

 

The rest of the code doesn't need to be changed. So, that's all there is to the story.  Intel, you really need to stop setting deprecated parameter values as defaults.

0 Kudos
ShanmukhS_Intel
Moderator
492 Views

Hi sudoLife,


Glad to know that your issue was resolved. Thanks for sharing the solution with us.

We would like to inform you, Although DFTI_CONJUGATE_EVEN_STORAGE=DFTI_COMPLEX_REAL is the default setting for the DFTI_REAL forward domain, we must avoid using this storage scheme. This storage scheme is deprecated for one-dimensional transforms and the default will change in a future release. For two-dimensional transforms, this storage scheme is deprecated, support will be removed, and the default will change in a future release as well.


If you need any additional information, please post a new question as this thread will no longer be monitored by Intel.


Best Regards,

Shanmukh.SS


0 Kudos
Reply