1 //
2 // Copyright (c) 2017-2019 The Khronos Group 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 #include "harness/compat.h"
17
18 #include <inttypes.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <errno.h>
22 #include "harness/testHarness.h"
23 #include "harness/errorHelpers.h"
24 #include "harness/kernelHelpers.h"
25
26 static int dump_supported_formats;
27
28 typedef struct
29 {
30 cl_device_type device_type;
31 const char* device_type_name;
32 unsigned num_devices;
33 cl_device_id* devices;
34 // more infos here
35 } device_info;
36
37 device_info device_infos[] = {
38 { CL_DEVICE_TYPE_DEFAULT, "CL_DEVICE_TYPE_DEFAULT", -1, NULL },
39 { CL_DEVICE_TYPE_CPU, "CL_DEVICE_TYPE_CPU", -1, NULL },
40 { CL_DEVICE_TYPE_GPU, "CL_DEVICE_TYPE_GPU", -1, NULL },
41 { CL_DEVICE_TYPE_ACCELERATOR, "CL_DEVICE_TYPE_ACCELERATOR", -1, NULL },
42 { CL_DEVICE_TYPE_ALL, "CL_DEVICE_TYPE_ALL", -1, NULL },
43 };
44
45 // config types
46 enum
47 {
48 type_cl_device_type,
49 type_cl_device_fp_config,
50 type_cl_device_mem_cache_type,
51 type_cl_local_mem_type,
52 type_cl_device_exec_capabilities,
53 type_cl_command_queue_properties,
54 type_cl_device_id,
55 type_cl_device_affinity_domain,
56 type_cl_uint,
57 type_size_t,
58 type_size_t_arr,
59 type_cl_ulong,
60 type_string,
61 type_cl_device_svm_capabilities,
62 type_cl_device_atomic_capabilities,
63 type_cl_device_device_enqueue_capabilities,
64 type_cl_name_version_array,
65 type_cl_name_version,
66 };
67
68 typedef union {
69 cl_device_type type;
70 cl_device_fp_config fp_config;
71 cl_device_mem_cache_type mem_cache_type;
72 cl_device_local_mem_type local_mem_type;
73 cl_device_exec_capabilities exec_capabilities;
74 cl_command_queue_properties queue_properties;
75 cl_device_id device_id;
76 cl_device_affinity_domain affinity_domain;
77 cl_int uint;
78 size_t sizet;
79 size_t sizet_arr[3];
80 cl_ulong ull;
81 char* string;
82 cl_device_svm_capabilities svmCapabilities;
83 cl_device_atomic_capabilities atomicCapabilities;
84 cl_device_device_enqueue_capabilities deviceEnqueueCapabilities;
85 cl_name_version* cl_name_version_array;
86 cl_name_version cl_name_version_single;
87 } config_data;
88
89 struct _version
90 {
91 int major;
92 int minor;
93 };
94 typedef struct _version version_t;
95
96 struct _extensions
97 {
98 int cl_khr_fp64;
99 int cl_khr_fp16;
100 };
101 typedef struct _extensions extensions_t;
102
103 // Compare two versions, return -1 (the first is lesser), 0 (equal), 1 (the
104 // first is greater).
vercmp(version_t a,version_t b)105 int vercmp(version_t a, version_t b)
106 {
107 if (a.major < b.major || (a.major == b.major && a.minor < b.minor))
108 {
109 return -1;
110 }
111 else if (a.major == b.major && a.minor == b.minor)
112 {
113 return 0;
114 }
115 else
116 {
117 return 1;
118 }
119 }
120
121 typedef struct
122 {
123 version_t version; // Opcode is introduced in this version of OpenCL spec.
124 cl_device_info opcode;
125 const char* opcode_name;
126 int config_type;
127 config_data config;
128 size_t opcode_ret_size;
129 } config_info;
130
131 #define CONFIG_INFO(major, minor, opcode, type) \
132 { \
133 { major, minor }, opcode, #opcode, type_##type, { 0 } \
134 }
135
136 config_info image_buffer_config_infos[] = {
137 #ifdef CL_DEVICE_IMAGE_PITCH_ALIGNMENT
138 CONFIG_INFO(1, 2, CL_DEVICE_IMAGE_PITCH_ALIGNMENT, cl_uint),
139 CONFIG_INFO(1, 2, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT, cl_uint),
140 #endif
141 };
142
143 config_info config_infos[] = {
144 // `CL_DEVICE_VERSION' must be the first item in the list! It's version must
145 // be 0, 0.
146 CONFIG_INFO(0, 0, CL_DEVICE_VERSION, string),
147 // `CL_DEVICE_EXTENSIONS' must be the second!
148 CONFIG_INFO(1, 1, CL_DEVICE_EXTENSIONS, string),
149
150 CONFIG_INFO(1, 1, CL_DEVICE_TYPE, cl_device_type),
151 CONFIG_INFO(1, 1, CL_DEVICE_VENDOR_ID, cl_uint),
152 CONFIG_INFO(1, 1, CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint),
153 CONFIG_INFO(1, 1, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, cl_uint),
154 CONFIG_INFO(1, 1, CL_DEVICE_MAX_WORK_ITEM_SIZES, size_t_arr),
155 CONFIG_INFO(1, 1, CL_DEVICE_MAX_WORK_GROUP_SIZE, size_t),
156 CONFIG_INFO(1, 1, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, cl_uint),
157 CONFIG_INFO(1, 1, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, cl_uint),
158 CONFIG_INFO(1, 1, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, cl_uint),
159 CONFIG_INFO(1, 1, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, cl_uint),
160 CONFIG_INFO(1, 1, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, cl_uint),
161 CONFIG_INFO(1, 1, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, cl_uint),
162 CONFIG_INFO(1, 1, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF, cl_uint),
163 CONFIG_INFO(1, 1, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, cl_uint),
164 CONFIG_INFO(1, 1, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, cl_uint),
165 CONFIG_INFO(1, 1, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, cl_uint),
166 CONFIG_INFO(1, 1, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, cl_uint),
167 CONFIG_INFO(1, 1, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, cl_uint),
168 CONFIG_INFO(1, 1, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, cl_uint),
169 CONFIG_INFO(1, 1, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, cl_uint),
170
171 CONFIG_INFO(1, 1, CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint),
172 CONFIG_INFO(1, 1, CL_DEVICE_ADDRESS_BITS, cl_uint),
173 CONFIG_INFO(1, 1, CL_DEVICE_MAX_READ_IMAGE_ARGS, cl_uint),
174 CONFIG_INFO(1, 1, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, cl_uint),
175 CONFIG_INFO(2, 0, CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS, cl_uint),
176 CONFIG_INFO(1, 1, CL_DEVICE_MAX_MEM_ALLOC_SIZE, cl_ulong),
177 CONFIG_INFO(1, 1, CL_DEVICE_IMAGE2D_MAX_WIDTH, size_t),
178 CONFIG_INFO(1, 1, CL_DEVICE_IMAGE2D_MAX_HEIGHT, size_t),
179 CONFIG_INFO(1, 1, CL_DEVICE_IMAGE3D_MAX_WIDTH, size_t),
180 CONFIG_INFO(1, 1, CL_DEVICE_IMAGE3D_MAX_HEIGHT, size_t),
181 CONFIG_INFO(1, 1, CL_DEVICE_IMAGE3D_MAX_DEPTH, size_t),
182 CONFIG_INFO(1, 2, CL_DEVICE_IMAGE_MAX_ARRAY_SIZE, size_t),
183 CONFIG_INFO(1, 2, CL_DEVICE_IMAGE_MAX_BUFFER_SIZE, size_t),
184 CONFIG_INFO(1, 1, CL_DEVICE_IMAGE_SUPPORT, cl_uint),
185 CONFIG_INFO(1, 1, CL_DEVICE_MAX_PARAMETER_SIZE, size_t),
186 CONFIG_INFO(1, 1, CL_DEVICE_MAX_SAMPLERS, cl_uint),
187 CONFIG_INFO(2, 0, CL_DEVICE_IMAGE_PITCH_ALIGNMENT, cl_uint),
188 CONFIG_INFO(2, 0, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT, cl_uint),
189
190 CONFIG_INFO(1, 1, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint),
191 CONFIG_INFO(1, 1, CL_DEVICE_SINGLE_FP_CONFIG, cl_device_fp_config),
192 CONFIG_INFO(1, 1, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config),
193 CONFIG_INFO(1, 1, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE,
194 cl_device_mem_cache_type),
195 CONFIG_INFO(1, 1, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint),
196 CONFIG_INFO(1, 1, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong),
197 CONFIG_INFO(1, 1, CL_DEVICE_GLOBAL_MEM_SIZE, cl_ulong),
198
199 CONFIG_INFO(1, 1, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, cl_ulong),
200 CONFIG_INFO(1, 1, CL_DEVICE_MAX_CONSTANT_ARGS, cl_uint),
201 CONFIG_INFO(1, 1, CL_DEVICE_LOCAL_MEM_TYPE, cl_local_mem_type),
202 CONFIG_INFO(1, 1, CL_DEVICE_LOCAL_MEM_SIZE, cl_ulong),
203 CONFIG_INFO(1, 1, CL_DEVICE_ERROR_CORRECTION_SUPPORT, cl_uint),
204 CONFIG_INFO(1, 1, CL_DEVICE_HOST_UNIFIED_MEMORY, cl_uint),
205 CONFIG_INFO(1, 1, CL_DEVICE_PROFILING_TIMER_RESOLUTION, size_t),
206 CONFIG_INFO(1, 1, CL_DEVICE_ENDIAN_LITTLE, cl_uint),
207 CONFIG_INFO(1, 1, CL_DEVICE_AVAILABLE, cl_uint),
208 CONFIG_INFO(1, 1, CL_DEVICE_COMPILER_AVAILABLE, cl_uint),
209 CONFIG_INFO(1, 2, CL_DEVICE_LINKER_AVAILABLE, cl_uint),
210
211 CONFIG_INFO(1, 2, CL_DEVICE_BUILT_IN_KERNELS, string),
212
213 CONFIG_INFO(1, 2, CL_DEVICE_PRINTF_BUFFER_SIZE, size_t),
214 CONFIG_INFO(1, 2, CL_DEVICE_PREFERRED_INTEROP_USER_SYNC, cl_uint),
215
216 CONFIG_INFO(1, 2, CL_DEVICE_PARENT_DEVICE, cl_device_id),
217 CONFIG_INFO(1, 2, CL_DEVICE_PARTITION_MAX_SUB_DEVICES, cl_uint),
218 CONFIG_INFO(1, 2, CL_DEVICE_PARTITION_AFFINITY_DOMAIN,
219 cl_device_affinity_domain),
220 CONFIG_INFO(1, 2, CL_DEVICE_REFERENCE_COUNT, cl_uint),
221
222 CONFIG_INFO(1, 1, CL_DEVICE_EXECUTION_CAPABILITIES,
223 cl_device_exec_capabilities),
224 CONFIG_INFO(1, 1, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES,
225 cl_command_queue_properties),
226 CONFIG_INFO(1, 1, CL_DEVICE_NAME, string),
227 CONFIG_INFO(1, 1, CL_DEVICE_VENDOR, string),
228 CONFIG_INFO(1, 1, CL_DRIVER_VERSION, string),
229 CONFIG_INFO(1, 1, CL_DEVICE_PROFILE, string),
230 CONFIG_INFO(1, 1, CL_DEVICE_OPENCL_C_VERSION, string),
231
232 CONFIG_INFO(2, 0, CL_DEVICE_MAX_PIPE_ARGS, cl_uint),
233 CONFIG_INFO(2, 0, CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS, cl_uint),
234 CONFIG_INFO(2, 0, CL_DEVICE_PIPE_MAX_PACKET_SIZE, cl_uint),
235
236 CONFIG_INFO(2, 0, CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE, size_t),
237 CONFIG_INFO(2, 0, CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE, size_t),
238
239 CONFIG_INFO(2, 0, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES,
240 cl_command_queue_properties),
241 CONFIG_INFO(2, 0, CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES,
242 cl_command_queue_properties),
243 CONFIG_INFO(2, 0, CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE, cl_uint),
244 CONFIG_INFO(2, 0, CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE, cl_uint),
245 CONFIG_INFO(2, 0, CL_DEVICE_MAX_ON_DEVICE_QUEUES, cl_uint),
246 CONFIG_INFO(2, 0, CL_DEVICE_MAX_ON_DEVICE_EVENTS, cl_uint),
247
248 CONFIG_INFO(2, 0, CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT, cl_uint),
249 CONFIG_INFO(2, 0, CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT, cl_uint),
250 CONFIG_INFO(2, 0, CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT, cl_uint),
251
252 CONFIG_INFO(2, 0, CL_DEVICE_SVM_CAPABILITIES, cl_device_svm_capabilities),
253
254 CONFIG_INFO(2, 1, CL_DEVICE_IL_VERSION, string),
255 CONFIG_INFO(2, 1, CL_DEVICE_MAX_NUM_SUB_GROUPS, cl_uint),
256 CONFIG_INFO(2, 1, CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS,
257 cl_uint),
258 CONFIG_INFO(3, 0, CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES,
259 cl_device_atomic_capabilities),
260 CONFIG_INFO(3, 0, CL_DEVICE_ATOMIC_FENCE_CAPABILITIES,
261 cl_device_atomic_capabilities),
262 CONFIG_INFO(3, 0, CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT, cl_uint),
263 CONFIG_INFO(3, 0, CL_DEVICE_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, size_t),
264 CONFIG_INFO(3, 0, CL_DEVICE_WORK_GROUP_COLLECTIVE_FUNCTIONS_SUPPORT,
265 cl_uint),
266 CONFIG_INFO(3, 0, CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT, cl_uint),
267 CONFIG_INFO(3, 0, CL_DEVICE_OPENCL_C_FEATURES, cl_name_version_array),
268 CONFIG_INFO(3, 0, CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES,
269 cl_device_device_enqueue_capabilities),
270 CONFIG_INFO(3, 0, CL_DEVICE_PIPE_SUPPORT, cl_uint),
271 CONFIG_INFO(3, 0, CL_DEVICE_NUMERIC_VERSION, cl_name_version),
272 CONFIG_INFO(3, 0, CL_DEVICE_EXTENSIONS_WITH_VERSION, cl_name_version_array),
273 CONFIG_INFO(3, 0, CL_DEVICE_OPENCL_C_ALL_VERSIONS, cl_name_version_array),
274 CONFIG_INFO(3, 0, CL_DEVICE_ILS_WITH_VERSION, cl_name_version_array),
275 CONFIG_INFO(3, 0, CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION,
276 cl_name_version_array),
277 };
278
279 #define ENTRY(major, minor, T) \
280 { \
281 { major, minor }, T, #T \
282 }
283 struct image_type_entry
284 {
285 version_t
286 version; // Image type is introduced in this version of OpenCL spec.
287 cl_mem_object_type val;
288 const char* str;
289 };
290 static const struct image_type_entry image_types[] = {
291 ENTRY(1, 2, CL_MEM_OBJECT_IMAGE1D),
292 ENTRY(1, 2, CL_MEM_OBJECT_IMAGE1D_BUFFER),
293 ENTRY(1, 0, CL_MEM_OBJECT_IMAGE2D),
294 ENTRY(1, 0, CL_MEM_OBJECT_IMAGE3D),
295 ENTRY(1, 2, CL_MEM_OBJECT_IMAGE1D_ARRAY),
296 ENTRY(1, 2, CL_MEM_OBJECT_IMAGE2D_ARRAY)
297 };
298
299 struct supported_flags_entry
300 {
301 version_t
302 version; // Memory flag is introduced in this version of OpenCL spec.
303 cl_mem_flags val;
304 const char* str;
305 };
306
307 static const struct supported_flags_entry supported_flags[] = {
308 ENTRY(1, 0, CL_MEM_READ_ONLY), ENTRY(1, 0, CL_MEM_WRITE_ONLY),
309 ENTRY(1, 0, CL_MEM_READ_WRITE), ENTRY(2, 0, CL_MEM_KERNEL_READ_AND_WRITE)
310 };
311
getImageInfo(cl_device_id device,const version_t & version)312 int getImageInfo(cl_device_id device, const version_t& version)
313 {
314 cl_context ctx;
315 cl_int err;
316 cl_uint i, num_supported;
317 cl_image_format* formats;
318 int num_errors;
319 int ii, ni = sizeof(image_types) / sizeof(image_types[0]);
320 int fi, nf = sizeof(supported_flags) / sizeof(supported_flags[0]);
321
322 ctx = clCreateContext(NULL, 1, &device, notify_callback, NULL, &err);
323 if (!ctx)
324 {
325 print_error(err, "Unable to create context from device");
326 return 1;
327 }
328
329 num_errors = 0;
330 for (ii = 0; ii < ni; ++ii)
331 {
332 if (vercmp(version, image_types[ii].version) < 0)
333 {
334 continue;
335 }
336
337 log_info("\t%s supported formats:\n", image_types[ii].str);
338 for (fi = 0; fi < nf; ++fi)
339 {
340 if (vercmp(version, supported_flags[fi].version) < 0)
341 {
342 continue;
343 }
344
345 err = clGetSupportedImageFormats(ctx, supported_flags[fi].val,
346 image_types[ii].val, 5000, NULL,
347 &num_supported);
348 if (err != CL_SUCCESS)
349 {
350 print_error(err, "clGetSupportedImageFormats failed");
351 ++num_errors;
352 continue;
353 }
354
355 log_info("\t\t%s: %u supported formats\n", supported_flags[fi].str,
356 num_supported);
357
358 if (num_supported == 0 || dump_supported_formats == 0) continue;
359
360 formats = (cl_image_format*)malloc(num_supported
361 * sizeof(cl_image_format));
362 if (formats == NULL)
363 {
364 log_error("malloc failed\n");
365 clReleaseContext(ctx);
366 return num_errors + 1;
367 }
368
369 err = clGetSupportedImageFormats(ctx, supported_flags[fi].val,
370 image_types[ii].val, num_supported,
371 formats, NULL);
372 if (err != CL_SUCCESS)
373 {
374 print_error(err, "clGetSupportedImageFormats failed");
375 ++num_errors;
376 free(formats);
377 continue;
378 }
379
380 for (i = 0; i < num_supported; ++i)
381 log_info(
382 "\t\t\t%s / %s\n",
383 GetChannelOrderName(formats[i].image_channel_order),
384 GetChannelTypeName(formats[i].image_channel_data_type));
385
386 free(formats);
387 }
388 }
389
390 err = clReleaseContext(ctx);
391 if (err)
392 {
393 print_error(err, "Failed to release context\n");
394 ++num_errors;
395 }
396
397 return num_errors;
398 }
getPlatformConfigInfo(cl_platform_id platform,config_info * info)399 int getPlatformConfigInfo(cl_platform_id platform, config_info* info)
400 {
401 int err = CL_SUCCESS;
402 int size_err = 0;
403 size_t config_size_set;
404 size_t config_size_ret;
405 switch (info->config_type)
406 {
407 case type_string:
408 err = clGetPlatformInfo(platform, info->opcode, 0, NULL,
409 &config_size_set);
410 info->config.string = NULL;
411 if (err == CL_SUCCESS && config_size_set > 0)
412 {
413 info->config.string = (char*)malloc(config_size_set);
414 err = clGetPlatformInfo(platform, info->opcode, config_size_set,
415 info->config.string, &config_size_ret);
416 size_err = config_size_set != config_size_ret;
417 }
418 break;
419 case type_cl_name_version_array:
420 err = clGetPlatformInfo(platform, info->opcode, 0, NULL,
421 &config_size_set);
422 info->config.cl_name_version_array = NULL;
423 if (err == CL_SUCCESS && config_size_set > 0)
424 {
425 info->config.cl_name_version_array = (cl_name_version*)malloc(
426 config_size_set * sizeof(cl_name_version));
427 err = clGetPlatformInfo(platform, info->opcode, config_size_set,
428 info->config.cl_name_version_array,
429 &config_size_ret);
430 size_err = config_size_set != config_size_ret;
431 info->opcode_ret_size = config_size_ret;
432 }
433 break;
434 case type_cl_name_version:
435 err = clGetPlatformInfo(platform, info->opcode, 0, NULL,
436 &config_size_set);
437 if (err == CL_SUCCESS && config_size_set > 0)
438 {
439 err = clGetPlatformInfo(platform, info->opcode, config_size_set,
440 &info->config.cl_name_version_single,
441 &config_size_ret);
442 }
443 size_err = config_size_set != config_size_ret;
444 break;
445 default:
446 log_error("Unknown config type: %d\n", info->config_type);
447 break;
448 }
449 if (err || size_err)
450 log_error("\tFailed clGetPlatformInfo for %s.\n", info->opcode_name);
451 if (err) print_error(err, "\t\tclGetPlatformInfo failed.");
452 if (size_err) log_error("\t\tWrong size return from clGetPlatformInfo.\n");
453 return err || size_err;
454 }
455
getConfigInfo(cl_device_id device,config_info * info)456 int getConfigInfo(cl_device_id device, config_info* info)
457 {
458 int err = CL_SUCCESS;
459 int size_err = 0;
460 size_t config_size_set;
461 size_t config_size_ret;
462 switch (info->config_type)
463 {
464 case type_cl_device_type:
465 err =
466 clGetDeviceInfo(device, info->opcode, sizeof(info->config.type),
467 &info->config.type, &config_size_ret);
468 size_err = config_size_ret != sizeof(info->config.type);
469 break;
470 case type_cl_device_fp_config:
471 err = clGetDeviceInfo(device, info->opcode,
472 sizeof(info->config.fp_config),
473 &info->config.fp_config, &config_size_ret);
474 size_err = config_size_ret != sizeof(info->config.fp_config);
475 break;
476 case type_cl_device_mem_cache_type:
477 err = clGetDeviceInfo(
478 device, info->opcode, sizeof(info->config.mem_cache_type),
479 &info->config.mem_cache_type, &config_size_ret);
480 size_err = config_size_ret != sizeof(info->config.mem_cache_type);
481 break;
482 case type_cl_local_mem_type:
483 err = clGetDeviceInfo(
484 device, info->opcode, sizeof(info->config.local_mem_type),
485 &info->config.local_mem_type, &config_size_ret);
486 size_err = config_size_ret != sizeof(info->config.local_mem_type);
487 break;
488 case type_cl_device_exec_capabilities:
489 err = clGetDeviceInfo(
490 device, info->opcode, sizeof(info->config.exec_capabilities),
491 &info->config.exec_capabilities, &config_size_ret);
492 size_err =
493 config_size_ret != sizeof(info->config.exec_capabilities);
494 break;
495 case type_cl_command_queue_properties:
496 err = clGetDeviceInfo(
497 device, info->opcode, sizeof(info->config.queue_properties),
498 &info->config.queue_properties, &config_size_ret);
499 size_err = config_size_ret != sizeof(info->config.queue_properties);
500 break;
501 case type_cl_device_id:
502 err = clGetDeviceInfo(device, info->opcode,
503 sizeof(info->config.device_id),
504 &info->config.device_id, &config_size_ret);
505 size_err = config_size_ret != sizeof(info->config.device_id);
506 break;
507 case type_cl_device_affinity_domain:
508 err = clGetDeviceInfo(
509 device, info->opcode, sizeof(info->config.affinity_domain),
510 &info->config.affinity_domain, &config_size_ret);
511 size_err = config_size_ret != sizeof(info->config.affinity_domain);
512 break;
513 case type_cl_uint:
514 err =
515 clGetDeviceInfo(device, info->opcode, sizeof(info->config.uint),
516 &info->config.uint, &config_size_ret);
517 size_err = config_size_ret != sizeof(info->config.uint);
518 break;
519 case type_size_t_arr:
520 err = clGetDeviceInfo(device, info->opcode,
521 sizeof(info->config.sizet_arr),
522 &info->config.sizet_arr, &config_size_ret);
523 size_err = config_size_ret != sizeof(info->config.sizet_arr);
524 break;
525 case type_size_t:
526 err = clGetDeviceInfo(device, info->opcode,
527 sizeof(info->config.sizet),
528 &info->config.sizet, &config_size_ret);
529 size_err = config_size_ret != sizeof(info->config.sizet);
530 break;
531 case type_cl_ulong:
532 err =
533 clGetDeviceInfo(device, info->opcode, sizeof(info->config.ull),
534 &info->config.ull, &config_size_ret);
535 size_err = config_size_ret != sizeof(info->config.ull);
536 break;
537 case type_string:
538 err = clGetDeviceInfo(device, info->opcode, 0, NULL,
539 &config_size_set);
540 info->config.string = NULL;
541 if (err == CL_SUCCESS && config_size_set > 0)
542 {
543 info->config.string = (char*)malloc(config_size_set);
544 err = clGetDeviceInfo(device, info->opcode, config_size_set,
545 info->config.string, &config_size_ret);
546 size_err = config_size_set != config_size_ret;
547 }
548 break;
549 case type_cl_device_svm_capabilities:
550 err = clGetDeviceInfo(
551 device, info->opcode, sizeof(info->config.svmCapabilities),
552 &info->config.svmCapabilities, &config_size_ret);
553 break;
554 case type_cl_device_device_enqueue_capabilities:
555 err = clGetDeviceInfo(
556 device, info->opcode,
557 sizeof(info->config.deviceEnqueueCapabilities),
558 &info->config.deviceEnqueueCapabilities, &config_size_ret);
559 break;
560 case type_cl_device_atomic_capabilities:
561 err = clGetDeviceInfo(
562 device, info->opcode, sizeof(info->config.atomicCapabilities),
563 &info->config.atomicCapabilities, &config_size_ret);
564 break;
565 case type_cl_name_version_array:
566 err = clGetDeviceInfo(device, info->opcode, 0, NULL,
567 &config_size_set);
568 info->config.cl_name_version_array = NULL;
569 if (err == CL_SUCCESS && config_size_set > 0)
570 {
571 info->config.cl_name_version_array = (cl_name_version*)malloc(
572 config_size_set * sizeof(cl_name_version));
573 err = clGetDeviceInfo(device, info->opcode, config_size_set,
574 info->config.cl_name_version_array,
575 &config_size_ret);
576 size_err = config_size_set != config_size_ret;
577 info->opcode_ret_size = config_size_ret;
578 }
579 break;
580 case type_cl_name_version:
581 err = clGetDeviceInfo(device, info->opcode, 0, NULL,
582 &config_size_set);
583 if (err == CL_SUCCESS && config_size_set > 0)
584 {
585 err = clGetDeviceInfo(device, info->opcode, config_size_set,
586 &info->config.cl_name_version_single,
587 &config_size_ret);
588 }
589 size_err = config_size_set != config_size_ret;
590 break;
591 default:
592 log_error("Unknown config type: %d\n", info->config_type);
593 break;
594 }
595 if (err || size_err)
596 log_error("\tFailed clGetDeviceInfo for %s.\n", info->opcode_name);
597 if (err) print_error(err, "\t\tclGetDeviceInfo failed.");
598 if (size_err) log_error("\t\tWrong size return from clGetDeviceInfo.\n");
599 return err || size_err;
600 }
601
dumpConfigInfo(config_info * info)602 void dumpConfigInfo(config_info* info)
603 {
604 // We should not error if we find an unknown configuration since vendors
605 // may specify their own options beyond the list in the specification.
606 switch (info->config_type)
607 {
608 case type_cl_device_type:
609 log_info("\t%s == %s|%s|%s|%s\n", info->opcode_name,
610 (info->config.fp_config & CL_DEVICE_TYPE_CPU)
611 ? "CL_DEVICE_TYPE_CPU"
612 : "",
613 (info->config.fp_config & CL_DEVICE_TYPE_GPU)
614 ? "CL_DEVICE_TYPE_GPU"
615 : "",
616 (info->config.fp_config & CL_DEVICE_TYPE_ACCELERATOR)
617 ? "CL_DEVICE_TYPE_ACCELERATOR"
618 : "",
619 (info->config.fp_config & CL_DEVICE_TYPE_DEFAULT)
620 ? "CL_DEVICE_TYPE_DEFAULT"
621 : "");
622 {
623 cl_device_type all_device_types = CL_DEVICE_TYPE_CPU
624 | CL_DEVICE_TYPE_GPU | CL_DEVICE_TYPE_ACCELERATOR
625 | CL_DEVICE_TYPE_DEFAULT;
626 if (info->config.fp_config & ~all_device_types)
627 {
628 log_info("WARNING: %s unknown bits found 0x%08" PRIX64,
629 info->opcode_name,
630 (info->config.fp_config & ~all_device_types));
631 }
632 }
633 break;
634 case type_cl_device_fp_config:
635 log_info(
636 "\t%s == %s|%s|%s|%s|%s|%s|%s\n", info->opcode_name,
637 (info->config.fp_config & CL_FP_DENORM) ? "CL_FP_DENORM" : "",
638 (info->config.fp_config & CL_FP_INF_NAN) ? "CL_FP_INF_NAN" : "",
639 (info->config.fp_config & CL_FP_ROUND_TO_NEAREST)
640 ? "CL_FP_ROUND_TO_NEAREST"
641 : "",
642 (info->config.fp_config & CL_FP_ROUND_TO_ZERO)
643 ? "CL_FP_ROUND_TO_ZERO"
644 : "",
645 (info->config.fp_config & CL_FP_ROUND_TO_INF)
646 ? "CL_FP_ROUND_TO_INF"
647 : "",
648 (info->config.fp_config & CL_FP_FMA) ? "CL_FP_FMA" : "",
649 (info->config.fp_config & CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT)
650 ? "CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT"
651 : "");
652 {
653 cl_device_fp_config all_fp_config = CL_FP_DENORM | CL_FP_INF_NAN
654 | CL_FP_ROUND_TO_NEAREST | CL_FP_ROUND_TO_ZERO
655 | CL_FP_ROUND_TO_INF | CL_FP_FMA
656 | CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT;
657 if (info->config.fp_config & ~all_fp_config)
658 log_info("WARNING: %s unknown bits found 0x%08" PRIX64,
659 info->opcode_name,
660 (info->config.fp_config & ~all_fp_config));
661 }
662 break;
663 case type_cl_device_mem_cache_type:
664 switch (info->config.mem_cache_type)
665 {
666 case CL_NONE:
667 log_info("\t%s == CL_NONE\n", info->opcode_name);
668 break;
669 case CL_READ_ONLY_CACHE:
670 log_info("\t%s == CL_READ_ONLY_CACHE\n", info->opcode_name);
671 break;
672 case CL_READ_WRITE_CACHE:
673 log_info("\t%s == CL_READ_WRITE_CACHE\n",
674 info->opcode_name);
675 break;
676 default:
677 log_error("ERROR: %s out of range, %d\n", info->opcode_name,
678 info->config.mem_cache_type);
679 break;
680 }
681 break;
682 case type_cl_local_mem_type:
683 switch (info->config.local_mem_type)
684 {
685 case CL_NONE:
686 log_info("\t%s == CL_NONE\n", info->opcode_name);
687 break;
688 case CL_LOCAL:
689 log_info("\t%s == CL_LOCAL\n", info->opcode_name);
690 break;
691 case CL_GLOBAL:
692 log_info("\t%s == CL_GLOBAL\n", info->opcode_name);
693 break;
694 default:
695 log_info("WARNING: %s out of range, %d\n",
696 info->opcode_name, info->config.local_mem_type);
697 break;
698 }
699 break;
700 case type_cl_device_exec_capabilities:
701 log_info("\t%s == %s|%s\n", info->opcode_name,
702 (info->config.exec_capabilities & CL_EXEC_KERNEL)
703 ? "CL_EXEC_KERNEL"
704 : "",
705 (info->config.exec_capabilities & CL_EXEC_NATIVE_KERNEL)
706 ? "CL_EXEC_NATIVE_KERNEL"
707 : "");
708 {
709 cl_device_exec_capabilities all_exec_cap =
710 CL_EXEC_KERNEL | CL_EXEC_NATIVE_KERNEL;
711 if (info->config.exec_capabilities & ~all_exec_cap)
712 log_info("WARNING: %s unknown bits found 0x%08" PRIX64,
713 info->opcode_name,
714 (info->config.exec_capabilities & ~all_exec_cap));
715 }
716 break;
717 case type_cl_command_queue_properties:
718 log_info("\t%s == %s|%s\n", info->opcode_name,
719 (info->config.queue_properties
720 & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE)
721 ? "CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE"
722 : "",
723 (info->config.queue_properties & CL_QUEUE_PROFILING_ENABLE)
724 ? "CL_QUEUE_PROFILING_ENABLE"
725 : "");
726 {
727 cl_command_queue_properties all_queue_properties =
728 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
729 | CL_QUEUE_PROFILING_ENABLE;
730 if (info->config.queue_properties & ~all_queue_properties)
731 log_info("WARNING: %s unknown bits found 0x%08" PRIX64,
732 info->opcode_name,
733 (info->config.exec_capabilities
734 & ~all_queue_properties));
735 }
736 break;
737 case type_cl_device_id:
738 log_info("\t%s == %ld\n", info->opcode_name,
739 (intptr_t)info->config.device_id);
740 break;
741 case type_cl_device_affinity_domain:
742 log_info(
743 "\t%s == %s|%s|%s|%s|%s|%s\n", info->opcode_name,
744 (info->config.affinity_domain & CL_DEVICE_AFFINITY_DOMAIN_NUMA)
745 ? "CL_DEVICE_AFFINITY_DOMAIN_NUMA"
746 : "",
747 (info->config.affinity_domain
748 & CL_DEVICE_AFFINITY_DOMAIN_L4_CACHE)
749 ? "CL_DEVICE_AFFINITY_DOMAIN_L4_CACHE"
750 : "",
751 (info->config.affinity_domain
752 & CL_DEVICE_AFFINITY_DOMAIN_L3_CACHE)
753 ? "CL_DEVICE_AFFINITY_DOMAIN_L3_CACHE"
754 : "",
755 (info->config.affinity_domain
756 & CL_DEVICE_AFFINITY_DOMAIN_L2_CACHE)
757 ? "CL_DEVICE_AFFINITY_DOMAIN_L2_CACHE"
758 : "",
759 (info->config.affinity_domain
760 & CL_DEVICE_AFFINITY_DOMAIN_L1_CACHE)
761 ? "CL_DEVICE_AFFINITY_DOMAIN_L1_CACHE"
762 : "",
763 (info->config.affinity_domain
764 & CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE)
765 ? "CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE"
766 : "");
767 {
768 cl_device_affinity_domain all_affinity_domain =
769 CL_DEVICE_AFFINITY_DOMAIN_NUMA
770 | CL_DEVICE_AFFINITY_DOMAIN_L4_CACHE
771 | CL_DEVICE_AFFINITY_DOMAIN_L3_CACHE
772 | CL_DEVICE_AFFINITY_DOMAIN_L2_CACHE
773 | CL_DEVICE_AFFINITY_DOMAIN_L1_CACHE
774 | CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE;
775 if (info->config.affinity_domain & ~all_affinity_domain)
776 log_error(
777 "ERROR: %s unknown bits found 0x%08" PRIX64,
778 info->opcode_name,
779 (info->config.affinity_domain & ~all_affinity_domain));
780 }
781 break;
782 case type_cl_uint:
783 log_info("\t%s == %u\n", info->opcode_name, info->config.uint);
784 break;
785 case type_size_t_arr:
786 log_info("\t%s == %zu %zu %zu\n", info->opcode_name,
787 info->config.sizet_arr[0], info->config.sizet_arr[1],
788 info->config.sizet_arr[2]);
789 break;
790 case type_size_t:
791 log_info("\t%s == %zu\n", info->opcode_name, info->config.sizet);
792 break;
793 case type_cl_ulong:
794 log_info("\t%s == %" PRIu64 "\n", info->opcode_name,
795 info->config.ull);
796 break;
797 case type_string:
798 log_info("\t%s == \"%s\"\n", info->opcode_name,
799 info->config.string ? info->config.string : "");
800 break;
801 case type_cl_device_svm_capabilities:
802 log_info(
803 "\t%s == %s|%s|%s|%s\n", info->opcode_name,
804 (info->config.svmCapabilities
805 & CL_DEVICE_SVM_COARSE_GRAIN_BUFFER)
806 ? "CL_DEVICE_SVM_COARSE_GRAIN_BUFFER"
807 : "",
808 (info->config.svmCapabilities & CL_DEVICE_SVM_FINE_GRAIN_BUFFER)
809 ? "CL_DEVICE_SVM_FINE_GRAIN_BUFFER"
810 : "",
811 (info->config.svmCapabilities & CL_DEVICE_SVM_FINE_GRAIN_SYSTEM)
812 ? "CL_DEVICE_SVM_FINE_GRAIN_SYSTEM"
813 : "",
814 (info->config.svmCapabilities & CL_DEVICE_SVM_ATOMICS)
815 ? "CL_DEVICE_SVM_ATOMICS"
816 : "");
817 {
818 cl_device_svm_capabilities all_svm_capabilities =
819 CL_DEVICE_SVM_COARSE_GRAIN_BUFFER
820 | CL_DEVICE_SVM_FINE_GRAIN_BUFFER
821 | CL_DEVICE_SVM_FINE_GRAIN_SYSTEM | CL_DEVICE_SVM_ATOMICS;
822 if (info->config.svmCapabilities & ~all_svm_capabilities)
823 log_info(
824 "WARNING: %s unknown bits found 0x%08" PRIX64,
825 info->opcode_name,
826 (info->config.svmCapabilities & ~all_svm_capabilities));
827 }
828 break;
829 case type_cl_device_device_enqueue_capabilities:
830 log_info("\t%s == %s|%s\n", info->opcode_name,
831 (info->config.deviceEnqueueCapabilities
832 & CL_DEVICE_QUEUE_SUPPORTED)
833 ? "CL_DEVICE_QUEUE_SUPPORTED"
834 : "",
835 (info->config.deviceEnqueueCapabilities
836 & CL_DEVICE_QUEUE_REPLACEABLE_DEFAULT)
837 ? "CL_DEVICE_QUEUE_REPLACEABLE_DEFAULT"
838 : "");
839 {
840 cl_device_device_enqueue_capabilities
841 all_device_enqueue_capabilities = CL_DEVICE_QUEUE_SUPPORTED
842 | CL_DEVICE_QUEUE_REPLACEABLE_DEFAULT;
843 if (info->config.deviceEnqueueCapabilities
844 & ~all_device_enqueue_capabilities)
845 log_info("WARNING: %s unknown bits found 0x%08" PRIX64,
846 info->opcode_name,
847 (info->config.deviceEnqueueCapabilities
848 & ~all_device_enqueue_capabilities));
849 }
850 break;
851 case type_cl_device_atomic_capabilities:
852 log_info("\t%s == %s|%s|%s|%s|%s|%s|%s\n", info->opcode_name,
853 (info->config.atomicCapabilities
854 & CL_DEVICE_ATOMIC_ORDER_RELAXED)
855 ? "CL_DEVICE_ATOMIC_ORDER_RELAXED"
856 : "",
857 (info->config.atomicCapabilities
858 & CL_DEVICE_ATOMIC_ORDER_ACQ_REL)
859 ? "CL_DEVICE_ATOMIC_ORDER_ACQ_REL"
860 : "",
861 (info->config.atomicCapabilities
862 & CL_DEVICE_ATOMIC_ORDER_SEQ_CST)
863 ? "CL_DEVICE_ATOMIC_ORDER_SEQ_CST"
864 : "",
865 (info->config.atomicCapabilities
866 & CL_DEVICE_ATOMIC_SCOPE_WORK_ITEM)
867 ? "CL_DEVICE_ATOMIC_SCOPE_WORK_ITEM"
868 : "",
869 (info->config.atomicCapabilities
870 & CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP)
871 ? "CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP"
872 : "",
873 (info->config.atomicCapabilities
874 & CL_DEVICE_ATOMIC_SCOPE_DEVICE)
875 ? "CL_DEVICE_ATOMIC_SCOPE_DEVICE"
876 : "",
877 (info->config.atomicCapabilities
878 & CL_DEVICE_ATOMIC_SCOPE_ALL_DEVICES)
879 ? "CL_DEVICE_ATOMIC_SCOPE_ALL_DEVICES"
880 : "");
881 {
882 cl_device_atomic_capabilities all_atomic_capabilities =
883 CL_DEVICE_ATOMIC_ORDER_RELAXED
884 | CL_DEVICE_ATOMIC_ORDER_ACQ_REL
885 | CL_DEVICE_ATOMIC_ORDER_SEQ_CST
886 | CL_DEVICE_ATOMIC_SCOPE_WORK_ITEM
887 | CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP
888 | CL_DEVICE_ATOMIC_SCOPE_DEVICE
889 | CL_DEVICE_ATOMIC_SCOPE_ALL_DEVICES;
890 if (info->config.atomicCapabilities & ~all_atomic_capabilities)
891 log_info("WARNING: %s unknown bits found 0x%08" PRIX64,
892 info->opcode_name,
893 (info->config.atomicCapabilities
894 & ~all_atomic_capabilities));
895 }
896 break;
897 case type_cl_name_version_array: {
898 int number_of_version_items = info->opcode_ret_size
899 / sizeof(*info->config.cl_name_version_array);
900 log_info("\t%s supported name and version:\n", info->opcode_name);
901 if (number_of_version_items == 0)
902 {
903 log_info("\t\t\"\"\n");
904 }
905 else
906 {
907 for (int f = 0; f < number_of_version_items; f++)
908 {
909 cl_name_version new_version_item =
910 info->config.cl_name_version_array[f];
911 cl_version new_version_major =
912 CL_VERSION_MAJOR_KHR(new_version_item.version);
913 cl_version new_version_minor =
914 CL_VERSION_MINOR_KHR(new_version_item.version);
915 cl_version new_version_patch =
916 CL_VERSION_PATCH_KHR(new_version_item.version);
917 log_info("\t\t\"%s\" %d.%d.%d\n", new_version_item.name,
918 CL_VERSION_MAJOR_KHR(new_version_item.version),
919 CL_VERSION_MINOR_KHR(new_version_item.version),
920 CL_VERSION_PATCH_KHR(new_version_item.version));
921 }
922 }
923 break;
924 }
925 case type_cl_name_version:
926 log_info("\t%s == %d.%d.%d\n", info->opcode_name,
927 CL_VERSION_MAJOR_KHR(
928 info->config.cl_name_version_single.version),
929 CL_VERSION_MINOR_KHR(
930 info->config.cl_name_version_single.version),
931 CL_VERSION_PATCH_KHR(
932 info->config.cl_name_version_single.version));
933 break;
934 }
935 }
936
print_platform_string_selector(cl_platform_id platform,const char * selector_name,cl_platform_info selector)937 void print_platform_string_selector(cl_platform_id platform,
938 const char* selector_name,
939 cl_platform_info selector)
940 {
941 // Currently all the selectors are strings
942 size_t size = 0;
943 char* value;
944 int err;
945
946 if ((err = clGetPlatformInfo(platform, selector, 0, NULL, &size)))
947 {
948 log_error("FAILURE: Unable to get platform info size for %s.\n",
949 selector_name);
950 exit(-1);
951 }
952
953 if (size == 0)
954 {
955 log_error("FAILURE: The size of %s was returned to be zero.\n",
956 selector_name);
957 exit(-1);
958 }
959
960 value = (char*)malloc(size);
961 if (NULL == value)
962 {
963 log_error("Internal test failure: Unable to allocate %zu bytes\n",
964 size);
965 exit(-1);
966 }
967
968 memset(value, -1, size);
969 if ((err = clGetPlatformInfo(platform, selector, size, value, NULL)))
970 {
971 log_error("FAILURE: Unable to get platform info for %s.\n",
972 selector_name);
973 free(value);
974 exit(-1);
975 }
976
977 if (value[size - 1] != '\0')
978 {
979 log_error("FAILURE: platform info for %s is either not NUL terminated, "
980 "or the size is wrong.\n",
981 selector_name);
982 free(value);
983 exit(-1);
984 }
985
986 log_info("\t%s: %s\n", selector_name, value);
987 free(value);
988 }
989
parseVersion(char const * str,version_t * version)990 int parseVersion(char const* str, version_t* version)
991 {
992 int rc = -1;
993 version->major = 0;
994 version->minor = 0;
995 if (strncmp(str, "OpenCL 1.2", 10) == 0 && (str[10] == 0 || str[10] == ' '))
996 {
997 version->major = 1;
998 version->minor = 2;
999 rc = 0;
1000 }
1001 else if (strncmp(str, "OpenCL 1.0", 10) == 0
1002 && (str[10] == 0 || str[10] == ' '))
1003 {
1004 version->major = 1;
1005 version->minor = 0;
1006 rc = 0;
1007 }
1008 else if (strncmp(str, "OpenCL 1.1", 10) == 0
1009 && (str[10] == 0 || str[10] == ' '))
1010 {
1011 version->major = 1;
1012 version->minor = 1;
1013 rc = 0;
1014 }
1015 else if (strncmp(str, "OpenCL 2.0", 10) == 0
1016 && (str[10] == 0 || str[10] == ' '))
1017 {
1018 version->major = 2;
1019 version->minor = 0;
1020 rc = 0;
1021 }
1022 else if (strncmp(str, "OpenCL 2.1", 10) == 0
1023 && (str[10] == 0 || str[10] == ' '))
1024 {
1025 version->major = 2;
1026 version->minor = 1;
1027 rc = 0;
1028 }
1029 else if (strncmp(str, "OpenCL 2.2", 10) == 0
1030 && (str[10] == 0 || str[10] == ' '))
1031 {
1032 version->major = 2;
1033 version->minor = 2;
1034 rc = 0;
1035 }
1036 else if (strncmp(str, "OpenCL 3.0", 10) == 0
1037 && (str[10] == 0 || str[10] == ' '))
1038 {
1039 version->major = 3;
1040 version->minor = 0;
1041 rc = 0;
1042 }
1043 else
1044 {
1045 log_error("ERROR: Unexpected version string: `%s'.\n", str);
1046 };
1047 return rc;
1048 }
1049
parseExtensions(char const * str,extensions_t * extensions)1050 int parseExtensions(char const* str, extensions_t* extensions)
1051 {
1052 char const* begin = NULL;
1053 char const* space = NULL;
1054 size_t length = 0;
1055
1056 memset(extensions, 0, sizeof(extensions_t));
1057
1058 begin = str;
1059 while (begin[0] != 0)
1060 {
1061 space = strchr(begin, ' '); // Find space position.
1062 if (space != NULL)
1063 { // Calculate length of word.
1064 length = space - begin;
1065 }
1066 else
1067 {
1068 length = strlen(begin);
1069 }
1070 if (strncmp(begin, "cl_khr_fp64", length) == 0)
1071 {
1072 extensions->cl_khr_fp64 = 1;
1073 }
1074 if (strncmp(begin, "cl_khr_fp16", length) == 0)
1075 {
1076 extensions->cl_khr_fp16 = 1;
1077 }
1078 begin += length; // Skip word.
1079 if (begin[0] == ' ')
1080 { // Skip space, if any.
1081 begin += 1;
1082 }
1083 }
1084
1085 return 0;
1086 }
1087
getConfigInfos(cl_device_id device)1088 int getConfigInfos(cl_device_id device)
1089 {
1090 int total_errors = 0;
1091 unsigned onConfigInfo;
1092 version_t version = { 0, 0 }; // Version of the device. Will get real value
1093 // on the first loop iteration.
1094 version_t const ver11 = { 1, 1 }; // Version 1.1.
1095 extensions_t extensions = { 0 };
1096 int get; // Boolean flag: true = get property, false = skip it.
1097 int err;
1098 for (onConfigInfo = 0;
1099 onConfigInfo < sizeof(config_infos) / sizeof(config_infos[0]);
1100 onConfigInfo++)
1101 {
1102 config_info info = config_infos[onConfigInfo];
1103 // Get a property only if device version is equal or greater than
1104 // property version.
1105 get = (vercmp(version, info.version) >= 0);
1106 if (info.opcode == CL_DEVICE_DOUBLE_FP_CONFIG
1107 && vercmp(version, ver11) <= 0)
1108 {
1109 // CL_DEVICE_DOUBLE_FP_CONFIG is a special case. It was introduced
1110 // in OpenCL 1.1, but device is required to report it only if
1111 // doubles are supported. So, before querying it on device
1112 // version 1.1, we have to check doubles are sopported. In
1113 // OpenCL 1.2 CL_DEVICE_DOUBLE_FP_CONFIG should be reported
1114 // unconditionally.
1115 get = extensions.cl_khr_fp64;
1116 };
1117 if (info.opcode == CL_DEVICE_HALF_FP_CONFIG)
1118 {
1119 // CL_DEVICE_HALF_FP_CONFIG should be reported only when cl_khr_fp16
1120 // extension is available
1121 get = extensions.cl_khr_fp16;
1122 };
1123 if (get)
1124 {
1125 err = getConfigInfo(device, &info);
1126 if (!err)
1127 {
1128 dumpConfigInfo(&info);
1129 if (info.opcode == CL_DEVICE_VERSION)
1130 {
1131 err = parseVersion(info.config.string, &version);
1132 if (err)
1133 {
1134 total_errors++;
1135 free(info.config.string);
1136 break;
1137 }
1138 }
1139 else if (info.opcode == CL_DEVICE_EXTENSIONS)
1140 {
1141 err = parseExtensions(info.config.string, &extensions);
1142 if (err)
1143 {
1144 total_errors++;
1145 free(info.config.string);
1146 break;
1147 }
1148 }
1149 if (info.config_type == type_string)
1150 {
1151 free(info.config.string);
1152 }
1153 if (info.config_type == type_cl_name_version_array)
1154 {
1155 free(info.config.cl_name_version_array);
1156 }
1157 }
1158 else
1159 {
1160 total_errors++;
1161 }
1162 }
1163 else
1164 {
1165 log_info("\tSkipped: %s.\n", info.opcode_name);
1166 }
1167 }
1168
1169 if (is_extension_available(device, "cl_khr_image2d_from_buffer"))
1170 {
1171 for (onConfigInfo = 0; onConfigInfo < sizeof(image_buffer_config_infos)
1172 / sizeof(image_buffer_config_infos[0]);
1173 onConfigInfo++)
1174 {
1175 config_info info = image_buffer_config_infos[onConfigInfo];
1176 get = (vercmp(version, info.version) >= 0);
1177 if (get)
1178 {
1179 err = getConfigInfo(device, &info);
1180 if (!err)
1181 {
1182 dumpConfigInfo(&info);
1183 }
1184 else
1185 {
1186 total_errors++;
1187 }
1188 }
1189 }
1190 }
1191
1192 total_errors += getImageInfo(device, version);
1193
1194 return total_errors;
1195 }
1196
1197 config_info config_platform_infos[] = {
1198 // CL_PLATFORM_VERSION has to be first defined with version 0 0.
1199 CONFIG_INFO(0, 0, CL_PLATFORM_VERSION, string),
1200 CONFIG_INFO(1, 1, CL_PLATFORM_PROFILE, string),
1201 CONFIG_INFO(1, 1, CL_PLATFORM_NAME, string),
1202 CONFIG_INFO(1, 1, CL_PLATFORM_VENDOR, string),
1203 CONFIG_INFO(1, 1, CL_PLATFORM_EXTENSIONS, string),
1204 CONFIG_INFO(3, 0, CL_PLATFORM_EXTENSIONS_WITH_VERSION,
1205 cl_name_version_array),
1206 CONFIG_INFO(3, 0, CL_PLATFORM_NUMERIC_VERSION, cl_name_version)
1207 };
1208
getPlatformCapabilities(cl_platform_id platform)1209 int getPlatformCapabilities(cl_platform_id platform)
1210 {
1211 int total_errors = 0;
1212 version_t version = { 0, 0 }; // Version of the device. Will get real value
1213 // on the first loop iteration.
1214 int err;
1215 for (unsigned onConfigInfo = 0; onConfigInfo
1216 < sizeof(config_platform_infos) / sizeof(config_platform_infos[0]);
1217 onConfigInfo++)
1218 {
1219 config_info info = config_platform_infos[onConfigInfo];
1220
1221 if (vercmp(version, info.version) >= 0)
1222 {
1223 err = getPlatformConfigInfo(platform, &info);
1224 if (!err)
1225 {
1226 dumpConfigInfo(&info);
1227 if (info.opcode == CL_PLATFORM_VERSION)
1228 {
1229 err = parseVersion(info.config.string, &version);
1230 if (err)
1231 {
1232 total_errors++;
1233 free(info.config.string);
1234 break;
1235 }
1236 }
1237 if (info.config_type == type_string)
1238 {
1239 free(info.config.string);
1240 }
1241 if (info.config_type == type_cl_name_version_array)
1242 {
1243 free(info.config.cl_name_version_array);
1244 }
1245 }
1246 else
1247 {
1248 total_errors++;
1249 }
1250 }
1251 else
1252 {
1253 log_info("\tSkipped: %s.\n", info.opcode_name);
1254 }
1255 }
1256 return total_errors;
1257 }
1258
test_computeinfo(cl_device_id deviceID,cl_context context,cl_command_queue ignoreQueue,int num_elements)1259 int test_computeinfo(cl_device_id deviceID, cl_context context,
1260 cl_command_queue ignoreQueue, int num_elements)
1261 {
1262 int err;
1263 int total_errors = 0;
1264 cl_platform_id platform;
1265
1266 err = clGetPlatformIDs(1, &platform, NULL);
1267 test_error(err, "clGetPlatformIDs failed");
1268
1269 // print platform info
1270 log_info("\nclGetPlatformInfo:\n------------------\n");
1271 err = getPlatformCapabilities(platform);
1272 test_error(err, "getPlatformCapabilities failed");
1273 log_info("\n");
1274
1275 // Check to see if this test is being run on a specific device
1276 char* device_type_env = getenv("CL_DEVICE_TYPE");
1277 char* device_index_env = getenv("CL_DEVICE_INDEX");
1278
1279 if (device_type_env || device_index_env)
1280 {
1281
1282 cl_device_type device_type = CL_DEVICE_TYPE_DEFAULT;
1283 size_t device_type_idx = 0;
1284 size_t device_index = 0;
1285
1286 // Check to see if a device type was specified.
1287 if (device_type_env)
1288 {
1289 if (!strcmp(device_type_env, "default")
1290 || !strcmp(device_type_env, "CL_DEVICE_TYPE_DEFAULT"))
1291 {
1292 device_type = CL_DEVICE_TYPE_DEFAULT;
1293 device_type_idx = 0;
1294 }
1295 else if (!strcmp(device_type_env, "cpu")
1296 || !strcmp(device_type_env, "CL_DEVICE_TYPE_CPU"))
1297 {
1298 device_type = CL_DEVICE_TYPE_CPU;
1299 device_type_idx = 1;
1300 }
1301 else if (!strcmp(device_type_env, "gpu")
1302 || !strcmp(device_type_env, "CL_DEVICE_TYPE_GPU"))
1303 {
1304 device_type = CL_DEVICE_TYPE_GPU;
1305 device_type_idx = 2;
1306 }
1307 else if (!strcmp(device_type_env, "accelerator")
1308 || !strcmp(device_type_env, "CL_DEVICE_TYPE_ACCELERATOR"))
1309 {
1310 device_type = CL_DEVICE_TYPE_ACCELERATOR;
1311 device_type_idx = 3;
1312 }
1313 else
1314 {
1315 log_error("CL_DEVICE_TYPE=\"%s\" is invalid\n",
1316 device_type_env);
1317 return -1;
1318 }
1319 }
1320
1321 // Check to see if a device index was specified
1322 if (device_index_env) device_index = atoi(device_index_env);
1323
1324 // Look up the device
1325 cl_uint num_devices;
1326 err = clGetDeviceIDs(platform, device_type, 0, NULL, &num_devices);
1327 if (err)
1328 {
1329 log_error("No devices of type %s found.\n", device_type_env);
1330 return -1;
1331 }
1332
1333 if (device_index >= num_devices)
1334 {
1335 log_error("CL_DEVICE_INDEX=%d is greater than the number of "
1336 "matching devices %d\n",
1337 (unsigned)device_index, num_devices);
1338 return -1;
1339 }
1340
1341 if (num_devices == 0)
1342 {
1343 log_error("No devices of type %s found.\n", device_type_env);
1344 return -1;
1345 }
1346
1347 cl_device_id* devices =
1348 (cl_device_id*)malloc(num_devices * sizeof(cl_device_id));
1349 err = clGetDeviceIDs(platform, device_type, num_devices, devices, NULL);
1350 if (err)
1351 {
1352 log_error("No devices of type %s found.\n", device_type_env);
1353 free(devices);
1354 return -1;
1355 }
1356
1357 cl_device_id device = devices[device_index];
1358 free(devices);
1359
1360 log_info("%s Device %d of %d Info:\n",
1361 device_infos[device_type_idx].device_type_name,
1362 (unsigned)device_index + 1, num_devices);
1363 total_errors += getConfigInfos(device);
1364 log_info("\n");
1365 }
1366
1367 // Otherwise iterate over all of the devices in the platform
1368 else
1369 {
1370 // print device info
1371 int onInfo;
1372 for (onInfo = 0;
1373 onInfo < sizeof(device_infos) / sizeof(device_infos[0]); onInfo++)
1374 {
1375 log_info("Getting device IDs for %s devices\n",
1376 device_infos[onInfo].device_type_name);
1377 err = clGetDeviceIDs(platform, device_infos[onInfo].device_type, 0,
1378 NULL, &device_infos[onInfo].num_devices);
1379 if (err == CL_DEVICE_NOT_FOUND)
1380 {
1381 log_info("No devices of type %s found.\n",
1382 device_infos[onInfo].device_type_name);
1383 continue;
1384 }
1385 test_error(err, "clGetDeviceIDs failed");
1386
1387 log_info("Found %d %s devices:\n", device_infos[onInfo].num_devices,
1388 device_infos[onInfo].device_type_name);
1389 if (device_infos[onInfo].num_devices)
1390 {
1391 device_infos[onInfo].devices = (cl_device_id*)malloc(
1392 sizeof(cl_device_id) * device_infos[onInfo].num_devices);
1393 err = clGetDeviceIDs(platform, device_infos[onInfo].device_type,
1394 device_infos[onInfo].num_devices,
1395 device_infos[onInfo].devices, NULL);
1396 test_error(err, "clGetDeviceIDs failed");
1397 }
1398
1399 int onDevice;
1400 for (onDevice = 0; onDevice < device_infos[onInfo].num_devices;
1401 onDevice++)
1402 {
1403 log_info("%s Device %d of %d Info:\n",
1404 device_infos[onInfo].device_type_name, onDevice + 1,
1405 device_infos[onInfo].num_devices);
1406 total_errors +=
1407 getConfigInfos(device_infos[onInfo].devices[onDevice]);
1408 log_info("\n");
1409 }
1410
1411 if (device_infos[onInfo].num_devices)
1412 {
1413 free(device_infos[onInfo].devices);
1414 }
1415 }
1416 }
1417
1418 return total_errors;
1419 }
1420
1421 extern int test_extended_versioning(cl_device_id, cl_context, cl_command_queue,
1422 int);
1423 extern int test_device_uuid(cl_device_id, cl_context, cl_command_queue, int);
1424
1425 extern int test_conformance_version(cl_device_id, cl_context, cl_command_queue,
1426 int);
1427
1428 test_definition test_list[] = {
1429 ADD_TEST(computeinfo),
1430 ADD_TEST(extended_versioning),
1431 ADD_TEST(device_uuid),
1432 ADD_TEST_VERSION(conformance_version, Version(3, 0)),
1433 };
1434
1435 const int test_num = ARRAY_SIZE(test_list);
1436
main(int argc,const char ** argv)1437 int main(int argc, const char** argv)
1438 {
1439 const char** argList = (const char**)calloc(argc, sizeof(char*));
1440 if (NULL == argList)
1441 {
1442 log_error("Failed to allocate memory for argList array.\n");
1443 return 1;
1444 }
1445
1446 argList[0] = argv[0];
1447 size_t argCount = 1;
1448
1449 for (int i = 1; i < argc; i++)
1450 {
1451 if (strcmp(argv[1], "-v") == 0)
1452 {
1453 dump_supported_formats = 1;
1454 }
1455 else
1456 {
1457 argList[argCount] = argv[i];
1458 argCount++;
1459 }
1460 }
1461
1462 return runTestHarness(argCount, argList, test_num, test_list, true, 0);
1463 }
1464