CUFFT and 2D array of complex numbers
Greetings,

I am a complete beginner in CUDA (I've never hear of it up until a few weeks ago). I was given a project which requires using the CUFFT library to perform transforms in one and two dimensions. In order to test whether I had implemented CUFFT properly, I used a 1D array of 1's which should return 0's after being transformed. The data being passed to cufftPlan1D is a 1D array of complex numbers as shown in the following code:

void runTest(int argc, char** argv);

#define SIGNAL_SIZE 4096
#define REPEAT 5000

int main(int argc, char** argv)
{
runTest(argc, argv);

cutilExit(argc, argv);
}

void runTest(int argc, char** argv)
{
if( cutCheckCmdLineFlag(argc, (const char**)argv, "device") )
cutilDeviceInit(argc, argv);
else
cudaSetDevice( cutGetMaxGflopsDeviceId() );

// Allocate host memory for the signal
cufftComplex* h_signal = (cufftComplex*)malloc(SIGNAL_SIZE * REPEAT * sizeof(cufftComplex));

// Initalize the memory for the signal
for (unsigned int i = 0; i < SIGNAL_SIZE; i++) {
h_signal[i].x = 1.0f; //real
h_signal[i].y = 0.0f; //imag
}

// display the signal
for (unsigned int i = 0; i < SIGNAL_SIZE; i++) {
printf("%g %g\n", h_signal[i].x, h_signal[i].y);
}

printf("End of signal\n");

// Allocate device memory for signal
Complex* d_signal;
cudaMalloc((void**)&d_signal, SIGNAL_SIZE * REPEAT * sizeof(Complex));

// Copy host memory to device
cudaMemcpy(d_signal, h_signal, SIGNAL_SIZE * REPEAT * sizeof(Complex),
cudaMemcpyHostToDevice);

// Create a 1D FFT plan
cufftHandle plan;
cufftPlan1d(&plan, SIGNAL_SIZE, CUFFT_C2C, REPEAT);

// Use the CUFFT plan to transform the signal in place
cufftExecC2C(plan, (cufftComplex *)d_signal,
(cufftComplex *)d_signal, CUFFT_FORWARD);

// Check if CUFFT library initialized successfully
if (CUFFT_SETUP_FAILED != 0)
printf("CUFFT Library initialized\n");

// Check if CUUFT executed the transform on the GPU
if (CUFFT_EXEC_FAILED != 0)
printf( "FFT successfully executed on the GPU\n" );

// Copy result from device to host
cufftComplex* h_transformed_signal = h_signal;
cutilSafeCall(cudaMemcpy(h_transformed_signal, d_signal,
SIGNAL_SIZE * REPEAT * sizeof(Complex), cudaMemcpyDeviceToHost));

// Display results
for (unsigned int i = 0; i < SIGNAL_SIZE; i++) {
printf("%g %g\n", h_transformed_signal[i].x, h_transformed_signal[i].y);
}

printf("End of result\n");

// Destroy the CUFFT plan
cufftDestroy(plan);

// Free host and device memories
free(h_signal);
cutilSafeCall(cudaFree(d_signal));

cudaThreadExit();
}

I've been struggling trying to figure out [i]how to initialize and pass a 2D array of complex numbers to a 2d C2C CUFFT plan[/i]. I've read everything on the forums that I could, but it's still not clear to me. I know most people mention it better to flatten multidimensional arrays, but even getting to this point is proving to be very frustrating. I've tried the following with no success:

// Allocate memory for host signal
cufftComplex *h_idata = (cufftComplex *)malloc(size);

for (unsigned int col = 0; col < NX; col++) {
for (unsigned int row = 0; row < NY; row++) {
h_idata[row][col].x = 1.0f; //real
h_idata[row][col].y = 0.0f; //imag
}
}

But, I do believe that CUDA flattens multidimensional arrays(?).

I sincerely appreciate any help.

Thanks
Greetings,



I am a complete beginner in CUDA (I've never hear of it up until a few weeks ago). I was given a project which requires using the CUFFT library to perform transforms in one and two dimensions. In order to test whether I had implemented CUFFT properly, I used a 1D array of 1's which should return 0's after being transformed. The data being passed to cufftPlan1D is a 1D array of complex numbers as shown in the following code:



void runTest(int argc, char** argv);



#define SIGNAL_SIZE 4096

#define REPEAT 5000



int main(int argc, char** argv)

{

runTest(argc, argv);



cutilExit(argc, argv);

}



void runTest(int argc, char** argv)

{

if( cutCheckCmdLineFlag(argc, (const char**)argv, "device") )

cutilDeviceInit(argc, argv);

else

cudaSetDevice( cutGetMaxGflopsDeviceId() );



// Allocate host memory for the signal

cufftComplex* h_signal = (cufftComplex*)malloc(SIGNAL_SIZE * REPEAT * sizeof(cufftComplex));



// Initalize the memory for the signal

for (unsigned int i = 0; i < SIGNAL_SIZE; i++) {

h_signal.x = 1.0f; //real

h_signal[i].y = 0.0f; //imag

}



// display the signal

for (unsigned int i = 0; i < SIGNAL_SIZE; i++) {

printf("%g %g\n", h_signal[i].x, h_signal[i].y);

}



printf("End of signal\n");



// Allocate device memory for signal

Complex* d_signal;

cudaMalloc((void**)&d_signal, SIGNAL_SIZE * REPEAT * sizeof(Complex));



// Copy host memory to device

cudaMemcpy(d_signal, h_signal, SIGNAL_SIZE * REPEAT * sizeof(Complex),

cudaMemcpyHostToDevice);



// Create a 1D FFT plan

cufftHandle plan;

cufftPlan1d(&plan, SIGNAL_SIZE, CUFFT_C2C, REPEAT);



// Use the CUFFT plan to transform the signal in place

cufftExecC2C(plan, (cufftComplex *)d_signal,

(cufftComplex *)d_signal, CUFFT_FORWARD);



// Check if CUFFT library initialized successfully

if (CUFFT_SETUP_FAILED != 0)

printf("CUFFT Library initialized\n");



// Check if CUUFT executed the transform on the GPU

if (CUFFT_EXEC_FAILED != 0)

printf( "FFT successfully executed on the GPU\n" );



// Copy result from device to host

cufftComplex* h_transformed_signal = h_signal;

cutilSafeCall(cudaMemcpy(h_transformed_signal, d_signal,

SIGNAL_SIZE * REPEAT * sizeof(Complex), cudaMemcpyDeviceToHost));



// Display results

for (unsigned int i = 0; i < SIGNAL_SIZE; i++) {

printf("%g %g\n", h_transformed_signal[i].x, h_transformed_signal[i].y);

}



printf("End of result\n");



// Destroy the CUFFT plan

cufftDestroy(plan);



// Free host and device memories

free(h_signal);

cutilSafeCall(cudaFree(d_signal));



cudaThreadExit();

}



I've been struggling trying to figure out [i]how to initialize and pass a 2D array of complex numbers to a 2d C2C CUFFT plan
. I've read everything on the forums that I could, but it's still not clear to me. I know most people mention it better to flatten multidimensional arrays, but even getting to this point is proving to be very frustrating. I've tried the following with no success:



// Allocate memory for host signal

cufftComplex *h_idata = (cufftComplex *)malloc(size);



for (unsigned int col = 0; col < NX; col++) {

for (unsigned int row = 0; row < NY; row++) {

h_idata[row][col].x = 1.0f; //real

h_idata[row][col].y = 0.0f; //imag

}

}



But, I do believe that CUDA flattens multidimensional arrays(?).



I sincerely appreciate any help.



Thanks

#1
Posted 07/12/2011 10:42 PM   
In Cuda CUFFT take complex numbers as input in the form of

cufftComplex *a_h;
for (i=0; i < N; i++) {
a_h[i].x = (your choice);
a_h[i].y = (your choice));
}
then it can be easily transferred to GPU by cudaMalloc and cudaMemcpy.

cufftComplex *h_idata = (cufftComplex *)malloc(size);

for (int col = 0; col < NX; col++) { {
h_idata[col].x = 1.0f; //real
h_idata[col].y = 0.0f; //imag
}
}
this will work hopefully.
In Cuda CUFFT take complex numbers as input in the form of



cufftComplex *a_h;

for (i=0; i < N; i++) {

a_h[i].x = (your choice);

a_h[i].y = (your choice));

}

