Home | History | Annotate | Line # | Download | only in lib
cl_util.c revision 1.6
      1 /* This testcase is part of GDB, the GNU debugger.
      2 
      3    Copyright 2010-2016 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 (at) 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