xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/lib/cl_util.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* This testcase is part of GDB, the GNU debugger.
2 
3    Copyright 2010-2023 Free Software Foundation, Inc.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 
18    Contributed by Ken Werner <ken.werner@de.ibm.com>  */
19 
20 /* Utility macros and functions for OpenCL applications.  */
21 
22 #include "cl_util.h"
23 
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <sys/stat.h>
27 #include <string.h>
28 
29 const char *get_clerror_string (int errcode)
30 {
31   switch (errcode)
32     {
33     case CL_SUCCESS:
34       return "CL_SUCCESS";
35     case CL_DEVICE_NOT_FOUND:
36       return "CL_DEVICE_NOT_FOUND";
37     case CL_DEVICE_NOT_AVAILABLE:
38       return "CL_DEVICE_NOT_AVAILABLE";
39     case CL_COMPILER_NOT_AVAILABLE:
40       return "CL_COMPILER_NOT_AVAILABLE";
41     case CL_MEM_OBJECT_ALLOCATION_FAILURE:
42       return "CL_MEM_OBJECT_ALLOCATION_FAILURE";
43     case CL_OUT_OF_RESOURCES:
44       return "CL_OUT_OF_RESOURCES";
45     case CL_OUT_OF_HOST_MEMORY:
46       return "CL_OUT_OF_HOST_MEMORY";
47     case CL_PROFILING_INFO_NOT_AVAILABLE:
48       return "CL_PROFILING_INFO_NOT_AVAILABLE";
49     case CL_MEM_COPY_OVERLAP:
50       return "CL_MEM_COPY_OVERLAP";
51     case CL_IMAGE_FORMAT_MISMATCH:
52       return "CL_IMAGE_FORMAT_MISMATCH";
53     case CL_IMAGE_FORMAT_NOT_SUPPORTED:
54       return "CL_IMAGE_FORMAT_NOT_SUPPORTED";
55     case CL_BUILD_PROGRAM_FAILURE:
56       return "CL_BUILD_PROGRAM_FAILURE";
57     case CL_MAP_FAILURE:
58       return "CL_MAP_FAILURE";
59     case CL_INVALID_VALUE:
60       return "CL_INVALID_VALUE";
61     case CL_INVALID_DEVICE_TYPE:
62       return "CL_INVALID_DEVICE_TYPE";
63     case CL_INVALID_PLATFORM:
64       return "CL_INVALID_PLATFORM";
65     case CL_INVALID_DEVICE:
66       return "CL_INVALID_DEVICE";
67     case CL_INVALID_CONTEXT:
68       return "CL_INVALID_CONTEXT";
69     case CL_INVALID_QUEUE_PROPERTIES:
70       return "CL_INVALID_QUEUE_PROPERTIES";
71     case CL_INVALID_COMMAND_QUEUE:
72       return "CL_INVALID_COMMAND_QUEUE";
73     case CL_INVALID_HOST_PTR:
74       return "CL_INVALID_HOST_PTR";
75     case CL_INVALID_MEM_OBJECT:
76       return "CL_INVALID_MEM_OBJECT";
77     case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR:
78       return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR";
79     case CL_INVALID_IMAGE_SIZE:
80       return "CL_INVALID_IMAGE_SIZE";
81     case CL_INVALID_SAMPLER:
82       return "CL_INVALID_SAMPLER";
83     case CL_INVALID_BINARY:
84       return "CL_INVALID_BINARY";
85     case CL_INVALID_BUILD_OPTIONS:
86       return "CL_INVALID_BUILD_OPTIONS";
87     case CL_INVALID_PROGRAM:
88       return "CL_INVALID_PROGRAM";
89     case CL_INVALID_PROGRAM_EXECUTABLE:
90       return "CL_INVALID_PROGRAM_EXECUTABLE";
91     case CL_INVALID_KERNEL_NAME:
92       return "CL_INVALID_KERNEL_NAME";
93     case CL_INVALID_KERNEL_DEFINITION:
94       return "CL_INVALID_KERNEL_DEFINITION";
95     case CL_INVALID_KERNEL:
96       return "CL_INVALID_KERNEL";
97     case CL_INVALID_ARG_INDEX:
98       return "CL_INVALID_ARG_INDEX";
99     case CL_INVALID_ARG_VALUE:
100       return "CL_INVALID_ARG_VALUE";
101     case CL_INVALID_ARG_SIZE:
102       return "CL_INVALID_ARG_SIZE";
103     case CL_INVALID_KERNEL_ARGS:
104       return "CL_INVALID_KERNEL_ARGS";
105     case CL_INVALID_WORK_DIMENSION:
106       return "CL_INVALID_WORK_DIMENSION";
107     case CL_INVALID_WORK_GROUP_SIZE:
108       return "CL_INVALID_WORK_GROUP_SIZE";
109     case CL_INVALID_WORK_ITEM_SIZE:
110       return "CL_INVALID_WORK_ITEM_SIZE";
111     case CL_INVALID_GLOBAL_OFFSET:
112       return "CL_INVALID_GLOBAL_OFFSET";
113     case CL_INVALID_EVENT_WAIT_LIST:
114       return "CL_INVALID_EVENT_WAIT_LIST";
115     case CL_INVALID_EVENT:
116       return "CL_INVALID_EVENT";
117     case CL_INVALID_OPERATION:
118       return "CL_INVALID_OPERATION";
119     case CL_INVALID_GL_OBJECT:
120       return "CL_INVALID_GL_OBJECT";
121     case CL_INVALID_BUFFER_SIZE:
122       return "CL_INVALID_BUFFER_SIZE";
123     case CL_INVALID_MIP_LEVEL:
124       return "CL_INVALID_MIP_LEVEL";
125 #ifndef CL_PLATFORM_NVIDIA
126     case CL_INVALID_GLOBAL_WORK_SIZE:
127       return "CL_INVALID_GLOBAL_WORK_SIZE";
128 #endif
129     default:
130       return "Unknown";
131     };
132 }
133 
134 
135 void print_clinfo ()
136 {
137   char *s = NULL;
138   size_t len;
139   unsigned i, j;
140   cl_uint platform_count;
141   cl_platform_id *platforms;
142 
143   /* Determine number of OpenCL Platforms available.  */
144   clGetPlatformIDs (0, NULL, &platform_count);
145   printf ("number of OpenCL Platforms available:\t%d\n", platform_count);
146   /* Get platforms.  */
147   platforms
148     = (cl_platform_id*) malloc (sizeof (cl_platform_id) * platform_count);
149   if (platforms == NULL)
150     {
151       fprintf (stderr, "malloc failed\n");
152       exit (EXIT_FAILURE);
153     }
154   clGetPlatformIDs (platform_count, platforms, NULL);
155 
156   /* Querying platforms.  */
157   for (i = 0; i < platform_count; i++)
158     {
159       cl_device_id *devices;
160       cl_uint device_count;
161       cl_device_id default_dev;
162       printf (" OpenCL Platform:                       %d\n", i);
163 
164 #define PRINT_PF_INFO(PARM)\
165       clGetPlatformInfo (platforms[i], PARM, 0, NULL, &len); \
166       s = realloc (s, len); \
167       clGetPlatformInfo (platforms[i], PARM, len, s, NULL); \
168       printf ("  %-36s%s\n", #PARM ":", s);
169 
170       PRINT_PF_INFO (CL_PLATFORM_PROFILE)
171       PRINT_PF_INFO (CL_PLATFORM_VERSION)
172       PRINT_PF_INFO (CL_PLATFORM_NAME)
173       PRINT_PF_INFO (CL_PLATFORM_VENDOR)
174       PRINT_PF_INFO (CL_PLATFORM_EXTENSIONS)
175 #undef PRINT_PF_INFO
176 
177       clGetDeviceIDs (platforms[i], CL_DEVICE_TYPE_DEFAULT, 1, &default_dev,
178 		      NULL);
179       clGetDeviceInfo (default_dev, CL_DEVICE_NAME, 0, NULL, &len);
180       s = realloc (s, len);
181       clGetDeviceInfo (default_dev, CL_DEVICE_NAME, len, s, NULL);
182       printf ("  CL_DEVICE_TYPE_DEFAULT:             %s\n", s);
183 
184       /* Determine number of devices.  */
185       clGetDeviceIDs (platforms[i], CL_DEVICE_TYPE_ALL, 0, NULL, &device_count);
186       printf ("\n  number of OpenCL Devices available:   %d\n", device_count);
187       /* Get devices.  */
188       devices = (cl_device_id*) malloc (sizeof (cl_device_id) * device_count);
189       if (devices == NULL)
190 	{
191 	  fprintf (stderr, "malloc failed\n");
192 	  exit (EXIT_FAILURE);
193 	}
194       clGetDeviceIDs (platforms[i], CL_DEVICE_TYPE_ALL, device_count, devices,
195 		      NULL);
196 
197       /* Querying devices.  */
198       for (j = 0; j < device_count; j++)
199 	{
200 	  cl_device_type dtype;
201 	  cl_device_mem_cache_type mctype;
202 	  cl_device_local_mem_type mtype;
203 	  cl_device_fp_config fpcfg;
204 	  cl_device_exec_capabilities xcap;
205 	  cl_command_queue_properties qprops;
206 	  cl_bool clbool;
207 	  cl_uint cluint;
208 	  cl_ulong clulong;
209 	  size_t sizet;
210 	  size_t workitem_size[3];
211 	  printf ("   OpenCL Device:                       %d\n", j);
212 
213 #define PRINT_DEV_INFO(PARM)\
214 	  clGetDeviceInfo (devices[j], PARM, 0, NULL, &len); \
215 	  s = realloc (s, len); \
216 	  clGetDeviceInfo (devices[j], PARM, len, s, NULL); \
217 	  printf ("    %-41s%s\n", #PARM ":", s);
218 
219 	  PRINT_DEV_INFO (CL_DEVICE_NAME)
220 	  PRINT_DEV_INFO (CL_DRIVER_VERSION)
221 	  PRINT_DEV_INFO (CL_DEVICE_VENDOR)
222 	  clGetDeviceInfo (devices[j], CL_DEVICE_VENDOR_ID, sizeof (cluint),
223 			   &cluint, NULL);
224 	  printf ("    CL_DEVICE_VENDOR_ID:                     %d\n", cluint);
225 
226 	  clGetDeviceInfo (devices[j], CL_DEVICE_TYPE, sizeof (dtype), &dtype, NULL);
227 	  if (dtype & CL_DEVICE_TYPE_CPU)
228 	    printf ("    CL_DEVICE_TYPE:                          CL_DEVICE_TYPE_CPU\n");
229 	  if (dtype & CL_DEVICE_TYPE_GPU)
230 	    printf ("    CL_DEVICE_TYPE:                          CL_DEVICE_TYPE_GPU\n");
231 	  if (dtype & CL_DEVICE_TYPE_ACCELERATOR)
232 	    printf ("    CL_DEVICE_TYPE:                          CL_DEVICE_TYPE_ACCELERATOR\n");
233 	  if (dtype & CL_DEVICE_TYPE_DEFAULT)
234 	    printf ("    CL_DEVICE_TYPE:                          CL_DEVICE_TYPE_DEFAULT\n");
235 
236 	  clGetDeviceInfo (devices[j], CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof (cluint), &cluint, NULL);
237 	  printf ("    CL_DEVICE_MAX_CLOCK_FREQUENCY:           %d\n", cluint);
238 
239 	  PRINT_DEV_INFO (CL_DEVICE_PROFILE)
240 	  PRINT_DEV_INFO (CL_DEVICE_EXTENSIONS)
241 
242 	  clGetDeviceInfo (devices[j], CL_DEVICE_AVAILABLE, sizeof (clbool), &clbool, NULL);
243 	  if (clbool == CL_TRUE)
244 	    printf ("    CL_DEVICE_AVAILABLE:                     CL_TRUE\n");
245 	  else
246 	    printf ("    CL_DEVICE_AVAILABLE:                     CL_FALSE\n");
247 	  clGetDeviceInfo (devices[j], CL_DEVICE_ENDIAN_LITTLE, sizeof (clbool), &clbool, NULL);
248 	  if (clbool == CL_TRUE)
249 	    printf ("    CL_DEVICE_ENDIAN_LITTLE:                 CL_TRUE\n");
250 	  else
251 	    printf ("    CL_DEVICE_ENDIAN_LITTLE:                 CL_FALSE\n");
252 
253 	  clGetDeviceInfo (devices[j], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof (cluint), &cluint, NULL);
254 	  printf ("    CL_DEVICE_MAX_COMPUTE_UNITS:             %d\n", cluint);
255 	  clGetDeviceInfo (devices[j], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof (sizet), &sizet, NULL);
256 	  printf ("    CL_DEVICE_MAX_WORK_GROUP_SIZE:           %d\n", sizet);
257 	  clGetDeviceInfo (devices[j], CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof (cluint), &cluint, NULL);
258 	  printf ("    CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:      %d\n", cluint);
259 	  clGetDeviceInfo (devices[j], CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof (workitem_size), &workitem_size, NULL);
260 	  printf ("    CL_DEVICE_MAX_WORK_ITEM_SIZES:           %d / %d / %d\n", workitem_size[0], workitem_size[1], workitem_size[2]);
261 
262 	  clGetDeviceInfo (devices[j], CL_DEVICE_ADDRESS_BITS, sizeof (cluint), &cluint, NULL);
263 	  printf ("    CL_DEVICE_ADDRESS_BITS:                  %d\n", cluint);
264 
265 	  clGetDeviceInfo (devices[j], CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof (clulong), &clulong, NULL);
266 	  printf ("    CL_DEVICE_MAX_MEM_ALLOC_SIZE:            %llu\n", clulong);
267 	  clGetDeviceInfo (devices[j], CL_DEVICE_MEM_BASE_ADDR_ALIGN, sizeof (cluint), &cluint, NULL);
268 	  printf ("    CL_DEVICE_MEM_BASE_ADDR_ALIGN:           %d\n", cluint);
269 	  clGetDeviceInfo(devices[j], CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, sizeof (cluint), &cluint, NULL);
270 	  printf ("    CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE:      %d\n", cluint);
271 	  clGetDeviceInfo(devices[j], CL_DEVICE_MAX_PARAMETER_SIZE, sizeof (sizet), &sizet, NULL);
272 	  printf ("    CL_DEVICE_MAX_PARAMETER_SIZE:            %d\n", sizet);
273 	  clGetDeviceInfo(devices[j], CL_DEVICE_GLOBAL_MEM_SIZE, sizeof (clulong), &clulong, NULL);
274 	  printf ("    CL_DEVICE_GLOBAL_MEM_SIZE:               %llu\n", clulong);
275 
276 	  clGetDeviceInfo (devices[j], CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, sizeof (mctype), &mctype, NULL);
277 	  if (mctype & CL_NONE)
278 	    printf ("    CL_DEVICE_GLOBAL_MEM_CACHE_TYPE:         CL_NONE\n");
279 	  if (mctype & CL_READ_ONLY_CACHE)
280 	    printf ("    CL_DEVICE_GLOBAL_MEM_CACHE_TYPE:         CL_READ_ONLY_CACHE\n");
281 	  if (mctype & CL_READ_WRITE_CACHE)
282 	    printf ("    CL_DEVICE_GLOBAL_MEM_CACHE_TYPE:         CL_READ_WRITE_CACHE\n");
283 
284 	  clGetDeviceInfo (devices[j], CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, sizeof (clulong), &clulong, NULL);
285 	  printf ("    CL_DEVICE_GLOBAL_MEM_CACHE_SIZE:         %llu\n", clulong);
286 	  clGetDeviceInfo (devices[j], CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, sizeof (cluint), &cluint, NULL);
287 	  printf ("    CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE:     %d\n", cluint);
288 
289 	  clGetDeviceInfo (devices[j], CL_DEVICE_LOCAL_MEM_TYPE, sizeof (mtype), &mtype, NULL);
290 	  if (mtype & CL_LOCAL)
291 	    printf ("    CL_DEVICE_LOCAL_MEM_TYPE:                CL_LOCAL\n");
292 	  if (mtype & CL_GLOBAL)
293 	    printf ("    CL_DEVICE_LOCAL_MEM_TYPE:                CL_GLOBAL\n");
294 
295 	  clGetDeviceInfo (devices[j], CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, sizeof (cluint), &cluint, NULL);
296 	  printf ("    CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE:      %d\n", cluint);
297 	  clGetDeviceInfo (devices[j], CL_DEVICE_MEM_BASE_ADDR_ALIGN, sizeof (cluint), &cluint, NULL);
298 	  printf ("    CL_DEVICE_MEM_BASE_ADDR_ALIGN:           %d\n", cluint);
299 	  clGetDeviceInfo (devices[j], CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, sizeof (cluint), &cluint, NULL);
300 	  printf ("    CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:   %d\n", cluint);
301 	  clGetDeviceInfo (devices[j], CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, sizeof (cluint), &cluint, NULL);
302 	  printf ("    CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:  %d\n", cluint);
303 	  clGetDeviceInfo (devices[j], CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, sizeof (cluint), &cluint, NULL);
304 	  printf ("    CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:    %d\n", cluint);
305 	  clGetDeviceInfo (devices[j], CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, sizeof (cluint), &cluint, NULL);
306 	  printf ("    CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:   %d\n", cluint);
307 	  clGetDeviceInfo (devices[j], CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, sizeof (cluint), &cluint, NULL);
308 	  printf ("    CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT:  %d\n", cluint);
309 	  clGetDeviceInfo (devices[j], CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, sizeof (cluint), &cluint, NULL);
310 	  printf ("    CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE: %d\n", cluint);
311 
312 	  clGetDeviceInfo (devices[j], CL_DEVICE_SINGLE_FP_CONFIG, sizeof (fpcfg), &fpcfg, NULL);
313 	  if (fpcfg & CL_FP_DENORM)
314 	    printf ("    CL_DEVICE_SINGLE_FP_CONFIG:              CL_FP_DENORM\n");
315 	  if (fpcfg & CL_FP_INF_NAN)
316 	    printf ("    CL_DEVICE_SINGLE_FP_CONFIG:              CL_FP_INF_NAN\n");
317 	  if (fpcfg & CL_FP_ROUND_TO_NEAREST)
318 	    printf ("    CL_DEVICE_SINGLE_FP_CONFIG:              CL_FP_ROUND_TO_NEAREST\n");
319 	  if (fpcfg & CL_FP_ROUND_TO_ZERO)
320 	    printf ("    CL_DEVICE_SINGLE_FP_CONFIG:              CL_FP_ROUND_TO_ZERO\n");
321 
322 	  clGetDeviceInfo (devices[j], CL_DEVICE_EXECUTION_CAPABILITIES, sizeof (xcap), &xcap, NULL);
323 	  if (xcap & CL_EXEC_KERNEL )
324 	    printf ("    CL_DEVICE_EXECUTION_CAPABILITIES:        CL_EXEC_KERNEL\n");
325 	  if (xcap & CL_EXEC_NATIVE_KERNEL)
326 	    printf ("    CL_DEVICE_EXECUTION_CAPABILITIES:        CL_EXEC_NATIVE_KERNEL\n");
327 
328 	  clGetDeviceInfo (devices[j], CL_DEVICE_QUEUE_PROPERTIES, sizeof (qprops), &qprops, NULL);
329 	  if (qprops & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE)
330 	    printf ("    CL_DEVICE_QUEUE_PROPERTIES:              CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE\n");
331 	  if (qprops & CL_QUEUE_PROFILING_ENABLE)
332 	    printf ("    CL_DEVICE_QUEUE_PROPERTIES:              CL_QUEUE_PROFILING_ENABLE\n");
333 
334 	  clGetDeviceInfo (devices[j], CL_DEVICE_PROFILING_TIMER_RESOLUTION, sizeof (sizet), &sizet, NULL);
335 	  printf ("    CL_DEVICE_PROFILING_TIMER_RESOLUTION:    %d\n", sizet);
336 
337 	  clGetDeviceInfo (devices[j], CL_DEVICE_COMPILER_AVAILABLE, sizeof (clbool), &clbool, NULL);
338 	  if (clbool == CL_TRUE)
339 	    printf ("    CL_DEVICE_COMPILER_AVAILABLE:            CL_TRUE\n");
340 	  else
341 	    printf ("    CL_DEVICE_COMPILER_AVAILABLE:            CL_FALSE\n");
342 	  clGetDeviceInfo (devices[j], CL_DEVICE_ERROR_CORRECTION_SUPPORT, sizeof (clbool), &clbool, NULL);
343 	  if (clbool == CL_TRUE)
344 	    printf ("    CL_DEVICE_ERROR_CORRECTION_SUPPORT:      CL_TRUE\n");
345 	  else
346 	    printf ("    CL_DEVICE_ERROR_CORRECTION_SUPPORT:      CL_FALSE\n");
347 
348 	  clGetDeviceInfo (devices[j], CL_DEVICE_IMAGE_SUPPORT, sizeof (clbool), &clbool, NULL);
349 	  if (clbool == CL_FALSE)
350 	    {
351 	      printf ("    CL_DEVICE_IMAGE_SUPPORT:                 CL_FALSE\n");
352 	    }
353 	  else
354 	    {
355 	      printf ("    CL_DEVICE_IMAGE_SUPPORT:                 CL_TRUE\n");
356 	      clGetDeviceInfo (devices[j], CL_DEVICE_MAX_SAMPLERS, sizeof (cluint), &cluint, NULL);
357 	      printf ("    CL_DEVICE_MAX_SAMPLERS:                  %d\n", cluint);
358 	      clGetDeviceInfo (devices[j], CL_DEVICE_MAX_READ_IMAGE_ARGS, sizeof (cluint), &cluint, NULL);
359 	      printf ("    CL_DEVICE_MAX_READ_IMAGE_ARGS:           %d\n", cluint);
360 	      clGetDeviceInfo (devices[j], CL_DEVICE_MAX_WRITE_IMAGE_ARGS, sizeof (cluint), &cluint, NULL);
361 	      printf ("    CL_DEVICE_MAX_WRITE_IMAGE_ARGS:          %d\n", cluint);
362 	      clGetDeviceInfo (devices[j], CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof (sizet), &sizet, NULL);
363 	      printf ("    CL_DEVICE_IMAGE2D_MAX_WIDTH:             %d\n", sizet);
364 	      clGetDeviceInfo (devices[j], CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof (sizet), &sizet, NULL);
365 	      printf ("    CL_DEVICE_IMAGE2D_MAX_HEIGHT:            %d\n", sizet);
366 	      clGetDeviceInfo (devices[j], CL_DEVICE_IMAGE3D_MAX_WIDTH, sizeof (sizet), &sizet, NULL);
367 	      printf ("    CL_DEVICE_IMAGE3D_MAX_WIDTH:             %d\n", sizet);
368 	      clGetDeviceInfo (devices[j], CL_DEVICE_IMAGE3D_MAX_HEIGHT, sizeof (sizet), &sizet, NULL);
369 	      printf ("    CL_DEVICE_IMAGE3D_MAX_HEIGHT:            %d\n", sizet);
370 	      clGetDeviceInfo (devices[j], CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof (sizet), &sizet, NULL);
371 	      printf ("    CL_DEVICE_IMAGE3D_MAX_DEPTH:             %d\n", sizet);
372 	    }
373 #undef PRINT_DEV_INFO
374 	} /* devices */
375       free (devices);
376     } /* platforms */
377   free (s);
378   free (platforms);
379 }
380 
381 
382 const char *
383 read_file (const char * const filename, size_t *size)
384 {
385   char *buf = NULL;
386   FILE *fd;
387   struct stat st;
388   if (stat (filename, &st) == -1)
389     {
390       /* Check if the file exists.  */
391       if (errno == ENOENT)
392 	return buf;
393       perror ("stat failed");
394       exit (EXIT_FAILURE);
395     }
396   buf = (char *) malloc (st.st_size);
397   if (buf == NULL)
398     {
399       fprintf (stderr, "malloc failed\n");
400       exit (EXIT_FAILURE);
401     }
402   fd = fopen (filename, "r");
403   if (fd == NULL)
404     {
405       perror ("fopen failed");
406       free (buf);
407       exit (EXIT_FAILURE);
408     }
409   if (fread (buf, st.st_size, 1, fd) != 1)
410     {
411       fprintf (stderr, "fread failed\n");
412       free (buf);
413       fclose (fd);
414       exit (EXIT_FAILURE);
415     }
416   fclose (fd);
417   *size = st.st_size;
418   return buf;
419 }
420 
421 
422 void
423 save_program_binaries (cl_program program)
424 {
425   cl_device_id *devices;
426   cl_uint device_count;
427   size_t *sizes;
428   unsigned char **binaries;
429   unsigned i, j;
430 
431   /* Query the amount of devices for the given program.  */
432   CHK (clGetProgramInfo (program, CL_PROGRAM_NUM_DEVICES, sizeof (cl_uint),
433 			&device_count, NULL));
434 
435   /* Get the sizes of the binaries.  */
436   sizes = (size_t*) malloc (sizeof (size_t) * device_count);
437   if (sizes == NULL)
438     {
439       fprintf (stderr, "malloc failed\n");
440       exit (EXIT_FAILURE);
441     }
442   CHK (clGetProgramInfo (program, CL_PROGRAM_BINARY_SIZES, sizeof (sizes),
443 			 sizes, NULL));
444 
445   /* Get the binaries.  */
446   binaries
447     = (unsigned char **) malloc (sizeof (unsigned char *) * device_count);
448   if (binaries == NULL)
449     {
450       fprintf (stderr, "malloc failed\n");
451       exit (EXIT_FAILURE);
452     }
453   for (i = 0; i < device_count; i++)
454     {
455       binaries[i] = (unsigned char *) malloc (sizes[i]);
456       if (binaries[i] == NULL)
457 	{
458 	  fprintf (stderr, "malloc failed\n");
459 	  exit (EXIT_FAILURE);
460 	}
461     }
462   CHK (clGetProgramInfo (program, CL_PROGRAM_BINARIES, sizeof (binaries),
463 			 binaries, NULL));
464 
465   /* Get the devices for the given program to extract the file names.  */
466   devices = (cl_device_id*) malloc (sizeof (cl_device_id) * device_count);
467   if (devices == NULL)
468     {
469       fprintf (stderr, "malloc failed\n");
470       exit (EXIT_FAILURE);
471     }
472   CHK (clGetProgramInfo (program, CL_PROGRAM_DEVICES, sizeof (devices),
473 			 devices, NULL));
474 
475   for (i = 0; i < device_count; i++)
476     {
477       FILE *fd;
478       char *dev_name = NULL;
479       size_t len;
480       CHK (clGetDeviceInfo (devices[i], CL_DEVICE_NAME, 0, NULL, &len));
481       dev_name = malloc (len);
482       if (dev_name == NULL)
483 	{
484 	  fprintf (stderr, "malloc failed\n");
485 	  exit (EXIT_FAILURE);
486 	}
487       CHK (clGetDeviceInfo (devices[i], CL_DEVICE_NAME, len, dev_name, NULL));
488       /* Convert spaces to underscores.  */
489       for (j = 0; j < strlen (dev_name); j++)
490 	{
491 	  if (dev_name[j] == ' ')
492 	    dev_name[j] = '_';
493 	}
494 
495       /*  Save the binaries.  */
496       printf ("saving program binary for device: %s\n", dev_name);
497       /* Save binaries[i].  */
498       fd = fopen (dev_name, "w");
499       if (fd == NULL)
500 	{
501 	  perror ("fopen failed");
502 	  exit (EXIT_FAILURE);
503 	}
504       if (fwrite (binaries[i], sizes[i], 1, fd) != 1)
505 	{
506 	  fprintf (stderr, "fwrite failed\n");
507 	  for (j = i; j < device_count; j++)
508 	    free (binaries[j]);
509 	  fclose (fd);
510 	  exit (EXIT_FAILURE);
511 	}
512       fclose (fd);
513       free (binaries[i]);
514       free (dev_name);
515       free (sizes);
516     }
517   free (devices);
518   free (binaries);
519 }
520