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

The FFT adjusts only half size...

siinii
Beginner
225 Views

I attacthed the example source and the results.

Please check it.

Best regards

siinii

--------------------------------------------------------------------------------------------------------------------- -----

The excerpt looks good, and it should process whole array.

Could you provide a self-contained example that shows your problem?

Thanks

Dima

--------------------------------------------------------------------------------------------------------------------- -----

I received below source code from Dima. I adjusted it to image.

--------------------------------------------------------------------------------------------------------------------- -----

You probably did the small size on a static array, defined as x[100][40]. The way the dynamic array is arranged in your example is incorrect and it demonstrates typical mistake. For static array '_complex x' expression 'x' has type '_complex *' whereas for dynamic array that one would use with double-subscript notation 'x' the type of 'x' is '_complex**' that is pointer to pointers. In other words, in this example when you call DftiComputeForward(..., x) the input data to the FFT routine is pointers, not the complex numbers!

I'd suggest you to refrain from the practice of using double-subscript notation for dynamic arrays, and adopt the following usage instead:

const int ROWS=3072, COLS=2560;

const int ROWSIZE=COLS, COLSIZE=ROWS;

_complex *x = new _complex[ROWS*COLS];

#define x(r,c) x[*ROWSIZE+(c)] /* explicit row-major indexing */

memset(x,0,sizeof(x[0])*ROWS*COLS); /* zero fill initialization */