then it can be easily transferred to GPU by cudaMalloc and cudaMemcpy.



cufftComplex *h_idata = (cufftComplex *)malloc(size);



for (int col = 0; col < NX; col++) { {

h_idata[col].x = 1.0f; //real

h_idata[col].y = 0.0f; //imag

}

}

this will work hopefully.

#2
Posted 03/30/2012 06:52 AM   
[quote name='dualdrive' date='12 July 2011 - 11:42 PM' timestamp='1310510533' post='1263852']
Greetings,

I've been struggling trying to figure out [i]how to initialize and pass a 2D array of complex numbers to a 2d C2C CUFFT plan[/i]. I've read everything on the forums that I could, but it's still not clear to me. I know most people mention it better to flatten multidimensional arrays, but even getting to this point is proving to be very frustrating. I've tried the following with no success:

// Allocate memory for host signal
cufftComplex *h_idata = (cufftComplex *)malloc(size);

for (unsigned int col = 0; col < NX; col++) {
for (unsigned int row = 0; row < NY; row++) {
h_idata[row][col].x = 1.0f; //real
h_idata[row][col].y = 0.0f; //imag
}
}

But, I do believe that CUDA flattens multidimensional arrays(?).

I sincerely appreciate any help.

Thanks
[/quote]

I am using something like this:

[code]
int count=0;
for (int i=0;i<nx;i++)
{
for(int j=0;j<ny;j++)
{
h_data[count].x=...;
h_data[count].y=...;
count=count+1;
}
}
[/code]
You transfer the data as a 1D array of size nx*ny
[quote name='dualdrive' date='12 July 2011 - 11:42 PM' timestamp='1310510533' post='1263852']

Greetings,



I've been struggling trying to figure out how to initialize and pass a 2D array of complex numbers to a 2d C2C CUFFT plan. I've read everything on the forums that I could, but it's still not clear to me. I know most people mention it better to flatten multidimensional arrays, but even getting to this point is proving to be very frustrating. I've tried the following with no success:



// Allocate memory for host signal

cufftComplex *h_idata = (cufftComplex *)malloc(size);



for (unsigned int col = 0; col < NX; col++) {

for (unsigned int row = 0; row < NY; row++) {

h_idata[row][col].x = 1.0f; //real

h_idata[row][col].y = 0.0f; //imag

}

}



But, I do believe that CUDA flattens multidimensional arrays(?).



I sincerely appreciate any help.



Thanks





I am using something like this:





int count=0;

for (int i=0;i<nx;i++)

{

for(int j=0;j<ny;j++)

{

h_data[count].x=...;

h_data[count].y=...;

count=count+1;

}

}


You transfer the data as a 1D array of size nx*ny

#3
Posted 03/30/2012 09:55 AM   
Scroll To Top