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