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

Convert FFT to IPP

jupiter_s_
Beginner
934 Views

I want to convert a source script in c/c++ to IPP, but output's not right.

 [cpp]void four1(double data[], int nn, int isign)

{
int n, mmax, m, j, istep, i;
double wtemp, wr, wpr, wpi, wi, theta;
double tempr, tempi;

n = nn << 1;
j = 1;
for (i = 1; i < n; i += 2) {
if (j > i) {
tempr = data; data = data; data = tempr;
tempr = data[j+1]; data[j+1] = data[i+1]; data[i+1] = tempr;
}
m = n >> 1;
while (m >= 2 && j > m) {
j -= m;
m >>= 1;
}
j += m;
}
mmax = 2;
while (n > mmax) {
istep = 2*mmax;
theta = TWOPI/(isign*mmax);
wtemp = sin(0.5*theta);
wpr = -2.0*wtemp*wtemp;
wpi = sin(theta);
wr = 1.0;
wi = 0.0;
for (m = 1; m < mmax; m += 2) {
for (i = m; i <= n; i += istep) {
j =i + mmax;
tempr = wr*data - wi*data[j+1];
tempi = wr*data[j+1] + wi*data;
data = data - tempr;
data[j+1] = data[i+1] - tempi;
data += tempr;
data[i+1] += tempi;
}
wr = (wtemp = wr)*wpr - wi*wpi + wr;
wi = wi*wpr + wtemp*wpi + wi;
}
mmax = istep;
}
}[/cpp]

I convert to below source but output data is not right.

 [cpp]

void fft_ipp( double data[], int nn, int isign )
{
const int order = (int)log(((double)(nn)) / log(2.0));
Ipp64fc *pTmp = ippsMalloc_64fc((1<<order)+2);

// Spec and working buffers
IppsFFTSpec_C_64fc * pFFTSpec=0;
Ipp8u *pFFTSpecBuf, *pFFTInitBuf, *pFFTWorkBuf;
// Query to get buffer sizes
int sizeFFTSpec,sizeFFTInitBuf,sizeFFTWorkBuf;
ippsFFTGetSize_C_64fc(order, IPP_FFT_NODIV_BY_ANY,
ippAlgHintAccurate, &sizeFFTSpec, &sizeFFTInitBuf, &sizeFFTWorkBuf);
// Alloc FFT buffers
pFFTSpecBuf = ippsMalloc_8u(sizeFFTSpec);
pFFTInitBuf = ippsMalloc_8u(sizeFFTInitBuf);
pFFTWorkBuf = ippsMalloc_8u(sizeFFTWorkBuf);
// Initialize FFT
ippsFFTInit_C_64fc(&pFFTSpec, order, IPP_FFT_NODIV_BY_ANY, ippAlgHintAccurate, pFFTSpecBuf, pFFTInitBuf);
if (pFFTInitBuf) ippFree(pFFTInitBuf);

// Do FFT
if(isign > 0)
{
ippsFFTFwd_CToC_64fc((Ipp64fc*)data, (Ipp64fc*)data, pFFTSpec, pFFTWorkBuf);
}
else
{
ippsFFTInv_CToC_64fc((Ipp64fc*)data, (Ipp64fc*)data, pFFTSpec, pFFTWorkBuf);
}
if (pFFTWorkBuf) ippFree(pFFTWorkBuf);
if (pFFTSpecBuf) ippFree(pFFTSpecBuf);
ippsFFTFree_C_64fc(pFFTSpec);
}

[/cpp]

Please help me!

0 Kudos
3 Replies
jupiter_s_
Beginner
934 Views

Add test file

0 Kudos
Igor_A_Intel
Employee
934 Views

Hi,

attached one works correctly - the main issue in your code - wrong callculation of order for ippsFFT - C always rounds result to zero - so in your case you have 3 instead of 4. One more minor bug - you should not use ippsFFTFree, this one should be used with InitAlloc only (when allocations are performed by IPP functions internally). And main performance bug - if you've created FFT Spec once - you should not free it before you do all required transforms, you shouldn't create it twice for fwd and inv operations. Also I corrected normalization flag - it should be done internally.

regards, Igor

0 Kudos
jupiter_s_
Beginner
934 Views

Tks u very much!

0 Kudos
Reply