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 has_cl_khr_fp64;
99 int has_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 size_err = config_size_set != config_size_ret;
443 }
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 size_err = config_size_set != config_size_ret;
589 }
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 log_info("\t\t\"%s\" %d.%d.%d\n", new_version_item.name,
912 CL_VERSION_MAJOR_KHR(new_version_item.version),
913 CL_VERSION_MINOR_KHR(new_version_item.version),
914 CL_VERSION_PATCH_KHR(new_version_item.version));
915 }
916 }
917 break;
918 }
919 case type_cl_name_version:
920 log_info("\t%s == %d.%d.%d\n", info->opcode_name,
921 CL_VERSION_MAJOR_KHR(
922 info->config.cl_name_version_single.version),
923 CL_VERSION_MINOR_KHR(
924 info->config.cl_name_version_single.version),
925 CL_VERSION_PATCH_KHR(
926 info->config.cl_name_version_single.version));
927 break;
928 }
929 }
930
print_platform_string_selector(cl_platform_id platform,const char * selector_name,cl_platform_info selector)931 void print_platform_string_selector(cl_platform_id platform,
932 const char* selector_name,
933 cl_platform_info selector)
934 {
935 // Currently all the selectors are strings
936 size_t size = 0;
937 char* value;
938 int err;
939
940 if ((err = clGetPlatformInfo(platform, selector, 0, NULL, &size)))
941 {
942 log_error("FAILURE: Unable to get platform info size for %s.\n",
943 selector_name);
944 exit(-1);
945 }
946
947 if (size == 0)
948 {
949 log_error("FAILURE: The size of %s was returned to be zero.\n",
950 selector_name);
951 exit(-1);
952 }
953
954 value = (char*)malloc(size);
955 if (NULL == value)
956 {
957 log_error("Internal test failure: Unable to allocate %zu bytes\n",
958 size);
959 exit(-1);
960 }
961
962 memset(value, -1, size);
963 if ((err = clGetPlatformInfo(platform, selector, size, value, NULL)))
964 {
965 log_error("FAILURE: Unable to get platform info for %s.\n",
966 selector_name);
967 free(value);
968 exit(-1);
969 }
970
971 if (value[size - 1] != '\0')
972 {
973 log_error("FAILURE: platform info for %s is either not NUL terminated, "
974 "or the size is wrong.\n",
975 selector_name);
976 free(value);
977 exit(-1);
978 }
979
980 log_info("\t%s: %s\n", selector_name, value);
981 free(value);
982 }
983
parseVersion(char const * str,version_t * version)984 int parseVersion(char const* str, version_t* version)
985 {
986 int rc = -1;
987 version->major = 0;
988 version->minor = 0;
989 if (strncmp(str, "OpenCL 1.2", 10) == 0 && (str[10] == 0 || str[10] == ' '))
990 {
991 version->major = 1;
992 version->minor = 2;
993 rc = 0;
994 }
995 else if (strncmp(str, "OpenCL 1.0", 10) == 0
996 && (str[10] == 0 || str[10] == ' '))
997 {
998 version->major = 1;
999 version->minor = 0;
1000 rc = 0;
1001 }
1002 else if (strncmp(str, "OpenCL 1.1", 10) == 0
1003 && (str[10] == 0 || str[10] == ' '))
1004 {
1005 version->major = 1;
1006 version->minor = 1;
1007 rc = 0;
1008 }
1009 else if (strncmp(str, "OpenCL 2.0", 10) == 0
1010 && (str[10] == 0 || str[10] == ' '))
1011 {
1012 version->major = 2;
1013 version->minor = 0;
1014 rc = 0;
1015 }
1016 else if (strncmp(str, "OpenCL 2.1", 10) == 0
1017 && (str[10] == 0 || str[10] == ' '))
1018 {
1019 version->major = 2;
1020 version->minor = 1;
1021 rc = 0;
1022 }
1023 else if (strncmp(str, "OpenCL 2.2", 10) == 0
1024 && (str[10] == 0 || str[10] == ' '))
1025 {
1026 version->major = 2;
1027 version->minor = 2;
1028 rc = 0;
1029 }
1030 else if (strncmp(str, "OpenCL 3.0", 10) == 0
1031 && (str[10] == 0 || str[10] == ' '))
1032 {
1033 version->major = 3;
1034 version->minor = 0;
1035 rc = 0;
1036 }
1037 else
1038 {
1039 log_error("ERROR: Unexpected version string: `%s'.\n", str);
1040 };
1041 return rc;
1042 }
1043
parseExtensions(char const * str,extensions_t * extensions)1044 int parseExtensions(char const* str, extensions_t* extensions)
1045 {
1046 char const* begin = NULL;
1047 char const* space = NULL;
1048 size_t length = 0;
1049
1050 memset(extensions, 0, sizeof(extensions_t));
1051
1052 begin = str;
1053 while (begin[0] != 0)
1054 {
1055 space = strchr(begin, ' '); // Find space position.
1056 if (space != NULL)
1057 { // Calculate length of word.
1058 length = space - begin;
1059 }
1060 else
1061 {
1062 length = strlen(begin);
1063 }
1064 if (strncmp(begin, "cl_khr_fp64", length) == 0)
1065 {
1066 extensions->has_cl_khr_fp64 = 1;
1067 }
1068 if (strncmp(begin, "cl_khr_fp16", length) == 0)
1069 {
1070 extensions->has_cl_khr_fp16 = 1;
1071 }
1072 begin += length; // Skip word.
1073 if (begin[0] == ' ')
1074 { // Skip space, if any.
1075 begin += 1;
1076 }
1077 }
1078
1079 return 0;
1080 }
1081
getConfigInfos(cl_device_id device)1082 int getConfigInfos(cl_device_id device)
1083 {
1084 int total_errors = 0;
1085 unsigned onConfigInfo;
1086 version_t version = { 0, 0 }; // Version of the device. Will get real value
1087 // on the first loop iteration.
1088 version_t const ver11 = { 1, 1 }; // Version 1.1.
1089 extensions_t extensions = { 0 };
1090 int get; // Boolean flag: true = get property, false = skip it.
1091 int err;
1092 for (onConfigInfo = 0;
1093 onConfigInfo < sizeof(config_infos) / sizeof(config_infos[0]);
1094 onConfigInfo++)
1095 {
1096 config_info info = config_infos[onConfigInfo];
1097 // Get a property only if device version is equal or greater than
1098 // property version.
1099 get = (vercmp(version, info.version) >= 0);
1100 if (info.opcode == CL_DEVICE_DOUBLE_FP_CONFIG
1101 && vercmp(version, ver11) <= 0)
1102 {
1103 // CL_DEVICE_DOUBLE_FP_CONFIG is a special case. It was introduced
1104 // in OpenCL 1.1, but device is required to report it only if
1105 // doubles are supported. So, before querying it on device
1106 // version 1.1, we have to check doubles are sopported. In
1107 // OpenCL 1.2 CL_DEVICE_DOUBLE_FP_CONFIG should be reported
1108 // unconditionally.
1109 get = extensions.has_cl_khr_fp64;
1110 };
1111 if (info.opcode == CL_DEVICE_HALF_FP_CONFIG)
1112 {
1113 // CL_DEVICE_HALF_FP_CONFIG should be reported only when cl_khr_fp16
1114 // extension is available
1115 get = extensions.has_cl_khr_fp16;
1116 };
1117 if (get)
1118 {
1119 err = getConfigInfo(device, &info);
1120 if (!err)
1121 {
1122 dumpConfigInfo(&info);
1123 if (info.opcode == CL_DEVICE_VERSION)
1124 {
1125 err = parseVersion(info.config.string, &version);
1126 if (err)
1127 {
1128 total_errors++;
1129 free(info.config.string);
1130 break;
1131 }
1132 }
1133 else if (info.opcode == CL_DEVICE_EXTENSIONS)
1134 {
1135 err = parseExtensions(info.config.string, &extensions);
1136 if (err)
1137 {
1138 total_errors++;
1139 free(info.config.string);
1140 break;
1141 }
1142 }
1143 if (info.config_type == type_string)
1144 {
1145 free(info.config.string);
1146 }
1147 if (info.config_type == type_cl_name_version_array)
1148 {
1149 free(info.config.cl_name_version_array);
1150 }
1151 }
1152 else
1153 {
1154 total_errors++;
1155 }
1156 }
1157 else
1158 {
1159 log_info("\tSkipped: %s.\n", info.opcode_name);
1160 }
1161 }
1162
1163 if (is_extension_available(device, "cl_khr_image2d_from_buffer"))
1164 {
1165 for (onConfigInfo = 0; onConfigInfo < sizeof(image_buffer_config_infos)
1166 / sizeof(image_buffer_config_infos[0]);
1167 onConfigInfo++)
1168 {
1169 config_info info = image_buffer_config_infos[onConfigInfo];
1170 get = (vercmp(version, info.version) >= 0);
1171 if (get)
1172 {
1173 err = getConfigInfo(device, &info);
1174 if (!err)
1175 {
1176 dumpConfigInfo(&info);
1177 }
1178 else
1179 {
1180 total_errors++;
1181 }
1182 }
1183 }
1184 }
1185
1186 total_errors += getImageInfo(device, version);
1187
1188 return total_errors;
1189 }
1190
1191 config_info config_platform_infos[] = {
1192 // CL_PLATFORM_VERSION has to be first defined with version 0 0.
1193 CONFIG_INFO(0, 0, CL_PLATFORM_VERSION, string),
1194 CONFIG_INFO(1, 1, CL_PLATFORM_PROFILE, string),
1195 CONFIG_INFO(1, 1, CL_PLATFORM_NAME, string),
1196 CONFIG_INFO(1, 1, CL_PLATFORM_VENDOR, string),
1197 CONFIG_INFO(1, 1, CL_PLATFORM_EXTENSIONS, string),
1198 CONFIG_INFO(3, 0, CL_PLATFORM_EXTENSIONS_WITH_VERSION,
1199 cl_name_version_array),
1200 CONFIG_INFO(3, 0, CL_PLATFORM_NUMERIC_VERSION, cl_name_version)
1201 };
1202
getPlatformCapabilities(cl_platform_id platform)1203 int getPlatformCapabilities(cl_platform_id platform)
1204 {
1205 int total_errors = 0;
1206 version_t version = { 0, 0 }; // Version of the device. Will get real value
1207 // on the first loop iteration.
1208 int err;
1209 for (unsigned onConfigInfo = 0; onConfigInfo
1210 < sizeof(config_platform_infos) / sizeof(config_platform_infos[0]);
1211 onConfigInfo++)
1212 {
1213 config_info info = config_platform_infos[onConfigInfo];
1214
1215 if (vercmp(version, info.version) >= 0)
1216 {
1217 err = getPlatformConfigInfo(platform, &info);
1218 if (!err)
1219 {
1220 dumpConfigInfo(&info);
1221 if (info.opcode == CL_PLATFORM_VERSION)
1222 {
1223 err = parseVersion(info.config.string, &version);
1224 if (err)
1225 {
1226 total_errors++;
1227 free(info.config.string);
1228 break;
1229 }
1230 }
1231 if (info.config_type == type_string)
1232 {
1233 free(info.config.string);
1234 }
1235 if (info.config_type == type_cl_name_version_array)
1236 {
1237 free(info.config.cl_name_version_array);
1238 }
1239 }
1240 else
1241 {
1242 total_errors++;
1243 }
1244 }
1245 else
1246 {
1247 log_info("\tSkipped: %s.\n", info.opcode_name);
1248 }
1249 }
1250 return total_errors;
1251 }
1252
test_computeinfo(cl_device_id deviceID,cl_context context,cl_command_queue ignoreQueue,int num_elements)1253 int test_computeinfo(cl_device_id deviceID, cl_context context,
1254 cl_command_queue ignoreQueue, int num_elements)
1255 {
1256 int err;
1257 int total_errors = 0;
1258 cl_platform_id platform;
1259
1260 err = clGetPlatformIDs(1, &platform, NULL);
1261 test_error(err, "clGetPlatformIDs failed");
1262
1263 // print platform info
1264 log_info("\nclGetPlatformInfo:\n------------------\n");
1265 err = getPlatformCapabilities(platform);
1266 test_error(err, "getPlatformCapabilities failed");
1267 log_info("\n");
1268
1269 // Check to see if this test is being run on a specific device
1270 char* device_type_env = getenv("CL_DEVICE_TYPE");
1271 char* device_index_env = getenv("CL_DEVICE_INDEX");
1272
1273 if (device_type_env || device_index_env)
1274 {
1275
1276 cl_device_type device_type = CL_DEVICE_TYPE_DEFAULT;
1277 size_t device_type_idx = 0;
1278 size_t device_index = 0;
1279
1280 // Check to see if a device type was specified.
1281 if (device_type_env)
1282 {
1283 if (!strcmp(device_type_env, "default")
1284 || !strcmp(device_type_env, "CL_DEVICE_TYPE_DEFAULT"))
1285 {
1286 device_type = CL_DEVICE_TYPE_DEFAULT;
1287 device_type_idx = 0;
1288 }
1289 else if (!strcmp(device_type_env, "cpu")
1290 || !strcmp(device_type_env, "CL_DEVICE_TYPE_CPU"))
1291 {
1292 device_type = CL_DEVICE_TYPE_CPU;
1293 device_type_idx = 1;
1294 }
1295 else if (!strcmp(device_type_env, "gpu")
1296 || !strcmp(device_type_env, "CL_DEVICE_TYPE_GPU"))
1297 {
1298 device_type = CL_DEVICE_TYPE_GPU;
1299 device_type_idx = 2;
1300 }
1301 else if (!strcmp(device_type_env, "accelerator")
1302 || !strcmp(device_type_env, "CL_DEVICE_TYPE_ACCELERATOR"))
1303 {
1304 device_type = CL_DEVICE_TYPE_ACCELERATOR;
1305 device_type_idx = 3;
1306 }
1307 else
1308 {
1309 log_error("CL_DEVICE_TYPE=\"%s\" is invalid\n",
1310 device_type_env);
1311 return -1;
1312 }
1313 }
1314
1315 // Check to see if a device index was specified
1316 if (device_index_env) device_index = atoi(device_index_env);
1317
1318 // Look up the device
1319 cl_uint num_devices;
1320 err = clGetDeviceIDs(platform, device_type, 0, NULL, &num_devices);
1321 if (err)
1322 {
1323 log_error("No devices of type %s found.\n", device_type_env);
1324 return -1;
1325 }
1326
1327 if (device_index >= num_devices)
1328 {
1329 log_error("CL_DEVICE_INDEX=%d is greater than the number of "
1330 "matching devices %d\n",
1331 (unsigned)device_index, num_devices);
1332 return -1;
1333 }
1334
1335 if (num_devices == 0)
1336 {
1337 log_error("No devices of type %s found.\n", device_type_env);
1338 return -1;
1339 }
1340
1341 cl_device_id* devices =
1342 (cl_device_id*)malloc(num_devices * sizeof(cl_device_id));
1343 err = clGetDeviceIDs(platform, device_type, num_devices, devices, NULL);
1344 if (err)
1345 {
1346 log_error("No devices of type %s found.\n", device_type_env);
1347 free(devices);
1348 return -1;
1349 }
1350
1351 cl_device_id device = devices[device_index];
1352 free(devices);
1353
1354 log_info("%s Device %d of %d Info:\n",
1355 device_infos[device_type_idx].device_type_name,
1356 (unsigned)device_index + 1, num_devices);
1357 total_errors += getConfigInfos(device);
1358 log_info("\n");
1359 }
1360
1361 // Otherwise iterate over all of the devices in the platform
1362 else
1363 {
1364 // print device info
1365 for (size_t onInfo = 0;
1366 onInfo < sizeof(device_infos) / sizeof(device_infos[0]); onInfo++)
1367 {
1368 log_info("Getting device IDs for %s devices\n",
1369 device_infos[onInfo].device_type_name);
1370 err = clGetDeviceIDs(platform, device_infos[onInfo].device_type, 0,
1371 NULL, &device_infos[onInfo].num_devices);
1372 if (err == CL_DEVICE_NOT_FOUND)
1373 {
1374 log_info("No devices of type %s found.\n",
1375 device_infos[onInfo].device_type_name);
1376 continue;
1377 }
1378 test_error(err, "clGetDeviceIDs failed");
1379
1380 log_info("Found %d %s devices:\n", device_infos[onInfo].num_devices,
1381 device_infos[onInfo].device_type_name);
1382 if (device_infos[onInfo].num_devices)
1383 {
1384 device_infos[onInfo].devices = (cl_device_id*)malloc(
1385 sizeof(cl_device_id) * device_infos[onInfo].num_devices);
1386 err = clGetDeviceIDs(platform, device_infos[onInfo].device_type,
1387 device_infos[onInfo].num_devices,
1388 device_infos[onInfo].devices, NULL);
1389 test_error(err, "clGetDeviceIDs failed");
1390 }
1391
1392 for (size_t onDevice = 0;
1393 onDevice < device_infos[onInfo].num_devices; onDevice++)
1394 {
1395 log_info("%s Device %d of %d Info:\n",
1396 device_infos[onInfo].device_type_name, onDevice + 1,
1397 device_infos[onInfo].num_devices);
1398 total_errors +=
1399 getConfigInfos(device_infos[onInfo].devices[onDevice]);
1400 log_info("\n");
1401 }
1402
1403 if (device_infos[onInfo].num_devices)
1404 {
1405 free(device_infos[onInfo].devices);
1406 }
1407 }
1408 }
1409
1410 return total_errors;
1411 }
1412
1413 extern int test_extended_versioning(cl_device_id, cl_context, cl_command_queue,
1414 int);
1415 extern int test_device_uuid(cl_device_id, cl_context, cl_command_queue, int);
1416 extern int test_conformance_version(cl_device_id, cl_context, cl_command_queue,
1417 int);
1418 extern int test_pci_bus_info(cl_device_id, cl_context, cl_command_queue, int);
1419
1420 test_definition test_list[] = {
1421 ADD_TEST(computeinfo),
1422 ADD_TEST(extended_versioning),
1423 ADD_TEST(device_uuid),
1424 ADD_TEST_VERSION(conformance_version, Version(3, 0)),
1425 ADD_TEST(pci_bus_info),
1426 };
1427
1428 const int test_num = ARRAY_SIZE(test_list);
1429
main(int argc,const char ** argv)1430 int main(int argc, const char** argv)
1431 {
1432 const char** argList = (const char**)calloc(argc, sizeof(char*));
1433 if (NULL == argList)
1434 {
1435 log_error("Failed to allocate memory for argList array.\n");
1436 return 1;
1437 }
1438
1439 argList[0] = argv[0];
1440 size_t argCount = 1;
1441
1442 for (int i = 1; i < argc; i++)
1443 {
1444 if (strcmp(argv[1], "-v") == 0)
1445 {
1446 dump_supported_formats = 1;
1447 }
1448 else
1449 {
1450 argList[argCount] = argv[i];
1451 argCount++;
1452 }
1453 }
1454
1455 return runTestHarness(argCount, argList, test_num, test_list, true, 0);
1456 }
1457