Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

Fourier transfom in c#

L_Y_
Beginner
561 Views

Hi,

I have been looking for a working example for the fourier transform using IPP in C#. Issue here is most of the example code here don’t work with the IPP version 9.0.

I wrote following code finally but unfortunately no data is assigned to the destination array. What might be the problem here?

And I have real signal and I create a complex signal to apply fft. Is it better to do fft directly using real signal?

Thanks!

 

using System.Runtime.InteropServices;
using ipp;

namespace IntelIPP_Test
{
    unsafe public class Program
    {
        // Spec and working buffers
        static IppsFFTSpec_C_32fc* pFFTSpec;
        static byte[] pFFTSpecBuf, pFFTInitBuf, pFFTWorkBuf;

        // Allocate complex buffers
        static Ipp32fc[] pSrc, pDst;

        // Query to get buffer sizes
        static int _sizeFFTSpec, _sizeFFTInitBuf, _sizeFFTWorkBuf;

        //Set the size
        static int N = 128;
        static int order = (int)(Math.Log10((double)N) / Math.Log10(2.0));

        static void Main(string[] args)
        {
            // Query to get buffer sizes
            int ippDivisionAlgorithm = 8; // (int)sp.IPP_FFT_DIV_INV_BY_N;
            IppHintAlgorithm ippPerformanceHint = IppHintAlgorithm.ippAlgHintAccurate; 

            IppStatus result;

            fixed (int* sizeFFTSpec = &_sizeFFTSpec, sizeFFTInitBuf = &_sizeFFTInitBuf, sizeFFTWorkBuf = &_sizeFFTWorkBuf)
            {
                result = sp.ippsFFTGetSize_C_32fc(order, ippDivisionAlgorithm, ippPerformanceHint, 
                    sizeFFTSpec, sizeFFTInitBuf, sizeFFTWorkBuf);
            }

            // Alloc FFT buffers
            pFFTSpecBuf = new byte[_sizeFFTSpec];
            pFFTInitBuf = new byte[_sizeFFTInitBuf];
            pFFTWorkBuf = new byte[_sizeFFTWorkBuf];

            // Initialize FFT
            fixed (byte* p_dftInitBuf = pFFTInitBuf)
            fixed (byte* p_dftSpecBuf = pFFTSpecBuf)
            {
                var p_dftSpec = (IppsFFTSpec_C_32fc*)pFFTSpec;

                result = sp.ippsFFTInit_C_32fc(&p_dftSpec, order, ippDivisionAlgorithm, ippPerformanceHint, p_dftSpecBuf, p_dftInitBuf);
            }            

            getData(); // to assign data to pSrc

            fixed (Ipp32fc* pSource = pSrc, pssDst = pDst)
            fixed (byte* p_workBuffer = pFFTWorkBuf)
            fixed (byte* p_dftSpecBuf = pFFTSpecBuf)
            {
                var p_dftSpec = (IppsFFTSpec_C_32fc*)p_dftSpecBuf;

                // Fast Forward Fourier to spectra domain
                sp.ippsFFTFwd_CToC_32fc(pSource, pssDst, p_dftSpec, p_workBuffer);
            }
        }

 

0 Kudos
2 Replies
Ying_H_Intel
Employee
561 Views

Hi L.Y.

You mentioned, most of the example code here don’t work with the IPP version 9.0.  I recalled there is some C# sample in previous version, do you mean them?

I search them, include MKL C# sample,  it seems no FFT sample, 

https://software.intel.com/en-us/articles/using-intel-mkl-in-your-c-program

Could you attach the small test case, so I can debug directly? 

Best Regards

Ying 

0 Kudos
L_Y_
Beginner
561 Views

Hi Ying,

Thanks for your response. Actually, I used "here" in context of Intel IPP forum. I have searched through forum using "c# fft" and "c# fourier" keywords and evaluated the codes found. For example:

https://software.intel.com/en-us/forums/intel-integrated-performance-primitives/topic/306767

https://software.intel.com/en-us/forums/intel-integrated-performance-primitives/topic/304898

https://software.intel.com/en-us/forums/intel-integrated-performance-primitives/topic/309242

https://software.intel.com/en-us/forums/intel-integrated-performance-primitives/topic/309240

All examples use "ippsFFTInitAlloc_R_32f" for initialization. I have written finally following codes for the fft of real signal.

namespace IntelIPP_Test
{
    unsafe public class program3
    {