for (r=0;r

The rest of this reply is duplicating your example in the above terms.

DftiCreateDescriptor(rowfft,DFTI_SINGLE,DFTI_COMPLEX,1,ROWSIZE); /* stride 1 by default */

DftiSetValue(rowfft,DFTI_NUMBER_OF_TRANSFORMS,(MKL_LONG)ROWS);

DftiSetValue(rowfft,DFTI_INPUT_DISTANCE,(MKL_LONG)ROWSIZE);

DftiSetValue(rowfft,DFTI_OUTPUT_DISTANCE,(MKL_LONG)ROWSIZE);

DftiCreateDescriptor(colfft,DFTI_SINGLE,DFTI_COMPLEX,1,COLSIZE); /* will set strides */

MKL_LONG colfft_strides[] = { 0, ROWSIZE };

DftiSetValue(colfft,DFTI_INPUT_STRIDES,colfft_strides);

DftiSetValue(colfft,DFTI_OUTPUT_STRIDES,colfft_strides);

DftiSetValue(colfft,DFTI_NUMBER_OF_TRANSFORMS,(MKL_LONG)COLS);

DftiSetValue(colfft,DFTI_INPUT_DISTANCE,(MKL_LONG)1);

DftiSetValue(colfft,DFTI_OUTPUT_DISTANCE,(MKL_LONG)1);

...

DftiComputeForward(rowfft,x);

DftiComputeForward(colfft,x);

Thanks

Dima

--------------------------------------------------------------------------------------------------------------------- -----

///FFT

DftiComputeForward(rowfft,x);

DftiComputeForward(colfft,x);

//Inverse FFT

DftiComputeBackward(rowfft,x);

DftiComputeBackward(colfft,x);

like this...

but The FFT adjusted only 2560*1536(original image size is 2560*3072)

Which code should I change?

0 Kudos
1 Reply
barragan_villanueva_
Valued Contributor I
225 Views

Hi,

See below slightly corrected test (on plain Cbut printing elements) with just added scaling because DFTI is not normalized.

Also, the last loop at the end was deleted (maybe,it's your problem?)

#include "stdio.h"
#include "string.h"
#include "mkl.h"

typedef struct {float x,y;} singlecomplex;
int main(void) {
int r,c;

const int ROWS=3072, COLS=2560;
//const int ROWS=3, COLS=5;

const int ROWSIZE=COLS, COLSIZE=ROWS;

//float complex *xx; = new _complex[ROWS*COLS];
singlecomplex* xx;

xx = (singlecomplex *)malloc(2*sizeof(float)*ROWS*COLS);

memset(xx,0,2*sizeof(float)*ROWS*COLS); /* zero fill initialization */

for(r=0;r{
for (c=0;c{
xx[*ROWSIZE+(c)].x = r*10.0f+c;
xx[*ROWSIZE+(c)].y = c*10.0f+r;
//xx[*ROWSIZE+(c)].x = (img[*ROWSIZE+(c)]);
//xx[*ROWSIZE+(c)].y = (img[*ROWSIZE+(c)]);
//printf("init xx[%d,%d]=%f %f\n", r, c, xx[*ROWSIZE+(c)].x, xx[*ROWSIZE+(c)].y);
}
}
printf("init xx[*-1,*-1]=%f %f\n", xx[(ROWS-1)*ROWSIZE+(COLS-1)].x, xx[(ROWS-1)*ROWSIZE+(COLS-1)].y);

int Height_f = ROWS;
int Widtht_f = COLS;

DFTI_DESCRIPTOR_HANDLE rowfft;
DFTI_DESCRIPTOR_HANDLE colfft;
MKL_LONG status;
MKL_LONG colfft_strides[] = {0, ROWSIZE};

////////////////////////////////////////////////////////////////////////////////////////

status = DftiCreateDescriptor(&rowfft, DFTI_SINGLE, DFTI_COMPLEX, 1, (MKL_LONG)ROWSIZE); /* stride 1 by default */
status = DftiSetValue(rowfft, DFTI_NUMBER_OF_TRANSFORMS, (MKL_LONG)ROWS);
status = DftiSetValue(rowfft, DFTI_INPUT_DISTANCE, (MKL_LONG)ROWSIZE);
status = DftiSetValue(rowfft, DFTI_BACKWARD_SCALE, 1.0/(ROWS*COLS));
//status = DftiSetValue(rowfft, DFTI_OUTPUT_DISTANCE, (MKL_LONG)ROWSIZE); // not needed for in-place

status = DftiCreateDescriptor(&colfft, DFTI_SINGLE, DFTI_COMPLEX, 1, (MKL_LONG)COLSIZE); /* will set strides */
status = DftiSetValue(colfft, DFTI_NUMBER_OF_TRANSFORMS, (MKL_LONG)COLS);
status = DftiSetValue(colfft, DFTI_INPUT_DISTANCE, (MKL_LONG)1);
//status = DftiSetValue(colfft, DFTI_OUTPUT_DISTANCE, (MKL_LONG)1); // not needed for in-place
status = DftiSetValue(colfft, DFTI_INPUT_STRIDES, colfft_strides);
//status = DftiSetValue(colfft, DFTI_OUTPUT_STRIDES, colfft_strides); // not needed for in-place

status = DftiCommitDescriptor( rowfft);
status = DftiComputeForward(rowfft, xx);

status = DftiCommitDescriptor( colfft);
status = DftiComputeForward(colfft, xx);

//////
printf("\n");
for(r=0;r{
for (c=0;c{
//printf("transformed xx[%d,%d]=%f %f\n", r, c, xx[*ROWSIZE+(c)].x, xx[*ROWSIZE+(c)].y);
}
}
printf("transformed xx[*-1,*-1]=%f %f\n", xx[(ROWS-1)*ROWSIZE+(COLS-1)].x, xx[(ROWS-1)*ROWSIZE+(COLS-1)].y);

//////When Inverse FFT I add below

//status = DftiCommitDescriptor( rowfft); // not needed at all
//status = DftiCommitDescriptor( colfft);

status = DftiComputeBackward(colfft, xx);
status = DftiComputeBackward(rowfft, xx);

status = DftiFreeDescriptor(&rowfft);
status = DftiFreeDescriptor(&colfft);

printf("\n");
for(r=0;r{
for (c=0;c{
//(img[*ROWSIZE+(c)]) = xx[*ROWSIZE+(c)].y;
//printf("after xx[%d,%d]=%f %f\n", r, c, xx[*ROWSIZE+(c)].x, xx[*ROWSIZE+(c)].y);

}
}
printf("after xx[*-1,*-1]=%f %f\n", xx[(ROWS-1)*ROWSIZE+(COLS-1)].x, xx[(ROWS-1)*ROWSIZE+(COLS-1)].y);

return 0;
}

what outputs last elements:

init xx[*-1,*-1]=33269.000000 28661.000000

transformed xx[*-1,*-1]=0.000000 0.000000

after xx[*-1,*-1]=33269.000000 28661.003906

Please try to uncomment all prints to see all elements.

0 Kudos
Reply