Note that there are some explanatory texts on larger screens.

plurals
  1. POOpenCL: clAmdFft (OpenCL FFT lib from AMD) on NVIDIA GPUs
    text
    copied!<p>Has anyone experiences with running the OpenCL FFT library from AMD (http://developer.amd.com/libraries/appmathlibs/pages/default.aspx) on NVIDIA GPUs?</p> <p>I'm trying to port an existing algorithm from CUDA (with the most recent CUFFT) to OpenCL. The new code is running fine with an AMD GPU but not with my NVIDIA GPU. The NVIDIA GPU is recognized properly but the resulting array is zero all over without throwing any errors. By the way, the code runs also fine on an Intel Core i3 CPU. So my code seems to be fine.</p> <p>AMD as well as NVIDIA seem to refuse support for this topic.</p> <p>Any ideas?</p> <p>EDIT:</p> <p>My environment is a Windows 7 Professional x64 OS and I'm using the Visual Studio C++ Professional IDE with it's build-in x86 compiler. The NVIDIA GPU is a GeForce GTX 560 Ti (MSI N560GTX-Ti Twin Frozr II/OC 1GB). The well working CPU is a Intel Core i3-2100 (2x3.1GHz) and than there is the Radeon HD 6850 (Sapphire Radeon HD 6850 1GB). I tried compiling the code against the newest OpenCL releases of AMD, NVIDIA and Intel, with the same results and have of cause the newest developer drivers installed.</p> <p>Here is my pretty basic sample code ...</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;complex&gt; #include &lt;clAmdFft.h&gt; #if defined (__APPLE__) || defined(MACOSX) #include &lt;OpenCL/opencl.h&gt; #else #include &lt;CL/opencl.h&gt; #endif // Typedef for complex field objects using namespace std; typedef std::complex&lt;float&gt; cl_compl_flt; int main(int argc, char* argv[]) { cl_uint width = 1024, height = 1024; // Field dimensions cl_uint cl_platformsN = 0; // Platform count cl_platform_id *cl_platformIDs = NULL; // IDs of OpenCL platforms cl_uint cl_deviceCount = 0; // Device count cl_device_id *cl_devices = NULL; // Device IDs cl_int cl_err = 0; // Buffer for error informations cl_context cl_dev_context; // Context cl_command_queue cl_queue; // Queue clAmdFftSetupData fftSetupData; // FFT setup data clAmdFftPlanHandle fftPlan; // FFT plan clAmdFftDim fftDim = CLFFT_2D; // FFT dimension size_t fftSize[2]; // FFT size fftSize[0] = width; fftSize[1] = height; cl_mem d_data; // Device level data cl_compl_flt* h_src; // Host level input data cl_compl_flt* h_res; // Host level output data // Allocate host memory h_src = (cl_compl_flt*)malloc(width*height*sizeof(cl_compl_flt)); h_res = (cl_compl_flt*)malloc(width*height*sizeof(cl_compl_flt)); // Get source field createPinholeField( h_src, width, height, 5 ); // Get FFT version checkCL( clAmdFftInitSetupData(&amp;fftSetupData) ); printf("Using clAmdFft %u.%u.%u\n",fftSetupData.major,fftSetupData.minor,fftSetupData.patch); // Get available platforms checkCL( clGetPlatformIDs ( 0, NULL, &amp;cl_platformsN)); cl_platformIDs = (cl_platform_id*) malloc( cl_platformsN * sizeof(cl_platform_id)); checkCL( clGetPlatformIDs( cl_platformsN, cl_platformIDs, NULL) ); // Loop over platforms for( cl_uint i = 0; i &lt; cl_platformsN; i++) { // Get number of available devices for this platform checkCL( clGetDeviceIDs( cl_platformIDs[i], CL_DEVICE_TYPE_ALL, NULL, NULL, &amp;cl_deviceCount)); // Skip platform if no device available if(cl_deviceCount &lt; 1) continue; // Get available device IDs for this platform cl_devices = (cl_device_id*) malloc( cl_deviceCount * sizeof(cl_device_id)); checkCL( clGetDeviceIDs( cl_platformIDs[i], CL_DEVICE_TYPE_ALL, cl_deviceCount, cl_devices, NULL)); // Print platform name char platform_name[1024]; checkCL( clGetPlatformInfo( cl_platformIDs[i], CL_PLATFORM_NAME, 1024, &amp;platform_name, NULL) ); printf("\nCompute using OpenCl platfrom #%i [ %s ]\n", i,platform_name); // Loop over devices for( cl_uint j = 0; j &lt; cl_deviceCount; j++) { // Print device name and type cl_device_type device_type; char device_name[1024]; checkCL( clGetDeviceInfo( cl_devices[j], CL_DEVICE_NAME, 1024, &amp;device_name, NULL) ); checkCL( clGetDeviceInfo( cl_devices[j],CL_DEVICE_TYPE, sizeof(cl_device_type), &amp;device_type, NULL) ); printf("\n\tUsing OpenCl device #%i [ %s -- %s ]\n", j, device_name, getDevTypeString(device_type)); // Create OpenCL context cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)cl_platformIDs[i], 0 }; cl_dev_context = clCreateContext( cps, cl_deviceCount, cl_devices, NULL, NULL, &amp;cl_err); checkCL( cl_err); // Create command queue cl_queue = clCreateCommandQueue( cl_dev_context, cl_devices[j], CL_QUEUE_PROFILING_ENABLE, &amp;cl_err); checkCL( cl_err); // Create device buffer d_data = clCreateBuffer( cl_dev_context, CL_MEM_READ_WRITE, width*height*sizeof(cl_compl_flt), NULL, &amp;cl_err); checkCL( cl_err); // Setup FFT checkCL( clAmdFftSetup(&amp;fftSetupData) ); // Create FFT plan checkCL( clAmdFftCreateDefaultPlan( &amp;fftPlan, cl_dev_context, fftDim, fftSize) ); // Copy data from host to device clEnqueueWriteBuffer( cl_queue, d_data, CL_TRUE, 0, width*height*sizeof(cl_compl_flt), h_src, 0, NULL, NULL); // Execute FFT checkCL( clAmdFftEnqueueTransform( fftPlan, CLFFT_FORWARD, 1, &amp;cl_queue, 0, NULL, NULL, &amp;d_data, NULL, NULL) ); clFinish( cl_queue); // Copy result from device to host checkCL( clEnqueueReadBuffer(cl_queue, d_data, CL_TRUE, 0, width*height*sizeof(cl_compl_flt), h_res, 0, NULL, NULL) ); clFinish( cl_queue); // Save result char filename[512]; sprintf( filename, "raw/result_%u_%u_in.raw",i,j); printf("\tSave result to \"%s\" ", filename); saveRawData( h_res, filename, width, height, true); printf("\n"); // Free FFT plan checkCL( clAmdFftDestroyPlan( &amp;fftPlan) ); // Free FFT checkCL( clAmdFftTeardown() ); // Free device memory checkCL( clReleaseMemObject(d_data) ); // Release OpenCL context and queue checkCL( clReleaseCommandQueue( cl_queue ) ); checkCL( clReleaseContext( cl_dev_context) ); } // Free OpenCL devices free( cl_devices); } free( h_src); free( h_res); printf("\n\nPress any key ..."); getchar(); return 0; } </code></pre> <p>and the additional used functions ...</p> <pre><code>// Generate a pinhole void createPinholeField( cl_compl_flt* data, cl_uint width, cl_uint height, cl_uint radius) { if(data==NULL) data = (cl_compl_flt*)malloc(width*height*sizeof(cl_compl_flt)); if(radius &lt; 1) radius = (width&gt;height)?height/2:width/2; cl_float min_val = 0.0f; cl_float max_val = 255.0f; for(cl_uint y = 0; y &lt; height; y++) for(cl_uint x = 0; x &lt; width; x++) { if ( ceil( sqrt( pow(x-width/2., 2.) + pow(y-height/2., 2.) )) &lt;= radius ) { data[x+y*width].real(max_val); data[x+y*width].imag(0.f); } else { data[x+y*width].real(min_val); data[x+y*width].imag(0.f); } } } // Save a cl_compl_flt array as an unsigned char raw image file void saveRawData( cl_compl_flt* char_array, const char* filepath, cl_uint width, cl_uint height, bool print_minmax ) { cl_float* abs_v = (cl_float*) malloc(width*height*sizeof(cl_float)); for( cl_uint i = 0; i &lt; width*height; i++) abs_v[i] = abs(char_array[i]); cl_float min = abs_v[0]; cl_float max = abs_v[0]; for( cl_uint i = 1; i &lt; width*height; i++) { if( abs_v[i] &lt; min) min = abs_v[i]; if( abs_v[i] &gt; max) max = abs_v[i]; } if( print_minmax) printf(" [min=%f , max=%f] ",min,max); max *= .01f; cl_uchar* temp = (cl_uchar*) malloc(width*height*sizeof(cl_uchar)); for( cl_uint i = 0; i &lt; width*height; i++) temp[i] = 255*(cl_uchar)(( (cl_float)abs_v[i] - min) / ( max-min )); FILE *pFile = NULL; pFile=fopen(filepath,"wb"); fwrite(temp,1,width*height,pFile); fclose(pFile); free(abs_v); free(temp); } // Check functions that return OpenCL error IDs. bool checkCL( cl_int oclErrorCode) { if( oclErrorCode == CL_SUCCESS) return true; else { printf("\n\nAn OpenCL related error occured!\nError ID #%d\nPress ENTER to exit the program...\n\n", oclErrorCode); getchar(); exit( oclErrorCode); return false; } } // Get device type as string char* getDevTypeString(cl_device_type type) { switch(type) { case CL_DEVICE_TYPE_CPU: return "CPU"; break; case CL_DEVICE_TYPE_GPU: return "GPU"; break; case CL_DEVICE_TYPE_ACCELERATOR: return "ACCELERATOR"; break; default: return "DEFAULT"; break; } } </code></pre> <p>I hope this helps to narrow down the problem.</p> <p>P.S.: Images can be seen here: <a href="http://devgurus.amd.com/thread/159149" rel="nofollow">http://devgurus.amd.com/thread/159149</a></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload