xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/computeinfo/main.cpp (revision 6467f958c7de8070b317fc65bcb0f6472e388d82)
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