aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/lib
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/testsuite/lib')
-rw-r--r--gdb/testsuite/lib/cl_util.c519
-rw-r--r--gdb/testsuite/lib/cl_util.h88
-rw-r--r--gdb/testsuite/lib/opencl.exp83
-rw-r--r--gdb/testsuite/lib/opencl_hostapp.c168
-rw-r--r--gdb/testsuite/lib/opencl_kernel.cl5
5 files changed, 863 insertions, 0 deletions
diff --git a/gdb/testsuite/lib/cl_util.c b/gdb/testsuite/lib/cl_util.c
new file mode 100644
index 0000000..5b731b2
--- /dev/null
+++ b/gdb/testsuite/lib/cl_util.c
@@ -0,0 +1,519 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ Contributed by Ken Werner <ken.werner@de.ibm.com> */
+
+/* Utility macros and functions for OpenCL applications. */
+
+#include "cl_util.h"
+
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <string.h>
+
+const char *get_clerror_string (int errcode)
+{
+ switch (errcode)
+ {
+ case CL_SUCCESS:
+ return "CL_SUCCESS";
+ case CL_DEVICE_NOT_FOUND:
+ return "CL_DEVICE_NOT_FOUND";
+ case CL_DEVICE_NOT_AVAILABLE:
+ return "CL_DEVICE_NOT_AVAILABLE";
+ case CL_COMPILER_NOT_AVAILABLE:
+ return "CL_COMPILER_NOT_AVAILABLE";
+ case CL_MEM_OBJECT_ALLOCATION_FAILURE:
+ return "CL_MEM_OBJECT_ALLOCATION_FAILURE";
+ case CL_OUT_OF_RESOURCES:
+ return "CL_OUT_OF_RESOURCES";
+ case CL_OUT_OF_HOST_MEMORY:
+ return "CL_OUT_OF_HOST_MEMORY";
+ case CL_PROFILING_INFO_NOT_AVAILABLE:
+ return "CL_PROFILING_INFO_NOT_AVAILABLE";
+ case CL_MEM_COPY_OVERLAP:
+ return "CL_MEM_COPY_OVERLAP";
+ case CL_IMAGE_FORMAT_MISMATCH:
+ return "CL_IMAGE_FORMAT_MISMATCH";
+ case CL_IMAGE_FORMAT_NOT_SUPPORTED:
+ return "CL_IMAGE_FORMAT_NOT_SUPPORTED";
+ case CL_BUILD_PROGRAM_FAILURE:
+ return "CL_BUILD_PROGRAM_FAILURE";
+ case CL_MAP_FAILURE:
+ return "CL_MAP_FAILURE";
+ case CL_INVALID_VALUE:
+ return "CL_INVALID_VALUE";
+ case CL_INVALID_DEVICE_TYPE:
+ return "CL_INVALID_DEVICE_TYPE";
+ case CL_INVALID_PLATFORM:
+ return "CL_INVALID_PLATFORM";
+ case CL_INVALID_DEVICE:
+ return "CL_INVALID_DEVICE";
+ case CL_INVALID_CONTEXT:
+ return "CL_INVALID_CONTEXT";
+ case CL_INVALID_QUEUE_PROPERTIES:
+ return "CL_INVALID_QUEUE_PROPERTIES";
+ case CL_INVALID_COMMAND_QUEUE:
+ return "CL_INVALID_COMMAND_QUEUE";
+ case CL_INVALID_HOST_PTR:
+ return "CL_INVALID_HOST_PTR";
+ case CL_INVALID_MEM_OBJECT:
+ return "CL_INVALID_MEM_OBJECT";
+ case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR:
+ return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR";
+ case CL_INVALID_IMAGE_SIZE:
+ return "CL_INVALID_IMAGE_SIZE";
+ case CL_INVALID_SAMPLER:
+ return "CL_INVALID_SAMPLER";
+ case CL_INVALID_BINARY:
+ return "CL_INVALID_BINARY";
+ case CL_INVALID_BUILD_OPTIONS:
+ return "CL_INVALID_BUILD_OPTIONS";
+ case CL_INVALID_PROGRAM:
+ return "CL_INVALID_PROGRAM";
+ case CL_INVALID_PROGRAM_EXECUTABLE:
+ return "CL_INVALID_PROGRAM_EXECUTABLE";
+ case CL_INVALID_KERNEL_NAME:
+ return "CL_INVALID_KERNEL_NAME";
+ case CL_INVALID_KERNEL_DEFINITION:
+ return "CL_INVALID_KERNEL_DEFINITION";
+ case CL_INVALID_KERNEL:
+ return "CL_INVALID_KERNEL";
+ case CL_INVALID_ARG_INDEX:
+ return "CL_INVALID_ARG_INDEX";
+ case CL_INVALID_ARG_VALUE:
+ return "CL_INVALID_ARG_VALUE";
+ case CL_INVALID_ARG_SIZE:
+ return "CL_INVALID_ARG_SIZE";
+ case CL_INVALID_KERNEL_ARGS:
+ return "CL_INVALID_KERNEL_ARGS";
+ case CL_INVALID_WORK_DIMENSION:
+ return "CL_INVALID_WORK_DIMENSION";
+ case CL_INVALID_WORK_GROUP_SIZE:
+ return "CL_INVALID_WORK_GROUP_SIZE";
+ case CL_INVALID_WORK_ITEM_SIZE:
+ return "CL_INVALID_WORK_ITEM_SIZE";
+ case CL_INVALID_GLOBAL_OFFSET:
+ return "CL_INVALID_GLOBAL_OFFSET";
+ case CL_INVALID_EVENT_WAIT_LIST:
+ return "CL_INVALID_EVENT_WAIT_LIST";
+ case CL_INVALID_EVENT:
+ return "CL_INVALID_EVENT";
+ case CL_INVALID_OPERATION:
+ return "CL_INVALID_OPERATION";
+ case CL_INVALID_GL_OBJECT:
+ return "CL_INVALID_GL_OBJECT";
+ case CL_INVALID_BUFFER_SIZE:
+ return "CL_INVALID_BUFFER_SIZE";
+ case CL_INVALID_MIP_LEVEL:
+ return "CL_INVALID_MIP_LEVEL";
+#ifndef CL_PLATFORM_NVIDIA
+ case CL_INVALID_GLOBAL_WORK_SIZE:
+ return "CL_INVALID_GLOBAL_WORK_SIZE";
+#endif
+ default:
+ return "Unknown";
+ };
+}
+
+
+void print_clinfo ()
+{
+ char *s = NULL;
+ size_t len;
+ unsigned i, j;
+ cl_uint platform_count;
+ cl_platform_id *platforms;
+
+ /* Determine number of OpenCL Platforms available. */
+ clGetPlatformIDs (0, NULL, &platform_count);
+ printf ("number of OpenCL Platforms available:\t%d\n", platform_count);
+ /* Get platforms. */
+ platforms
+ = (cl_platform_id*) malloc (sizeof (cl_platform_id) * platform_count);
+ if (platforms == NULL)
+ {
+ fprintf (stderr, "malloc failed\n");
+ exit (EXIT_FAILURE);
+ }
+ clGetPlatformIDs (platform_count, platforms, NULL);
+
+ /* Querying platforms. */
+ for (i = 0; i < platform_count; i++)
+ {
+ cl_device_id *devices;
+ cl_uint device_count;
+ cl_device_id default_dev;
+ printf (" OpenCL Platform: %d\n", i);
+
+#define PRINT_PF_INFO(PARM)\
+ clGetPlatformInfo (platforms[i], PARM, 0, NULL, &len); \
+ s = realloc (s, len); \
+ clGetPlatformInfo (platforms[i], PARM, len, s, NULL); \
+ printf (" %-36s%s\n", #PARM ":", s);
+
+ PRINT_PF_INFO (CL_PLATFORM_PROFILE)
+ PRINT_PF_INFO (CL_PLATFORM_VERSION)
+ PRINT_PF_INFO (CL_PLATFORM_NAME)
+ PRINT_PF_INFO (CL_PLATFORM_VENDOR)
+ PRINT_PF_INFO (CL_PLATFORM_EXTENSIONS)
+#undef PRINT_PF_INFO
+
+ clGetDeviceIDs (platforms[i], CL_DEVICE_TYPE_DEFAULT, 1, &default_dev,
+ NULL);
+ clGetDeviceInfo (default_dev, CL_DEVICE_NAME, 0, NULL, &len);
+ s = realloc (s, len);
+ clGetDeviceInfo (default_dev, CL_DEVICE_NAME, len, s, NULL);
+ printf (" CL_DEVICE_TYPE_DEFAULT: %s\n", s);
+
+ /* Determine number of devices. */
+ clGetDeviceIDs (platforms[i], CL_DEVICE_TYPE_ALL, 0, NULL, &device_count);
+ printf ("\n number of OpenCL Devices available: %d\n", device_count);
+ /* Get devices. */
+ devices = (cl_device_id*) malloc (sizeof (cl_device_id) * device_count);
+ if (devices == NULL)
+ {
+ fprintf (stderr, "malloc failed\n");
+ exit (EXIT_FAILURE);
+ }
+ clGetDeviceIDs (platforms[i], CL_DEVICE_TYPE_ALL, device_count, devices,
+ NULL);
+
+ /* Querying devices. */
+ for (j = 0; j < device_count; j++)
+ {
+ cl_device_type dtype;
+ cl_device_mem_cache_type mctype;
+ cl_device_local_mem_type mtype;
+ cl_device_fp_config fpcfg;
+ cl_device_exec_capabilities xcap;
+ cl_command_queue_properties qprops;
+ cl_bool clbool;
+ cl_uint cluint;
+ cl_ulong clulong;
+ size_t sizet;
+ size_t workitem_size[3];
+ printf (" OpenCL Device: %d\n", j);
+
+#define PRINT_DEV_INFO(PARM)\
+ clGetDeviceInfo (devices[j], PARM, 0, NULL, &len); \
+ s = realloc (s, len); \
+ clGetDeviceInfo (devices[j], PARM, len, s, NULL); \
+ printf (" %-41s%s\n", #PARM ":", s);
+
+ PRINT_DEV_INFO (CL_DEVICE_NAME)
+ PRINT_DEV_INFO (CL_DRIVER_VERSION)
+ PRINT_DEV_INFO (CL_DEVICE_VENDOR)
+ clGetDeviceInfo (devices[j], CL_DEVICE_VENDOR_ID, sizeof (cluint),
+ &cluint, NULL);
+ printf (" CL_DEVICE_VENDOR_ID: %d\n", cluint);
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_TYPE, sizeof (dtype), &dtype, NULL);
+ if (dtype & CL_DEVICE_TYPE_CPU)
+ printf (" CL_DEVICE_TYPE: CL_DEVICE_TYPE_CPU\n");
+ if (dtype & CL_DEVICE_TYPE_GPU)
+ printf (" CL_DEVICE_TYPE: CL_DEVICE_TYPE_GPU\n");
+ if (dtype & CL_DEVICE_TYPE_ACCELERATOR)
+ printf (" CL_DEVICE_TYPE: CL_DEVICE_TYPE_ACCELERATOR\n");
+ if (dtype & CL_DEVICE_TYPE_DEFAULT)
+ printf (" CL_DEVICE_TYPE: CL_DEVICE_TYPE_DEFAULT\n");
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_MAX_CLOCK_FREQUENCY: %d\n", cluint);
+
+ PRINT_DEV_INFO (CL_DEVICE_PROFILE)
+ PRINT_DEV_INFO (CL_DEVICE_EXTENSIONS)
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_AVAILABLE, sizeof (clbool), &clbool, NULL);
+ if (clbool == CL_TRUE)
+ printf (" CL_DEVICE_AVAILABLE: CL_TRUE\n");
+ else
+ printf (" CL_DEVICE_AVAILABLE: CL_FALSE\n");
+ clGetDeviceInfo (devices[j], CL_DEVICE_ENDIAN_LITTLE, sizeof (clbool), &clbool, NULL);
+ if (clbool == CL_TRUE)
+ printf (" CL_DEVICE_ENDIAN_LITTLE: CL_TRUE\n");
+ else
+ printf (" CL_DEVICE_ENDIAN_LITTLE: CL_FALSE\n");
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_MAX_COMPUTE_UNITS: %d\n", cluint);
+ clGetDeviceInfo (devices[j], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof (sizet), &sizet, NULL);
+ printf (" CL_DEVICE_MAX_WORK_GROUP_SIZE: %d\n", sizet);
+ clGetDeviceInfo (devices[j], CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: %d\n", cluint);
+ clGetDeviceInfo (devices[j], CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof (workitem_size), &workitem_size, NULL);
+ printf (" CL_DEVICE_MAX_WORK_ITEM_SIZES: %d / %d / %d\n", workitem_size[0], workitem_size[1], workitem_size[2]);
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_ADDRESS_BITS, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_ADDRESS_BITS: %d\n", cluint);
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof (clulong), &clulong, NULL);
+ printf (" CL_DEVICE_MAX_MEM_ALLOC_SIZE: %llu\n", clulong);
+ clGetDeviceInfo (devices[j], CL_DEVICE_MEM_BASE_ADDR_ALIGN, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_MEM_BASE_ADDR_ALIGN: %d\n", cluint);
+ clGetDeviceInfo(devices[j], CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE: %d\n", cluint);
+ clGetDeviceInfo(devices[j], CL_DEVICE_MAX_PARAMETER_SIZE, sizeof (sizet), &sizet, NULL);
+ printf (" CL_DEVICE_MAX_PARAMETER_SIZE: %d\n", sizet);
+ clGetDeviceInfo(devices[j], CL_DEVICE_GLOBAL_MEM_SIZE, sizeof (clulong), &clulong, NULL);
+ printf (" CL_DEVICE_GLOBAL_MEM_SIZE: %llu\n", clulong);
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, sizeof (mctype), &mctype, NULL);
+ if (mctype & CL_NONE)
+ printf (" CL_DEVICE_GLOBAL_MEM_CACHE_TYPE: CL_NONE\n");
+ if (mctype & CL_READ_ONLY_CACHE)
+ printf (" CL_DEVICE_GLOBAL_MEM_CACHE_TYPE: CL_READ_ONLY_CACHE\n");
+ if (mctype & CL_READ_WRITE_CACHE)
+ printf (" CL_DEVICE_GLOBAL_MEM_CACHE_TYPE: CL_READ_WRITE_CACHE\n");
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, sizeof (clulong), &clulong, NULL);
+ printf (" CL_DEVICE_GLOBAL_MEM_CACHE_SIZE: %llu\n", clulong);
+ clGetDeviceInfo (devices[j], CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE: %d\n", cluint);
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_LOCAL_MEM_TYPE, sizeof (mtype), &mtype, NULL);
+ if (mtype & CL_LOCAL)
+ printf (" CL_DEVICE_LOCAL_MEM_TYPE: CL_LOCAL\n");
+ if (mtype & CL_GLOBAL)
+ printf (" CL_DEVICE_LOCAL_MEM_TYPE: CL_GLOBAL\n");
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE: %d\n", cluint);
+ clGetDeviceInfo (devices[j], CL_DEVICE_MEM_BASE_ADDR_ALIGN, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_MEM_BASE_ADDR_ALIGN: %d\n", cluint);
+ clGetDeviceInfo (devices[j], CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR: %d\n", cluint);
+ clGetDeviceInfo (devices[j], CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT: %d\n", cluint);
+ clGetDeviceInfo (devices[j], CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT: %d\n", cluint);
+ clGetDeviceInfo (devices[j], CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG: %d\n", cluint);
+ clGetDeviceInfo (devices[j], CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT: %d\n", cluint);
+ clGetDeviceInfo (devices[j], CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE: %d\n", cluint);
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_SINGLE_FP_CONFIG, sizeof (fpcfg), &fpcfg, NULL);
+ if (fpcfg & CL_FP_DENORM)
+ printf (" CL_DEVICE_SINGLE_FP_CONFIG: CL_FP_DENORM\n");
+ if (fpcfg & CL_FP_INF_NAN)
+ printf (" CL_DEVICE_SINGLE_FP_CONFIG: CL_FP_INF_NAN\n");
+ if (fpcfg & CL_FP_ROUND_TO_NEAREST)
+ printf (" CL_DEVICE_SINGLE_FP_CONFIG: CL_FP_ROUND_TO_NEAREST\n");
+ if (fpcfg & CL_FP_ROUND_TO_ZERO)
+ printf (" CL_DEVICE_SINGLE_FP_CONFIG: CL_FP_ROUND_TO_ZERO\n");
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_EXECUTION_CAPABILITIES, sizeof (xcap), &xcap, NULL);
+ if (xcap & CL_EXEC_KERNEL )
+ printf (" CL_DEVICE_EXECUTION_CAPABILITIES: CL_EXEC_KERNEL\n");
+ if (xcap & CL_EXEC_NATIVE_KERNEL)
+ printf (" CL_DEVICE_EXECUTION_CAPABILITIES: CL_EXEC_NATIVE_KERNEL\n");
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_QUEUE_PROPERTIES, sizeof (qprops), &qprops, NULL);
+ if (qprops & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE)
+ printf (" CL_DEVICE_QUEUE_PROPERTIES: CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE\n");
+ if (qprops & CL_QUEUE_PROFILING_ENABLE)
+ printf (" CL_DEVICE_QUEUE_PROPERTIES: CL_QUEUE_PROFILING_ENABLE\n");
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_PROFILING_TIMER_RESOLUTION, sizeof (sizet), &sizet, NULL);
+ printf (" CL_DEVICE_PROFILING_TIMER_RESOLUTION: %d\n", sizet);
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_COMPILER_AVAILABLE, sizeof (clbool), &clbool, NULL);
+ if (clbool == CL_TRUE)
+ printf (" CL_DEVICE_COMPILER_AVAILABLE: CL_TRUE\n");
+ else
+ printf (" CL_DEVICE_COMPILER_AVAILABLE: CL_FALSE\n");
+ clGetDeviceInfo (devices[j], CL_DEVICE_ERROR_CORRECTION_SUPPORT, sizeof (clbool), &clbool, NULL);
+ if (clbool == CL_TRUE)
+ printf (" CL_DEVICE_ERROR_CORRECTION_SUPPORT: CL_TRUE\n");
+ else
+ printf (" CL_DEVICE_ERROR_CORRECTION_SUPPORT: CL_FALSE\n");
+
+ clGetDeviceInfo (devices[j], CL_DEVICE_IMAGE_SUPPORT, sizeof (clbool), &clbool, NULL);
+ if (clbool == CL_FALSE)
+ {
+ printf (" CL_DEVICE_IMAGE_SUPPORT: CL_FALSE\n");
+ }
+ else
+ {
+ printf (" CL_DEVICE_IMAGE_SUPPORT: CL_TRUE\n");
+ clGetDeviceInfo (devices[j], CL_DEVICE_MAX_SAMPLERS, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_MAX_SAMPLERS: %d\n", cluint);
+ clGetDeviceInfo (devices[j], CL_DEVICE_MAX_READ_IMAGE_ARGS, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_MAX_READ_IMAGE_ARGS: %d\n", cluint);
+ clGetDeviceInfo (devices[j], CL_DEVICE_MAX_WRITE_IMAGE_ARGS, sizeof (cluint), &cluint, NULL);
+ printf (" CL_DEVICE_MAX_WRITE_IMAGE_ARGS: %d\n", cluint);
+ clGetDeviceInfo (devices[j], CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof (sizet), &sizet, NULL);
+ printf (" CL_DEVICE_IMAGE2D_MAX_WIDTH: %d\n", sizet);
+ clGetDeviceInfo (devices[j], CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof (sizet), &sizet, NULL);
+ printf (" CL_DEVICE_IMAGE2D_MAX_HEIGHT: %d\n", sizet);
+ clGetDeviceInfo (devices[j], CL_DEVICE_IMAGE3D_MAX_WIDTH, sizeof (sizet), &sizet, NULL);
+ printf (" CL_DEVICE_IMAGE3D_MAX_WIDTH: %d\n", sizet);
+ clGetDeviceInfo (devices[j], CL_DEVICE_IMAGE3D_MAX_HEIGHT, sizeof (sizet), &sizet, NULL);
+ printf (" CL_DEVICE_IMAGE3D_MAX_HEIGHT: %d\n", sizet);
+ clGetDeviceInfo (devices[j], CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof (sizet), &sizet, NULL);
+ printf (" CL_DEVICE_IMAGE3D_MAX_DEPTH: %d\n", sizet);
+ }
+#undef PRINT_DEV_INFO
+ } /* devices */
+ free (devices);
+ } /* platforms */
+ free (s);
+ free (platforms);
+}
+
+
+const char *
+read_file (const char * const filename, size_t *size)
+{
+ char *buf = NULL;
+ FILE *fd;
+ struct stat st;
+ if (stat (filename, &st) == -1)
+ {
+ /* Check if the file exists. */
+ if (errno == ENOENT)
+ return buf;
+ perror ("stat failed");
+ exit (EXIT_FAILURE);
+ }
+ buf = (char *) malloc (st.st_size);
+ if (buf == NULL)
+ {
+ fprintf (stderr, "malloc failed\n");
+ exit (EXIT_FAILURE);
+ }
+ fd = fopen (filename, "r");
+ if (fd == NULL)
+ {
+ perror ("fopen failed");
+ free (buf);
+ exit (EXIT_FAILURE);
+ }
+ if (fread (buf, st.st_size, 1, fd) != 1)
+ {
+ fprintf (stderr, "fread failed\n");
+ free (buf);
+ fclose (fd);
+ exit (EXIT_FAILURE);
+ }
+ fclose (fd);
+ *size = st.st_size;
+ return buf;
+}
+
+
+void
+save_program_binaries (cl_program program)
+{
+ cl_device_id *devices;
+ cl_uint device_count;
+ size_t *sizes;
+ unsigned char **binaries;
+ unsigned i, j;
+
+ /* Query the amount of devices for the given program. */
+ CHK (clGetProgramInfo (program, CL_PROGRAM_NUM_DEVICES, sizeof (cl_uint),
+ &device_count, NULL));
+
+ /* Get the sizes of the binaries. */
+ sizes = (size_t*) malloc (sizeof (size_t) * device_count);
+ if (sizes == NULL)
+ {
+ fprintf (stderr, "malloc failed\n");
+ exit (EXIT_FAILURE);
+ }
+ CHK (clGetProgramInfo (program, CL_PROGRAM_BINARY_SIZES, sizeof (sizes),
+ sizes, NULL));
+
+ /* Get the binaries. */
+ binaries
+ = (unsigned char **) malloc (sizeof (unsigned char *) * device_count);
+ if (binaries == NULL)
+ {
+ fprintf (stderr, "malloc failed\n");
+ exit (EXIT_FAILURE);
+ }
+ for (i = 0; i < device_count; i++)
+ {
+ binaries[i] = (unsigned char *) malloc (sizes[i]);
+ if (binaries[i] == NULL)
+ {
+ fprintf (stderr, "malloc failed\n");
+ exit (EXIT_FAILURE);
+ }
+ }
+ CHK (clGetProgramInfo (program, CL_PROGRAM_BINARIES, sizeof (binaries),
+ binaries, NULL));
+
+ /* Get the devices for the given program to extract the file names. */
+ devices = (cl_device_id*) malloc (sizeof (cl_device_id) * device_count);
+ if (devices == NULL)
+ {
+ fprintf (stderr, "malloc failed\n");
+ exit (EXIT_FAILURE);
+ }
+ CHK (clGetProgramInfo (program, CL_PROGRAM_DEVICES, sizeof (devices),
+ devices, NULL));
+
+ for (i = 0; i < device_count; i++)
+ {
+ FILE *fd;
+ char *dev_name = NULL;
+ size_t len;
+ CHK (clGetDeviceInfo (devices[i], CL_DEVICE_NAME, 0, NULL, &len));
+ dev_name = malloc (len);
+ if (dev_name == NULL)
+ {
+ fprintf (stderr, "malloc failed\n");
+ exit (EXIT_FAILURE);
+ }
+ CHK (clGetDeviceInfo (devices[i], CL_DEVICE_NAME, len, dev_name, NULL));
+ /* Convert spaces to underscores. */
+ for (j = 0; j < strlen (dev_name); j++)
+ {
+ if (dev_name[j] == ' ')
+ dev_name[j] = '_';
+ }
+
+ /* Save the binaries. */
+ printf ("saving program binary for device: %s\n", dev_name);
+ /* Save binaries[i]. */
+ fd = fopen (dev_name, "w");
+ if (fd == NULL)
+ {
+ perror ("fopen failed");
+ exit (EXIT_FAILURE);
+ }
+ if (fwrite (binaries[i], sizes[i], 1, fd) != 1)
+ {
+ fprintf (stderr, "fwrite failed\n");
+ for (j = i; j < device_count; j++)
+ free (binaries[j]);
+ fclose (fd);
+ exit (EXIT_FAILURE);
+ }
+ fclose (fd);
+ free (binaries[i]);
+ free (dev_name);
+ free (sizes);
+ }
+ free (devices);
+ free (binaries);
+}
diff --git a/gdb/testsuite/lib/cl_util.h b/gdb/testsuite/lib/cl_util.h
new file mode 100644
index 0000000..acdbc5d
--- /dev/null
+++ b/gdb/testsuite/lib/cl_util.h
@@ -0,0 +1,88 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ Contributed by Ken Werner <ken.werner@de.ibm.com> */
+
+/* Utility macros and functions for OpenCL applications. */
+
+#ifndef CL_UTIL_H
+#define CL_UTIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __APPLE__
+#include <OpenCL/opencl.h>
+#else
+#include <CL/cl.h>
+#endif
+#include <stdio.h>
+
+/* Executes the given OpenCL function and checks its return value.
+ In case of failure (rc != CL_SUCCESS) an error string will be
+ printed to stderr and the program will be terminated. This Macro
+ is only intended for OpenCL routines which return cl_int. */
+
+#define CHK(func)\
+{\
+ int rc = (func);\
+ CHK_ERR (#func, rc);\
+}
+
+/* Macro that checks an OpenCL error code. In case of failure
+ (err != CL_SUCCESS) an error string will be printed to stderr
+ including the prefix and the program will be terminated. This
+ Macro is only intended to use in conjunction with OpenCL routines
+ which take a pointer to a cl_int as an argument to place their
+ error code. */
+
+#define CHK_ERR(prefix, err)\
+if (err != CL_SUCCESS)\
+ {\
+ fprintf (stderr, "CHK_ERR (%s, %d)\n", prefix, err);\
+ fprintf (stderr, "%s:%d error: %s\n", __FILE__, __LINE__,\
+ get_clerror_string (err));\
+ exit (EXIT_FAILURE);\
+ };
+
+/* Return a pointer to a string that describes the error code specified
+ by the errcode argument. */
+
+extern const char *get_clerror_string (int errcode);
+
+/* Prints OpenCL information to stdout. */
+
+extern void print_clinfo ();
+
+/* Reads a given file into the memory and returns a pointer to the data or NULL
+ if the file does not exist. FILENAME specifies the location of the file to
+ be read. SIZE is an output parameter that returns the size of the file in
+ bytes. */
+
+extern const char *read_file (const char * const filename, size_t *size);
+
+/* Saves all program binaries of the given OpenCL PROGRAM. The file
+ names are extracted from the devices. */
+
+extern void save_program_binaries (cl_program program);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CL_UTIL_H */
diff --git a/gdb/testsuite/lib/opencl.exp b/gdb/testsuite/lib/opencl.exp
new file mode 100644
index 0000000..33d3688
--- /dev/null
+++ b/gdb/testsuite/lib/opencl.exp
@@ -0,0 +1,83 @@
+# Copyright 2010 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Contributed by Ken Werner <ken.werner@de.ibm.com>.
+#
+# Support library for testing OpenCL GDB features
+
+# Compile OpenCL programs using a generic host app.
+proc gdb_compile_opencl_hostapp {clsource executable options} {
+ global srcdir objdir subdir
+ set src "${srcdir}/lib/cl_util.c ${srcdir}/lib/opencl_hostapp.c"
+ set binfile ${objdir}/${subdir}/${executable}
+ set compile_flags [concat additional_flags=-I${srcdir}/lib/ additional_flags=-DCL_SOURCE=$clsource]
+ set options_opencl [concat {debug} $compile_flags $options [list libs=-lOpenCL]]
+ return [gdb_compile ${src} ${binfile} "executable" ${options_opencl}]
+}
+
+# Run a test on the target to check if it supports OpenCL. Return 0 if so, 1 if
+# it does not.
+proc skip_opencl_tests {} {
+ global skip_opencl_tests_saved srcdir objdir subdir gdb_prompt
+
+ # Use the cached value, if it exists. Cache value per "board" to handle
+ # runs with multiple options (e.g. unix/{-m32,-64}) correctly.
+ set me "skip_opencl_tests"
+ set board [target_info name]
+ if [info exists skip_opencl_tests_saved($board)] {
+ verbose "$me: returning saved $skip_opencl_tests_saved($board)" 2
+ return $skip_opencl_tests_saved($board)
+ }
+
+ # Set up, compile, and execute an OpenCL program. Include the current
+ # process ID in the file name of the executable to prevent conflicts with
+ # invocations for multiple testsuites.
+ set clprogram [remote_download target ${srcdir}/lib/opencl_kernel.cl]
+ set executable opencltest[pid].x
+
+ verbose "$me: compiling OpenCL test app" 2
+ set compile_flags {debug nowarnings quiet}
+
+ if { [gdb_compile_opencl_hostapp "${clprogram}" "${executable}" "" ] != "" } {
+ verbose "$me: compiling OpenCL binary failed, returning 1" 2
+ return [set skip_opencl_tests_saved($board) 1]
+ }
+
+ # Compilation succeeded so now run it via gdb.
+ clean_restart "$executable"
+ gdb_run_cmd
+ gdb_expect 30 {
+ -re ".*Program exited normally.*${gdb_prompt} $" {
+ verbose -log "\n$me: OpenCL support detected"
+ set skip_opencl_tests_saved($board) 0
+ }
+ -re ".*Program exited with code.*${gdb_prompt} $" {
+ verbose -log "\n$me: OpenCL support not detected"
+ set skip_opencl_tests_saved($board) 1
+ }
+ default {
+ verbose -log "\n$me OpenCL support not detected (default case)"
+ set skip_opencl_tests_saved($board) 1
+ }
+ }
+ gdb_exit
+ remote_file build delete $executable
+
+ # Delete the OpenCL program source file.
+ remote_file target delete ${clprogram}
+
+ verbose "$me: returning $skip_opencl_tests_saved($board)" 2
+ return $skip_opencl_tests_saved($board)
+}
diff --git a/gdb/testsuite/lib/opencl_hostapp.c b/gdb/testsuite/lib/opencl_hostapp.c
new file mode 100644
index 0000000..4bc9658
--- /dev/null
+++ b/gdb/testsuite/lib/opencl_hostapp.c
@@ -0,0 +1,168 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ Contributed by Ken Werner <ken.werner@de.ibm.com> */
+
+/* Simple OpenCL application that executes a kernel on the default device
+ in a data parallel fashion. The filename of the OpenCL program source
+ should be specified using the CL_SOURCE define. The name of the kernel
+ routine is expected to be "testkernel". */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <CL/cl.h>
+#include "cl_util.h"
+
+#ifndef CL_SOURCE
+#error "Please specify the OpenCL source file using the CL_SOURCE define"
+#endif
+
+#define STRINGIFY(S) _STRINGIFY(S)
+#define _STRINGIFY(S) #S
+
+#define SIZE 16
+
+int
+main ()
+{
+ int err, i;
+ cl_platform_id platform;
+ cl_device_id device;
+ cl_context context;
+ cl_context_properties context_props[3];
+ cl_command_queue queue;
+ cl_program program;
+ cl_kernel kernel;
+ cl_mem buffer;
+
+ size_t len;
+ const char *program_source = NULL;
+ char *device_extensions = NULL;
+ char kernel_build_opts[256];
+ size_t size = sizeof (cl_int) * SIZE;
+ const size_t global_work_size[] = {SIZE, 0, 0}; /* size of each dimension */
+ cl_int *data;
+
+ /* In order to see which devices the OpenCL implementation on your platform
+ provides you may issue a call to the print_clinfo () fuction. */
+
+ /* Initialize the data the OpenCl program operates on. */
+ data = (cl_int*) calloc (1, size);
+ if (data == NULL)
+ {
+ fprintf (stderr, "calloc failed\n");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Pick the first platform. */
+ CHK (clGetPlatformIDs (1, &platform, NULL));
+ /* Get the default device and create context. */
+ CHK (clGetDeviceIDs (platform, CL_DEVICE_TYPE_DEFAULT, 1, &device, NULL));
+ context_props[0] = CL_CONTEXT_PLATFORM;
+ context_props[1] = (cl_context_properties) platform;
+ context_props[2] = 0;
+ context = clCreateContext (context_props, 1, &device, NULL, NULL, &err);
+ CHK_ERR ("clCreateContext", err);
+ queue = clCreateCommandQueue (context, device, 0, &err);
+ CHK_ERR ("clCreateCommandQueue", err);
+
+ /* Query OpenCL extensions of that device. */
+ CHK (clGetDeviceInfo (device, CL_DEVICE_EXTENSIONS, 0, NULL, &len));
+ device_extensions = (char *) malloc (len);
+ CHK (clGetDeviceInfo (device, CL_DEVICE_EXTENSIONS, len, device_extensions,
+ NULL));
+ strcpy (kernel_build_opts, "-Werror -cl-opt-disable");
+ if (strstr (device_extensions, "cl_khr_fp64") != NULL)
+ strcpy (kernel_build_opts + strlen (kernel_build_opts),
+ " -D HAVE_cl_khr_fp64");
+ if (strstr (device_extensions, "cl_khr_fp16") != NULL)
+ strcpy (kernel_build_opts + strlen (kernel_build_opts),
+ " -D HAVE_cl_khr_fp16");
+
+ /* Read the OpenCL kernel source into the main memory. */
+ program_source = read_file (STRINGIFY (CL_SOURCE), &len);
+ if (program_source == NULL)
+ {
+ fprintf (stderr, "file does not exist: %s\n", STRINGIFY (CL_SOURCE));
+ exit (EXIT_FAILURE);
+ }
+
+ /* Build the OpenCL kernel. */
+ program = clCreateProgramWithSource (context, 1, &program_source,
+ &len, &err);
+ free ((void*) program_source);
+ CHK_ERR ("clCreateProgramWithSource", err);
+ err = clBuildProgram (program, 0, NULL, kernel_build_opts, NULL,
+ NULL);
+ if (err != CL_SUCCESS)
+ {
+ size_t len;
+ char *clbuild_log = NULL;
+ CHK (clGetProgramBuildInfo (program, device, CL_PROGRAM_BUILD_LOG, 0,
+ NULL, &len));
+ clbuild_log = malloc (len);
+ if (clbuild_log)
+ {
+ CHK (clGetProgramBuildInfo (program, device, CL_PROGRAM_BUILD_LOG,
+ len, clbuild_log, NULL));
+ fprintf (stderr, "clBuildProgram failed with:\n%s\n", clbuild_log);
+ free (clbuild_log);
+ }
+ exit (EXIT_FAILURE);
+ }
+
+ /* In some cases it might be handy to save the OpenCL program binaries to do
+ further analysis on them. In order to do so you may call the following
+ function: save_program_binaries (program);. */
+
+ kernel = clCreateKernel (program, "testkernel", &err);
+ CHK_ERR ("clCreateKernel", err);
+
+ /* Setup the input data for the kernel. */
+ buffer = clCreateBuffer (context, CL_MEM_USE_HOST_PTR, size, data, &err);
+ CHK_ERR ("clCreateBuffer", err);
+
+ /* Execute the kernel (data parallel). */
+ CHK (clSetKernelArg (kernel, 0, sizeof (buffer), &buffer));
+ CHK (clEnqueueNDRangeKernel (queue, kernel, 1, NULL, global_work_size, NULL,
+ 0, NULL, NULL));
+
+ /* Fetch the results (blocking). */
+ CHK (clEnqueueReadBuffer (queue, buffer, CL_TRUE, 0, size, data, 0, NULL,
+ NULL));
+
+ /* Compare the results. */
+ for (i = 0; i < SIZE; i++)
+ {
+ if (data[i] != 0x1)
+ {
+ fprintf (stderr, "error: data[%d]: %d != 0x1\n", i, data[i]);
+ exit (EXIT_FAILURE);
+ }
+ }
+
+ /* Cleanup. */
+ CHK (clReleaseMemObject (buffer));
+ CHK (clReleaseKernel (kernel));
+ CHK (clReleaseProgram (program));
+ CHK (clReleaseCommandQueue (queue));
+ CHK (clReleaseContext (context));
+ free (data);
+
+ return 0;
+}
diff --git a/gdb/testsuite/lib/opencl_kernel.cl b/gdb/testsuite/lib/opencl_kernel.cl
new file mode 100644
index 0000000..32cba64
--- /dev/null
+++ b/gdb/testsuite/lib/opencl_kernel.cl
@@ -0,0 +1,5 @@
+/* OpenCL kernel for testing purposes. */
+__kernel void testkernel (__global int *data)
+{
+ data[get_global_id(0)] = 0x1;
+}