• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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