1 /* ************************************************************************
2  * Copyright 2013 Advanced Micro Devices, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  * ************************************************************************/
16 
17 
18 // clfft.opencl.cpp : Provides functions to set up openCL
19 //
20 
21 #include "stdafx.h"
22 #include <stdexcept>
23 #include <iomanip>
24 #include <sstream>
25 #include <cstring>
26 #include <vector>
27 #include "clFFT.h"
28 #include "openCL.misc.h"
29 
30 
31 
prettyPrintPlatformInfo(const cl_platform_id & pId)32 void prettyPrintPlatformInfo( const cl_platform_id& pId )
33 {
34     size_t platformProfileSize	= 0;
35     OPENCL_V_THROW( ::clGetPlatformInfo( pId, CL_PLATFORM_PROFILE, 0, NULL, &platformProfileSize ),
36         "Getting CL_PLATFORM_PROFILE Platform Info string size ( ::clGetPlatformInfo() )" );
37 
38     std::vector< char > szPlatformProfile( platformProfileSize );
39     OPENCL_V_THROW( ::clGetPlatformInfo( pId, CL_PLATFORM_PROFILE, platformProfileSize, &szPlatformProfile[ 0 ], NULL),
40         "Getting CL_PLATFORM_PROFILE Platform Info string ( ::clGetPlatformInfo() )" );
41 
42     size_t platformVersionSize	= 0;
43     OPENCL_V_THROW( ::clGetPlatformInfo( pId, CL_PLATFORM_VERSION, 0, NULL, &platformVersionSize ),
44         "Getting CL_PLATFORM_VERSION Platform Info string size ( ::clGetPlatformInfo() )" );
45 
46     std::vector< char > szPlatformVersion( platformVersionSize );
47     OPENCL_V_THROW( ::clGetPlatformInfo( pId, CL_PLATFORM_VERSION, platformVersionSize, &szPlatformVersion[ 0 ], NULL),
48         "Getting CL_PLATFORM_VERSION Platform Info string ( ::clGetPlatformInfo() )" );
49 
50     size_t platformNameSize	= 0;
51     OPENCL_V_THROW( ::clGetPlatformInfo( pId, CL_PLATFORM_NAME, 0, NULL, &platformNameSize ),
52         "Getting CL_PLATFORM_NAME Platform Info string size ( ::clGetPlatformInfo() )" );
53 
54     std::vector< char > szPlatformName( platformNameSize );
55     OPENCL_V_THROW( ::clGetPlatformInfo( pId, CL_PLATFORM_NAME, platformNameSize, &szPlatformName[ 0 ], NULL),
56         "Getting CL_PLATFORM_NAME Platform Info string ( ::clGetPlatformInfo() )" );
57 
58     size_t vendorStringSize	= 0;
59     OPENCL_V_THROW( ::clGetPlatformInfo( pId, CL_PLATFORM_VENDOR, 0, NULL, &vendorStringSize ),
60         "Getting CL_PLATFORM_VENDOR Platform Info string size ( ::clGetPlatformInfo() )" );
61 
62     std::vector< char > szPlatformVendor( vendorStringSize );
63     OPENCL_V_THROW( ::clGetPlatformInfo( pId, CL_PLATFORM_VENDOR, vendorStringSize, &szPlatformVendor[ 0 ], NULL),
64         "Getting CL_PLATFORM_VENDOR Platform Info string ( ::clGetPlatformInfo() )" );
65 
66     size_t platformExtensionsSize	= 0;
67     OPENCL_V_THROW( ::clGetPlatformInfo( pId, CL_PLATFORM_EXTENSIONS, 0, NULL, &platformExtensionsSize ),
68         "Getting CL_PLATFORM_EXTENSIONS Platform Info string size ( ::clGetPlatformInfo() )" );
69 
70     std::vector< char > szPlatformExtensions( platformExtensionsSize );
71     OPENCL_V_THROW( ::clGetPlatformInfo( pId, CL_PLATFORM_EXTENSIONS, platformExtensionsSize, &szPlatformExtensions[ 0 ], NULL),
72         "Getting CL_PLATFORM_EXTENSIONS Platform Info string ( ::clGetPlatformInfo() )" );
73 
74     const int indent = countOf( "    CL_PLATFORM_EXTENSIONS: " );
75     std::cout << std::left << std::setw( indent ) << "    CL_PLATFORM_PROFILE: " << &szPlatformProfile[ 0 ] << std::endl;
76     std::cout << std::left << std::setw( indent ) << "    CL_PLATFORM_VERSION: " << &szPlatformVersion[ 0 ] << std::endl;
77     std::cout << std::left << std::setw( indent ) << "    CL_PLATFORM_NAME: " << &szPlatformName[ 0 ] << std::endl;
78     std::cout << std::left << std::setw( indent ) << "    CL_PLATFORM_VENDOR: " << &szPlatformVendor[ 0 ] << std::endl;
79     std::cout << std::left << std::setw( indent ) << "    CL_PLATFORM_EXTENSIONS: " << &szPlatformExtensions[ 0 ] << std::endl;
80     std::cout << std::right << std::endl;
81 }
82 
prettyPrintDeviceInfo(const cl_device_id & dId)83 void prettyPrintDeviceInfo( const cl_device_id& dId )
84 {
85     size_t deviceNameSize	= 0;
86     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_NAME, 0, NULL, &deviceNameSize ),
87         "Getting CL_DEVICE_NAME Platform Info string size ( ::clGetDeviceInfo() )" );
88 
89     std::vector< char > szDeviceName( deviceNameSize );
90     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_NAME, deviceNameSize, &szDeviceName[ 0 ], NULL ),
91         "Getting CL_DEVICE_NAME Platform Info string ( ::clGetDeviceInfo() )" );
92 
93     size_t deviceVersionSize	= 0;
94     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_VERSION, 0, NULL, &deviceVersionSize ),
95         "Getting CL_DEVICE_VERSION Platform Info string size ( ::clGetDeviceInfo() )" );
96 
97     std::vector< char > szDeviceVersion( deviceVersionSize );
98     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_VERSION, deviceVersionSize, &szDeviceVersion[ 0 ], NULL ),
99         "Getting CL_DEVICE_VERSION Platform Info string ( ::clGetDeviceInfo() )" );
100 
101     size_t driverVersionSize	= 0;
102     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DRIVER_VERSION, 0, NULL, &driverVersionSize ),
103         "Getting CL_DRIVER_VERSION Platform Info string size ( ::clGetDeviceInfo() )" );
104 
105     std::vector< char > szDriverVersion( driverVersionSize );
106     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DRIVER_VERSION, driverVersionSize, &szDriverVersion[ 0 ], NULL ),
107         "Getting CL_DRIVER_VERSION Platform Info string ( ::clGetDeviceInfo() )" );
108 
109     size_t openCLVersionSize	= 0;
110     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_OPENCL_C_VERSION, 0, NULL, &openCLVersionSize ),
111         "Getting CL_DEVICE_OPENCL_C_VERSION Platform Info string size ( ::clGetDeviceInfo() )" );
112 
113     std::vector< char > szOpenCLVersion( openCLVersionSize );
114     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_OPENCL_C_VERSION, openCLVersionSize, &szOpenCLVersion[ 0 ], NULL ),
115         "Getting CL_DEVICE_OPENCL_C_VERSION Platform Info string ( ::clGetDeviceInfo() )" );
116 
117     cl_device_type devType = CL_DEVICE_TYPE_DEFAULT;
118     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_TYPE, sizeof( cl_device_type ), &devType, NULL ),
119         "Getting CL_DEVICE_TYPE device info ( ::clGetDeviceInfo() )" );
120 
121     cl_uint devAddrBits = 0;
122     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_ADDRESS_BITS, sizeof( cl_uint ), &devAddrBits, NULL ),
123         "Getting CL_DEVICE_ADDRESS_BITS device info ( ::clGetDeviceInfo() )" );
124 
125     cl_uint maxClockFreq = 0;
126     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof( cl_uint ), &maxClockFreq, NULL ),
127         "Getting CL_DEVICE_MAX_CLOCK_FREQUENCY device info ( ::clGetDeviceInfo() )" );
128 
129     cl_bool devAvailable = CL_FALSE;
130     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_AVAILABLE, sizeof( cl_bool ), &devAvailable, NULL ),
131         "Getting CL_DEVICE_AVAILABLE device info ( ::clGetDeviceInfo() )" );
132 
133     cl_bool devCompAvailable = CL_FALSE;
134     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_COMPILER_AVAILABLE, sizeof( cl_bool ), &devCompAvailable, NULL ),
135         "Getting CL_DEVICE_COMPILER_AVAILABLE device info ( ::clGetDeviceInfo() )" );
136 
137     size_t devMaxWorkGroup	= 0;
138     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof( size_t ), &devMaxWorkGroup, NULL ),
139         "Getting CL_DEVICE_MAX_WORK_GROUP_SIZE device info ( ::clGetDeviceInfo() )" );
140 
141     cl_uint devMaxWorkItemDim = CL_FALSE;
142     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof( cl_uint ), &devMaxWorkItemDim, NULL ),
143         "Getting CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS device info ( ::clGetDeviceInfo() )" );
144 
145     std::vector< size_t >	devMaxWorkItemSizes( devMaxWorkItemDim );
146     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof( size_t )*devMaxWorkItemSizes.size( ), &devMaxWorkItemSizes[0], NULL),
147         "Getting CL_DEVICE_MAX_WORK_ITEM_SIZES device info ( ::clGetDeviceInfo() )" );
148 
149     cl_bool deviceHostUnified = 0;
150     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_HOST_UNIFIED_MEMORY, sizeof( cl_bool ), &deviceHostUnified, NULL ),
151         "Getting CL_DEVICE_HOST_UNIFIED_MEMORY Platform Info string ( ::clGetDeviceInfo() )" );
152 
153     cl_ulong devMaxConstantBuffer	= 0;
154     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof( cl_ulong ), &devMaxConstantBuffer, NULL ),
155         "Getting CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE device info ( ::clGetDeviceInfo() )" );
156 
157     cl_ulong devLocalMemSize	= 0;
158     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_LOCAL_MEM_SIZE, sizeof( cl_ulong ), &devLocalMemSize, NULL ),
159         "Getting CL_DEVICE_LOCAL_MEM_SIZE device info ( ::clGetDeviceInfo() )" );
160 
161     cl_ulong deviceGlobalMemSize = 0;
162     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof( cl_ulong ), &deviceGlobalMemSize, NULL ),
163         "Getting CL_DEVICE_GLOBAL_MEM_SIZE device info ( ::clGetDeviceInfo() )" );
164 
165     cl_ulong deviceMaxMemAllocSize = 0;
166     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof( cl_ulong ), &deviceMaxMemAllocSize, NULL ),
167         "Getting CL_DEVICE_MAX_MEM_ALLOC_SIZE device info ( ::clGetDeviceInfo() )" );
168 
169     size_t deviceExtSize	= 0;
170     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_EXTENSIONS, 0, NULL, &deviceExtSize ),
171         "Getting CL_DEVICE_EXTENSIONS Platform Info string size ( ::clGetDeviceInfo() )" );
172 
173     std::vector< char > szDeviceExt( deviceExtSize );
174     OPENCL_V_THROW( ::clGetDeviceInfo( dId, CL_DEVICE_EXTENSIONS, deviceExtSize, &szDeviceExt[ 0 ], NULL ),
175         "Getting CL_DEVICE_EXTENSIONS Platform Info string ( ::clGetDeviceInfo() )" );
176 
177     const int indent = countOf( "    CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: " );
178     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_NAME: " << &szDeviceName[ 0 ] << std::endl;
179     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_VERSION: " << &szDeviceVersion[ 0 ] << std::endl;
180     std::cout << std::left << std::setw( indent ) << "    CL_DRIVER_VERSION: " << &szDriverVersion[ 0 ] << std::endl;
181     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_TYPE: "
182         << (CL_DEVICE_TYPE_DEFAULT     & devType ? "default"     : "")
183         << (CL_DEVICE_TYPE_CPU         & devType ? "CPU"         : "")
184         << (CL_DEVICE_TYPE_GPU         & devType ? "GPU"         : "")
185         << (CL_DEVICE_TYPE_ACCELERATOR & devType ? "Accelerator" : "")
186         << std::endl;
187     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_MAX_CLOCK_FREQUENCY: " << maxClockFreq << std::endl;
188     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_ADDRESS_BITS: " << devAddrBits << std::endl;
189     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_AVAILABLE: " << ( devAvailable ? "TRUE": "FALSE") << std::endl;
190     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_COMPILER_AVAILABLE: " << ( devCompAvailable ? "TRUE": "FALSE") << std::endl;
191     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_OPENCL_C_VERSION: " << &szOpenCLVersion[ 0 ] << std::endl;
192     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_MAX_WORK_GROUP_SIZE: " << devMaxWorkGroup << std::endl;
193     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: " << devMaxWorkItemDim << std::endl;
194     for( cl_uint wis = 0; wis < devMaxWorkItemSizes.size( ); ++wis )
195     {
196         std::stringstream dimString;
197         dimString << "Dimension[ " << wis << " ]  ";
198         std::cout << std::right << std::setw( indent ) << dimString.str( ) << devMaxWorkItemSizes[wis] << std::endl;
199     }
200     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_HOST_UNIFIED_MEMORY: " << ( deviceHostUnified ? "TRUE": "FALSE") << std::endl;
201     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: " << devMaxConstantBuffer;
202     std::cout << " ( " << devMaxConstantBuffer / 1024 << " KB )" << std::endl;
203     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_LOCAL_MEM_SIZE: " << devLocalMemSize;
204     std::cout << " ( " << devLocalMemSize / 1024 << " KB )" << std::endl;
205     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_GLOBAL_MEM_SIZE: " << deviceGlobalMemSize;
206     std::cout << " ( " << deviceGlobalMemSize / 1048576 << " MB )" << std::endl;
207     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_MAX_MEM_ALLOC_SIZE: " << deviceMaxMemAllocSize;
208     std::cout << " ( " << deviceMaxMemAllocSize / 1048576 << " MB )" << std::endl;
209     std::cout << std::left << std::setw( indent ) << "    CL_DEVICE_EXTENSIONS: " << &szDeviceExt[ 0 ] << std::endl;
210 
211     std::cout << std::right << std::endl;
212 }
213 
prettyPrintCLPlatforms(std::vector<cl_platform_id> & platforms,std::vector<std::vector<cl_device_id>> & devices)214 void prettyPrintCLPlatforms(std::vector< cl_platform_id >& platforms,
215 	std::vector< std::vector< cl_device_id > >& devices)
216 {
217 	for (unsigned int i = 0; i < platforms.size(); ++i)
218 	{
219 		std::cout << "OpenCL platform [ " << i << " ]:" << std::endl;
220 		prettyPrintPlatformInfo(platforms[i]);
221 
222 		for (unsigned int n = 0; n < devices[i].size(); ++n)
223 		{
224 			std::cout << "OpenCL platform [ " << i << " ], device [ " << n << " ]:" << std::endl;
225 			prettyPrintDeviceInfo((devices[i])[n]);
226 		}
227 	}
228 
229 }
230 
231 //	Verify a failed condition; return true on fail
OPENCL_V_FAIL(cl_int res)232 inline cl_bool OPENCL_V_FAIL( cl_int res )
233 {
234     if( res == CL_SUCCESS )
235         return CL_FALSE;
236     else
237         return CL_TRUE;
238 }
239 
prettyPrintclFFTStatus(const cl_int & status)240 std::string prettyPrintclFFTStatus( const cl_int& status )
241 {
242     switch( status )
243     {
244         case CLFFT_INVALID_GLOBAL_WORK_SIZE:
245             return "CLFFT_INVALID_GLOBAL_WORK_SIZE";
246         case CLFFT_INVALID_MIP_LEVEL:
247             return "CLFFT_INVALID_MIP_LEVEL";
248         case CLFFT_INVALID_BUFFER_SIZE:
249             return "CLFFT_INVALID_BUFFER_SIZE";
250         case CLFFT_INVALID_GL_OBJECT:
251             return "CLFFT_INVALID_GL_OBJECT";
252         case CLFFT_INVALID_OPERATION:
253             return "CLFFT_INVALID_OPERATION";
254         case CLFFT_INVALID_EVENT:
255             return "CLFFT_INVALID_EVENT";
256         case CLFFT_INVALID_EVENT_WAIT_LIST:
257             return "CLFFT_INVALID_EVENT_WAIT_LIST";
258         case CLFFT_INVALID_GLOBAL_OFFSET:
259             return "CLFFT_INVALID_GLOBAL_OFFSET";
260         case CLFFT_INVALID_WORK_ITEM_SIZE:
261             return "CLFFT_INVALID_WORK_ITEM_SIZE";
262         case CLFFT_INVALID_WORK_GROUP_SIZE:
263             return "CLFFT_INVALID_WORK_GROUP_SIZE";
264         case CLFFT_INVALID_WORK_DIMENSION:
265             return "CLFFT_INVALID_WORK_DIMENSION";
266         case CLFFT_INVALID_KERNEL_ARGS:
267             return "CLFFT_INVALID_KERNEL_ARGS";
268         case CLFFT_INVALID_ARG_SIZE:
269             return "CLFFT_INVALID_ARG_SIZE";
270         case CLFFT_INVALID_ARG_VALUE:
271             return "CLFFT_INVALID_ARG_VALUE";
272         case CLFFT_INVALID_ARG_INDEX:
273             return "CLFFT_INVALID_ARG_INDEX";
274         case CLFFT_INVALID_KERNEL:
275             return "CLFFT_INVALID_KERNEL";
276         case CLFFT_INVALID_KERNEL_DEFINITION:
277             return "CLFFT_INVALID_KERNEL_DEFINITION";
278         case CLFFT_INVALID_KERNEL_NAME:
279             return "CLFFT_INVALID_KERNEL_NAME";
280         case CLFFT_INVALID_PROGRAM_EXECUTABLE:
281             return "CLFFT_INVALID_PROGRAM_EXECUTABLE";
282         case CLFFT_INVALID_PROGRAM:
283             return "CLFFT_INVALID_PROGRAM";
284         case CLFFT_INVALID_BUILD_OPTIONS:
285             return "CLFFT_INVALID_BUILD_OPTIONS";
286         case CLFFT_INVALID_BINARY:
287             return "CLFFT_INVALID_BINARY";
288         case CLFFT_INVALID_SAMPLER:
289             return "CLFFT_INVALID_SAMPLER";
290         case CLFFT_INVALID_IMAGE_SIZE:
291             return "CLFFT_INVALID_IMAGE_SIZE";
292         case CLFFT_INVALID_IMAGE_FORMAT_DESCRIPTOR:
293             return "CLFFT_INVALID_IMAGE_FORMAT_DESCRIPTOR";
294         case CLFFT_INVALID_MEM_OBJECT:
295             return "CLFFT_INVALID_MEM_OBJECT";
296         case CLFFT_INVALID_HOST_PTR:
297             return "CLFFT_INVALID_HOST_PTR";
298         case CLFFT_INVALID_COMMAND_QUEUE:
299             return "CLFFT_INVALID_COMMAND_QUEUE";
300         case CLFFT_INVALID_QUEUE_PROPERTIES:
301             return "CLFFT_INVALID_QUEUE_PROPERTIES";
302         case CLFFT_INVALID_CONTEXT:
303             return "CLFFT_INVALID_CONTEXT";
304         case CLFFT_INVALID_DEVICE:
305             return "CLFFT_INVALID_DEVICE";
306         case CLFFT_INVALID_PLATFORM:
307             return "CLFFT_INVALID_PLATFORM";
308         case CLFFT_INVALID_DEVICE_TYPE:
309             return "CLFFT_INVALID_DEVICE_TYPE";
310         case CLFFT_INVALID_VALUE:
311             return "CLFFT_INVALID_VALUE";
312         case CLFFT_MAP_FAILURE:
313             return "CLFFT_MAP_FAILURE";
314         case CLFFT_BUILD_PROGRAM_FAILURE:
315             return "CLFFT_BUILD_PROGRAM_FAILURE";
316         case CLFFT_IMAGE_FORMAT_NOT_SUPPORTED:
317             return "CLFFT_IMAGE_FORMAT_NOT_SUPPORTED";
318         case CLFFT_IMAGE_FORMAT_MISMATCH:
319             return "CLFFT_IMAGE_FORMAT_MISMATCH";
320         case CLFFT_MEM_COPY_OVERLAP:
321             return "CLFFT_MEM_COPY_OVERLAP";
322         case CLFFT_PROFILING_INFO_NOT_AVAILABLE:
323             return "CLFFT_PROFILING_INFO_NOT_AVAILABLE";
324         case CLFFT_OUT_OF_HOST_MEMORY:
325             return "CLFFT_OUT_OF_HOST_MEMORY";
326         case CLFFT_OUT_OF_RESOURCES:
327             return "CLFFT_OUT_OF_RESOURCES";
328         case CLFFT_MEM_OBJECT_ALLOCATION_FAILURE:
329             return "CLFFT_MEM_OBJECT_ALLOCATION_FAILURE";
330         case CLFFT_COMPILER_NOT_AVAILABLE:
331             return "CLFFT_COMPILER_NOT_AVAILABLE";
332         case CLFFT_DEVICE_NOT_AVAILABLE:
333             return "CLFFT_DEVICE_NOT_AVAILABLE";
334         case CLFFT_DEVICE_NOT_FOUND:
335             return "CLFFT_DEVICE_NOT_FOUND";
336         case CLFFT_SUCCESS:
337             return "CLFFT_SUCCESS";
338         case CLFFT_NOTIMPLEMENTED:
339             return "CLFFT_NOTIMPLEMENTED";
340         case CLFFT_TRANSPOSED_NOTIMPLEMENTED:
341             return "CLFFT_TRANSPOSED_NOTIMPLEMENTED";
342         case CLFFT_FILE_NOT_FOUND:
343             return "CLFFT_FILE_NOT_FOUND";
344         case CLFFT_FILE_CREATE_FAILURE:
345             return "CLFFT_FILE_CREATE_FAILURE";
346         case CLFFT_VERSION_MISMATCH:
347             return "CLFFT_VERSION_MISMATCH";
348         case CLFFT_INVALID_PLAN:
349             return "CLFFT_INVALID_PLAN";
350         default:
351             return "Error code not defined";
352         break;
353     }
354 }
355 
356 
discoverCLPlatforms(cl_device_type deviceType,std::vector<cl_platform_id> & platforms,std::vector<std::vector<cl_device_id>> & devices)357 int discoverCLPlatforms( cl_device_type deviceType,
358 						 std::vector< cl_platform_id >& platforms,
359 						 std::vector< std::vector< cl_device_id > >& devices )
360 {
361 	cl_int status = 0;
362 
363 	/*
364 	* Find all OpenCL platforms this system has to offer.
365 	*/
366 
367 	cl_uint numPlatforms = 0;
368 	cl_platform_id platform = NULL;
369 	OPENCL_V_THROW(::clGetPlatformIDs(0, NULL, &numPlatforms),
370 		"Getting number of platforms( ::clGetPlatformsIDs() )");
371 
372 	if (numPlatforms > 0)
373 	{
374 		platforms.resize( numPlatforms );
375 		devices.resize( numPlatforms );
376 		OPENCL_V_THROW(::clGetPlatformIDs(numPlatforms, &platforms[0], NULL),
377 			"Getting Platform Id's ( ::clGetPlatformsIDs() )");
378 
379 		if (NULL == platforms[0])
380 		{
381 			throw std::runtime_error("No appropriate OpenCL platform could be found");
382 		}
383 
384 		/*
385 		* Now, for each platform get all available devices matching deviceType.
386 		*/
387 		for (unsigned int i = 0; i < numPlatforms; ++i)
388 		{
389 			//	Get the device list for deviceType.
390 			//
391 			cl_uint numDevices = 0;
392 			OPENCL_V_WARN(::clGetDeviceIDs(platforms[i], deviceType, 0, NULL, &numDevices),
393 				"Getting OpenCL devices ( ::clGetDeviceIDs() )");
394 			if (0 == numDevices)
395 			{
396 				// OPENCL_V_WARN(CLFFT_DEVICE_NOT_AVAILABLE, "No devices available");
397 				continue;
398 			}
399 
400 			devices[i].resize(numDevices);
401 			OPENCL_V_THROW(::clGetDeviceIDs(platforms[i], deviceType, numDevices, &(devices[i])[0], NULL),
402 				"Getting OpenCL deviceIDs ( ::clGetDeviceIDs() )");
403 		}
404 	}
405 
406 	return 0;
407 }
408 
initializeCL(cl_device_type deviceType,cl_int deviceId,cl_int platformId,cl_context & context,bool printclInfo)409 std::vector< cl_device_id > initializeCL( cl_device_type deviceType,
410 										  cl_int deviceId,
411 										  cl_int platformId,
412 										  cl_context& context,
413 										  bool printclInfo )
414 {
415 	cl_int status = 0;
416 	cl_platform_id platform = NULL;
417 	std::vector< cl_device_id > devices(1);
418 	devices[0] = NULL;
419 
420 	// Have a look at all the available platforms on this system
421 	std::vector< cl_platform_id > platformInfos;
422 	std::vector< std::vector< cl_device_id > > deviceInfos;
423 	discoverCLPlatforms( deviceType, platformInfos, deviceInfos );
424 
425 
426 	for (unsigned int i = 0; i < platformInfos.size(); ++i)
427 	{
428 		if(i == platformId)
429 		{
430 			for (unsigned int n = 0; n < deviceInfos[i].size(); ++n)
431 			{
432 				if (n == deviceId)
433 				{
434 					platform = platformInfos[i];
435 					devices[0] = deviceInfos[i][n];
436 
437 					if(printclInfo)
438 					{
439 						prettyPrintPlatformInfo(platform);
440 						prettyPrintDeviceInfo(devices[0]);
441 					}
442 
443 					break;
444 				}
445 			}
446 
447 			break;
448 		}
449 	}
450 
451 
452 
453 	// Do some error checking if we really selected a valid platform and a valid device
454 	if (NULL == devices[0])
455 	{
456 		OPENCL_V_THROW(CLFFT_DEVICE_NOT_AVAILABLE, "No devices available");
457 	}
458 
459 	if (NULL == platform)
460 	{
461 		throw std::runtime_error("No appropriate OpenCL platform could be found");
462 	}
463 
464 	// Create an OpenCL context
465 	cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties) platform, 0 };
466 	context = clCreateContext(cps,
467 		(cl_uint)devices.size(),
468 		&devices[0],
469 		NULL,
470 		NULL,
471 		&status);
472 	OPENCL_V_THROW(status, "Creating Context ( ::clCreateContextFromType() )");
473 
474 	return devices;
475 }
476 
cleanupCL(cl_context * context,cl_command_queue * commandQueue,const cl_uint numBuffersIn,cl_mem inputBuffer[],const cl_uint numBuffersOut,cl_mem outputBuffer[],cl_event * outEvent)477 int cleanupCL( cl_context* context, cl_command_queue* commandQueue,
478     const cl_uint numBuffersIn, cl_mem inputBuffer[], const cl_uint numBuffersOut, cl_mem outputBuffer[], cl_event* outEvent )
479 {
480 	if(outEvent != NULL)
481 	{
482 		if( *outEvent != NULL )
483 			OPENCL_V_THROW( clReleaseEvent( *outEvent ), "Error: In clReleaseEvent\n" );
484 	}
485 
486     releaseOpenCLMemBuffer( numBuffersIn, inputBuffer);
487     releaseOpenCLMemBuffer( numBuffersOut, outputBuffer);
488 
489     if( *commandQueue != NULL )
490         OPENCL_V_THROW( clReleaseCommandQueue( *commandQueue ), "Error: In clReleaseCommandQueue\n" );
491 
492     if( *context != NULL )
493         OPENCL_V_THROW( clReleaseContext( *context ), "Error: In clReleaseContext\n" );
494 
495     return 0;
496 }
497 
createOpenCLMemoryBuffer(cl_context & context,const size_t bufferSizeBytes,const cl_uint numBuffers,cl_mem buffer[],cl_mem_flags accessibility)498 int createOpenCLMemoryBuffer( cl_context& context, const size_t bufferSizeBytes, const cl_uint numBuffers, cl_mem buffer[], cl_mem_flags accessibility) {
499     cl_int status = 0;
500 
501     for( cl_uint i = 0; i < numBuffers; ++i )
502     {
503         buffer[ i ] = ::clCreateBuffer( context, accessibility, bufferSizeBytes, NULL, &status);
504         OPENCL_V_THROW( status, "Creating Buffer ( ::clCreateBuffer() )" );
505     }
506 
507     return 0;
508 }
509 
releaseOpenCLMemBuffer(const cl_uint numBuffers,cl_mem buffer[])510 int releaseOpenCLMemBuffer( const cl_uint numBuffers, cl_mem buffer[])
511 {
512     for( cl_uint i = 0; i < numBuffers; ++i )
513     {
514         if( buffer[ i ] != NULL )
515             OPENCL_V_THROW( clReleaseMemObject( buffer[ i ] ), "Error: In clReleaseMemObject\n" );
516     }
517 
518     return 0;
519 }
520 
createOpenCLCommandQueue(cl_context & context,cl_uint commandQueueFlags,cl_command_queue & commandQueue,std::vector<cl_device_id> devices,const size_t bufferSizeBytesIn,const cl_uint numBuffersIn,cl_mem clMemBufferIn[],const size_t bufferSizeBytesOut,const cl_uint numBuffersOut,cl_mem clMemBufferOut[])521 void createOpenCLCommandQueue( cl_context& context,
522                                cl_uint commandQueueFlags,
523                                cl_command_queue& commandQueue,
524                                std::vector< cl_device_id > devices,
525                                const size_t bufferSizeBytesIn,
526                                const cl_uint numBuffersIn,
527                                cl_mem clMemBufferIn[],
528                                const size_t bufferSizeBytesOut,
529                                const cl_uint numBuffersOut,
530                                cl_mem clMemBufferOut[] )
531 {
532     cl_int status = 0;
533     commandQueue = ::clCreateCommandQueue( context, devices[0], commandQueueFlags, &status );
534     OPENCL_V_THROW( status, "Creating Command Queue ( ::clCreateCommandQueue() )" );
535 
536     createOpenCLMemoryBuffer( context, bufferSizeBytesIn,  numBuffersIn,  clMemBufferIn,  CL_MEM_READ_WRITE);
537     createOpenCLMemoryBuffer( context, bufferSizeBytesOut, numBuffersOut, clMemBufferOut, CL_MEM_READ_WRITE);
538 }
539 
540