        static byte[] fFTSpecBuf, fFTInitBuf, fFTWorkBuf;

        // Query to get buffer sizes
        static int sizeFFTSpec, sizeFFTInitBuf, sizeFFTWorkBuf;

        static IppsFFTSpec_R_32f ppFFTSpec2 = new IppsFFTSpec_R_32f();
    
        //Set the size
        static int N = 8;
        static int order = (int)(Math.Log10((double)N) / Math.Log10(2.0));

        static float[] h = { 1.0f / 3, 1.0f / 3, 1.0f / 3, 0, 0, 0, 0, 0 };
        static float[] x = new float[8];
        static float[] X = new float[8];
        static float[] H = new float[8];


        public static void Main()
        {
            // initialize status
            IppStatus st;
                        
            // Query to get buffer sizes
            int ippDivisionAlgorithm = 4; 
            IppHintAlgorithm ippPerformanceHint = IppHintAlgorithm.ippAlgHintAccurate; 

            // Query to get buffer sizes
            fixed (int* p_sizeFFTSpec = &sizeFFTSpec, p_sizeFFTInitBuf = &sizeFFTInitBuf, p_sizeFFTWorkBuf = &sizeFFTWorkBuf)
            {
                st = sp.ippsFFTGetSize_R_32f(N, ippDivisionAlgorithm, ippPerformanceHint, p_sizeFFTSpec, p_sizeFFTInitBuf, p_sizeFFTWorkBuf);               
            }

            // Alloc FFT buffers
            fFTSpecBuf = new byte[sizeFFTSpec];
            fFTInitBuf = new byte[sizeFFTInitBuf];
            fFTWorkBuf = new byte[sizeFFTWorkBuf];

            // Initialize FFT
            fixed(IppsFFTSpec_R_32f* ppFFTSpec = &ppFFTSpec2)
            fixed (byte* p_fftInitBuf = fFTInitBuf)
            fixed (byte* p_fftSpecBuf = fFTSpecBuf)
            {
                IppsFFTSpec_R_32f* _ppFFTSpec = (IppsFFTSpec_R_32f*)ppFFTSpec;

                st = sp.ippsFFTInit_R_32f(&_ppFFTSpec, N, ippDivisionAlgorithm, ippPerformanceHint, p_fftSpecBuf, p_fftInitBuf);
            }
            

            fixed(IppsFFTSpec_R_32f* pSpec3 = &ppFFTSpec2)
            fixed (byte* p_FFTWorkBuf = fFTWorkBuf)
            fixed (float* px = x, pX = X, ph = h, pH = H)
            {

                IppsFFTSpec_R_32f* _ppFFTSpec = (IppsFFTSpec_R_32f*)pSpec3;

                st = sp.ippsSet_32f(3.0f, px, 8);

                x[3] = 5.0f;

                st = sp.ippsFFTFwd_RToCCS_32f(px, pX, _ppFFTSpec, null);
                st = sp.ippsFFTFwd_RToPerm_32f(px, pX, _ppFFTSpec, null);
                st = sp.ippsFFTFwd_RToPack_32f(px, pX, _ppFFTSpec, null);

                //________________________

                st = sp.ippsFFTFwd_RToCCS_32f(ph, pH, _ppFFTSpec, null);
                st = sp.ippsFFTFwd_RToPerm_32f(ph, pH, _ppFFTSpec, null);
                st = sp.ippsFFTFwd_RToPack_32f(ph, pH, _ppFFTSpec, null);

                //________________________

                st = sp.ippsFFTFwd_RToPack_32f(ph, pH, _ppFFTSpec, null);

                st = sp.ippsMulPack_32f_I(pH, pX, 8);

                st = sp.ippsFFTInv_PackToR_32f(pX, px, _ppFFTSpec, null);

            }


        }

    }

 

At the end of the code, I would like to try different kind of conversions (ippsFFTFwd_RToCCS_32f, ippsFFTFwd_RToPerm_32f, ippsFFTFwd_RToPack_32f). However, I get following error as status for all cases: "ippStsContextMatchErr". I would be grateful if you can have a look at my code. And other issue is using of "ippsFree" which I couldn't find a way to make it work.

Thanks,

L.Y.

0 Kudos
Reply